Esempio n. 1
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out PkiStatusInfo decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);


            if (!sequenceReader.TryReadInt32(out decoded.Status))
            {
                sequenceReader.ThrowIfNotEmpty();
            }


            if (sequenceReader.HasData)
            {
                decoded.StatusString = sequenceReader.GetEncodedValue();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.PrimitiveBitString))
            {
                decoded.FailInfo = sequenceReader.GetNamedBitListValue <System.Security.Cryptography.Pkcs.Asn1.PkiFailureInfo>();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 2
0
        private SignerInfoCollection GetCounterSigners(AttributeAsn[] unsignedAttrs)
        {
            // Since each "attribute" can have multiple "attribute values" there's no real
            // correlation to a predictive size here.
            List <SignerInfo> signerInfos = new List <SignerInfo>();

            foreach (AttributeAsn attributeAsn in unsignedAttrs)
            {
                if (attributeAsn.AttrType.Value == Oids.CounterSigner)
                {
                    AsnReader reader     = new AsnReader(attributeAsn.AttrValues, AsnEncodingRules.BER);
                    AsnReader collReader = reader.ReadSetOf();

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

                    while (collReader.HasData)
                    {
                        SignerInfoAsn parsedData =
                            AsnSerializer.Deserialize <SignerInfoAsn>(collReader.GetEncodedValue(), AsnEncodingRules.BER);

                        SignerInfo signerInfo = new SignerInfo(ref parsedData, _document)
                        {
                            _parentSignerInfo = this
                        };

                        signerInfos.Add(signerInfo);
                    }
                }
            }

            return(new SignerInfoCollection(signerInfos.ToArray()));
        }
Esempio n. 3
0
        public static void TagMustBeCorrect_Custom_Indefinite(PublicEncodingRules ruleSet)
        {
            byte[]    inputData = "A58005000000".HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            AssertExtensions.Throws <ArgumentException>(
                "expectedTag",
                () => reader.ReadSetOf(Asn1Tag.Null));

            Assert.True(reader.HasData, "HasData after bad universal tag");

            Assert.Throws <CryptographicException>(() => reader.ReadSetOf());

            Assert.True(reader.HasData, "HasData after default tag");

            Assert.Throws <CryptographicException>(
                () => reader.ReadSetOf(new Asn1Tag(TagClass.Application, 5)));

            Assert.True(reader.HasData, "HasData after wrong custom class");

            Assert.Throws <CryptographicException>(
                () => reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 7)));

            Assert.True(reader.HasData, "HasData after wrong custom tag value");

            AsnReader seq = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 5));

            Assert.Equal("0500", seq.GetEncodedValue().ByteArrayToHex());

            Assert.False(reader.HasData, "HasData after reading value");
        }
Esempio n. 4
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SignerInfoAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);
            AsnReader collectionReader;


            if (!sequenceReader.TryReadInt32(out decoded.Version))
            {
                sequenceReader.ThrowIfNotEmpty();
            }

            System.Security.Cryptography.Pkcs.Asn1.SignerIdentifierAsn.Decode(sequenceReader, out decoded.Sid);
            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.DigestAlgorithm);

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                decoded.SignedAttributes = sequenceReader.GetEncodedValue();
            }

            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.SignatureAlgorithm);

            if (sequenceReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpSignatureValue))
            {
                decoded.SignatureValue = tmpSignatureValue;
            }
            else
            {
                decoded.SignatureValue = sequenceReader.ReadOctetString();
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                // Decode SEQUENCE OF for UnsignedAttributes
                {
                    collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1));
                    var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>();
                    System.Security.Cryptography.Asn1.AttributeAsn tmpItem;

                    while (collectionReader.HasData)
                    {
                        System.Security.Cryptography.Asn1.AttributeAsn.Decode(collectionReader, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.UnsignedAttributes = tmpList.ToArray();
                }
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 5
0
        public override Oid GetEncodedMessageType(byte[] encodedMessage)
        {
            AsnReader reader = new AsnReader(encodedMessage, AsnEncodingRules.BER);

            ContentInfoAsn contentInfo = AsnSerializer.Deserialize <ContentInfoAsn>(
                reader.GetEncodedValue(),
                AsnEncodingRules.BER);

            return(new Oid(contentInfo.ContentType));
        }
Esempio n. 6
0
        internal static unsafe Pkcs8Response ImportEncryptedPkcs8PrivateKey(
            ReadOnlySpan <char> password,
            ReadOnlySpan <byte> source,
            out int bytesRead)
        {
            fixed(byte *ptr = &MemoryMarshal.GetReference(source))
            {
                using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length))
                {
                    AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER);
                    int       len    = reader.GetEncodedValue().Length;
                    source = source.Slice(0, len);

                    try
                    {
                        bytesRead = len;
                        return(ImportPkcs8(source, password));
                    }
                    catch (CryptographicException)
                    {
                    }

                    ArraySegment <byte> decrypted = KeyFormatHelper.DecryptPkcs8(
                        password,
                        manager.Memory.Slice(0, len),
                        out int innerRead);

                    Span <byte> decryptedSpan = decrypted;

                    try
                    {
                        if (innerRead != len)
                        {
                            throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                        }

                        bytesRead = len;
                        return(ImportPkcs8(decryptedSpan));
                    }
                    catch (CryptographicException e)
                    {
                        throw new CryptographicException(SR.Cryptography_Pkcs8_EncryptedReadFailed, e);
                    }
                    finally
                    {
                        CryptographicOperations.ZeroMemory(decryptedSpan);
                        ArrayPool <byte> .Shared.Return(decrypted.Array);
                    }
                }
            }
        }
Esempio n. 7
0
        public static void HasDataAndThrowIfNotEmpty()
        {
            AsnReader reader = new AsnReader(new byte[] { 0x01, 0x01, 0x00 }, AsnEncodingRules.BER);

            Assert.True(reader.HasData);
            Assert.Throws <CryptographicException>(() => reader.ThrowIfNotEmpty());

            // Consume the current value and move on.
            reader.GetEncodedValue();

            Assert.False(reader.HasData);
            // Assert.NoThrow
            reader.ThrowIfNotEmpty();
        }
Esempio n. 8
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out PolicyQualifierInfo decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);

            decoded.PolicyQualifierId = sequenceReader.ReadObjectIdentifierAsString();
            decoded.Qualifier         = sequenceReader.GetEncodedValue();

            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 9
0
        public void Decode(byte[] encodedMessage)
        {
            if (encodedMessage == null)
            {
                throw new ArgumentNullException(nameof(encodedMessage));
            }

            // Windows (and thus NetFx) reads the leading data and ignores extra.
            // The deserializer will complain if too much data is given, so use the reader
            // to ask how much we want to deserialize.
            AsnReader             reader     = new AsnReader(encodedMessage, AsnEncodingRules.BER);
            ReadOnlyMemory <byte> cmsSegment = reader.GetEncodedValue();

            ContentInfoAsn contentInfo = AsnSerializer.Deserialize <ContentInfoAsn>(cmsSegment, AsnEncodingRules.BER);

            if (contentInfo.ContentType != Oids.Pkcs7Signed)
            {
                throw new CryptographicException(SR.Cryptography_Cms_InvalidMessageType);
            }

            // Hold a copy of the SignedData memory so we are protected against memory reuse by the caller.
            _heldData    = contentInfo.Content.ToArray();
            _signedData  = AsnSerializer.Deserialize <SignedDataAsn>(_heldData, AsnEncodingRules.BER);
            _contentType = _signedData.EncapContentInfo.ContentType;

            if (!Detached)
            {
                ReadOnlyMemory <byte>?content = _signedData.EncapContentInfo.Content;

                // This is in _heldData, so we don't need a defensive copy.
                _heldContent = content ?? ReadOnlyMemory <byte> .Empty;

                // The ContentInfo object/property DOES need a defensive copy, because
                // a) it is mutable by the user, and
                // b) it is no longer authoritative
                //
                // (and c: it takes a byte[] and we have a ReadOnlyMemory<byte>)
                ContentInfo = new ContentInfo(new Oid(_contentType), _heldContent.Value.ToArray());
            }
            else
            {
                // Hold a defensive copy of the content bytes, (Windows/NetFx compat)
                _heldContent = ContentInfo.Content.CloneByteArray();
            }

            Version  = _signedData.Version;
            _hasData = true;
        }
Esempio n. 10
0
        protected Pkcs12SafeBag(string bagIdValue, ReadOnlyMemory <byte> encodedBagValue, bool skipCopy = false)
        {
            if (string.IsNullOrEmpty(bagIdValue))
            {
                throw new ArgumentNullException(nameof(bagIdValue));
            }

            // Read to ensure that there is precisely one legally encoded value.
            AsnReader reader = new AsnReader(encodedBagValue, AsnEncodingRules.BER);

            reader.GetEncodedValue();
            reader.ThrowIfNotEmpty();

            _bagIdValue     = bagIdValue;
            EncodedBagValue = skipCopy ? encodedBagValue : encodedBagValue.ToArray();
        }
Esempio n. 11
0
        internal static unsafe Pkcs8Response ImportPkcs8PrivateKey(ReadOnlySpan <byte> source, out int bytesRead)
        {
            int len;

            fixed(byte *ptr = &MemoryMarshal.GetReference(source))
            {
                using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length))
                {
                    AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER);
                    len = reader.GetEncodedValue().Length;
                }
            }

            bytesRead = len;
            return(ImportPkcs8(source.Slice(0, len)));
        }
Esempio n. 12
0
        public static void ValidateDer(ReadOnlyMemory <byte> encodedValue)
        {
            Asn1Tag   tag;
            AsnReader reader = new AsnReader(encodedValue, AsnEncodingRules.DER);

            while (reader.HasData)
            {
                tag = reader.PeekTag();

                // If the tag is in the UNIVERSAL class
                //
                // DER limits the constructed encoding to SEQUENCE and SET, as well as anything which gets
                // a defined encoding as being an IMPLICIT SEQUENCE.
                if (tag.TagClass == TagClass.Universal)
                {
                    switch ((UniversalTagNumber)tag.TagValue)
                    {
                    case UniversalTagNumber.External:
                    case UniversalTagNumber.Embedded:
                    case UniversalTagNumber.Sequence:
                    case UniversalTagNumber.Set:
                    case UniversalTagNumber.UnrestrictedCharacterString:
                        if (!tag.IsConstructed)
                        {
                            throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                        }
                        break;

                    default:
                        if (tag.IsConstructed)
                        {
                            throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                        }
                        break;
                    }
                }

                if (tag.IsConstructed)
                {
                    ValidateDer(reader.PeekContentBytes());
                }

                // Skip past the current value.
                reader.GetEncodedValue();
            }
        }
Esempio n. 13
0
        public Pkcs12SecretBag AddSecret(Oid secretType, ReadOnlyMemory <byte> secretValue)
        {
            if (secretType == null)
            {
                throw new ArgumentNullException(nameof(secretType));
            }

            // Read to ensure that there is precisely one legally encoded value.
            AsnReader reader = new AsnReader(secretValue, AsnEncodingRules.BER);

            reader.GetEncodedValue();
            reader.ThrowIfNotEmpty();

            Pkcs12SecretBag bag = new Pkcs12SecretBag(secretType, secretValue);

            AddSafeBag(bag);
            return(bag);
        }
Esempio n. 14
0
        internal static void Decode(AsnReader reader, out CertificateChoiceAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            Asn1Tag tag = reader.PeekTag();

            if (tag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                decoded.Certificate = reader.GetEncodedValue();
            }
            else
            {
                throw new CryptographicException();
            }
        }
Esempio n. 15
0
        public static Pkcs8PrivateKeyInfo Decode(
            ReadOnlyMemory <byte> source,
            out int bytesRead,
            bool skipCopy = false)
        {
            if (!skipCopy)
            {
                AsnReader reader = new AsnReader(source, AsnEncodingRules.BER);
                source = reader.GetEncodedValue().ToArray();
            }

            PrivateKeyInfoAsn privateKeyInfo =
                AsnSerializer.Deserialize <PrivateKeyInfoAsn>(source, AsnEncodingRules.BER, out bytesRead);

            return(new Pkcs8PrivateKeyInfo(
                       privateKeyInfo.PrivateKeyAlgorithm.Algorithm,
                       privateKeyInfo.PrivateKeyAlgorithm.Parameters,
                       privateKeyInfo.PrivateKey,
                       SignerInfo.MakeAttributeCollection(privateKeyInfo.Attributes)));
        }
Esempio n. 16
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Rfc3161TimeStampResp decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);

            System.Security.Cryptography.Pkcs.Asn1.PkiStatusInfo.Decode(sequenceReader, out decoded.Status);

            if (sequenceReader.HasData)
            {
                decoded.TimeStampToken = sequenceReader.GetEncodedValue();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 17
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out OtherKeyAttributeAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);

            decoded.KeyAttrId = sequenceReader.ReadObjectIdentifierAsString();

            if (sequenceReader.HasData)
            {
                decoded.KeyAttr = sequenceReader.GetEncodedValue();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out IssuerAndSerialNumberAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);

            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

            decoded.Issuer       = sequenceReader.GetEncodedValue();
            decoded.SerialNumber = sequenceReader.GetIntegerBytes();

            sequenceReader.ThrowIfNotEmpty();
        }
        public override Oid GetEncodedMessageType(byte[] encodedMessage)
        {
            AsnReader reader = new AsnReader(encodedMessage, AsnEncodingRules.BER);

            ContentInfoAsn contentInfo = AsnSerializer.Deserialize <ContentInfoAsn>(
                reader.GetEncodedValue(),
                AsnEncodingRules.BER);

            switch (contentInfo.ContentType)
            {
            case Oids.Pkcs7Data:
            case Oids.Pkcs7Signed:
            case Oids.Pkcs7Enveloped:
            case Oids.Pkcs7SignedEnveloped:
            case Oids.Pkcs7Hashed:
            case Oids.Pkcs7Encrypted:
                return(new Oid(contentInfo.ContentType));
            }

            throw new CryptographicException(SR.Cryptography_Cms_InvalidMessageType);
        }
Esempio n. 20
0
        public static void ExpectedTag_IgnoresConstructed(
            PublicEncodingRules ruleSet,
            string inputHex,
            PublicTagClass tagClass,
            int tagValue)
        {
            byte[]    inputData = inputHex.HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            AsnReader val1 = reader.ReadSetOf(new Asn1Tag((TagClass)tagClass, tagValue, true));

            Assert.False(reader.HasData);

            reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            AsnReader val2 = reader.ReadSetOf(new Asn1Tag((TagClass)tagClass, tagValue, false));

            Assert.False(reader.HasData);

            Assert.Equal(val1.GetEncodedValue().ByteArrayToHex(), val2.GetEncodedValue().ByteArrayToHex());
        }
Esempio n. 21
0
        private static byte[] EncodeBagValue(string certificateType, ReadOnlyMemory <byte> encodedCertificate)
        {
            // Read to ensure that there is precisely one legally encoded value.
            AsnReader reader = new AsnReader(encodedCertificate, AsnEncodingRules.BER);

            reader.GetEncodedValue();
            reader.ThrowIfNotEmpty();

            // No need to copy encodedCertificate here, because it will be copied into the
            // return value.
            CertBagAsn certBagAsn = new CertBagAsn
            {
                CertId    = certificateType,
                CertValue = encodedCertificate,
            };

            using (AsnWriter writer = AsnSerializer.Serialize(certBagAsn, AsnEncodingRules.BER))
            {
                return(writer.Encode());
            }
        }
Esempio n. 22
0
        public static void TagMustBeCorrect_Universal_Definite(PublicEncodingRules ruleSet)
        {
            byte[]    inputData = "30020500".HexToByteArray();
            AsnReader reader    = new AsnReader(inputData, (AsnEncodingRules)ruleSet);

            AssertExtensions.Throws <ArgumentException>(
                "expectedTag",
                () => reader.ReadSequence(Asn1Tag.Null));

            Assert.True(reader.HasData, "HasData after bad universal tag");

            Assert.Throws <CryptographicException>(
                () => reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)));

            Assert.True(reader.HasData, "HasData after wrong tag");

            AsnReader seq = reader.ReadSequence();

            Assert.Equal("0500", seq.GetEncodedValue().ByteArrayToHex());

            Assert.False(reader.HasData, "HasData after read");
        }
Esempio n. 23
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out CertificationRequestInfoAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);
            AsnReader collectionReader;

            decoded.Version = sequenceReader.GetInteger();
            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

            decoded.Subject = sequenceReader.GetEncodedValue();
            System.Security.Cryptography.Asn1.SubjectPublicKeyInfoAsn.Decode(sequenceReader, out decoded.SubjectPublicKeyInfo);

            // Decode SEQUENCE OF for Attributes
            {
                collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0));
                var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>();
                System.Security.Cryptography.Asn1.AttributeAsn tmpItem;

                while (collectionReader.HasData)
                {
                    System.Security.Cryptography.Asn1.AttributeAsn.Decode(collectionReader, out tmpItem);
                    tmpList.Add(tmpItem);
                }

                decoded.Attributes = tmpList.ToArray();
            }


            sequenceReader.ThrowIfNotEmpty();
        }
Esempio n. 24
0
        public static Pkcs8PrivateKeyInfo Decode(
            ReadOnlyMemory <byte> source,
            out int bytesRead,
            bool skipCopy = false)
        {
            AsnReader reader = new AsnReader(source, AsnEncodingRules.BER);

            if (!skipCopy)
            {
                reader = new AsnReader(reader.GetEncodedValue().ToArray(), AsnEncodingRules.BER);
            }

            int localRead = reader.PeekEncodedValue().Length;

            PrivateKeyInfoAsn.Decode(reader, out PrivateKeyInfoAsn privateKeyInfo);
            bytesRead = localRead;

            return(new Pkcs8PrivateKeyInfo(
                       privateKeyInfo.PrivateKeyAlgorithm.Algorithm,
                       privateKeyInfo.PrivateKeyAlgorithm.Parameters,
                       privateKeyInfo.PrivateKey,
                       SignerInfo.MakeAttributeCollection(privateKeyInfo.Attributes)));
        }
Esempio n. 25
0
        internal static void Decode(AsnReader reader, out DistributionPointNameAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            Asn1Tag   tag = reader.PeekTag();
            AsnReader collectionReader;

            if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                // Decode SEQUENCE OF for FullName
                {
                    collectionReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                    var tmpList = new List <System.Security.Cryptography.Asn1.GeneralNameAsn>();
                    System.Security.Cryptography.Asn1.GeneralNameAsn tmpItem;

                    while (collectionReader.HasData)
                    {
                        System.Security.Cryptography.Asn1.GeneralNameAsn.Decode(collectionReader, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.FullName = tmpList.ToArray();
                }
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                decoded.NameRelativeToCRLIssuer = reader.GetEncodedValue();
            }
            else
            {
                throw new CryptographicException();
            }
        }
Esempio n. 26
0
        private static void AssertRdn(
            AsnReader reader,
            string atvOid,
            int offset,
            Asn1Tag valueTag,
            byte[] bytes,
            string label,
            string stringValue = null)
        {
            AsnReader rdn = reader.ReadSetOf();
            AsnReader attributeTypeAndValue = rdn.ReadSequence();

            Assert.Equal(atvOid, attributeTypeAndValue.ReadObjectIdentifierAsString());

            ReadOnlyMemory <byte> value     = attributeTypeAndValue.GetEncodedValue();
            ReadOnlySpan <byte>   valueSpan = value.Span;

            Assert.True(Asn1Tag.TryParse(valueSpan, out Asn1Tag actualTag, out int bytesRead));
            Assert.Equal(1, bytesRead);
            Assert.Equal(valueTag, actualTag);

            AssertRefSame(
                ref MemoryMarshal.GetReference(valueSpan),
                ref bytes[offset],
                $"{label} is at bytes[{offset}]");

            if (stringValue != null)
            {
                AsnReader valueReader = new AsnReader(value, AsnEncodingRules.DER);
                Assert.Equal(stringValue, valueReader.GetCharacterString((UniversalTagNumber)valueTag.TagValue));
                Assert.False(valueReader.HasData, "valueReader.HasData");
            }

            Assert.False(attributeTypeAndValue.HasData, $"attributeTypeAndValue.HasData ({label})");
            Assert.False(rdn.HasData, $"rdn.HasData ({label})");
        }
        internal CertificateDataAsn(byte[] rawData)
        {
            AsnReader reader = new AsnReader(rawData, AsnEncodingRules.DER).ReadSequence();

            AsnReader tbsCertificate = reader.ReadSequence();

            if (tbsCertificate.PeekTag() == explicit0)
            {
                AsnReader version = tbsCertificate.ReadSequence(explicit0);
                version.TryReadInt32(out Version);
            }
            else if (tbsCertificate.PeekTag() != Asn1Tag.Integer)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }
            else
            {
                Version = 0;
            }

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

            SerialNumber = tbsCertificate.GetIntegerBytes().ToArray();

            AsnReader tbsSignature = tbsCertificate.ReadSequence();

            TbsSignature.AlgorithmId = tbsSignature.ReadObjectIdentifierAsString();
            TbsSignature.Parameters  = tbsSignature.HasData ? tbsSignature.GetEncodedValue().ToArray() : Array.Empty <byte>();

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

            Issuer = new X500DistinguishedName(tbsCertificate.GetEncodedValue().ToArray());

            AsnReader validity = tbsCertificate.ReadSequence();

            NotBefore = validity.GetUtcTime().UtcDateTime;             // FIXME
            NotAfter  = validity.GetUtcTime().UtcDateTime;

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

            Subject = new X500DistinguishedName(tbsCertificate.GetEncodedValue().ToArray());

            SubjectPublicKeyInfo = tbsCertificate.GetEncodedValue().ToArray();
            AsnReader subjectPublicKeyInfo = new AsnReader(SubjectPublicKeyInfo, AsnEncodingRules.DER).ReadSequence();
            AsnReader subjectKeyAlgorithm  = subjectPublicKeyInfo.ReadSequence();

            PublicKeyAlgorithm.AlgorithmId = subjectKeyAlgorithm.ReadObjectIdentifierAsString();
            PublicKeyAlgorithm.Parameters  = subjectKeyAlgorithm.HasData ? subjectKeyAlgorithm.GetEncodedValue().ToArray() : 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() == explicit1)
            {
                IssuerUniqueId = tbsCertificate.ReadBitString();
            }
            else
            {
                IssuerUniqueId = null;
            }

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

            Extensions = new List <X509Extension>();

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

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

                    if (extensionReader.PeekTag() == Asn1Tag.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);
            }

            AsnReader signatureAlgorithm = reader.ReadSequence();

            SignatureAlgorithm.AlgorithmId = signatureAlgorithm.ReadObjectIdentifierAsString();
            SignatureAlgorithm.Parameters  = signatureAlgorithm.HasData ? signatureAlgorithm.GetEncodedValue().ToArray() : 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;
        }
Esempio n. 28
0
        public override DecryptorPal Decode(
            byte[] encodedMessage,
            out int version,
            out ContentInfo contentInfo,
            out AlgorithmIdentifier contentEncryptionAlgorithm,
            out X509Certificate2Collection originatorCerts,
            out CryptographicAttributeObjectCollection unprotectedAttributes)
        {
            // Read using BER because the CMS specification says the encoding is BER.
            AsnReader reader = new AsnReader(encodedMessage, AsnEncodingRules.BER);

            ContentInfoAsn parsedContentInfo = AsnSerializer.Deserialize <ContentInfoAsn>(
                reader.GetEncodedValue(),
                AsnEncodingRules.BER);

            if (parsedContentInfo.ContentType != Oids.Pkcs7Enveloped)
            {
                throw new CryptographicException(SR.Cryptography_Cms_InvalidMessageType);
            }

            byte[] copy = parsedContentInfo.Content.ToArray();

            EnvelopedDataAsn data = AsnSerializer.Deserialize <EnvelopedDataAsn>(
                copy,
                AsnEncodingRules.BER);

            version = data.Version;

            contentInfo = new ContentInfo(
                new Oid(data.EncryptedContentInfo.ContentType),
                data.EncryptedContentInfo.EncryptedContent?.ToArray() ?? Array.Empty <byte>());

            contentEncryptionAlgorithm =
                data.EncryptedContentInfo.ContentEncryptionAlgorithm.ToPresentationObject();

            originatorCerts = new X509Certificate2Collection();

            if (data.OriginatorInfo != null && data.OriginatorInfo.CertificateSet != null)
            {
                foreach (CertificateChoiceAsn certChoice in data.OriginatorInfo.CertificateSet)
                {
                    if (certChoice.Certificate != null)
                    {
                        originatorCerts.Add(new X509Certificate2(certChoice.Certificate.Value.ToArray()));
                    }
                }
            }

            unprotectedAttributes = SignerInfo.MakeAttributeCollection(data.UnprotectedAttributes);

            var recipientInfos = new List <RecipientInfo>();

            foreach (RecipientInfoAsn recipientInfo in data.RecipientInfos)
            {
                if (recipientInfo.Ktri != null)
                {
                    recipientInfos.Add(new KeyTransRecipientInfo(new ManagedKeyTransPal(recipientInfo.Ktri)));
                }
                else if (recipientInfo.Kari != null)
                {
                    for (int i = 0; i < recipientInfo.Kari.RecipientEncryptedKeys.Length; i++)
                    {
                        recipientInfos.Add(
                            new KeyAgreeRecipientInfo(new ManagedKeyAgreePal(recipientInfo.Kari, i)));
                    }
                }
                else
                {
                    Debug.Fail($"{nameof(RecipientInfoAsn)} deserialized with an unknown recipient type");
                    throw new CryptographicException();
                }
            }

            return(new ManagedDecryptorPal(copy, data, new RecipientInfoCollection(recipientInfos)));
        }
Esempio n. 29
0
        internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out TbsCertificateAsn decoded)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = default;
            AsnReader sequenceReader = reader.ReadSequence(expectedTag);
            AsnReader explicitReader;
            AsnReader defaultReader;
            AsnReader collectionReader;


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));

                if (!explicitReader.TryReadInt32(out decoded.Version))
                {
                    explicitReader.ThrowIfNotEmpty();
                }

                explicitReader.ThrowIfNotEmpty();
            }
            else
            {
                defaultReader = new AsnReader(s_defaultVersion, AsnEncodingRules.DER);

                if (!defaultReader.TryReadInt32(out decoded.Version))
                {
                    defaultReader.ThrowIfNotEmpty();
                }
            }

            decoded.SerialNumber = sequenceReader.GetIntegerBytes();
            System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.SignatureAlgorithm);
            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

            decoded.Issuer = sequenceReader.GetEncodedValue();
            System.Security.Cryptography.X509Certificates.Asn1.ValidityAsn.Decode(sequenceReader, out decoded.Validity);
            if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16)))
            {
                throw new CryptographicException();
            }

            decoded.Subject = sequenceReader.GetEncodedValue();
            System.Security.Cryptography.Asn1.SubjectPublicKeyInfoAsn.Decode(sequenceReader, out decoded.SubjectPublicKeyInfo);

            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                if (sequenceReader.TryGetPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 1), out _, out ReadOnlyMemory <byte> tmpIssuerUniqueId))
                {
                    decoded.IssuerUniqueId = tmpIssuerUniqueId;
                }
                else
                {
                    decoded.IssuerUniqueId = sequenceReader.ReadBitString(new Asn1Tag(TagClass.ContextSpecific, 1), out _);
                }
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2)))
            {
                if (sequenceReader.TryGetPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 2), out _, out ReadOnlyMemory <byte> tmpSubjectUniqueId))
                {
                    decoded.SubjectUniqueId = tmpSubjectUniqueId;
                }
                else
                {
                    decoded.SubjectUniqueId = sequenceReader.ReadBitString(new Asn1Tag(TagClass.ContextSpecific, 2), out _);
                }
            }


            if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3)))
            {
                explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3));

                // Decode SEQUENCE OF for Extensions
                {
                    collectionReader = explicitReader.ReadSequence();
                    var tmpList = new List <System.Security.Cryptography.Asn1.X509ExtensionAsn>();
                    System.Security.Cryptography.Asn1.X509ExtensionAsn tmpItem;

                    while (collectionReader.HasData)
                    {
                        System.Security.Cryptography.Asn1.X509ExtensionAsn.Decode(collectionReader, out tmpItem);
                        tmpList.Add(tmpItem);
                    }

                    decoded.Extensions = tmpList.ToArray();
                }

                explicitReader.ThrowIfNotEmpty();
            }


            sequenceReader.ThrowIfNotEmpty();
        }