예제 #1
0
        private void TestSimpleDecrypt_RoundTrip(CertLoader certLoader, ContentInfo contentInfo, string algorithmOidValue, SubjectIdentifierType type, ContentInfo expectedContentInfo = null)
        {
            // Deep-copy the contentInfo since the real ContentInfo doesn't do this. This defends against a bad implementation changing
            // our "expectedContentInfo" to match what it produces.
            expectedContentInfo = expectedContentInfo ?? new ContentInfo(new Oid(contentInfo.ContentType), (byte[])(contentInfo.Content.Clone()));

            string certSubjectName;

            byte[] encodedMessage;
            byte[] originalCopy = (byte[])(contentInfo.Content.Clone());
            using (X509Certificate2 certificate = certLoader.GetCertificate())
            {
                certSubjectName = certificate.Subject;
                AlgorithmIdentifier alg          = new AlgorithmIdentifier(new Oid(algorithmOidValue));
                EnvelopedCms        ecms         = new EnvelopedCms(contentInfo, alg);
                CmsRecipient        cmsRecipient = new CmsRecipient(type, certificate);
                ecms.Encrypt(cmsRecipient);
                Assert.Equal(originalCopy.ByteArrayToHex(), ecms.ContentInfo.Content.ByteArrayToHex());
                encodedMessage = ecms.Encode();
            }

            // We don't pass "certificate" down because it's expected that the certificate used for encrypting doesn't have a private key (part of the purpose of this test is
            // to ensure that you don't need the recipient's private key to encrypt.) The decrypt phase will have to locate the matching cert with the private key.
            VerifySimpleDecrypt(encodedMessage, certLoader, expectedContentInfo);
        }
예제 #2
0
        private void VerifySimpleDecrypt(byte[] encodedMessage, CertLoader certLoader, ContentInfo expectedContent)
        {
            EnvelopedCms ecms = new EnvelopedCms();

            ecms.Decode(encodedMessage);

            using (X509Certificate2 cert = certLoader.TryGetCertificateWithPrivateKey())
            {
                if (cert == null)
                {
                    return; // Sorry - CertLoader is not configured to load certs with private keys - we've tested as much as we can.
                }
#if netcoreapp              // API not present on netfx
                if (_useExplicitPrivateKey)
                {
                    using (X509Certificate2 pubCert = certLoader.GetCertificate())
                    {
                        RecipientInfo recipient = ecms.RecipientInfos.Cast <RecipientInfo>().Where((r) => r.RecipientIdentifier.MatchesCertificate(cert)).Single();
                        ecms.Decrypt(recipient, cert.PrivateKey);
                    }
                }
                else
#endif
                {
                    X509Certificate2Collection extraStore = new X509Certificate2Collection(cert);
                    ecms.Decrypt(extraStore);
                }
                ContentInfo contentInfo = ecms.ContentInfo;
                Assert.Equal(expectedContent.ContentType.Value, contentInfo.ContentType.Value);
                Assert.Equal(expectedContent.Content.ByteArrayToHex(), contentInfo.Content.ByteArrayToHex());
            }
        }
예제 #3
0
        public static void TwoEkuExtensions(X509IncludeOption includeOption)
        {
            CertLoader     loader = Certificates.TwoEkuTsaCert;
            DateTimeOffset referenceTime;

            using (X509Certificate2 cert = loader.GetCertificate())
            {
                referenceTime = cert.NotAfter.AddDays(-1);

                var ekuExts = cert.Extensions.OfType <X509EnhancedKeyUsageExtension>().ToList();

                Assert.Equal(2, ekuExts.Count);

                // Make sure we're validating that "early success" doesn't happen.
                Assert.Contains(
                    Oids.TimeStampingPurpose,
                    ekuExts[0].EnhancedKeyUsages.OfType <Oid>().Select(o => o.Value));
            }

            CustomBuild_CertMismatch(
                loader,
                referenceTime,
                SigningCertificateOption.ValidHashNoName,
                SigningCertificateOption.Omit,
                includeOption: includeOption);
        }
예제 #4
0
        private static void Assert_Certificate_Roundtrip(CertLoader certificateLoader)
        {
            ContentInfo  contentInfo = new ContentInfo(new byte[] { 1, 2, 3 });
            EnvelopedCms ecms        = new EnvelopedCms(contentInfo);

            using (X509Certificate2 cert = certificateLoader.GetCertificate())
            {
                CmsRecipient recipient = new CmsRecipient(cert);
                ecms.Encrypt(recipient);
            }

            byte[] encodedMessage = ecms.Encode();

            ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);

            using (X509Certificate2 privateCert = certificateLoader.TryGetCertificateWithPrivateKey())
            {
                if (privateCert == null)
                {
                    return; // CertLoader can't load the private certificate.
                }
                ecms.Decrypt(new X509Certificate2Collection(privateCert));
            }
            Assert.Equal(contentInfo.ContentType.Value, ecms.ContentInfo.ContentType.Value);
            Assert.Equal <byte>(contentInfo.Content, ecms.ContentInfo.Content);
        }
예제 #5
0
        private static KeyTransRecipientInfo EncodeKeyTransl_Rsa2048(RSAEncryptionPadding encryptionPadding, CertLoader loader)
        {
            ContentInfo  contentInfo = new ContentInfo(new byte[] { 1, 2, 3 });
            EnvelopedCms ecms        = new EnvelopedCms(contentInfo);

            using (X509Certificate2 cert = loader.GetCertificate())
            {
                CmsRecipient cmsRecipient;
                if (encryptionPadding is null)
                {
                    cmsRecipient = new CmsRecipient(cert);
                }
                else
                {
                    cmsRecipient = new CmsRecipient(cert, encryptionPadding);
                }

                ecms.Encrypt(cmsRecipient);
            }
            byte[] encodedMessage = ecms.Encode();

            EnvelopedCms ecms2 = new EnvelopedCms();

            ecms2.Decode(encodedMessage);

            RecipientInfoCollection recipients = ecms2.RecipientInfos;

            Assert.Equal(1, recipients.Count);
            RecipientInfo recipientInfo = recipients[0];

            Assert.IsType <KeyTransRecipientInfo>(recipientInfo);
            return((KeyTransRecipientInfo)recipientInfo);
        }
예제 #6
0
        public static void NoTsaEku(X509IncludeOption includeOption)
        {
            CertLoader     loader = Certificates.TlsClientServerCert;
            DateTimeOffset referenceTime;

            using (X509Certificate2 cert = loader.GetCertificate())
            {
                referenceTime = cert.NotAfter.AddDays(-1);
            }

            CustomBuild_CertMismatch(
                loader,
                referenceTime,
                SigningCertificateOption.ValidHashNoName,
                SigningCertificateOption.Omit,
                includeOption: includeOption);
        }
예제 #7
0
        public static void TimestampTooNew(X509IncludeOption includeOption)
        {
            CertLoader     loader = Certificates.ValidLookingTsaCert;
            DateTimeOffset referenceTime;

            using (X509Certificate2 cert = loader.GetCertificate())
            {
                referenceTime = cert.NotAfter.AddSeconds(1);
            }

            CustomBuild_CertMismatch(
                loader,
                referenceTime,
                SigningCertificateOption.ValidHashNoName,
                SigningCertificateOption.Omit,
                includeOption: includeOption);
        }
예제 #8
0
        public void EncryptToNegativeSerialNumber()
        {
            CertLoader negativeSerial = Certificates.NegativeSerialNumber;

            const string expectedSerial = "FD319CB1514B06AF49E00522277E43C8";

            byte[]       content     = { 1, 2, 3 };
            ContentInfo  contentInfo = new ContentInfo(content);
            EnvelopedCms cms         = new EnvelopedCms(contentInfo);

            using (X509Certificate2 cert = negativeSerial.GetCertificate())
            {
                Assert.Equal(expectedSerial, cert.SerialNumber);

                CmsRecipient recipient = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, cert);
                cms.Encrypt(recipient);
            }

            EnvelopedCms cms2 = new EnvelopedCms();

            cms2.Decode(cms.Encode());

            RecipientInfoCollection recipients = cms2.RecipientInfos;

            Assert.Equal(1, recipients.Count);

            RecipientInfo recipientInfo = recipients[0];

            Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, recipientInfo.RecipientIdentifier.Type);

            X509IssuerSerial issuerSerial = (X509IssuerSerial)recipientInfo.RecipientIdentifier.Value;

            Assert.Equal(expectedSerial, issuerSerial.SerialNumber);

            using (X509Certificate2 cert = negativeSerial.TryGetCertificateWithPrivateKey())
            {
                Assert.Equal(expectedSerial, cert.SerialNumber);

                cms2.Decrypt(new X509Certificate2Collection(cert));
            }

            Assert.Equal(content, cms2.ContentInfo.Content);
        }
예제 #9
0
        public static void NoEkuExtension(X509IncludeOption includeOption)
        {
            CertLoader     loader = Certificates.RSA2048SignatureOnly;
            DateTimeOffset referenceTime;

            using (X509Certificate2 cert = loader.GetCertificate())
            {
                referenceTime = cert.NotAfter.AddDays(-1);

                Assert.Equal(0, cert.Extensions.OfType <X509EnhancedKeyUsageExtension>().Count());
            }

            CustomBuild_CertMismatch(
                loader,
                referenceTime,
                SigningCertificateOption.ValidHashNoName,
                SigningCertificateOption.Omit,
                includeOption: includeOption);
        }
예제 #10
0
        public static void NonCriticalEkuExtension(X509IncludeOption includeOption)
        {
            CertLoader     loader = Certificates.NonCriticalTsaEku;
            DateTimeOffset referenceTime;

            using (X509Certificate2 cert = loader.GetCertificate())
            {
                referenceTime = cert.NotAfter.AddDays(-1);

                var ekuExts = cert.Extensions.OfType <X509EnhancedKeyUsageExtension>().ToList();

                Assert.Equal(1, ekuExts.Count);
                Assert.False(ekuExts[0].Critical, "ekuExts[0].Critical");
            }

            CustomBuild_CertMismatch(
                loader,
                referenceTime,
                SigningCertificateOption.ValidHashNoName,
                SigningCertificateOption.Omit,
                includeOption: includeOption);
        }
예제 #11
0
        private static void CustomBuild_CertMismatch(
            CertLoader loader,
            DateTimeOffset referenceTime,
            SigningCertificateOption v1Option,
            SigningCertificateOption v2Option,
            HashAlgorithmName v2AlgorithmName    = default,
            X509IncludeOption includeOption      = default,
            SubjectIdentifierType identifierType = SubjectIdentifierType.IssuerAndSerialNumber)
        {
            byte[] tokenBytes = BuildCustomToken(
                loader,
                referenceTime,
                v1Option,
                v2Option,
                v2AlgorithmName,
                includeOption,
                identifierType);

            Rfc3161TimestampToken token;

            bool willParse = includeOption == X509IncludeOption.None;

            if (willParse && identifierType == SubjectIdentifierType.IssuerAndSerialNumber)
            {
                // Because IASN matches against the ESSCertId(V2) directly it will reject the token.

                switch (v1Option)
                {
                case SigningCertificateOption.ValidHashWithInvalidName:
                case SigningCertificateOption.ValidHashWithInvalidSerial:
                case SigningCertificateOption.InvalidHashWithInvalidName:
                case SigningCertificateOption.InvalidHashWithInvalidSerial:
                    willParse = false;
                    break;
                }

                switch (v2Option)
                {
                case SigningCertificateOption.ValidHashWithInvalidName:
                case SigningCertificateOption.ValidHashWithInvalidSerial:
                case SigningCertificateOption.InvalidHashWithInvalidName:
                case SigningCertificateOption.InvalidHashWithInvalidSerial:
                    willParse = false;
                    break;
                }
            }

            if (willParse)
            {
                Assert.True(Rfc3161TimestampToken.TryDecode(tokenBytes, out token, out int bytesRead));
                Assert.NotNull(token);
                Assert.Equal(tokenBytes.Length, bytesRead);

                using (X509Certificate2 cert = loader.GetCertificate())
                {
                    Assert.False(
                        token.VerifySignatureForHash(
                            token.TokenInfo.GetMessageHash().Span,
                            token.TokenInfo.HashAlgorithmId,
                            out X509Certificate2 signer,
                            new X509Certificate2Collection(cert)));

                    Assert.Null(signer);
                }
            }
            else
            {
                Assert.False(Rfc3161TimestampToken.TryDecode(tokenBytes, out token, out int bytesRead));

                Assert.Null(token);
                Assert.Equal(0, bytesRead);
            }
        }