Ejemplo n.º 1
0
        /// <summary>
        /// Decoder for the signature sequence.
        /// </summary>
        /// <param name="crl">The encoded CRL or certificate sequence.</param>
        private void Decode(byte[] crl)
        {
            try
            {
                AsnReader crlReader = new AsnReader(crl, AsnEncodingRules.DER);
                var       seqReader = crlReader.ReadSequence(Asn1Tag.Sequence);
                if (seqReader != null)
                {
                    // Tbs encoded data
                    Tbs = seqReader.ReadEncodedValue().ToArray();

                    // Signature Algorithm Identifier
                    var sigOid = seqReader.ReadSequence();
                    SignatureAlgorithm = sigOid.ReadObjectIdentifier();
                    Name = Oids.GetHashAlgorithmName(SignatureAlgorithm);

                    // Signature
                    int unusedBitCount;
                    Signature = seqReader.ReadBitString(out unusedBitCount);
                    if (unusedBitCount != 0)
                    {
                        throw new AsnContentException("Unexpected data in signature.");
                    }
                    seqReader.ThrowIfNotEmpty();
                    return;
                }
                throw new CryptographicException("No valid data in the X509 signature.");
            }
            catch (AsnContentException ace)
            {
                throw new CryptographicException("Failed to decode the X509 signature.", ace);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Encode Tbs with a signature in ASN format.
        /// </summary>
        /// <returns>X509 ASN format of EncodedData+SignatureOID+Signature bytes.</returns>
        public byte[] Encode()
        {
            AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

            var tag = Asn1Tag.Sequence;

            writer.PushSequence(tag);

            // write Tbs encoded data
            writer.WriteEncodedValue(Tbs);

            // Signature Algorithm Identifier
            if (SignatureAlgorithmIdentifier != null)
            {
                writer.WriteEncodedValue(SignatureAlgorithmIdentifier);
            }
            else
            {
                writer.PushSequence();
                string signatureAlgorithmIdentifier = Oids.GetRSAOid(Name);
                writer.WriteObjectIdentifier(signatureAlgorithmIdentifier);
                writer.WriteNull();
                writer.PopSequence();
            }

            // Add signature
            writer.WriteBitString(Signature);

            writer.PopSequence(tag);

            return(writer.Encode());
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Initialize the X509 signature values.
 /// </summary>
 /// <param name="tbs">The data to be signed.</param>
 /// <param name="signature">The signature of the data.</param>
 /// <param name="signatureAlgorithmIdentifier">The algorithm used to create the signature.</param>
 public X509Signature(byte[] tbs, byte[] signature, byte[] signatureAlgorithmIdentifier)
 {
     Tbs       = tbs;
     Signature = signature;
     SignatureAlgorithmIdentifier = signatureAlgorithmIdentifier;
     SignatureAlgorithm           = DecodeAlgorithm(signatureAlgorithmIdentifier);
     Name = Oids.GetHashAlgorithmName(SignatureAlgorithm);
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Constructs Certificate Revocation List raw data in X509 ASN format.
        /// </summary>
        /// <remarks>
        /// CRL fields -- https://tools.ietf.org/html/rfc5280#section-5.1
        ///
        /// CertificateList  ::=  SEQUENCE  {
        ///    tbsCertList          TBSCertList,
        ///    signatureAlgorithm   AlgorithmIdentifier,
        ///    signatureValue       BIT STRING
        ///    }
        ///
        /// TBSCertList  ::=  SEQUENCE  {
        ///    version                 Version OPTIONAL,
        ///                            -- if present, MUST be v2
        ///    signature               AlgorithmIdentifier,
        ///    issuer                  Name,
        ///    thisUpdate              Time,
        ///    nextUpdate              Time OPTIONAL,
        ///    revokedCertificates     SEQUENCE OF SEQUENCE  {
        ///        userCertificate         CertificateSerialNumber,
        ///        revocationDate          Time,
        ///        crlEntryExtensions      Extensions OPTIONAL
        ///                              -- if present, version MUST be v2
        ///                            }  OPTIONAL,
        ///    crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
        ///                              -- if present, version MUST be v2
        ///                            }
        /// </remarks>
        internal byte[] Encode()
        {
            AsnWriter crlWriter = new AsnWriter(AsnEncodingRules.DER);
            {
                // tbsCertList
                crlWriter.PushSequence();

                // version
                crlWriter.WriteInteger(1);

                // Signature Algorithm Identifier
                crlWriter.PushSequence();
                string signatureAlgorithm = Oids.GetRSAOid(HashAlgorithmName);
                crlWriter.WriteObjectIdentifier(signatureAlgorithm);
                crlWriter.WriteNull();

                // pop
                crlWriter.PopSequence();

                // Issuer
                crlWriter.WriteEncodedValue((ReadOnlySpan <byte>)IssuerName.RawData);

                // this update
                crlWriter.WriteUtcTime(this.ThisUpdate);

                if (NextUpdate != DateTime.MinValue &&
                    NextUpdate > ThisUpdate)
                {
                    // next update
                    crlWriter.WriteUtcTime(NextUpdate);
                }

                // sequence to start the revoked certificates.
                crlWriter.PushSequence();

                foreach (var revokedCert in RevokedCertificates)
                {
                    crlWriter.PushSequence();

                    BigInteger srlNumberValue = new BigInteger(revokedCert.UserCertificate);
                    crlWriter.WriteInteger(srlNumberValue);
                    crlWriter.WriteUtcTime(revokedCert.RevocationDate);

                    if (revokedCert.CrlEntryExtensions.Count > 0)
                    {
                        crlWriter.PushSequence();
                        foreach (var crlEntryExt in revokedCert.CrlEntryExtensions)
                        {
                            crlWriter.WriteExtension(crlEntryExt);
                        }
                        crlWriter.PopSequence();
                    }
                    crlWriter.PopSequence();
                }

                crlWriter.PopSequence();

                // CRL extensions
                if (CrlExtensions.Count > 0)
                {
                    // [0]  EXPLICIT Extensions OPTIONAL
                    var tag = new Asn1Tag(TagClass.ContextSpecific, 0);
                    crlWriter.PushSequence(tag);

                    // CRL extensions
                    crlWriter.PushSequence();
                    foreach (var extension in CrlExtensions)
                    {
                        crlWriter.WriteExtension(extension);
                    }
                    crlWriter.PopSequence();

                    crlWriter.PopSequence(tag);
                }

                crlWriter.PopSequence();

                return(crlWriter.Encode());
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Decode the Tbs of the CRL.
        /// </summary>
        /// <param name="tbs">The raw TbsCertList of the CRL.</param>
        internal void DecodeCrl(byte[] tbs)
        {
            try
            {
                AsnReader crlReader = new AsnReader(tbs, AsnEncodingRules.DER);
                var       tag       = Asn1Tag.Sequence;
                var       seqReader = crlReader.ReadSequence(tag);
                crlReader.ThrowIfNotEmpty();
                if (seqReader != null)
                {
                    // Version is OPTIONAL
                    uint version = 0;
                    var  intTag  = new Asn1Tag(UniversalTagNumber.Integer);
                    var  peekTag = seqReader.PeekTag();
                    if (peekTag == intTag)
                    {
                        if (seqReader.TryReadUInt32(out version))
                        {
                            if (version != 1)
                            {
                                throw new AsnContentException($"The CRL contains an incorrect version {version}");
                            }
                        }
                    }

                    // Signature Algorithm Identifier
                    var sigReader = seqReader.ReadSequence();
                    var oid       = sigReader.ReadObjectIdentifier();
                    m_hashAlgorithmName = Oids.GetHashAlgorithmName(oid);
                    if (sigReader.HasData)
                    {
                        sigReader.ReadNull();
                    }
                    sigReader.ThrowIfNotEmpty();

                    // Issuer
                    m_issuerName = new X500DistinguishedName(seqReader.ReadEncodedValue().ToArray());

                    // thisUpdate
                    m_thisUpdate = seqReader.ReadUtcTime().UtcDateTime;

                    // nextUpdate is OPTIONAL
                    var utcTag = new Asn1Tag(UniversalTagNumber.UtcTime);
                    peekTag = seqReader.PeekTag();
                    if (peekTag == utcTag)
                    {
                        m_nextUpdate = seqReader.ReadUtcTime().UtcDateTime;
                    }

                    var seqTag = new Asn1Tag(UniversalTagNumber.Sequence, true);
                    peekTag = seqReader.PeekTag();
                    if (peekTag == seqTag)
                    {
                        // revoked certificates
                        var revReader           = seqReader.ReadSequence(tag);
                        var revokedCertificates = new List <RevokedCertificate>();
                        while (revReader.HasData)
                        {
                            var crlEntry           = revReader.ReadSequence();
                            var serial             = crlEntry.ReadInteger();
                            var revokedCertificate = new RevokedCertificate(serial.ToByteArray());
                            revokedCertificate.RevocationDate = crlEntry.ReadUtcTime().UtcDateTime;
                            if (version == 1 &&
                                crlEntry.HasData)
                            {
                                // CRL entry extensions
                                var crlEntryExtensions = crlEntry.ReadSequence();
                                while (crlEntryExtensions.HasData)
                                {
                                    var extension = crlEntryExtensions.ReadExtension();
                                    revokedCertificate.CrlEntryExtensions.Add(extension);
                                }
                                crlEntryExtensions.ThrowIfNotEmpty();
                            }
                            crlEntry.ThrowIfNotEmpty();
                            revokedCertificates.Add(revokedCertificate);
                        }
                        revReader.ThrowIfNotEmpty();
                        m_revokedCertificates = revokedCertificates;
                    }

                    // CRL extensions OPTIONAL
                    if (version == 1 &&
                        seqReader.HasData)
                    {
                        var extTag           = new Asn1Tag(TagClass.ContextSpecific, 0);
                        var optReader        = seqReader.ReadSequence(extTag);
                        var crlExtensionList = new X509ExtensionCollection();
                        var crlExtensions    = optReader.ReadSequence();
                        while (crlExtensions.HasData)
                        {
                            var extension = crlExtensions.ReadExtension();
                            crlExtensionList.Add(extension);
                        }
                        m_crlExtensions = crlExtensionList;
                    }
                    seqReader.ThrowIfNotEmpty();
                    m_decoded = true;
                    return;
                }
                throw new CryptographicException("The CRL contains ivalid data.");
            }
            catch (AsnContentException ace)
            {
                throw new CryptographicException("Failed to decode the CRL.", ace);
            }
        }