Exemplo n.º 1
0
        internal void Decode(ReadOnlyMemory <byte> encodedMessage)
        {
            // Windows (and thus NetFx) reads the leading data and ignores extra.
            // So use the Decode overload which doesn't throw on extra data.
            ContentInfoAsn.Decode(
                new AsnReader(encodedMessage, AsnEncodingRules.BER),
                out ContentInfoAsn contentInfo);

            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      = SignedDataAsn.Decode(_heldData, AsnEncodingRules.BER);
            _contentType     = _signedData.EncapContentInfo.ContentType;
            _hasPkcs7Content = false;

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

                if (content.HasValue)
                {
                    contentValue = GetContent(content.Value, _contentType);
                    // If no OCTET STRING was stripped off, we have PKCS7 interop concerns.
                    _hasPkcs7Content = content.Value.Length == contentValue.Length;
                }
                else
                {
                    contentValue = ReadOnlyMemory <byte> .Empty;
                }

                // This is in _heldData, so we don't need a defensive copy.
                _heldContent = contentValue;

                // 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), contentValue.ToArray());
            }
            else
            {
                // Hold a defensive copy of the content bytes, (Windows/NetFx compat)
                _heldContent = ContentInfo.Content.CloneByteArray();
            }

            Version  = _signedData.Version;
            _hasData = true;
        }
Exemplo n.º 2
0
        public override Oid GetEncodedMessageType(byte[] encodedMessage)
        {
            AsnReader reader = new AsnReader(encodedMessage, AsnEncodingRules.BER);

            ContentInfoAsn.Decode(reader, out ContentInfoAsn contentInfo);

            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);
        }
Exemplo n.º 3
0
        public static Pkcs12Info Decode(
            ReadOnlyMemory <byte> encodedBytes,
            out int bytesConsumed,
            bool skipCopy = false)
        {
            AsnReader reader = new AsnReader(encodedBytes, AsnEncodingRules.BER);

            // Trim it to the first value
            encodedBytes = reader.PeekEncodedValue();

            ReadOnlyMemory <byte> maybeCopy = skipCopy ? encodedBytes : encodedBytes.ToArray();
            PfxAsn pfx = PfxAsn.Decode(maybeCopy, AsnEncodingRules.BER);

            // https://tools.ietf.org/html/rfc7292#section-4 only defines version 3.
            if (pfx.Version != 3)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            ReadOnlyMemory <byte> authSafeBytes = ReadOnlyMemory <byte> .Empty;
            Pkcs12IntegrityMode   mode          = Pkcs12IntegrityMode.Unknown;

            if (pfx.AuthSafe.ContentType == Oids.Pkcs7Data)
            {
                authSafeBytes = PkcsHelpers.DecodeOctetStringAsMemory(pfx.AuthSafe.Content);

                if (pfx.MacData.HasValue)
                {
                    mode = Pkcs12IntegrityMode.Password;
                }
                else
                {
                    mode = Pkcs12IntegrityMode.None;
                }
            }
            else if (pfx.AuthSafe.ContentType == Oids.Pkcs7Signed)
            {
                SignedDataAsn signedData = SignedDataAsn.Decode(pfx.AuthSafe.Content, AsnEncodingRules.BER);

                mode = Pkcs12IntegrityMode.PublicKey;

                if (signedData.EncapContentInfo.ContentType == Oids.Pkcs7Data)
                {
                    authSafeBytes = signedData.EncapContentInfo.Content.GetValueOrDefault();
                }

                if (pfx.MacData.HasValue)
                {
                    throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                }
            }

            if (mode == Pkcs12IntegrityMode.Unknown)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            List <ContentInfoAsn> authSafeData   = new List <ContentInfoAsn>();
            AsnReader             authSafeReader = new AsnReader(authSafeBytes, AsnEncodingRules.BER);
            AsnReader             sequenceReader = authSafeReader.ReadSequence();

            authSafeReader.ThrowIfNotEmpty();
            while (sequenceReader.HasData)
            {
                ContentInfoAsn.Decode(sequenceReader, out ContentInfoAsn contentInfo);
                authSafeData.Add(contentInfo);
            }

            ReadOnlyCollection <Pkcs12SafeContents> authSafe;

            if (authSafeData.Count == 0)
            {
                authSafe = new ReadOnlyCollection <Pkcs12SafeContents>(Array.Empty <Pkcs12SafeContents>());
            }
            else
            {
                Pkcs12SafeContents[] contentsArray = new Pkcs12SafeContents[authSafeData.Count];

                for (int i = 0; i < contentsArray.Length; i++)
                {
                    contentsArray[i] = new Pkcs12SafeContents(authSafeData[i]);
                }

                authSafe = new ReadOnlyCollection <Pkcs12SafeContents>(contentsArray);
            }

            bytesConsumed = encodedBytes.Length;

            return(new Pkcs12Info
            {
                AuthenticatedSafe = authSafe,
                IntegrityMode = mode,
                _decoded = pfx,
                _authSafeContents = authSafeBytes,
            });
        }
Exemplo n.º 4
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.Decode(
                reader,
                out ContentInfoAsn parsedContentInfo);

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

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

            EnvelopedDataAsn data = EnvelopedDataAsn.Decode(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.HasValue && data.OriginatorInfo.Value.CertificateSet != null)
            {
                foreach (CertificateChoiceAsn certChoice in data.OriginatorInfo.Value.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.HasValue)
                {
                    recipientInfos.Add(new KeyTransRecipientInfo(new ManagedKeyTransPal(recipientInfo.Ktri.Value)));
                }
                else if (recipientInfo.Kari.HasValue)
                {
                    for (int i = 0; i < recipientInfo.Kari.Value.RecipientEncryptedKeys.Length; i++)
                    {
                        recipientInfos.Add(
                            new KeyAgreeRecipientInfo(new ManagedKeyAgreePal(recipientInfo.Kari.Value, i)));
                    }
                }
                else
                {
                    Debug.Fail($"{nameof(RecipientInfoAsn)} deserialized with an unknown recipient type");
                    throw new CryptographicException();
                }
            }

            return(new ManagedDecryptorPal(copy, data, new RecipientInfoCollection(recipientInfos)));
        }