public static void GenerateRSA(string[] args, Action<string, string> saveAction)
		{
			//Grab the incoming args.
			//Should contain cert name as first arg
			ArgParser appArgs = new ArgParser(args);

			//This will load the cert file with the provided path.
			CertLoader loader = new CertLoader(appArgs.CertName);

			//Once we've loaded the cert we need to pull the RSA data from it.
			//We want to also load it with the private key.
			RSACryptoServiceProvider provider = new CertToRSAProviderConverter(loader.Certificate, true).Provider;
			RSAExportFormatter formatter = new RSAExportFormatter(provider);

			try
			{
				saveAction(formatter.ClientRSAXML, $"{appArgs.CertName.Replace(".pfx", "")}Client.rsa");

				saveAction(formatter.ServerRSAXML, $"{appArgs.CertName.Replace(".pfx", "")}Server.rsa");
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
				Console.WriteLine(e.StackTrace);
				Console.ReadKey();
			}
		}
Example #2
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);
        }
        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);
        }
Example #4
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);
        }
Example #5
0
        public void TestDecryptSimpleAes256_IssuerAndSerial()
        {
            // Message encrypted on framework for a recipient using the certificate returned by Certificates.RSAKeyTransfer1.GetCertificate()
            // and of type IssuerAndSerialNumber. The symmetric algorithm used is Aes256
            byte[] encryptedMessage =
                ("3082011F06092A864886F70D010703A08201103082010C0201003181C83081C5020100302E301A311830160"
                 + "603550403130F5253414B65795472616E7366657231021031D935FB63E8CFAB48A0BF7B397B67C0300D0609"
                 + "2A864886F70D01010730000481800215BF7505BCD5D083F8EFDA01A4F91D61DE3967779B2F5E4360593D4CB"
                 + "96474E36198531A5E20E417B04C5C7E3263C3301DF8FA888FFBECC796500D382858379059C986285AFD605C"
                 + "B5DE125487CCA658DF261C836720E2E14440DA60E2F12D6D5E3992A0DB59973929DF6FC23D8E891F97CA956"
                 + "2A7AD160B502FA3C10477AA303C06092A864886F70D010701301D060960864801650304012A04101287FE80"
                 + "93F3C517AE86AFB95E599D7E80101823D88F47191857BE0743C4C730E39E").HexToByteArray();

            byte[]      expectedContent     = { 1, 2, 3, 4 };
            ContentInfo expectedContentInfo = new ContentInfo(expectedContent);
            CertLoader  certLoader          = Certificates.RSAKeyTransfer1;

            VerifySimpleDecrypt(encryptedMessage, certLoader, expectedContentInfo);
        }
Example #6
0
        public void TestDecryptSimpleTripleDes_IssuerAndSerial()
        {
            // Message encrypted on framework for a recipient using the certificate returned by Certificates.RSAKeyTransfer1.GetCertificate()
            // and of type IssuerAndSerialNumber. The symmetric algorithm used is 3DES-CBC
            byte[] encryptedMessage =
                ("3082010C06092A864886F70D010703A081FE3081FB0201003181C83081C5020100302E301A3118301606035"
                 + "50403130F5253414B65795472616E7366657231021031D935FB63E8CFAB48A0BF7B397B67C0300D06092A86"
                 + "4886F70D0101010500048180062F6F16637C8F35B73924AD85BA47D99DBB4800CB8F0C4094F6896050B7C1F"
                 + "11CE79BEE55A638EAAE70F2C32C01FC24B8D09D9D574CB7373788C8BC3A4748124154338C74B644A2A11750"
                 + "9E97D1B3535FAE70E4E7C8F2F866232CBFC6448E89CF9D72B948EDCF9C9FC9C153BCC7104680282A4BBBC1E"
                 + "E367F094F627EE45FCD302B06092A864886F70D010701301406082A864886F70D030704081E3F12D42E4041"
                 + "58800877A4A100165DD0F2").HexToByteArray();

            byte[]      expectedContent     = { 1, 2, 3, 4 };
            ContentInfo expectedContentInfo = new ContentInfo(expectedContent);
            CertLoader  certLoader          = Certificates.RSAKeyTransfer1;

            VerifySimpleDecrypt(encryptedMessage, certLoader, expectedContentInfo);
        }
Example #7
0
        public void TestDecryptSimpleAes128_IssuerAndSerial()
        {
            // Message encrypted on framework for a recipient using the certificate returned by Certificates.RSAKeyTransfer1.GetCertificate()
            // and of type IssuerAndSerialNumber. The symmetric algorithm is Aes128
            byte[] encryptedMessage =
                ("3082011F06092A864886F70D010703A08201103082010C0201003181C83081C5020100302E301A311830160"
                 + "603550403130F5253414B65795472616E7366657231021031D935FB63E8CFAB48A0BF7B397B67C0300D0609"
                 + "2A864886F70D0101073000048180862175CD3B2932235A67C6A025F75CDA1A43B53E785370895BA9AC8D0DD"
                 + "318EB36DFAE275B16ABD497FEBBFCF2D4B3F38C75B91DC40941A2CC1F7F47E701EEA2D5A770C485565F8726"
                 + "DC0D59DDE17AA6DB0F9384C919FC8BC6CB561A980A9AE6095486FDF9F52249FB466B3676E4AEFE4035C15DC"
                 + "EE769F25E4660D4BE664E7F303C06092A864886F70D010701301D060960864801650304010204100A068EE9"
                 + "03E085EA5A03D1D8B4B73DD88010740E5DE9B798AA062B449F104D0F5D35").HexToByteArray();

            byte[]      expectedContent     = { 1, 2, 3, 4 };
            ContentInfo expectedContentInfo = new ContentInfo(expectedContent);
            CertLoader  certLoader          = Certificates.RSAKeyTransfer1;

            VerifySimpleDecrypt(encryptedMessage, certLoader, expectedContentInfo);
        }
Example #8
0
        private static 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.
                }
                X509Certificate2Collection extraStore = new X509Certificate2Collection(cert);
                ecms.Decrypt(extraStore);
                ContentInfo contentInfo = ecms.ContentInfo;
                Assert.Equal(expectedContent.ContentType.Value, contentInfo.ContentType.Value);
                Assert.Equal <byte>(expectedContent.Content, contentInfo.Content);
            }
        }
Example #9
0
        public void TestDecryptSimpleAes256_RsaTransferCapi()
        {
            // Message encrypted on framework for a recipient using the certificate returned by Certificates.RSAKeyTransferCapi1.GetCertificate()
            // and of type IssuerAndSerialNumber. The symmetric algorithm used is Aes256
            byte[] encryptedMessage =
                ("3082012306092A864886F70D010703A0820114308201100201003181CC3081C90201003032301E311C301A0"
                 + "60355040313135253414B65795472616E73666572436170693102105D2FFFF863BABC9B4D3C80AB178A4CCA"
                 + "300D06092A864886F70D01010730000481804F3F4A6707B329AB9A7343C62F20D5C1EAF4E74ECBB2DC66D1C"
                 + "642FC4AA3E40FC4C13547C6C9F73D525EE2FE4147B2043B8FEBF8604C0E4091C657B48DFD83A322F0879580"
                 + "FA002C9B27AD1FCF9B8AF24EDDA927BB6728D11530B3F96EBFC859ED6B9F7B009F992171FACB587A7D05E8B"
                 + "467B3A1DACC08B2F3341413A7E96576303C06092A864886F70D010701301D060960864801650304012A0410"
                 + "6F911E14D9D991DAB93C0B7738D1EC208010044264D201501735F73052FFCA4B2A95").HexToByteArray();

            byte[]      expectedContent     = { 1, 2, 3, 4 };
            ContentInfo expectedContentInfo = new ContentInfo(expectedContent);
            CertLoader  certLoader          = Certificates.RSAKeyTransferCapi1;

            VerifySimpleDecrypt(encryptedMessage, certLoader, expectedContentInfo);
        }
Example #10
0
        public void TestDecryptSimpleAes256_RsaSha256()
        {
            // Message encrypted on framework for a recipient using the certificate returned by
            // Certificates.RSASha256KeyTransfer1.GetCertificate() and of type IssuerAndSerialNumber. The symmetric algorithm used is Aes256
            byte[] encryptedMessage =
                ("3082012506092A864886F70D010703A0820116308201120201003181CE3081CB02010030343020311E301C0"
                 + "60355040313155253415368613235364B65795472616E7366657231021072C6C7734916468C4D608253DA01"
                 + "7676300D06092A864886F70D01010730000481805C32FA32EBDCFFC3595166EEDACFC9E9D60842105B581E1"
                 + "8B85DE1409F4C999995637153480438530955EE4481A3B27B866FF4E106A525CDFFC6941BDD01EFECCC6CCC"
                 + "82A3D7F743F7543AB20A61A7831FE4DFB24A1652B072B3758FE4B2588D3B94A29575B6422DC5EF52E432565"
                 + "36CA25A11BB92817D61FEAFBDDDEC6EE331303C06092A864886F70D010701301D060960864801650304012A"
                 + "041021D59FDB89C13A3EC3766EF32FB333D080105AE8DEB71DF50DD85F66FEA63C8113F4").HexToByteArray();

            byte[]      expectedContent     = { 1, 2, 3, 4 };
            ContentInfo expectedContentInfo = new ContentInfo(expectedContent);
            CertLoader  certLoader          = Certificates.RSASha256KeyTransfer1;

            VerifySimpleDecrypt(encryptedMessage, certLoader, expectedContentInfo);
        }
Example #11
0
        public void TestDecryptSimpleAes256_RsaSha384()
        {
            // Message encrypted on framework for a recipient using the certificate returned by Certificates.RSASha384KeyTransfer1.GetCertificate()
            // and of type IssuerAndSerialNumber. The symmetric algorithm used is Aes256
            byte[] encryptedMessage =
                ("3082012506092A864886F70D010703A0820116308201120201003181CE3081CB02010030343020311E301C0"
                 + "60355040313155253415368613338344B65795472616E736665723102103C724FB7A0159A9345CAAC9E3DF5"
                 + "F136300D06092A864886F70D010107300004818011C1B85914331C005EA89E30D00364821B29BC0C459A22D"
                 + "917494A1092CDBDA2022792E46C5E88BAD0EE3FD4927B856722311F9B17934FB29CAB8FE595C2AB2B20096B"
                 + "9E2FC6F9D7B92125F571CBFC945C892EE4764D9B63369350FD2DAEFE455B367F48E100CB461F112808E792A"
                 + "8AA49B66C79E511508A877530BBAA896696303C06092A864886F70D010701301D060960864801650304012A"
                 + "0410D653E25E06BFF2EEB0BED4A90D00FE2680106B7EF143912ABA5C24F5E2C151E59D7D").HexToByteArray();

            byte[]      expectedContent     = { 1, 2, 3, 4 };
            ContentInfo expectedContentInfo = new ContentInfo(expectedContent);
            CertLoader  certLoader          = Certificates.RSASha384KeyTransfer1;

            VerifySimpleDecrypt(encryptedMessage, certLoader, expectedContentInfo);
        }
Example #12
0
        public void TestDecryptSimpleAes256_RsaSha512()
        {
            // Message encrypted on framework for a recipient using the certificate returned by Certificates.RSASha512KeyTransfer1.GetCertificate()
            // and of type IssuerAndSerialNumber. The symmetric algorithm used is Aes256
            byte[] encryptedMessage =
                ("3082012506092A864886F70D010703A0820116308201120201003181CE3081CB02010030343020311E301C0"
                 + "60355040313155253415368613531324B65795472616E736665723102102F5D9D58A5F41B844650AA233E68"
                 + "F105300D06092A864886F70D01010730000481802156D42FF5ED2F0338302E7298EF79BA1D04E20E68B079D"
                 + "B3239120E1FC03FEDA8B544F59142AACAFBC5E58205E8A0D124AAD17B5DCAA39BFC6BA634E820DE623BFDB6"
                 + "582BC48AF1B3DEF6849A57D2033586AF01079D67C9AB3AA9F6B51754BCC479A19581D4045EBE23145370219"
                 + "98ECB6F5E1BCF8D6BED6A75FE957A40077D303C06092A864886F70D010701301D060960864801650304012A"
                 + "04100B696608E489E7C35914D0A3DB9EB27F80103D362181B54721FB2CB7CE461CB31030").HexToByteArray();

            byte[]      expectedContent     = { 1, 2, 3, 4 };
            ContentInfo expectedContentInfo = new ContentInfo(expectedContent);
            CertLoader  certLoader          = Certificates.RSASha512KeyTransfer1;

            VerifySimpleDecrypt(encryptedMessage, certLoader, expectedContentInfo);
        }
Example #13
0
        public void TestDecryptSimpleAes256_Ski()
        {
            // Message encrypted on framework for a recipient using the certificate returned by Certificates.RSAKeyTransfer1.GetCertificate()
            // and of type SubjectKeyIdentifier. The symmetric algorithm used is Aes256
            byte[] encryptedMessage =
                ("3082010306092A864886F70D010703A081F53081F20201023181AE3081AB0201028014F2008AA9FA3742E83"
                 + "70CB1674CE1D1582921DCC3300D06092A864886F70D010101050004818055F258073615B95426A7021E1B30"
                 + "9CFE8DD135B58D29F174B9FE19AE80CFC84621BCE3DBD63A5422AF30A6FAA3E2DFC05CB1AB5AB4FBA6C84EB"
                 + "1C2E17D5BE5C4959DBE8F96BF1A9701F55B697843032EEC7AFEC58A36815168F017DCFD70C74AD05C48B5E4"
                 + "D9DDEE409FDC9DC3326B6C5BA9F433A9E031FF9B09473176637F50303C06092A864886F70D010701301D060"
                 + "960864801650304012A0410314DA87435ED110DFE4F52FA70CEF7B080104DDA6C617338DEBDD10913A9141B"
                 + "EE52").HexToByteArray();

            byte[]      expectedContent     = { 1, 2, 3, 4 };
            ContentInfo expectedContentInfo = new ContentInfo(expectedContent);
            CertLoader  certLoader          = Certificates.RSAKeyTransfer1;

            VerifySimpleDecrypt(encryptedMessage, certLoader, expectedContentInfo);
        }
Example #14
0
        public void TestDecryptSimpleAes192_IssuerAndSerial()
        {
            // Message encrypted on framework for a recipient using the certificate returned by Certificates.RSAKeyTransfer1.GetCertificate()
            // and of type IssuerAndSerialNumber. The symmetric algorithm used is Aes192
            byte[] encryptedMessage =
                ("3082011F06092A864886F70D010703A08201103082010C0201003181C83081C5020100302E301A311830160"
                 + "603550403130F5253414B65795472616E7366657231021031D935FB63E8CFAB48A0BF7B397B67C0300D0609"
                 + "2A864886F70D010107300004818029B82454B4C301F277D7872A14695A41ED24FD37AC4C9942F9EE96774E0"
                 + "C6ACC18E756993A38AB215E5702CD34F244E52402DA432E8B79DF748405135E8A6D8CB78D88D9E4C142565C"
                 + "06F9FAFB32F5A9A4074E10FCCB0758A708CA758C12A17A4961969FCB3B2A6E6C9EB49F5E688D107E1B1DF3D"
                 + "531BC684B944FCE6BD4550C303C06092A864886F70D010701301D06096086480165030401160410FD7CBBF5"
                 + "6101854387E584C1B6EF3B08801034BD11C68228CB683E0A43AB5D27A8A4").HexToByteArray();

            byte[]      expectedContent     = { 1, 2, 3, 4 };
            ContentInfo expectedContentInfo = new ContentInfo(expectedContent);
            CertLoader  certLoader          = Certificates.RSAKeyTransfer1;

            VerifySimpleDecrypt(encryptedMessage, certLoader, expectedContentInfo);
        }
        private static void CustomBuild_CertMatch(
            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;

            Assert.True(Rfc3161TimestampToken.TryDecode(tokenBytes, out token, out int bytesRead));

            Assert.Equal(tokenBytes.Length, bytesRead);
            Assert.NotNull(token);

            Assert.Equal(referenceTime, token.TokenInfo.Timestamp);

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

                Assert.Equal(cert, signer);
            }
        }
Example #16
0
        public void TestDecryptSimple_ExplicitSki()
        {
            // Message encrypted on framework for a recipient using the certificate returned by Certificates.RSAKeyTransfer_ExplicitSki.GetCertificate()
            // and of type SubjectKeyIdentifier. The symmetric algorithm used is Aes256
            byte[] encryptedMessage =
                ("3082018806092A864886F70D010703A082017930820175020102318201303082012C020102801401952851C"
                 + "55DB594B0C6167F5863C5B6B67AEFE6300D06092A864886F70D010101050004820100269EAF029262C87125"
                 + "314DD3FB02302FA212EB3CC06F73DF1474382BBA2A92845F39FF5A7F5020482849C36B4BC6BC82F7AF0E2E3"
                 + "9143548CC32B93B72EF0659C6895F77E6B5839962678532392185C9431658B34D1ABD31F64F4C4A9B348A77"
                 + "56783D60244519ADDD33560405E9377A91617127C2EECF2BAE53AB930FC13AFD25723FB60DB763286EDF6F1"
                 + "187D8124B6A569AA2BD19294A7D551A0D90F8436274690231520A2254C19EA9BF877FC99566059A29CDF503"
                 + "6BEA1D517916BA2F20AC9F1D8F164B6E8ACDD52BA8B2650EBBCC2ED9103561E11AF422D10DF7405404195FA"
                 + "EF79A1FDC680F3A3DC395E3E9C0B10394DF35AE134E6CB719E35152F8E5303C06092A864886F70D01070130"
                 + "1D060960864801650304012A041085072D8771A2A2BB403E3236A7C60C2A80105C71A04E73C57FE75C1DEDD"
                 + "94B57FD01").HexToByteArray();

            byte[]      expectedContent     = { 1, 2, 3, 4 };
            ContentInfo expectedContentInfo = new ContentInfo(expectedContent);
            CertLoader  certLoader          = Certificates.RSAKeyTransfer_ExplicitSki;

            VerifySimpleDecrypt(encryptedMessage, certLoader, expectedContentInfo);
        }
        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);
        }
Example #18
0
        private static void TestSimpleDecrypt_RoundTrip(CertLoader certLoader, ContentInfo contentInfo, string algorithmOidValue, SubjectIdentifierType type)
        {
            // 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.
            ContentInfo expectedContentInfo = new ContentInfo(new Oid(contentInfo.ContentType), (byte[])(contentInfo.Content.Clone()));

            string certSubjectName;

            byte[] encodedMessage;
            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);
                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);
        }
        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);
            }
        }
        private static byte[] BuildCustomToken(
            CertLoader cert,
            DateTimeOffset timestamp,
            SigningCertificateOption v1Option,
            SigningCertificateOption v2Option,
            HashAlgorithmName v2DigestAlg        = default,
            X509IncludeOption includeOption      = X509IncludeOption.ExcludeRoot,
            SubjectIdentifierType identifierType = SubjectIdentifierType.IssuerAndSerialNumber)
        {
            long accuracyMicroSeconds = (long)(TimeSpan.FromMinutes(1).TotalMilliseconds * 1000);

            byte[] serialNumber = BitConverter.GetBytes(DateTimeOffset.UtcNow.Ticks);
            Array.Reverse(serialNumber);

            Rfc3161TimestampTokenInfo info = new Rfc3161TimestampTokenInfo(
                new Oid("0.0", "0.0"),
                new Oid(Oids.Sha384),
                new byte[384 / 8],
                serialNumber,
                timestamp,
                accuracyMicroSeconds,
                isOrdering: true);

            ContentInfo contentInfo = new ContentInfo(new Oid(Oids.TstInfo, Oids.TstInfo), info.Encode());
            SignedCms   cms         = new SignedCms(contentInfo);

            using (X509Certificate2 tsaCert = cert.TryGetCertificateWithPrivateKey())
            {
                CmsSigner signer = new CmsSigner(identifierType, tsaCert)
                {
                    IncludeOption = includeOption
                };

                if (v1Option != SigningCertificateOption.Omit)
                {
                    ExpandOption(v1Option, out bool validHash, out bool skipIssuerSerial, out bool validName, out bool validSerial);

                    // simple SigningCertificate
                    byte[] signingCertificateV1Bytes =
                        "301A3018301604140000000000000000000000000000000000000000".HexToByteArray();

                    if (validHash)
                    {
                        byte[] hash = SHA1.HashData(tsaCert.RawData);

                        Buffer.BlockCopy(
                            hash,
                            0,
                            signingCertificateV1Bytes,
                            signingCertificateV1Bytes.Length - hash.Length,
                            hash.Length);
                    }

                    if (!skipIssuerSerial)
                    {
                        byte[] footer = BuildIssuerAndSerialNumber(tsaCert, validName, validSerial);

                        signingCertificateV1Bytes[1] += (byte)footer.Length;
                        signingCertificateV1Bytes[3] += (byte)footer.Length;
                        signingCertificateV1Bytes[5] += (byte)footer.Length;

                        Assert.InRange(signingCertificateV1Bytes[1], 0, 127);

                        signingCertificateV1Bytes = signingCertificateV1Bytes.Concat(footer).ToArray();
                    }

                    signer.SignedAttributes.Add(
                        new AsnEncodedData("1.2.840.113549.1.9.16.2.12", signingCertificateV1Bytes));
                }

                if (v2Option != SigningCertificateOption.Omit)
                {
                    byte[] attrBytes;
                    byte[] algBytes = Array.Empty <byte>();
                    byte[] hashBytes;
                    byte[] issuerNameBytes = Array.Empty <byte>();

                    if (v2DigestAlg != default)
                    {
                        switch (v2DigestAlg.Name)
                        {
                        case "MD5":
                            algBytes = "300C06082A864886F70D02050500".HexToByteArray();
                            break;

                        case "SHA1":
                            algBytes = "300906052B0E03021A0500".HexToByteArray();
                            break;

                        case "SHA256":
                            // Invalid under DER, because it's the default.
                            algBytes = "300D06096086480165030402010500".HexToByteArray();
                            break;

                        case "SHA384":
                            algBytes = "300D06096086480165030402020500".HexToByteArray();
                            break;

                        case "SHA512":
                            algBytes = "300D06096086480165030402030500".HexToByteArray();
                            break;

                        default:
                            throw new NotSupportedException(v2DigestAlg.Name);
                        }
                    }
                    else
                    {
                        v2DigestAlg = HashAlgorithmName.SHA256;
                    }

                    hashBytes = tsaCert.GetCertHash(v2DigestAlg);

                    ExpandOption(v2Option, out bool validHash, out bool skipIssuerSerial, out bool validName, out bool validSerial);

                    if (!validHash)
                    {
                        hashBytes[0] ^= 0xFF;
                    }

                    if (!skipIssuerSerial)
                    {
                        issuerNameBytes = BuildIssuerAndSerialNumber(tsaCert, validName, validSerial);
                    }

                    // hashBytes hasn't been wrapped in an OCTET STRING yet, so add 2 more.
                    int payloadSize = algBytes.Length + hashBytes.Length + issuerNameBytes.Length + 2;
                    Assert.InRange(payloadSize, 0, 123);

                    attrBytes = new byte[payloadSize + 6];

                    int index = 0;

                    // SEQUENCE (SigningCertificateV2)
                    attrBytes[index++] = 0x30;
                    attrBytes[index++] = (byte)(payloadSize + 4);

                    // SEQUENCE OF => certs
                    attrBytes[index++] = 0x30;
                    attrBytes[index++] = (byte)(payloadSize + 2);

                    // SEQUENCE (ESSCertIdV2)
                    attrBytes[index++] = 0x30;
                    attrBytes[index++] = (byte)payloadSize;

                    Buffer.BlockCopy(algBytes, 0, attrBytes, index, algBytes.Length);
                    index += algBytes.Length;

                    // OCTET STRING (Hash)
                    attrBytes[index++] = 0x04;
                    attrBytes[index++] = (byte)hashBytes.Length;
                    Buffer.BlockCopy(hashBytes, 0, attrBytes, index, hashBytes.Length);
                    index += hashBytes.Length;

                    Buffer.BlockCopy(issuerNameBytes, 0, attrBytes, index, issuerNameBytes.Length);

                    signer.SignedAttributes.Add(
                        new AsnEncodedData("1.2.840.113549.1.9.16.2.47", attrBytes));
                }

                cms.ComputeSignature(signer);
            }

            return(cms.Encode());
        }
Example #21
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);
        }