internal static int U2FTransportsFromAttnCert(X509ExtensionCollection exts) { var u2ftransports = 0; foreach (var ext in exts) { if (ext.Oid.Value.Equals("1.3.6.1.4.1.45724.2.1.1")) { using (var ms = new System.IO.MemoryStream(ext.RawData.ToArray())) { if (0x3 != ms.ReadByte()) { throw new Fido2VerificationException("Expected bit string"); } if (0x2 != ms.ReadByte()) { throw new Fido2VerificationException("Expected integer value"); } var unusedBits = ms.ReadByte(); // number of unused bits // https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-authenticator-transports-extension-v1.2-ps-20170411.html u2ftransports = ms.ReadByte(); // do something with this? } } } return(u2ftransports); }
public static X509ExtensionCollection DecodeX509Extensions(Byte[] rawData) { var extensions = new X509ExtensionCollection(); extensions.Decode(rawData); return(extensions); }
internal static (X509Certificate2 certificate, X509Certificate2Collection) GenerateCertificates(string name, string?testName = null) { X509Certificate2Collection chain = new X509Certificate2Collection(); X509ExtensionCollection extensions = new X509ExtensionCollection(); SubjectAlternativeNameBuilder builder = new SubjectAlternativeNameBuilder(); builder.AddDnsName(name); extensions.Add(builder.Build()); extensions.Add(s_eeConstraints); extensions.Add(s_eeKeyUsage); extensions.Add(s_tlsServerEku); CertificateAuthority.BuildPrivatePki( PkiOptions.IssuerRevocationViaCrl, out RevocationResponder responder, out CertificateAuthority root, out CertificateAuthority intermediate, out X509Certificate2 endEntity, subjectName: name, testName: testName, keySize: 2048, extensions: extensions); chain.Add(intermediate.CloneIssuerCert()); chain.Add(root.CloneIssuerCert()); responder.Dispose(); root.Dispose(); intermediate.Dispose(); return(endEntity, chain); }
public static IRfc3161TimestampRequest Create( byte[] messageHash, HashAlgorithmName hashAlgorithm, Oid requestedPolicyId, byte[] nonce, bool requestSignerCertificates, X509ExtensionCollection extensions) { if (messageHash == null) { throw new ArgumentNullException(nameof(messageHash)); } IRfc3161TimestampRequest iRfc3161TimestampRequest = null; #if IS_DESKTOP iRfc3161TimestampRequest = new Rfc3161TimestampRequestNet472Wrapper( messageHash, hashAlgorithm, requestedPolicyId, nonce, requestSignerCertificates, extensions); #else iRfc3161TimestampRequest = new Rfc3161TimestampRequestNetstandard21Wrapper( messageHash, hashAlgorithm, requestedPolicyId, nonce, requestSignerCertificates, extensions); #endif return(iRfc3161TimestampRequest); }
/// <summary> /// /// </summary> /// <param name="rawData"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="InvalidDataException"></exception> public static X509ExtensionCollection DecodeX509Extensions(Byte[] rawData) { if (rawData == null) { throw new ArgumentNullException("rawData"); } Asn1Reader asn = new Asn1Reader(rawData); if (asn.Tag != 48) { throw new InvalidDataException(); } X509ExtensionCollection exts = new X509ExtensionCollection(); if (!asn.MoveNext()) { throw new Asn1InvalidTagException(); } if (asn.NextOffset == 0) { return(exts); } do { exts.Add(DecodeX509Extension(asn.GetTagRawData())); } while (asn.MoveNextCurrentLevel()); return(exts); }
public static byte[] GetAppleAttestationExtensionValue(X509ExtensionCollection exts) { var appleExtension = exts.Cast <X509Extension>().FirstOrDefault(e => e.Oid !.Value is "1.2.840.113635.100.8.2"); if (appleExtension is null || appleExtension.RawData is null || appleExtension.RawData.Length < 0x26) { throw new Fido2VerificationException("Extension with OID 1.2.840.113635.100.8.2 not found on Apple attestation credCert"); } try { var appleAttestationASN = Asn1Element.Decode(appleExtension.RawData); appleAttestationASN.CheckTag(new Asn1Tag(UniversalTagNumber.Sequence, isConstructed: true)); appleAttestationASN.CheckExactSequenceLength(1); var appleAttestationASNSequence = appleAttestationASN[0]; appleAttestationASNSequence.CheckConstructed(); appleAttestationASNSequence.CheckExactSequenceLength(1); appleAttestationASNSequence[0].CheckTag(Asn1Tag.PrimitiveOctetString); return(appleAttestationASNSequence[0].GetOctetString()); } catch (Exception ex) { throw new Fido2VerificationException("Apple attestation extension has invalid data", ex); } }
/// <summary> /// Function determines whether the selected digital certificate was enrolled from a specified Certificate Template. /// Certificates enrolled from Certificate Templates are known as either "v1 certificates" or "v2 certificates" (depending on the template Version). /// </summary> /// <param name="x509Cert"> /// A digital certificate, passed in as an X509Certificate2 object. /// </param> /// <param name="template"> /// The certificate template to compare to the certificate. /// </param> /// <returns> /// Returns "true" if Certificate Template Information field matches specified string. /// Returns "false" if Certificate Template Information field does not exist or does not match. /// </returns> public static bool IsCertificateEnrolledFromSpecifiedTemplate( X509Certificate2 x509Cert, string template) { bool returnValue = false; X509ExtensionCollection extensions = x509Cert.Extensions; foreach (X509Extension extension in extensions) { // This determines that the digital certificate was enrolled from a v2 certificate template Trace.WriteLine("The extension's OID is " + extension.Oid.Value + Environment.NewLine); Trace.WriteLine("The extension's FriendlyName is " + extension.Oid.FriendlyName + Environment.NewLine); if (extension.Oid.Value == OID_ENROLL_CERTTYPE_EXTENSION) { // This should determine whether this certificate extension identifies the intended template // NOTE: the FriendlyName can only be resolved when the AD (or CA?) is accessible to the client - otherwise, just the OID is stored in the cert if (extension.Oid.FriendlyName == template) { returnValue = true; } } } return(returnValue); }
internal static (X509Certificate2 certificate, X509Certificate2Collection) GenerateCertificates(string targetName, [CallerMemberName] string?testName = null, bool longChain = false, bool serverCertificate = true) { const int keySize = 2048; if (PlatformDetection.IsWindows && testName != null) { CleanupCertificates(testName); } X509Certificate2Collection chain = new X509Certificate2Collection(); X509ExtensionCollection extensions = new X509ExtensionCollection(); SubjectAlternativeNameBuilder builder = new SubjectAlternativeNameBuilder(); builder.AddDnsName(targetName); extensions.Add(builder.Build()); extensions.Add(s_eeConstraints); extensions.Add(s_eeKeyUsage); extensions.Add(serverCertificate ? s_tlsServerEku : s_tlsClientEku); CertificateAuthority.BuildPrivatePki( PkiOptions.IssuerRevocationViaCrl, out RevocationResponder responder, out CertificateAuthority root, out CertificateAuthority[] intermediates,
/// <summary> /// Default constructor. /// </summary> private CrlBuilder() { ThisUpdate = DateTime.UtcNow; NextUpdate = DateTime.MinValue; m_revokedCertificates = new List <RevokedCertificate>(); m_crlExtensions = new X509ExtensionCollection(); }
void decode(Asn1Reader asn) { asn.MoveNextAndExpectTags((Byte)Asn1Type.INTEGER); Version = (Int32) new Asn1Integer(asn).Value; asn.MoveNextAndExpectTags(48); RequestMessage = new TspMessageImprint(asn.GetTagRawData()); while (asn.MoveNextCurrentLevel()) { switch (asn.Tag) { case (Byte)Asn1Type.OBJECT_IDENTIFIER: PolicyID = new Asn1ObjectIdentifier(asn).Value; break; case (Byte)Asn1Type.INTEGER: UseNonce = true; nonce = new Asn1Integer(asn).Value.ToByteArray(); break; case (Byte)Asn1Type.BOOLEAN: RequestCertificates = new Asn1Boolean(asn).Value; break; case 0xa0: var extList = new X509ExtensionCollection(); extList.Decode(asn.GetTagRawData()); foreach (X509Extension extension in extList) { _extensions.Add(extension); } break; } } }
/// <summary> /// Decodes ASN.1-encoded byte array that represents a collection of <see cref="X509Extension"/> objects. /// </summary> /// <param name="extensions">Destination collection where decoded extensions will be added.</param> /// <param name="rawData">ASN.1-encoded byte array that represents extension collection.</param> /// <exception cref="Asn1InvalidTagException">Decoder encountered an unexpected ASN.1 type identifier.</exception> /// <exception cref="ArgumentNullException"> /// <strong>extensions</strong> and/or <strong>rawData</strong> parameter is null. /// </exception> /// <remarks>If current collection contains items, decoded items will be appended to existing items.</remarks> public static void Decode(this X509ExtensionCollection extensions, Byte[] rawData) { if (extensions == null) { throw new ArgumentNullException(nameof(extensions)); } if (rawData == null) { throw new ArgumentNullException(nameof(rawData)); } Asn1Reader asn = new Asn1Reader(rawData); if (asn.Tag != 48) { throw new Asn1InvalidTagException(); } if (!asn.MoveNext() || asn.NextOffset == 0) { return; } do { extensions.Add(X509ExtensionExtensions.Decode(asn.GetTagRawData())); } while (asn.MoveNextCurrentLevel()); }
internal static byte U2FTransportsFromAttnCert(X509ExtensionCollection exts) { var u2ftransports = new byte(); var ext = exts.Cast <X509Extension>().FirstOrDefault(e => e.Oid.Value is "1.3.6.1.4.1.45724.2.1.1"); if (ext != null) { var decodedU2Ftransports = Asn1Element.Decode(ext.RawData); decodedU2Ftransports.CheckPrimitive(); // some certificates seem to have this encoded as an octet string // instead of a bit string, attempt to correct if (decodedU2Ftransports.Tag == Asn1Tag.PrimitiveOctetString) { ext.RawData[0] = (byte)UniversalTagNumber.BitString; decodedU2Ftransports = Asn1Element.Decode(ext.RawData); } decodedU2Ftransports.CheckTag(Asn1Tag.PrimitiveBitString); u2ftransports = decodedU2Ftransports.GetBitString()[0]; } return(u2ftransports); }
public static byte[] AaguidFromAttnCertExts(X509ExtensionCollection exts) { byte[] aaguid = null; foreach (var ext in exts) { if (ext.Oid.Value.Equals("1.3.6.1.4.1.45724.1.1.4")) // id-fido-gen-ce-aaguid { aaguid = new byte[16]; var ms = new System.IO.MemoryStream(ext.RawData.ToArray()); // OCTET STRING if (0x4 != ms.ReadByte()) { throw new Fido2VerificationException("Expected octet string value"); } // AAGUID if (0x10 != ms.ReadByte()) { throw new Fido2VerificationException("Unexpected length for aaguid"); } ms.Read(aaguid, 0, 0x10); //The extension MUST NOT be marked as critical if (true == ext.Critical) { throw new Fido2VerificationException("extension MUST NOT be marked as critical"); } } } return(aaguid); }
public void Indexer_Int() { X509ExtensionCollection c = new X509ExtensionCollection(); c.Add(extn_empty); Assert.AreEqual(extn_empty, c[0], "0"); }
private bool IsCACertificate(X509Certificate2 certificate) { // https://tools.ietf.org/html/rfc3280#section-4.2.1.3 // The keyCertSign bit is asserted when the subject public key is // used for verifying a signature on public key certificates. If the // keyCertSign bit is asserted, then the cA bit in the basic // constraints extension (section 4.2.1.10) MUST also be asserted. // https://tools.ietf.org/html/rfc3280#section-4.2.1.10 // The cA boolean indicates whether the certified public key belongs to // a CA. If the cA boolean is not asserted, then the keyCertSign bit in // the key usage extension MUST NOT be asserted. X509ExtensionCollection extensionCollection = certificate.Extensions; foreach (X509Extension extension in extensionCollection) { if (extension is X509BasicConstraintsExtension basicConstraintExtension) { if (basicConstraintExtension.CertificateAuthority) { return(true); } } } return(false); }
public Rfc3161TimestampTokenInfo( Oid policyId, Oid hashAlgorithmId, ReadOnlyMemory <byte> messageHash, ReadOnlyMemory <byte> serialNumber, DateTimeOffset timestamp, long?accuracyInMicroseconds = null, bool isOrdering = false, ReadOnlyMemory <byte>?nonce = null, ReadOnlyMemory <byte>?tsaName = null, X509ExtensionCollection extensions = null) { _encodedBytes = Encode( policyId, hashAlgorithmId, messageHash, serialNumber, timestamp, isOrdering, accuracyInMicroseconds, nonce, tsaName, extensions); if (!TryDecode(_encodedBytes, true, out _parsedData, out _, out _)) { Debug.Fail("Unable to decode the data we encoded"); throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } }
public static int U2FTransportsFromAttnCert(X509ExtensionCollection exts) { var u2ftransports = 0; foreach (var ext in exts) { if (ext.Oid.Value.Equals("1.3.6.1.4.1.45724.2.1.1")) { var ms = new System.IO.MemoryStream(ext.RawData.ToArray()); // BIT STRING if (0x3 != ms.ReadByte()) { throw new Fido2VerificationException("Expected bit string"); } if (0x2 != ms.ReadByte()) { throw new Fido2VerificationException("Expected integer value"); } var unused = ms.ReadByte(); // unused byte // https://fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-authenticator-transports-extension-v1.1-id-20160915.html#fido-u2f-certificate-transports-extension u2ftransports = ms.ReadByte(); // do something with this? } } return(u2ftransports); }
public static byte[] GetAppleAttestationExtensionValue(X509ExtensionCollection exts) { var appleExtension = exts.Cast <X509Extension>().FirstOrDefault(e => e.Oid.Value == "1.2.840.113635.100.8.2"); if (appleExtension == null || appleExtension.RawData == null || appleExtension.RawData.Length < 0x26) { throw new VerificationException("Extension with OID 1.2.840.113635.100.8.2 not found on Apple attestation credCert"); } try { var appleAttestationASN = AsnElt.Decode(appleExtension.RawData); appleAttestationASN.CheckConstructed(); appleAttestationASN.CheckTag(AsnElt.SEQUENCE); appleAttestationASN.CheckNumSub(1); var sequence = appleAttestationASN.GetSub(0); sequence.CheckConstructed(); sequence.CheckNumSub(1); var context = sequence.GetSub(0); context.CheckPrimitive(); context.CheckTag(AsnElt.OCTET_STRING); return(context.GetOctetString()); } catch (Exception ex) { throw new VerificationException("Apple attestation extension has invalid data", ex); } }
public static X509Certificate2 CreateSelfSignedCertificate(string subject) { var oids = new OidCollection(); oids.Add(new Oid("1.3.6.1.5.5.7.3.2")); // client auth var extensions = new X509ExtensionCollection(); extensions.Add(new X509EnhancedKeyUsageExtension(oids, true)); var cgr = new CertificateGenerationRequest() { Subject = subject, Extensions = extensions, ExpirationLength = TimeSpan.FromDays(365 * 5), KeySize = 2048 }; var cert = CertificateGenerator.CreateSelfSignedCertificate(cgr); X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); try { store.Open(OpenFlags.ReadWrite); store.Add(cert); } finally { store.Close(); } return(cert); }
public X509ExtensionCollection GetExtensions() { var coll = new X509ExtensionCollection(); if (!HasExtensions) { return(coll); } X509ExtensionAsn[] rawExtensions = _parsedData.Extensions; foreach (X509ExtensionAsn rawExtension in rawExtensions) { X509Extension extension = new X509Extension( rawExtension.ExtnId, rawExtension.ExtnValue.ToArray(), rawExtension.Critical); // Currently there are no extensions defined. // Should this dip into CryptoConfig or other extensible // mechanisms for the CopyTo rich type uplift? coll.Add(extension); } return(coll); }
void getAttributes(Asn1Reader asn) { asn.MoveNext(); if (asn.PayloadLength == 0) { return; } do { X509Attribute attribute = X509Attribute.Decode(asn.GetTagRawData()); if (attribute.Oid.Value == X509ExtensionOid.CertificateExtensions) { //Extensions var extensions = new X509ExtensionCollection(); extensions.Decode(attribute.RawData); foreach (X509Extension extension in extensions) { _extensions.Add(extension); } } else { _attributes.Add(attribute); } } while (asn.MoveNextCurrentLevel()); }
public static Rfc3161TimestampRequest CreateFromSignerInfo( SignerInfo signerInfo, HashAlgorithmName hashAlgorithm, Oid requestedPolicyId = null, ReadOnlyMemory <byte>?nonce = null, bool requestSignerCertificates = false, X509ExtensionCollection extensions = null) { if (signerInfo == null) { throw new ArgumentNullException(nameof(signerInfo)); } // https://tools.ietf.org/html/rfc3161, Appendix A. // // The value of messageImprint field within TimeStampToken shall be a // hash of the value of signature field within SignerInfo for the // signedData being time-stamped. return(CreateFromData( signerInfo.GetSignature(), hashAlgorithm, requestedPolicyId, nonce, requestSignerCertificates, extensions)); }
/// <summary> /// Default constructor. /// </summary> protected virtual void Initialize() { m_notBefore = DateTime.UtcNow.AddDays(-1).Date; m_notAfter = NotBefore.AddMonths(X509Defaults.LifeTime); m_hashAlgorithmName = X509Defaults.HashAlgorithmName; m_serialNumberLength = X509Defaults.SerialNumberLengthMin; m_extensions = new X509ExtensionCollection(); }
public void Add() { X509ExtensionCollection c = new X509ExtensionCollection(); Assert.AreEqual(0, c.Count, "Count-0"); c.Add(extn_empty); Assert.AreEqual(1, c.Count, "Count-1"); }
/// <summary> /// Default constructor, also internal test hook. /// </summary> internal X509CRL() { m_decoded = false; m_thisUpdate = DateTime.MinValue; m_nextUpdate = DateTime.MinValue; m_revokedCertificates = new List <RevokedCertificate>(); m_crlExtensions = new X509ExtensionCollection(); }
public TestResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration) { var signatures = graph.VisitAll(SignatureKind.AnySignature); var pass = false; foreach (var signature in signatures) { string serialNumber = ""; string KU = ""; Boolean KUCritical = false; int KU_extension = 0; string thumbprint = signature.Certificate.Thumbprint; serialNumber = signature.Certificate.SerialNumber; X509ExtensionCollection extensions = signature.Certificate.Extensions; foreach (X509Extension extension in extensions) { //extension.Oid.FriendlyName Console.WriteLine(extension.Oid.FriendlyName + "(" + extension.Oid.Value + ")"); if (extension.Oid.FriendlyName == "Key Usage") { X509KeyUsageExtension ext = (X509KeyUsageExtension)extension; KUCritical = ext.Critical; KU = ext.KeyUsages.ToString(); Console.WriteLine(KU); KU_extension++; } } if (KU_extension == 1) { if (KUCritical) { verboseWriter.LogSignatureMessage(signature, "Key Usage extension is marked critical."); pass = true; } else { verboseWriter.LogSignatureMessage(signature, "Key Usage extension is not marked critical."); pass = false; } } else if (KU_extension == 0) { verboseWriter.LogSignatureMessage(signature, "Signature does not have Key Usage extension."); pass = false; } else if (KU_extension > 1) { verboseWriter.LogSignatureMessage(signature, "Signature has duplicate Key Usage extension."); pass = false; } } return(pass ? TestResult.Pass : TestResult.Fail); }
/// <summary> /// Generate a self-signed CA certificate /// </summary> /// <param name="subject">The X500 subject string</param> /// <param name="rsaKeySize">The size of the RSA key to generate</param> /// <param name="hashAlgorithm">Specify the signature hash algorithm</param> /// <returns>An X509Certificate2 object containing the full certificate</returns> public static X509Certificate2 GenerateCACert(string subject, int rsaKeySize, CertificateHashAlgorithm hashAlgorithm) { X509ExtensionCollection exts = new X509ExtensionCollection(); DateTime dt = DateTime.Now.AddYears(-1); exts.Add(new X509BasicConstraintsExtension(true, false, 0, false)); return(builder.CreateCert(null, new X500DistinguishedName(subject), null, false, rsaKeySize, hashAlgorithm, dt, dt.AddYears(10), exts)); }
public void ICollection_CopyTo() { X509ExtensionCollection c = new X509ExtensionCollection(); c.Add(extn_empty); X509Extension[] array = new X509Extension[1]; (c as ICollection).CopyTo(array, 0); Assert.AreEqual(extn_empty, array[0], "0"); }
public void Indexer_String() { X509ExtensionCollection c = new X509ExtensionCollection(); c.Add(extn_empty); Assert.IsNull(c[String.Empty]); Assert.IsNull(c ["1.2.3"]); Assert.AreEqual(extn_empty, c["1.2"], "0"); }
public Rfc3161TimestampRequest( byte[] messageHash, HashAlgorithmName hashAlgorithm, Oid requestedPolicyId = null, byte[] nonce = null, bool requestSignerCertificates = false, X509ExtensionCollection extensions = null) { if (messageHash == null) { throw new ArgumentNullException(nameof(messageHash)); } int expectedSize; string algorithmIdentifier; if (!ResolveAlgorithm(hashAlgorithm, out expectedSize, out algorithmIdentifier)) { throw new ArgumentOutOfRangeException( nameof(hashAlgorithm), hashAlgorithm, "Hash algorithm is not supported by this method"); } if (messageHash.Length != expectedSize) { throw new ArgumentException("Hash is not the correct size for the identified algorithm", nameof(messageHash)); } if (requestedPolicyId != null && !Rfc3161TimestampUtils.IsLegalOid(requestedPolicyId.Value)) { throw new ArgumentException("Value is not a legal object identifier", nameof(requestedPolicyId)); } if (nonce != null && nonce.Length == 0) { throw new ArgumentException("Nonce must be null or non-empty", nameof(nonce)); } var data = new DataType { _version = 1, _hash = (byte[])messageHash.Clone(), _hashAlgorithm = OpportunisticOid(algorithmIdentifier), _nonce = (byte[])nonce?.Clone(), _requestSignerCertificate = requestSignerCertificates, _extensions = Rfc3161TimestampTokenInfo.ShallowCopy(extensions, preserveNull: true), }; if (requestedPolicyId != null) { data._requestedPolicyId = new Oid(requestedPolicyId.Value, requestedPolicyId.FriendlyName); } RawData = Encode(data); }
public override void Reset () { _cert = null; _archived = false; _extensions = null; _serial = null; _publicKey = null; issuer_name = null; subject_name = null; signature_algorithm = null; if (intermediateCerts != null) { intermediateCerts.Dispose (); intermediateCerts = null; } }
public override void Reset () { _cert = null; _archived = false; _extensions = null; _name = String.Empty; _serial = null; _publicKey = null; issuer_name = null; subject_name = null; signature_algorithm = null; base.Reset (); }
private byte[] GetUniqueName (X509ExtensionCollection extensions, byte[] serial = null) { // We prefer Subject Key Identifier as the unique name // as it will provide faster lookups X509Extension ext = extensions ["2.5.29.14"]; if (ext == null) return null; SubjectKeyIdentifierExtension ski = new SubjectKeyIdentifierExtension (ext); if (serial == null) { return ski.Identifier; } else { byte[] uniqueWithSerial = new byte[ski.Identifier.Length + serial.Length]; System.Buffer.BlockCopy (ski.Identifier, 0, uniqueWithSerial, 0, ski.Identifier.Length ); System.Buffer.BlockCopy (serial, 0, uniqueWithSerial, ski.Identifier.Length, serial.Length ); return uniqueWithSerial; } }
// that's were the real job is! private void Parse (byte[] data) { try { decoder = new ASN1 (data); // Certificate if (decoder.Tag != 0x30) throw new CryptographicException (encoding_error); // Certificate / TBSCertificate if (decoder [0].Tag != 0x30) throw new CryptographicException (encoding_error); ASN1 tbsCertificate = decoder [0]; int tbs = 0; // Certificate / TBSCertificate / Version ASN1 v = decoder [0][tbs]; version = 1; // DEFAULT v1 if ((v.Tag == 0xA0) && (v.Count > 0)) { // version (optional) is present only in v2+ certs version += v [0].Value [0]; // zero based tbs++; } // Certificate / TBSCertificate / CertificateSerialNumber ASN1 sn = decoder [0][tbs++]; if (sn.Tag != 0x02) throw new CryptographicException (encoding_error); serialnumber = sn.Value; Array.Reverse (serialnumber, 0, serialnumber.Length); // Certificate / TBSCertificate / AlgorithmIdentifier tbs++; // ASN1 signatureAlgo = tbsCertificate.Element (tbs++, 0x30); issuer = tbsCertificate.Element (tbs++, 0x30); m_issuername = X501.ToString (issuer); ASN1 validity = tbsCertificate.Element (tbs++, 0x30); ASN1 notBefore = validity [0]; m_from = ASN1Convert.ToDateTime (notBefore); ASN1 notAfter = validity [1]; m_until = ASN1Convert.ToDateTime (notAfter); subject = tbsCertificate.Element (tbs++, 0x30); m_subject = X501.ToString (subject); ASN1 subjectPublicKeyInfo = tbsCertificate.Element (tbs++, 0x30); ASN1 algorithm = subjectPublicKeyInfo.Element (0, 0x30); ASN1 algo = algorithm.Element (0, 0x06); m_keyalgo = ASN1Convert.ToOid (algo); // parameters ANY DEFINED BY algorithm OPTIONAL // so we dont ask for a specific (Element) type and return DER ASN1 parameters = algorithm [1]; m_keyalgoparams = ((algorithm.Count > 1) ? parameters.GetBytes () : null); ASN1 subjectPublicKey = subjectPublicKeyInfo.Element (1, 0x03); // we must drop th first byte (which is the number of unused bits // in the BITSTRING) int n = subjectPublicKey.Length - 1; m_publickey = new byte [n]; Buffer.BlockCopy (subjectPublicKey.Value, 1, m_publickey, 0, n); // signature processing byte[] bitstring = decoder [2].Value; // first byte contains unused bits in first byte signature = new byte [bitstring.Length - 1]; Buffer.BlockCopy (bitstring, 1, signature, 0, signature.Length); algorithm = decoder [1]; algo = algorithm.Element (0, 0x06); m_signaturealgo = ASN1Convert.ToOid (algo); parameters = algorithm [1]; if (parameters != null) m_signaturealgoparams = parameters.GetBytes (); else m_signaturealgoparams = null; // Certificate / TBSCertificate / issuerUniqueID ASN1 issuerUID = tbsCertificate.Element (tbs, 0x81); if (issuerUID != null) { tbs++; issuerUniqueID = issuerUID.Value; } // Certificate / TBSCertificate / subjectUniqueID ASN1 subjectUID = tbsCertificate.Element (tbs, 0x82); if (subjectUID != null) { tbs++; subjectUniqueID = subjectUID.Value; } // Certificate / TBSCertificate / Extensions ASN1 extns = tbsCertificate.Element (tbs, 0xA3); if ((extns != null) && (extns.Count == 1)) extensions = new X509ExtensionCollection (extns [0]); else extensions = new X509ExtensionCollection (null); // keep a copy of the original data m_encodedcert = (byte[]) data.Clone (); } catch (Exception ex) { throw new CryptographicException (encoding_error, ex); } }