예제 #1
0
        public virtual void DecodeX509KeyUsageExtension(byte[] encoded, out X509KeyUsageFlags keyUsages)
        {
            DerSequenceReader reader = DerSequenceReader.CreateForPayload(encoded);

            byte[] decoded = reader.ReadBitString();

            // Only 9 bits are defined.
            if (decoded.Length > 2)
            {
                throw new CryptographicException();
            }

            // DER encodings of BIT_STRING values number the bits as
            // 01234567 89 (big endian), plus a number saying how many bits of the last byte were padding.
            //
            // So digitalSignature (0) doesn't mean 2^0 (0x01), it means the most significant bit
            // is set in this byte stream.
            //
            // BIT_STRING values are compact.  So a value of cRLSign (6) | keyEncipherment (2), which
            // is 0b0010001 => 0b0010 0010 (1 bit padding) => 0x22 encoded is therefore
            // 0x02 (length remaining) 0x01 (1 bit padding) 0x22.
            //
            // We will read that, and return 0x22.  0x22 lines up
            // exactly with X509KeyUsageFlags.CrlSign (0x20) | X509KeyUsageFlags.KeyEncipherment (0x02)
            //
            // Once the decipherOnly (8) bit is added to the mix, the values become:
            // 0b001000101 => 0b0010 0010 1000 0000 (7 bits padding)
            // { 0x03 0x07 0x22 0x80 }
            // And we read new byte[] { 0x22 0x80 }
            //
            // The value of X509KeyUsageFlags.DecipherOnly is 0x8000.  0x8000 in a little endian
            // representation is { 0x00 0x80 }.  This means that the DER storage mechanism has effectively
            // ended up being little-endian for BIT_STRING values.  Untwist the bytes, and now the bits all
            // line up with the existing X509KeyUsageFlags.

            int value = 0;

            if (decoded.Length > 0)
            {
                value = decoded[0];
            }

            if (decoded.Length > 1)
            {
                value |= decoded[1] << 8;
            }

            keyUsages = (X509KeyUsageFlags)value;
        }
예제 #2
0
        internal CertificateData(byte[] rawData)
        {
#if DEBUG
            try
            {
#endif
            DerSequenceReader reader = new DerSequenceReader(rawData);

            DerSequenceReader tbsCertificate = reader.ReadSequence();

            if (tbsCertificate.PeekTag() == DerSequenceReader.ContextSpecificConstructedTag0)
            {
                DerSequenceReader version = tbsCertificate.ReadSequence();
                Version = version.ReadInteger();
            }
            else if (tbsCertificate.PeekTag() != (byte)DerSequenceReader.DerTag.Integer)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }
            else
            {
                Version = 0;
            }

            if (Version < 0 || Version > 2)
            {
                throw new CryptographicException();
            }

            SerialNumber = tbsCertificate.ReadIntegerBytes();

            DerSequenceReader tbsSignature = tbsCertificate.ReadSequence();
            TbsSignature.AlgorithmId = tbsSignature.ReadOidAsString();
            TbsSignature.Parameters  = tbsSignature.HasData ? tbsSignature.ReadNextEncodedValue() : Array.Empty <byte>();

            if (tbsSignature.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            Issuer = new X500DistinguishedName(tbsCertificate.ReadNextEncodedValue());

            DerSequenceReader validity = tbsCertificate.ReadSequence();
            NotBefore = validity.ReadX509Date();
            NotAfter  = validity.ReadX509Date();

            if (validity.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            Subject = new X500DistinguishedName(tbsCertificate.ReadNextEncodedValue());

            SubjectPublicKeyInfo = tbsCertificate.ReadNextEncodedValue();
            DerSequenceReader subjectPublicKeyInfo = new DerSequenceReader(SubjectPublicKeyInfo);
            DerSequenceReader subjectKeyAlgorithm  = subjectPublicKeyInfo.ReadSequence();
            PublicKeyAlgorithm.AlgorithmId = subjectKeyAlgorithm.ReadOidAsString();
            PublicKeyAlgorithm.Parameters  = subjectKeyAlgorithm.HasData ? subjectKeyAlgorithm.ReadNextEncodedValue() : Array.Empty <byte>();

            if (subjectKeyAlgorithm.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            PublicKey = subjectPublicKeyInfo.ReadBitString();

            if (subjectPublicKeyInfo.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            if (Version > 0 &&
                tbsCertificate.HasData &&
                tbsCertificate.PeekTag() == DerSequenceReader.ContextSpecificConstructedTag1)
            {
                IssuerUniqueId = tbsCertificate.ReadBitString();
            }
            else
            {
                IssuerUniqueId = null;
            }

            if (Version > 0 &&
                tbsCertificate.HasData &&
                tbsCertificate.PeekTag() == DerSequenceReader.ContextSpecificConstructedTag2)
            {
                SubjectUniqueId = tbsCertificate.ReadBitString();
            }
            else
            {
                SubjectUniqueId = null;
            }

            Extensions = new List <X509Extension>();

            if (Version > 1 &&
                tbsCertificate.HasData &&
                tbsCertificate.PeekTag() == DerSequenceReader.ContextSpecificConstructedTag3)
            {
                DerSequenceReader extensions = tbsCertificate.ReadSequence();
                extensions = extensions.ReadSequence();

                while (extensions.HasData)
                {
                    DerSequenceReader extensionReader = extensions.ReadSequence();
                    string            oid             = extensionReader.ReadOidAsString();
                    bool critical = false;

                    if (extensionReader.PeekTag() == (byte)DerSequenceReader.DerTag.Boolean)
                    {
                        critical = extensionReader.ReadBoolean();
                    }

                    byte[] extensionData = extensionReader.ReadOctetString();

                    Extensions.Add(new X509Extension(oid, extensionData, critical));

                    if (extensionReader.HasData)
                    {
                        throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                    }
                }
            }

            if (tbsCertificate.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            DerSequenceReader signatureAlgorithm = reader.ReadSequence();
            SignatureAlgorithm.AlgorithmId = signatureAlgorithm.ReadOidAsString();
            SignatureAlgorithm.Parameters  = signatureAlgorithm.HasData ? signatureAlgorithm.ReadNextEncodedValue() : Array.Empty <byte>();

            if (signatureAlgorithm.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            SignatureValue = reader.ReadBitString();

            if (reader.HasData)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            RawData = rawData;
#if DEBUG
        }

        catch (Exception e)
        {
            throw new CryptographicException(
                      $"Error in reading certificate:{Environment.NewLine}{PemPrintCert(rawData)}",
                      e);
        }
#endif
        }