Exemple #1
0
		// constructors

		public CmsSigner () 
		{
			_signer = SubjectIdentifierType.IssuerAndSerialNumber;
			_digest = new Oid ("1.3.14.3.2.26");
			_options = X509IncludeOption.ExcludeRoot;
			_signed = new CryptographicAttributeObjectCollection ();
			_unsigned = new CryptographicAttributeObjectCollection ();
			_coll = new X509Certificate2Collection ();
		}
Exemple #2
0
		// only accessible from SignedPkcs7.SignerInfos
		internal SignerInfo (string hashName, X509Certificate2 certificate, SubjectIdentifierType type, object o, int version)
		{
			_digest = new Oid (CryptoConfig.MapNameToOID (hashName));
			_certificate = certificate;
			_counter = new SignerInfoCollection ();
			_signed = new CryptographicAttributeObjectCollection ();
			_unsigned = new CryptographicAttributeObjectCollection ();
			_signer = new SubjectIdentifier (type, o);
			_version = version;
		}
Exemple #3
0
        public EnvelopedCms(ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm)
        {
            if (contentInfo == null)
                throw new ArgumentNullException(nameof(contentInfo));
            if (encryptionAlgorithm == null)
                throw new ArgumentNullException(nameof(encryptionAlgorithm));

            Version = 0;  // It makes little sense to ask for a version before you've decoded, but since the desktop returns 0 in that case, we will too.
            ContentInfo = contentInfo;
            ContentEncryptionAlgorithm = encryptionAlgorithm;
            Certificates = new X509Certificate2Collection();
            UnprotectedAttributes = new CryptographicAttributeObjectCollection();
            _decryptorPal = null;
            _lastCall = LastCall.Ctor;
        }
Exemple #4
0
        public static void NonEmbeddedCertificate()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.RsaCapiTransfer1_NoEmbeddedCert);

            Assert.Equal(3, cms.Version);
            Assert.Equal(Oids.Pkcs7Data, cms.ContentInfo.ContentType.Value);

            Assert.Equal(
                "4D6963726F736F667420436F72706F726174696F6E",
                cms.ContentInfo.Content.ByteArrayToHex());

            Assert.Empty(cms.Certificates);

            SignerInfoCollection signers = cms.SignerInfos;

            Assert.Single(signers);

            SignerInfo signer = signers[0];

            Assert.Equal(3, signer.Version);
            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, signer.SignerIdentifier.Type);
            Assert.Equal("6B4A6B92FDED07EE0119F3674A96D1A70D2A588D", (string)signer.SignerIdentifier.Value);
            Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value);

            CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes;

            Assert.Equal(3, signedAttrs.Count);

            Pkcs9ContentType   contentType   = (Pkcs9ContentType)signedAttrs[0].Values[0];
            Pkcs9SigningTime   signingTime   = (Pkcs9SigningTime)signedAttrs[1].Values[0];
            Pkcs9MessageDigest messageDigest = (Pkcs9MessageDigest)signedAttrs[2].Values[0];

            Assert.Equal(Oids.Pkcs7Data, contentType.ContentType.Value);
            Assert.Equal(
                new DateTimeOffset(2017, 11, 2, 15, 34, 4, TimeSpan.Zero),
                signingTime.SigningTime);

            Assert.Equal(DateTimeKind.Utc, signingTime.SigningTime.Kind);

            Assert.Empty(signer.UnsignedAttributes);
            Assert.Empty(signer.CounterSignerInfos);
            Assert.Null(signer.Certificate);

#if netcoreapp
            Assert.Equal(Oids.Rsa, signer.SignatureAlgorithm.Value);

            Assert.Equal(
                "0EDE3870B8A80B45A21BAEC4681D059B46502E1B1AA6B8920CF50D4D837646A5" +
                "5559B4C05849126C655D95FF3C6C1B420E07DC42629F294EE69822FEA56F32D4" +
                "1B824CBB6BF809B7583C27E77B7AC58DFC925B1C60EA4A67AA84D73FC9E9191D" +
                "33B36645F17FD6748A2D8B12C6C384C3C734D27273386211E4518FE2B4ED0147",
                signer.GetSignature().ByteArrayToHex());
#endif

            using (SHA1 sha1 = SHA1.Create())
            {
                Assert.Equal(
                    sha1.ComputeHash(cms.ContentInfo.Content).ByteArrayToHex(),
                    messageDigest.MessageDigest.ByteArrayToHex());
            }

            // Since it's not NoSignature CheckHash will throw.
            Assert.Throws <CryptographicException>(() => signer.CheckHash());

            // Since there's no matched certificate CheckSignature will throw.
            Assert.Throws <CryptographicException>(() => signer.CheckSignature(true));

            // Since there are no NoSignature signers, SignedCms.CheckHash will succeed
            cms.CheckHash();

            // Since there are no matched certificates SignedCms.CheckSignature will throw.
            Assert.Throws <CryptographicException>(() => cms.CheckSignature(true));

            using (X509Certificate2 wrongCert = Certificates.RSAKeyTransfer1.GetCertificate())
                using (X509Certificate2 rightCert = Certificates.RSAKeyTransferCapi1.GetCertificate())
                {
                    X509Certificate2Collection coll = new X509Certificate2Collection(wrongCert);

                    // Wrong certificate, still throw.
                    Assert.Throws <CryptographicException>(() => signer.CheckSignature(coll, true));
                    Assert.Throws <CryptographicException>(() => cms.CheckSignature(coll, true));

                    coll = new X509Certificate2Collection(rightCert);

                    // Right cert, success
                    signer.CheckSignature(coll, true);
                    Assert.Null(signer.Certificate);
                    cms.CheckSignature(coll, true);
                    Assert.Null(cms.SignerInfos[0].Certificate);

                    coll.Add(wrongCert);

                    // Both right and wrong, success
                    signer.CheckSignature(coll, true);
                    Assert.Null(signer.Certificate);
                    cms.CheckSignature(coll, true);
                    Assert.Null(cms.SignerInfos[0].Certificate);

                    coll = new X509Certificate2Collection(wrongCert);

                    // Just wrong again, no accidental stateful match
                    Assert.Throws <CryptographicException>(() => signer.CheckSignature(coll, true));
                    Assert.Throws <CryptographicException>(() => cms.CheckSignature(coll, true));

                    coll.Add(rightCert);

                    // Wrong then right, success
                    signer.CheckSignature(coll, true);
                    Assert.Null(signer.Certificate);
                    cms.CheckSignature(coll, true);
                    Assert.Null(cms.SignerInfos[0].Certificate);
                }
        }
Exemple #5
0
        public static void CheckNoSignatureDocument()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.NoSignatureSignedWithAttributesAndCounterSignature);

            Assert.Equal(1, cms.Version);
            Assert.Equal(Oids.Pkcs7Data, cms.ContentInfo.ContentType.Value);

            Assert.Equal(
                "4D6963726F736F667420436F72706F726174696F6E",
                cms.ContentInfo.Content.ByteArrayToHex());

            X509Certificate2Collection cmsCerts = cms.Certificates;

            Assert.Single(cmsCerts);

            SignerInfoCollection signers = cms.SignerInfos;

            Assert.Single(signers);

            SignerInfo signer = signers[0];

            Assert.Equal(SubjectIdentifierType.NoSignature, signer.SignerIdentifier.Type);
            Assert.Null(signer.SignerIdentifier.Value);
            Assert.Null(signer.Certificate);
            Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value);

#if netcoreapp
            Assert.Equal("1.3.6.1.5.5.7.6.2", signer.SignatureAlgorithm.Value);

            Assert.Equal(
                "8B70D20D0477A35CD84AB962C10DC52FBA6FAD6B",
                signer.GetSignature().ByteArrayToHex());
#endif

            CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes;
            Assert.Equal(3, signedAttrs.Count);

            Assert.Single(signedAttrs[0].Values);
            Assert.Single(signedAttrs[1].Values);
            Assert.Single(signedAttrs[2].Values);

            Pkcs9ContentType   contentType   = (Pkcs9ContentType)signedAttrs[0].Values[0];
            Pkcs9SigningTime   signingTime   = (Pkcs9SigningTime)signedAttrs[1].Values[0];
            Pkcs9MessageDigest messageDigest = (Pkcs9MessageDigest)signedAttrs[2].Values[0];

            Assert.Equal(Oids.Pkcs7Data, contentType.ContentType.Value);
            Assert.Equal(
                new DateTimeOffset(2017, 11, 1, 17, 17, 17, TimeSpan.Zero),
                signingTime.SigningTime);

            Assert.Equal(DateTimeKind.Utc, signingTime.SigningTime.Kind);

            using (SHA1 sha1 = SHA1.Create())
            {
                Assert.Equal(
                    sha1.ComputeHash(cms.ContentInfo.Content).ByteArrayToHex(),
                    messageDigest.MessageDigest.ByteArrayToHex());
            }

            CryptographicAttributeObjectCollection unsignedAttrs = signer.UnsignedAttributes;
            Assert.Single(unsignedAttrs);
            // No need to check the contents, it's a CounterSigner (tested next)

            SignerInfoCollection counterSigners = signer.CounterSignerInfos;
            Assert.Single(counterSigners);

            SignerInfo counterSigner = counterSigners[0];
            Assert.Equal(3, counterSigner.Version);
            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, counterSigner.SignerIdentifier.Type);
            Assert.Equal("6B4A6B92FDED07EE0119F3674A96D1A70D2A588D", (string)counterSigner.SignerIdentifier.Value);
            Assert.Equal(Oids.Sha1, counterSigner.DigestAlgorithm.Value);

            CryptographicAttributeObjectCollection csSignedAttrs = counterSigner.SignedAttributes;
            Assert.Equal(2, csSignedAttrs.Count);

            // RFC3369 says that the content-type attribute must not be present for counter-signers, but it is.
            // RFC2630 said that it "is not required".
            Pkcs9ContentType   csContentType   = (Pkcs9ContentType)csSignedAttrs[0].Values[0];
            Pkcs9MessageDigest csMessageDigest = (Pkcs9MessageDigest)csSignedAttrs[1].Values[0];

            Assert.Equal(Oids.Pkcs7Data, csContentType.ContentType.Value);
            Assert.Equal(
                "833378066BDCCBA7047EF6919843D181A57D6479",
                csMessageDigest.MessageDigest.ByteArrayToHex());

#if netcoreapp
            Assert.Equal(Oids.Rsa, counterSigner.SignatureAlgorithm.Value);

            Assert.Equal(
                "2155D226DD744166E582D040E60535210195050EA00F2C179897198521DABD0E" +
                "6B27750FD8BA5F9AAF58B4863B6226456F38553A22453CAF0A0F106766C7AB6F" +
                "3D6AFD106753DC50F8A6E4F9E5508426D236C2DBB4BCB8162FA42E995CBA16A3" +
                "40FD7C793569DF1B71368E68253299BC74E38312B40B8F52EAEDE10DF414A522",
                counterSigner.GetSignature().ByteArrayToHex());
#endif

            using (X509Certificate2 capiCert = Certificates.RSAKeyTransferCapi1.GetCertificate())
            {
                Assert.Equal(capiCert, cmsCerts[0]);
                Assert.Equal(capiCert, counterSigner.Certificate);
            }

            // The counter-signer has a (real) signature, and a certificate, so CheckSignature
            // will pass
            counterSigner.CheckSignature(true);

            // The (primary) signer has a hash-only signature with no certificate,
            // so CheckSignature will fail.
            Assert.Throws <CryptographicException>(() => signer.CheckSignature(true));

            // The (primary) signer is a NoSignature type, so CheckHash will succeed
            signer.CheckHash();

            // The document has a NoSignature signer, so CheckHash will do something (and succeed).
            cms.CheckHash();

            // Since the document's primary signer is NoSignature, CheckSignature will fail
            Assert.Throws <CryptographicException>(() => cms.CheckSignature(true));
        }
Exemple #6
0
        public static void ReadRsaPkcs1CounterSigned()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.CounterSignedRsaPkcs1OneSigner);

            Assert.Equal(1, cms.Version);

            ContentInfo contentInfo = cms.ContentInfo;

            Assert.Equal("1.2.840.113549.1.7.1", contentInfo.ContentType.Value);
            Assert.Equal("4D6963726F736F667420436F72706F726174696F6E", contentInfo.Content.ByteArrayToHex());

            SignerInfoCollection signers = cms.SignerInfos;

            Assert.Single(signers);
            SignerInfo signer = signers[0];

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.GetCertificate())
            {
                X509Certificate2Collection certs = cms.Certificates;

                Assert.Single(certs);

                Assert.Equal(cert, certs[0]);
                Assert.Equal(cert, signer.Certificate);
                Assert.NotSame(certs[0], signer.Certificate);
                Assert.NotSame(cert, signer.Certificate);
                Assert.NotSame(cert, certs[0]);
            }

            Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, signer.SignerIdentifier.Type);
            Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value);

#if netcoreapp
            Assert.Equal(Oids.Rsa, signer.SignatureAlgorithm.Value);

            Assert.Equal(
                "5A1717621D450130B3463662160EEC06F7AE77E017DD95F294E97A0BDD433FE6" +
                "B2CCB34FAAC33AEA50BFD7D9E78DC7174836284619F744278AE77B8495091E09" +
                "6EEF682D9CA95F6E81C7DDCEDDA6A12316B453C894B5000701EB09DF57A53B73" +
                "3A4E80DA27FA710870BD88C86E2FDB9DCA14D18BEB2F0C87E9632ABF02BE2FE3",
                signer.GetSignature().ByteArrayToHex());
#endif

            CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes;
            Assert.Empty(signedAttrs);

            CryptographicAttributeObjectCollection unsignedAttrs = signer.UnsignedAttributes;
            Assert.Single(unsignedAttrs);

            Assert.Equal(Oids.CounterSigner, unsignedAttrs[0].Oid.Value);

            SignerInfoCollection counterSigners = signer.CounterSignerInfos;
            Assert.Single(counterSigners);
            SignerInfo counterSigner = counterSigners[0];

            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, counterSigner.SignerIdentifier.Type);

            // Not universally true, but is in this case.
            Assert.Equal(signer.Certificate, counterSigner.Certificate);
            Assert.NotSame(signer.Certificate, counterSigner.Certificate);

            // Assert.NotThrows
            signer.CheckSignature(true);

            // Assert.NotThrows
            counterSigner.CheckSignature(true);

            // The document should be validly signed, then.
            // Assert.NotThrows
            cms.CheckSignature(true);

            // If CheckSignature succeeds then CheckHash cannot.
            Assert.Throws <CryptographicException>(() => counterSigner.CheckHash());
            Assert.Throws <CryptographicException>(() => signer.CheckHash());

            // Since there are no NoSignature signers, CheckHash won't throw.
            // Assert.NotThrows
            cms.CheckHash();
        }
Exemple #7
0
        public static void ReadRsaPssDocument()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.RsaPssDocument);

            Assert.Equal(3, cms.Version);

            ContentInfo contentInfo = cms.ContentInfo;

            Assert.Equal("1.2.840.113549.1.7.1", contentInfo.ContentType.Value);
            Assert.Equal("54686973206973206120746573740D0A", contentInfo.Content.ByteArrayToHex());

            X509Certificate2Collection certs = cms.Certificates;

            Assert.Single(certs);

            X509Certificate2 topLevelCert = certs[0];

            Assert.Equal("localhost", topLevelCert.GetNameInfo(X509NameType.SimpleName, false));

            Assert.Equal(
                new DateTimeOffset(2016, 3, 2, 2, 37, 54, TimeSpan.Zero),
                new DateTimeOffset(topLevelCert.NotBefore));

            Assert.Equal(
                new DateTimeOffset(2017, 3, 2, 2, 37, 54, TimeSpan.Zero),
                new DateTimeOffset(topLevelCert.NotAfter));

            SignerInfoCollection signers = cms.SignerInfos;

            Assert.Single(signers);

            SignerInfo signer = signers[0];

            Assert.Equal(3, signer.Version);
            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, signer.SignerIdentifier.Type);
            Assert.Equal("1063CAB14FB14C47DC211C0E0285F3EE5946BF2D", signer.SignerIdentifier.Value);
            Assert.Equal("2.16.840.1.101.3.4.2.1", signer.DigestAlgorithm.Value);
#if netcoreapp
            Assert.Equal("1.2.840.113549.1.1.10", signer.SignatureAlgorithm.Value);
#endif

            CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes;
            Assert.Equal(4, signedAttrs.Count);

            Assert.Equal("1.2.840.113549.1.9.3", signedAttrs[0].Oid.Value);
            Assert.Equal("1.2.840.113549.1.9.5", signedAttrs[1].Oid.Value);
            Assert.Equal("1.2.840.113549.1.9.4", signedAttrs[2].Oid.Value);
            Assert.Equal("1.2.840.113549.1.9.15", signedAttrs[3].Oid.Value);

            Assert.Equal(1, signedAttrs[0].Values.Count);
            Assert.Equal(1, signedAttrs[1].Values.Count);
            Assert.Equal(1, signedAttrs[2].Values.Count);
            Assert.Equal(1, signedAttrs[3].Values.Count);

            Pkcs9ContentType contentTypeAttr = (Pkcs9ContentType)signedAttrs[0].Values[0];
            Assert.Equal("1.2.840.113549.1.7.1", contentTypeAttr.ContentType.Value);

            Pkcs9SigningTime signingTimeAttr = (Pkcs9SigningTime)signedAttrs[1].Values[0];
            Assert.Equal(
                new DateTimeOffset(2017, 10, 26, 1, 6, 25, TimeSpan.Zero),
                new DateTimeOffset(signingTimeAttr.SigningTime));

            Pkcs9MessageDigest messageDigestAttr = (Pkcs9MessageDigest)signedAttrs[2].Values[0];
            Assert.Equal(
                "07849DC26FCBB2F3BD5F57BDF214BAE374575F1BD4E6816482324799417CB379",
                messageDigestAttr.MessageDigest.ByteArrayToHex());

            Assert.IsType <Pkcs9AttributeObject>(signedAttrs[3].Values[0]);
            Assert.NotSame(signedAttrs[3].Oid, signedAttrs[3].Values[0].Oid);
            Assert.Equal(
                "306A300B060960864801650304012A300B0609608648016503040116300B0609" +
                "608648016503040102300A06082A864886F70D0307300E06082A864886F70D03" +
                "0202020080300D06082A864886F70D0302020140300706052B0E030207300D06" +
                "082A864886F70D0302020128",
                signedAttrs[3].Values[0].RawData.ByteArrayToHex());

#if netcoreapp
            Assert.Equal(
                "B93E81D141B3C9F159AB0021910635DC72E8E860BE43C28E5D53243D6DC247B7" +
                "D4F18C20195E80DEDCC75B29C43CE5047AD775B65BFC93589BD748B950C68BAD" +
                "DF1A4673130302BBDA8667D5DDE5EA91ECCB13A9B4C04F1C4842FEB1697B7669" +
                "C7692DD3BDAE13B5AA8EE3EB5679F3729D1DC4F2EB9DC89B7E8773F2F8C6108C" +
                "05",
                signer.GetSignature().ByteArrayToHex());
#endif

            CryptographicAttributeObjectCollection unsignedAttrs = signer.UnsignedAttributes;
            Assert.Empty(unsignedAttrs);

            SignerInfoCollection counterSigners = signer.CounterSignerInfos;
            Assert.Empty(counterSigners);

            X509Certificate2 signerCertificate = signer.Certificate;
            Assert.Equal(
                "CN=localhost, OU=.NET Framework, O=Microsoft Corp., L=Redmond, S=Washington, C=US",
                signerCertificate.SubjectName.Name);

            // CheckHash always throws for certificate-based signers.
            Assert.Throws <CryptographicException>(() => signer.CheckHash());

            // At this time we cannot support the PSS parameters for this document.
            Assert.Throws <CryptographicException>(() => signer.CheckSignature(true));

            // Since there are no NoSignature signers the document CheckHash will succeed.
            // Assert.NotThrows
            cms.CheckHash();

            // Since at least one signer fails, the document signature will fail
            Assert.Throws <CryptographicException>(() => cms.CheckSignature(true));
        }
        public static void RemoveNegative()
        {
            CryptographicAttributeObjectCollection c = new CryptographicAttributeObjectCollection();

            Assert.Throws <ArgumentNullException>(() => c.Remove(null));
        }
Exemple #9
0
        public sealed unsafe override byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes)
        {
            using (SafeCryptMsgHandle hCryptMsg = EncodeHelpers.CreateCryptMsgHandleToEncode(recipients, contentInfo.ContentType, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes))
            {
                byte[] encodedContent;
                if (contentInfo.ContentType.Value.Equals(Oids.Pkcs7Data, StringComparison.OrdinalIgnoreCase))
                {
                    unsafe
                    {
                        byte[] content = contentInfo.Content;
                        fixed(byte *pContent = content)
                        {
                            DATA_BLOB blob = new DATA_BLOB((IntPtr)pContent, (uint)(content.Length));

                            encodedContent = Interop.Crypt32.CryptEncodeObjectToByteArray(CryptDecodeObjectStructType.X509_OCTET_STRING, &blob);
                        }
                    }
                }
                else
                {
                    encodedContent = contentInfo.Content;

                    if (encodedContent.Length > 0)
                    {
                        // Windows will throw if it encounters indefinite length encoding.
                        // Let's reencode if that is the case
                        ReencodeIfUsingIndefiniteLengthEncodingOnOuterStructure(ref encodedContent);
                    }
                }

                if (encodedContent.Length > 0)
                {
                    // Pin to avoid copy during heap compaction
                    fixed(byte *pinnedContent = encodedContent)
                    {
                        try
                        {
                            if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedContent, encodedContent.Length, fFinal: true))
                            {
                                throw Marshal.GetLastWin32Error().ToCryptographicException();
                            }
                        }
                        finally
                        {
                            if (!object.ReferenceEquals(encodedContent, contentInfo.Content))
                            {
                                Array.Clear(encodedContent, 0, encodedContent.Length);
                            }
                        }
                    }
                }

                byte[] encodedMessage = hCryptMsg.GetMsgParamAsByteArray(CryptMsgParamType.CMSG_CONTENT_PARAM);
                return(encodedMessage);
            }
        }
Exemple #10
0
            //
            // This returns an allocated native memory block. Its lifetime (and that of any allocated subblocks it may point to) is that of "hb".
            //
            private static unsafe CMSG_ENVELOPED_ENCODE_INFO *CreateCmsEnvelopedEncodeInfo(CmsRecipientCollection recipients, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes, HeapBlockRetainer hb)
            {
                CMSG_ENVELOPED_ENCODE_INFO *pEnvelopedEncodeInfo = (CMSG_ENVELOPED_ENCODE_INFO *)(hb.Alloc(sizeof(CMSG_ENVELOPED_ENCODE_INFO)));

                pEnvelopedEncodeInfo->cbSize     = sizeof(CMSG_ENVELOPED_ENCODE_INFO);
                pEnvelopedEncodeInfo->hCryptProv = IntPtr.Zero;

                string algorithmOidValue = contentEncryptionAlgorithm.Oid.Value;

                pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(algorithmOidValue);

                // Desktop compat: Though it seems like we could copy over the contents of contentEncryptionAlgorithm.Parameters, that property is for retrieving information from decoded Cms's only, and it
                // massages the raw data so it wouldn't be usable here anyway. To hammer home that fact, the EncryptedCms constructor rather rudely forces contentEncryptionAlgorithm.Parameters to be the empty array.
                pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.Parameters.cbData = 0;
                pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.Parameters.pbData = IntPtr.Zero;

                pEnvelopedEncodeInfo->pvEncryptionAuxInfo = GenerateEncryptionAuxInfoIfNeeded(contentEncryptionAlgorithm, hb);

                int numRecipients = recipients.Count;

                pEnvelopedEncodeInfo->cRecipients   = numRecipients;
                pEnvelopedEncodeInfo->rgpRecipients = IntPtr.Zero;

                CMSG_RECIPIENT_ENCODE_INFO *rgCmsRecipients = (CMSG_RECIPIENT_ENCODE_INFO *)(hb.Alloc(numRecipients, sizeof(CMSG_RECIPIENT_ENCODE_INFO)));

                for (int index = 0; index < numRecipients; index++)
                {
                    rgCmsRecipients[index] = EncodeRecipientInfo(recipients[index], contentEncryptionAlgorithm, hb);
                }
                pEnvelopedEncodeInfo->rgCmsRecipients = rgCmsRecipients;

                int numCertificates = originatorCerts.Count;

                pEnvelopedEncodeInfo->cCertEncoded  = numCertificates;
                pEnvelopedEncodeInfo->rgCertEncoded = null;
                if (numCertificates != 0)
                {
                    DATA_BLOB *pCertEncoded = (DATA_BLOB *)(hb.Alloc(numCertificates, sizeof(DATA_BLOB)));
                    for (int i = 0; i < numCertificates; i++)
                    {
                        byte[] certEncoded = originatorCerts[i].Export(X509ContentType.Cert);
                        pCertEncoded[i].cbData = (uint)(certEncoded.Length);
                        pCertEncoded[i].pbData = hb.AllocBytes(certEncoded);
                    }
                    pEnvelopedEncodeInfo->rgCertEncoded = pCertEncoded;
                }

                pEnvelopedEncodeInfo->cCrlEncoded  = 0;
                pEnvelopedEncodeInfo->rgCrlEncoded = null;

                pEnvelopedEncodeInfo->cAttrCertEncoded  = 0;
                pEnvelopedEncodeInfo->rgAttrCertEncoded = null;

                int numUnprotectedAttributes = unprotectedAttributes.Count;

                pEnvelopedEncodeInfo->cUnprotectedAttr  = numUnprotectedAttributes;
                pEnvelopedEncodeInfo->rgUnprotectedAttr = null;
                if (numUnprotectedAttributes != 0)
                {
                    CRYPT_ATTRIBUTE *pCryptAttribute = (CRYPT_ATTRIBUTE *)(hb.Alloc(numUnprotectedAttributes, sizeof(CRYPT_ATTRIBUTE)));
                    for (int i = 0; i < numUnprotectedAttributes; i++)
                    {
                        CryptographicAttributeObject attribute = unprotectedAttributes[i];
                        pCryptAttribute[i].pszObjId = hb.AllocAsciiString(attribute.Oid.Value);
                        AsnEncodedDataCollection values = attribute.Values;
                        int numValues = values.Count;
                        pCryptAttribute[i].cValue = numValues;
                        DATA_BLOB *pValues = (DATA_BLOB *)(hb.Alloc(numValues, sizeof(DATA_BLOB)));
                        for (int j = 0; j < numValues; j++)
                        {
                            byte[] rawData = values[j].RawData;
                            pValues[j].cbData = (uint)(rawData.Length);
                            pValues[j].pbData = hb.AllocBytes(rawData);
                        }
                        pCryptAttribute[i].rgValue = pValues;
                    }
                    pEnvelopedEncodeInfo->rgUnprotectedAttr = pCryptAttribute;
                }

                return(pEnvelopedEncodeInfo);
            }
Exemple #11
0
            public static SafeCryptMsgHandle CreateCryptMsgHandleToEncode(CmsRecipientCollection recipients, Oid innerContentType, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes)
            {
                using (HeapBlockRetainer hb = new HeapBlockRetainer())
                {
                    // Deep copy the CmsRecipients (and especially their underlying X509Certificate2 objects). This will prevent malicious callers from altering them or disposing them while we're performing
                    // unsafe memory crawling inside them.
                    recipients = recipients.DeepCopy();

                    // We must keep all the certificates inside recipients alive until the call to CryptMsgOpenToEncode() finishes. The CMSG_ENVELOPED_ENCODE_INFO* structure we passed to it
                    // contains direct pointers to memory owned by the CERT_INFO memory block whose lifetime is that of the certificate.
                    hb.KeepAlive(recipients);
                    unsafe
                    {
                        CMSG_ENVELOPED_ENCODE_INFO *pEnvelopedEncodeInfo = CreateCmsEnvelopedEncodeInfo(recipients, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes, hb);
                        SafeCryptMsgHandle          hCryptMsg            = Interop.Crypt32.CryptMsgOpenToEncode(MsgEncodingType.All, 0, CryptMsgType.CMSG_ENVELOPED, pEnvelopedEncodeInfo, innerContentType.Value, IntPtr.Zero);
                        if (hCryptMsg == null || hCryptMsg.IsInvalid)
                        {
                            throw Marshal.GetLastWin32Error().ToCryptographicException();
                        }

                        return(hCryptMsg);
                    }
                }
            }
 public sealed override unsafe byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes)
 {
     using (SafeCryptMsgHandle hCryptMsg = EncodeHelpers.CreateCryptMsgHandleToEncode(recipients, contentInfo.ContentType, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes))
     {
         byte[] encodedContent;
         if (contentInfo.ContentType.Value !.Equals(Oids.Pkcs7Data, StringComparison.OrdinalIgnoreCase))
         {
             encodedContent = PkcsHelpers.EncodeOctetString(contentInfo.Content);
         }
Exemple #13
0
        public static void Test1()
        {
            var loader = (CertLoaderFromRawData)Certificates.RSAKeyTransferCapi1;
            ReadOnlyMemory <byte> pfxData = loader.PfxData;

            Pkcs12Info info = Pkcs12Info.Decode(pfxData, out int bytesConsumed);

            Assert.Equal(pfxData.Length, bytesConsumed);

            Assert.Equal(Pkcs12IntegrityMode.Password, info.IntegrityMode);
            CheckMac(info, loader.Password);

            ReadOnlyCollection <Pkcs12SafeContents> authSafe = info.AuthenticatedSafe;

            Assert.Same(authSafe, info.AuthenticatedSafe);
            Assert.Equal(2, authSafe.Count);

            Assert.Equal(Pkcs12ConfidentialityMode.None, authSafe[0].ConfidentialityMode);
            Assert.Equal(Pkcs12ConfidentialityMode.None, authSafe[1].ConfidentialityMode);

            List <Pkcs12SafeBag> safe0Bags = new List <Pkcs12SafeBag>(authSafe[0].GetBags());

            Assert.Equal(1, safe0Bags.Count);
            Pkcs12ShroudedKeyBag shroudedKeyBag = Assert.IsType <Pkcs12ShroudedKeyBag>(safe0Bags[0]);

            CryptographicAttributeObjectCollection keyBagAttrs = shroudedKeyBag.Attributes;

            Assert.Same(keyBagAttrs, shroudedKeyBag.Attributes);
            Assert.Equal(2, keyBagAttrs.Count);
            Assert.Equal(Oids.LocalKeyId, keyBagAttrs[0].Oid.Value);
            Assert.Equal(1, keyBagAttrs[0].Values.Count);
            Pkcs9LocalKeyId keyKeyId = Assert.IsType <Pkcs9LocalKeyId>(keyBagAttrs[0].Values[0]);

            Assert.Equal("1.3.6.1.4.1.311.17.1", keyBagAttrs[1].Oid.Value);
            Assert.Equal(1, keyBagAttrs[1].Values.Count);
            Pkcs9AttributeObject cspNameAttr = Assert.IsType <Pkcs9AttributeObject>(keyBagAttrs[1].Values[0]);

            byte[] cspNameBytes = Encoding.BigEndianUnicode.GetBytes("Microsoft Strong Cryptographic Provider");

            Assert.Equal(
                $"1E{cspNameBytes.Length:X2}{cspNameBytes.ByteArrayToHex()}",
                cspNameAttr.RawData.ByteArrayToHex());

            List <Pkcs12SafeBag> safe1Bags = new List <Pkcs12SafeBag>(authSafe[1].GetBags());

            Assert.Equal(1, safe0Bags.Count);
            Assert.IsType <Pkcs12CertBag>(safe1Bags[0]);
            Pkcs12CertBag certBag = (Pkcs12CertBag)safe1Bags[0];

            Assert.True(certBag.IsX509Certificate, "certBag.IsX509Certificate");
            Assert.InRange(certBag.EncodedCertificate.Length, loader.CerData.Length + 2, int.MaxValue);

            CryptographicAttributeObjectCollection certBagAttrs = certBag.Attributes;

            Assert.Same(certBagAttrs, certBag.Attributes);
            Assert.Equal(1, certBagAttrs.Count);
            Assert.Equal(Oids.LocalKeyId, certBagAttrs[0].Oid.Value);
            Assert.Equal(1, certBagAttrs[0].Values.Count);
            Pkcs9LocalKeyId certKeyId = Assert.IsType <Pkcs9LocalKeyId>(certBagAttrs[0].Values[0]);

            Assert.Equal(keyKeyId.KeyId.ByteArrayToHex(), certKeyId.KeyId.ByteArrayToHex());

            byte[] data = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
            byte[] encrypted;

            using (X509Certificate2 fromLoader = loader.GetCertificate())
                using (X509Certificate2 fromBag = certBag.GetCertificate())
                    using (RSA loaderPub = fromLoader.GetRSAPublicKey())
                    {
                        Assert.Equal(fromLoader.RawData, fromBag.RawData);

                        encrypted = loaderPub.Encrypt(data, RSAEncryptionPadding.OaepSHA1);
                    }

            int bytesRead;

            using (RSA rsa = RSA.Create())
            {
                rsa.ImportEncryptedPkcs8PrivateKey(
                    loader.Password,
                    shroudedKeyBag.EncryptedPkcs8PrivateKey.Span,
                    out bytesRead);

                byte[] dec = rsa.Decrypt(encrypted, RSAEncryptionPadding.OaepSHA1);
                Assert.Equal(data, dec);
            }

            Assert.Equal(shroudedKeyBag.EncryptedPkcs8PrivateKey.Length, bytesRead);
        }
Exemple #14
0
        private byte[] Encrypt(
            CmsRecipientCollection recipients,
            ContentInfo contentInfo,
            AlgorithmIdentifier contentEncryptionAlgorithm,
            X509Certificate2Collection originatorCerts,
            CryptographicAttributeObjectCollection unprotectedAttributes,
            byte[] encryptedContent,
            byte[] cek,
            byte[] parameterBytes)
        {
            EnvelopedDataAsn envelopedData = new EnvelopedDataAsn
            {
                EncryptedContentInfo =
                {
                    ContentType                = contentInfo.ContentType.Value,

                    ContentEncryptionAlgorithm =
                    {
                        Algorithm  = contentEncryptionAlgorithm.Oid,
                        Parameters = parameterBytes,
                    },

                    EncryptedContent           = encryptedContent,
                },
            };

            if (unprotectedAttributes != null && unprotectedAttributes.Count > 0)
            {
                List <AttributeAsn> attrList = CmsSigner.BuildAttributes(unprotectedAttributes);

                envelopedData.UnprotectedAttributes = PkcsHelpers.NormalizeAttributeSet(attrList.ToArray());
            }

            if (originatorCerts != null && originatorCerts.Count > 0)
            {
                CertificateChoiceAsn[] certs = new CertificateChoiceAsn[originatorCerts.Count];

                for (int i = 0; i < originatorCerts.Count; i++)
                {
                    certs[i].Certificate = originatorCerts[i].RawData;
                }

                envelopedData.OriginatorInfo = new OriginatorInfoAsn
                {
                    CertificateSet = certs,
                };
            }

            envelopedData.RecipientInfos = new RecipientInfoAsn[recipients.Count];

            bool allRecipientsVersion0 = true;

            for (var i = 0; i < recipients.Count; i++)
            {
                CmsRecipient recipient = recipients[i];
                bool         v0Recipient;

                switch (recipient.Certificate.GetKeyAlgorithm())
                {
                case Oids.Rsa:
                    envelopedData.RecipientInfos[i].Ktri = MakeKtri(cek, recipient, out v0Recipient);
                    break;

                default:
                    throw new CryptographicException(
                              SR.Cryptography_Cms_UnknownAlgorithm,
                              recipient.Certificate.GetKeyAlgorithm());
                }

                allRecipientsVersion0 = allRecipientsVersion0 && v0Recipient;
            }

            // https://tools.ietf.org/html/rfc5652#section-6.1
            //
            // v4 (RFC 3852):
            //   * OriginatorInfo contains certificates with type other (not supported)
            //   * OriginatorInfo contains crls with type other (not supported)
            // v3 (RFC 3369):
            //   * OriginatorInfo contains v2 attribute certificates (not supported)
            //   * Any PWRI (password) recipients are present (not supported)
            //   * Any ORI (other) recipients are present (not supported)
            // v2 (RFC 2630):
            //   * OriginatorInfo is present
            //   * Any RecipientInfo has a non-zero version number
            //   * UnprotectedAttrs is present
            // v1 (not defined for EnvelopedData)
            // v0 (RFC 2315):
            //   * Anything not already matched

            if (envelopedData.OriginatorInfo != null ||
                !allRecipientsVersion0 ||
                envelopedData.UnprotectedAttributes != null)
            {
                envelopedData.Version = 2;
            }

            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                envelopedData.Encode(writer);
                return(PkcsHelpers.EncodeContentInfo(writer.Encode(), Oids.Pkcs7Enveloped));
            }
        }
        public static void Nullary()
        {
            CryptographicAttributeObjectCollection c = new CryptographicAttributeObjectCollection();

            AssertEquals(c, Array.Empty <CryptographicAttributeObject>());
        }
Exemple #16
0
        public static void ReadRsaPkcs1DoubleCounterSigned()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.OneRsaSignerTwoRsaCounterSigners);

            Assert.Equal(1, cms.Version);

            ContentInfo contentInfo = cms.ContentInfo;

            Assert.Equal("1.2.840.113549.1.7.1", contentInfo.ContentType.Value);
            Assert.Equal("4D6963726F736F667420436F72706F726174696F6E", contentInfo.Content.ByteArrayToHex());

            SignerInfoCollection signers = cms.SignerInfos;

            Assert.Single(signers);
            SignerInfo signer = signers[0];

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.GetCertificate())
            {
                X509Certificate2Collection certs = cms.Certificates;

                Assert.Equal(2, certs.Count);

                Assert.Equal(cert, certs[1]);
                Assert.Equal(cert, signer.Certificate);
                Assert.NotSame(certs[1], signer.Certificate);
                Assert.NotSame(cert, signer.Certificate);
                Assert.NotSame(cert, certs[1]);
            }

            Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, signer.SignerIdentifier.Type);
            Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value);

#if netcoreapp
            Assert.Equal(Oids.Rsa, signer.SignatureAlgorithm.Value);

            Assert.Equal(
                "5A1717621D450130B3463662160EEC06F7AE77E017DD95F294E97A0BDD433FE6" +
                "B2CCB34FAAC33AEA50BFD7D9E78DC7174836284619F744278AE77B8495091E09" +
                "6EEF682D9CA95F6E81C7DDCEDDA6A12316B453C894B5000701EB09DF57A53B73" +
                "3A4E80DA27FA710870BD88C86E2FDB9DCA14D18BEB2F0C87E9632ABF02BE2FE3",
                signer.GetSignature().ByteArrayToHex());
#endif

            CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes;
            Assert.Empty(signedAttrs);

            CryptographicAttributeObjectCollection unsignedAttrs = signer.UnsignedAttributes;
            Assert.Equal(2, unsignedAttrs.Count);

            Assert.Equal(Oids.CounterSigner, unsignedAttrs[0].Oid.Value);

            SignerInfoCollection counterSigners = signer.CounterSignerInfos;
            Assert.Equal(2, counterSigners.Count);
            SignerInfo cs1 = counterSigners[0];
            SignerInfo cs2 = counterSigners[1];

            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, cs1.SignerIdentifier.Type);

            // Not universally true, but is in this case.
            Assert.Equal(signer.Certificate, cs1.Certificate);
            Assert.NotSame(signer.Certificate, cs1.Certificate);

            Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, cs2.SignerIdentifier.Type);
            Assert.NotEqual(signer.Certificate, cs2.Certificate);

            // Assert.NotThrows
            signer.CheckSignature(true);

            // Assert.NotThrows
            cs1.CheckSignature(true);

            // Assert.NotThrows
            cs2.CheckSignature(true);

            // The document should be validly signed, then.
            // Assert.NotThrows
            cms.CheckSignature(true);

#if netcoreapp
            Assert.Equal(
                "1AA282DBED4D862D7CEA30F803E790BDB0C97EE852778CEEDDCD94BB9304A155" +
                "2E60A8D36052AC8C2D28755F3B2F473824100AB3A6ABD4C15ABD77E0FFE13D0D" +
                "F253BCD99C718FA673B6CB0CBBC68CE5A4AC671298C0A07C7223522E0E7FFF15" +
                "CEDBAB55AAA99588517674671691065EB083FB729D1E9C04B2BF99A9953DAA5E",
                cs2.GetSignature().ByteArrayToHex());
#endif

            // If CheckSignature succeeds then CheckHash cannot.
            Assert.Throws <CryptographicException>(() => cs1.CheckHash());
            Assert.Throws <CryptographicException>(() => cs2.CheckHash());
            Assert.Throws <CryptographicException>(() => signer.CheckHash());

            // Since there are no NoSignature signers, CheckHash won't throw.
            // Assert.NotThrows
            cms.CheckHash();
        }
Exemple #17
0
 public sealed override DecryptorPal Decode(ReadOnlySpan <byte> encodedMessage, out int version, out ContentInfo contentInfo, out AlgorithmIdentifier contentEncryptionAlgorithm, out X509Certificate2Collection originatorCerts, out CryptographicAttributeObjectCollection unprotectedAttributes)
 {
     return(DecryptorPalWindows.Decode(encodedMessage, out version, out contentInfo, out contentEncryptionAlgorithm, out originatorCerts, out unprotectedAttributes));
 }
Exemple #18
0
        public static void ReadIndefiniteEncodingNoMac(int trailingByteCount)
        {
            ReadOnlyMemory <byte> source = PadContents(Pkcs12Documents.IndefiniteEncodingNoMac, trailingByteCount);

            Pkcs12Info info = Pkcs12Info.Decode(
                source,
                out int bytesRead,
                skipCopy: true);

            Assert.Equal(Pkcs12Documents.IndefiniteEncodingNoMac.Length, bytesRead);
            Assert.Equal(Pkcs12IntegrityMode.None, info.IntegrityMode);

            ReadOnlyCollection <Pkcs12SafeContents> safes = info.AuthenticatedSafe;

            Assert.Equal(2, safes.Count);

            Pkcs12SafeContents firstSafe  = safes[0];
            Pkcs12SafeContents secondSafe = safes[1];

            Assert.Equal(Pkcs12ConfidentialityMode.None, firstSafe.ConfidentialityMode);
            Assert.Equal(Pkcs12ConfidentialityMode.None, secondSafe.ConfidentialityMode);

            Assert.True(firstSafe.IsReadOnly, "firstSafe.IsReadOnly");
            Assert.True(secondSafe.IsReadOnly, "secondSafe.IsReadOnly");

            Pkcs12SafeBag[] firstContents  = firstSafe.GetBags().ToArray();
            Pkcs12SafeBag[] secondContents = secondSafe.GetBags().ToArray();

            Assert.Equal(1, firstContents.Length);
            Assert.Equal(1, secondContents.Length);

            Pkcs12KeyBag  keyBag  = Assert.IsType <Pkcs12KeyBag>(firstContents[0]);
            Pkcs12CertBag certBag = Assert.IsType <Pkcs12CertBag>(secondContents[0]);

            CryptographicAttributeObjectCollection keyBagAttrs  = keyBag.Attributes;
            CryptographicAttributeObjectCollection certBagAttrs = certBag.Attributes;

            Assert.Equal(2, keyBagAttrs.Count);
            Assert.Equal(2, certBagAttrs.Count);

            Assert.Equal(Oids.FriendlyName, keyBagAttrs[0].Oid.Value);
            Assert.Equal(1, keyBagAttrs[0].Values.Count);
            Assert.Equal(Oids.LocalKeyId, keyBagAttrs[1].Oid.Value);
            Assert.Equal(1, keyBagAttrs[1].Values.Count);

            Pkcs9AttributeObject keyFriendlyName =
                Assert.IsAssignableFrom <Pkcs9AttributeObject>(keyBagAttrs[0].Values[0]);

            Pkcs9LocalKeyId keyKeyId = Assert.IsType <Pkcs9LocalKeyId>(keyBagAttrs[1].Values[0]);

            Assert.Equal(Oids.FriendlyName, certBagAttrs[0].Oid.Value);
            Assert.Equal(1, certBagAttrs[0].Values.Count);
            Assert.Equal(Oids.LocalKeyId, certBagAttrs[1].Oid.Value);
            Assert.Equal(1, certBagAttrs[1].Values.Count);

            Pkcs9AttributeObject certFriendlyName =
                Assert.IsAssignableFrom <Pkcs9AttributeObject>(certBagAttrs[0].Values[0]);

            Pkcs9LocalKeyId certKeyId = Assert.IsType <Pkcs9LocalKeyId>(certBagAttrs[1].Values[0]);

            // This PFX gave a friendlyName value of "cert" to both the key and the cert.
            Assert.Equal("1E080063006500720074", keyFriendlyName.RawData.ByteArrayToHex());
            Assert.Equal(keyFriendlyName.RawData, certFriendlyName.RawData);

            // The private key (KeyBag) and the public key (CertBag) are matched from their keyId value.
            Assert.Equal("0414EDF3D122CF623CF0CFC9CD226261E8415A83E630", keyKeyId.RawData.ByteArrayToHex());
            Assert.Equal("EDF3D122CF623CF0CFC9CD226261E8415A83E630", keyKeyId.KeyId.ByteArrayToHex());
            Assert.Equal(keyKeyId.RawData, certKeyId.RawData);

            using (X509Certificate2 cert = certBag.GetCertificate())
                using (RSA privateKey = RSA.Create())
                    using (RSA publicKey = cert.GetRSAPublicKey())
                    {
                        privateKey.ImportPkcs8PrivateKey(keyBag.Pkcs8PrivateKey.Span, out _);

                        Assert.Equal(
                            publicKey.ExportSubjectPublicKeyInfo().ByteArrayToHex(),
                            privateKey.ExportSubjectPublicKeyInfo().ByteArrayToHex());
                    }
        }
Exemple #19
0
		// constructors

		public EnvelopedCms () 
		{
			_certs = new X509Certificate2Collection ();
			_recipients = new RecipientInfoCollection ();
			_uattribs = new CryptographicAttributeObjectCollection ();
		}
Exemple #20
0
 /// <summary>
 /// Encrypt and encode a CMS. Return value is the RFC-compliant representation of the CMS that can be transmitted "on the wire."
 /// </summary>
 public abstract byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes);
Exemple #21
0
 /// <summary>
 /// Decode an encoded CMS.
 ///    Call RecipientInfos on the returned pal object to get the recipients.
 ///    Call TryDecrypt() on the returned pal object to attempt a decrypt for a single recipient.
 /// </summary>
 public abstract DecryptorPal Decode(byte[] encodedMessage, out int version, out ContentInfo contentInfo, out AlgorithmIdentifier contentEncryptionAlgorithm, out X509Certificate2Collection originatorCerts, out CryptographicAttributeObjectCollection unprotectedAttributes);
        internal static DecryptorPalWindows Decode(
            ReadOnlySpan <byte> encodedMessage,
            out int version,
            out ContentInfo contentInfo,
            out AlgorithmIdentifier contentEncryptionAlgorithm,
            out X509Certificate2Collection originatorCerts,
            out CryptographicAttributeObjectCollection unprotectedAttributes
            )
        {
            SafeCryptMsgHandle?hCryptMsg = null;

            try
            {
                hCryptMsg = Interop.Crypt32.CryptMsgOpenToDecode(MsgEncodingType.All, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
                if (hCryptMsg == null || hCryptMsg.IsInvalid)
                {
                    throw Marshal.GetLastPInvokeError().ToCryptographicException();
                }

                if (!Interop.Crypt32.CryptMsgUpdate(
                        hCryptMsg,
                        ref MemoryMarshal.GetReference(encodedMessage),
                        encodedMessage.Length,
                        fFinal: true))
                {
                    throw Marshal.GetLastPInvokeError().ToCryptographicException();
                }

                CryptMsgType cryptMsgType = hCryptMsg.GetMessageType();
                if (cryptMsgType != CryptMsgType.CMSG_ENVELOPED)
                {
                    throw ErrorCode.CRYPT_E_INVALID_MSG_TYPE.ToCryptographicException();
                }

                version = hCryptMsg.GetVersion();

                contentInfo = hCryptMsg.GetContentInfo();

                AlgorithmIdentifierAsn contentEncryptionAlgorithmAsn;
                using (SafeHandle sh = hCryptMsg.GetMsgParamAsMemory(CryptMsgParamType.CMSG_ENVELOPE_ALGORITHM_PARAM))
                {
                    unsafe
                    {
                        CRYPT_ALGORITHM_IDENTIFIER *pCryptAlgorithmIdentifier = (CRYPT_ALGORITHM_IDENTIFIER *)(sh.DangerousGetHandle());
                        contentEncryptionAlgorithm = (*pCryptAlgorithmIdentifier).ToAlgorithmIdentifier();
                        contentEncryptionAlgorithmAsn.Algorithm  = contentEncryptionAlgorithm.Oid.Value !;
                        contentEncryptionAlgorithmAsn.Parameters = (*pCryptAlgorithmIdentifier).Parameters.ToByteArray();
                    }
                }

                originatorCerts       = hCryptMsg.GetOriginatorCerts();
                unprotectedAttributes = hCryptMsg.GetUnprotectedAttributes();

                RecipientInfoCollection recipientInfos = CreateRecipientInfos(hCryptMsg);
                return(new DecryptorPalWindows(hCryptMsg, recipientInfos, contentEncryptionAlgorithmAsn));
            }
            catch
            {
                hCryptMsg?.Dispose();
                throw;
            }
        }