using System; using System.Collections; using System.Text; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Utilities; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.X509.Extension; namespace Org.BouncyCastle.X509 { /** * The following extensions are listed in RFC 2459 as relevant to CRL Entries * * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer * (critical) */ public class X509CrlEntry : X509ExtensionBase { private CrlEntry c; private bool isIndirect; private X509Name previousCertificateIssuer; private X509Name certificateIssuer; private volatile bool hashValueSet; private volatile int hashValue; public X509CrlEntry( CrlEntry c) { this.c = c; this.certificateIssuer = loadCertificateIssuer(); } /** * Constructor for CRLEntries of indirect CRLs. If isIndirect * is false {@link #getCertificateIssuer()} will always * return null, previousCertificateIssuer is * ignored. If this isIndirect is specified and this CrlEntry * has no certificate issuer CRL entry extension * previousCertificateIssuer is returned by * {@link #getCertificateIssuer()}. * * @param c * TbsCertificateList.CrlEntry object. * @param isIndirect * true if the corresponding CRL is a indirect * CRL. * @param previousCertificateIssuer * Certificate issuer of the previous CrlEntry. */ public X509CrlEntry( CrlEntry c, bool isIndirect, X509Name previousCertificateIssuer) { this.c = c; this.isIndirect = isIndirect; this.previousCertificateIssuer = previousCertificateIssuer; this.certificateIssuer = loadCertificateIssuer(); } private X509Name loadCertificateIssuer() { if (!isIndirect) { return null; } Asn1OctetString ext = GetExtensionValue(X509Extensions.CertificateIssuer); if (ext == null) { return previousCertificateIssuer; } try { GeneralName[] names = GeneralNames.GetInstance( X509ExtensionUtilities.FromExtensionValue(ext)).GetNames(); for (int i = 0; i < names.Length; i++) { if (names[i].TagNo == GeneralName.DirectoryName) { return X509Name.GetInstance(names[i].Name); } } } catch (Exception) { } return null; } public X509Name GetCertificateIssuer() { return certificateIssuer; } protected override X509Extensions GetX509Extensions() { return c.Extensions; } public byte[] GetEncoded() { try { return c.GetDerEncoded(); } catch (Exception e) { throw new CrlException(e.ToString()); } } public BigInteger SerialNumber { get { return c.UserCertificate.Value; } } public DateTime RevocationDate { get { return c.RevocationDate.ToDateTime(); } } public bool HasExtensions { get { return c.Extensions != null; } } public override bool Equals(object other) { if (this == other) return true; X509CrlEntry that = other as X509CrlEntry; if (null == that) return false; if (this.hashValueSet && that.hashValueSet) { if (this.hashValue != that.hashValue) return false; } return this.c.Equals(that.c); } public override int GetHashCode() { if (!hashValueSet) { hashValue = this.c.GetHashCode(); hashValueSet = true; } return hashValue; } public override string ToString() { StringBuilder buf = new StringBuilder(); string nl = Platform.NewLine; buf.Append(" userCertificate: ").Append(this.SerialNumber).Append(nl); buf.Append(" revocationDate: ").Append(this.RevocationDate).Append(nl); buf.Append(" certificateIssuer: ").Append(this.GetCertificateIssuer()).Append(nl); X509Extensions extensions = c.Extensions; if (extensions != null) { IEnumerator e = extensions.ExtensionOids.GetEnumerator(); if (e.MoveNext()) { buf.Append(" crlEntryExtensions:").Append(nl); do { DerObjectIdentifier oid = (DerObjectIdentifier)e.Current; X509Extension ext = extensions.GetExtension(oid); if (ext.Value != null) { Asn1Object obj = X509ExtensionUtilities.FromExtensionValue(ext.Value); buf.Append(" critical(") .Append(ext.IsCritical) .Append(") "); try { if (oid.Equals(X509Extensions.ReasonCode)) { buf.Append(new CrlReason(DerEnumerated.GetInstance(obj))); } else if (oid.Equals(X509Extensions.CertificateIssuer)) { buf.Append("Certificate issuer: ").Append( GeneralNames.GetInstance((Asn1Sequence)obj)); } else { buf.Append(oid.Id); buf.Append(" value = ").Append(Asn1Dump.DumpAsString(obj)); } buf.Append(nl); } catch (Exception) { buf.Append(oid.Id); buf.Append(" value = ").Append("*****").Append(nl); } } else { buf.Append(nl); } } while (e.MoveNext()); } } return buf.ToString(); } } }