Exemplo n.º 1
0
        internal void ValidateAndSkipDerValue()
        {
            byte tag = PeekTag();

            // If the tag is in the UNIVERSAL class
            if ((tag & TagClassMask) == 0)
            {
                // Tag 0 is special ("reserved for use by the encoding rules"), but mainly is used
                // as the End-of-Contents marker for the indefinite length encodings, which DER prohibits.
                //
                // Tag 15 is reserved.
                //
                // So either of these are invalid.

                if (tag == 0 || tag == 15)
                {
                    throw new CryptographicException(SR.GetString(SR.Cryptography_Der_Invalid_Encoding));
                }

                // DER limits the constructed encoding to SEQUENCE and SET, as well as anything which gets
                // a defined encoding as being an IMPLICIT SEQUENCE.

                bool expectConstructed = false;

                switch (tag & TagNumberMask)
                {
                case 0x08:     // External or Instance-Of
                case 0x0B:     // EmbeddedPDV
                case (byte)DerTag.Sequence:
                case (byte)DerTag.Set:
                case 0x1D:     // Unrestricted Character String
                    expectConstructed = true;
                    break;
                }

                bool isConstructed = (tag & ConstructedFlag) == ConstructedFlag;

                if (expectConstructed != isConstructed)
                {
                    throw new CryptographicException(SR.GetString(SR.Cryptography_Der_Invalid_Encoding));
                }
            }

            EatTag((DerTag)tag);
            int contentLength = EatLength();

            if (contentLength > 0 && (tag & ConstructedFlag) == ConstructedFlag)
            {
                var childReader = new DerSequenceReader(true, _data, _position, _end - _position);

                while (childReader.HasData)
                {
                    childReader.ValidateAndSkipDerValue();
                }
            }

            _position += contentLength;
        }
Exemplo n.º 2
0
        internal static byte[][] SegmentedEncodeSubjectPublicKeyInfo(this PublicKey publicKey)
        {
            if (publicKey == null)
            {
                throw new ArgumentNullException(nameof(publicKey));
            }

            if (publicKey.Oid == null ||
                string.IsNullOrEmpty(publicKey.Oid.Value) ||
                publicKey.EncodedKeyValue == null)
            {
                throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidPublicKey_Object));
            }

            // SubjectPublicKeyInfo::= SEQUENCE  {
            //   algorithm AlgorithmIdentifier,
            //   subjectPublicKey     BIT STRING
            // }
            //
            // AlgorithmIdentifier::= SEQUENCE  {
            //   algorithm OBJECT IDENTIFIER,
            //   parameters ANY DEFINED BY algorithm OPTIONAL
            // }

            byte[][] algorithmIdentifier;

            if (publicKey.EncodedParameters == null)
            {
                algorithmIdentifier = DerEncoder.ConstructSegmentedSequence(
                    DerEncoder.SegmentedEncodeOid(publicKey.Oid));
            }
            else
            {
                DerSequenceReader validator =
                    DerSequenceReader.CreateForPayload(publicKey.EncodedParameters.RawData);

                validator.ValidateAndSkipDerValue();

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

                algorithmIdentifier = DerEncoder.ConstructSegmentedSequence(
                    DerEncoder.SegmentedEncodeOid(publicKey.Oid),
                    publicKey.EncodedParameters.RawData.WrapAsSegmentedForSequence());
            }

            return(DerEncoder.ConstructSegmentedSequence(
                       algorithmIdentifier,
                       DerEncoder.SegmentedEncodeBitString(
                           publicKey.EncodedKeyValue.RawData)));
        }
Exemplo n.º 3
0
        internal static void ValidateSignatureAlgorithm(byte[] signatureAlgorithm)
        {
            Debug.Assert(signatureAlgorithm != null);

            // AlgorithmIdentifier ::= SEQUENCE { OBJECT IDENTIFIER, ANY }
            DerSequenceReader validator = new DerSequenceReader(signatureAlgorithm);

            validator.ReadOidAsString();

            if (validator.HasData)
            {
                validator.ValidateAndSkipDerValue();
            }

            if (validator.HasData)
            {
                throw new CryptographicException(SR.GetString(SR.Cryptography_Der_Invalid_Encoding));
            }
        }
Exemplo n.º 4
0
        private void Decode()
        {
            if (_decoded)
            {
                return;
            }

            // AuthorityKeyIdentifier ::= SEQUENCE {
            //   keyIdentifier             [0] KeyIdentifier           OPTIONAL,
            //   authorityCertIssuer       [1] GeneralNames            OPTIONAL,
            //   authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
            //
            // KeyIdentifier ::= OCTET STRING

            string keyId = null;
            X500DistinguishedName firstIssuerName = null;
            DerSequenceReader     reader          = new DerSequenceReader(RawData);

            byte[] serialNumber = null;

            // Primitive Context 0
            const byte KeyIdTag = DerSequenceReader.ContextSpecificTagFlag | 0;
            // Constructed Context 1
            const byte CertIssuerTag = DerSequenceReader.ContextSpecificConstructedTag1;
            // Primitive Context 2
            const byte CertSerialTag = DerSequenceReader.ContextSpecificTagFlag | 2;

            if (reader.HasTag(KeyIdTag))
            {
                keyId = reader.ReadOctetString().ToHexStringUpper();
            }

            if (reader.HasTag(CertIssuerTag))
            {
                DerSequenceReader generalNames = reader.ReadSequence();

                while (generalNames.HasData)
                {
                    const byte DirectoryNameTag = DerSequenceReader.ConstructedFlag |
                                                  (byte)GeneralNameEncoder.GeneralNameTag.DirectoryName;

                    if (firstIssuerName == null && generalNames.HasTag(DirectoryNameTag))
                    {
                        firstIssuerName = new X500DistinguishedName(generalNames.ReadNextEncodedValue());
                    }

                    reader.ValidateAndSkipDerValue();
                }
            }

            if (reader.HasTag(CertSerialTag))
            {
                serialNumber = reader.ReadOctetString();
            }

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

            _firstIssuerName = firstIssuerName;
            _serialNumber    = serialNumber;
            _keyIdentifier   = keyId;
            _decoded         = true;
        }