Пример #1
0
        public void SaveLoadCsr(PkiAsymmetricAlgorithm algor, int bits)
        {
            var hashAlgor = PkiHashAlgorithm.Sha256;

            var sn   = "CN=foo.example.com";
            var sans = new[] {
                "foo-alt1.example.com",
                "foo-alt2.example.com",
            };
            var keys = PkiKeyTests.GenerateKeyPair(algor, bits);
            var csr  = new PkiCertificateSigningRequest(sn, keys, hashAlgor);

            csr.CertificateExtensions.Add(
                PkiCertificateExtension.CreateDnsSubjectAlternativeNames(sans));

            var saveOut = Path.Combine(_testTemp,
                                       $"csrsave-{algor}-{bits}-{hashAlgor}-sans.ser");

            using (var ms = new MemoryStream())
            {
                csr.Save(ms);
                File.WriteAllBytes(saveOut, ms.ToArray());
            }

            PkiCertificateSigningRequest csr2;

            using (var fs = new FileStream(saveOut, FileMode.Open))
            {
                csr2 = PkiCertificateSigningRequest.Load(fs);
            }

            using (var ms = new MemoryStream())
            {
                csr2.Save(ms);
                File.WriteAllBytes(saveOut + 2, ms.ToArray());
            }

            File.WriteAllBytes(saveOut + "1a.pem", csr.ExportSigningRequest(PkiEncodingFormat.Pem));
            File.WriteAllBytes(saveOut + "1b.pem", csr.ExportSigningRequest(PkiEncodingFormat.Pem));
            File.WriteAllBytes(saveOut + "2a.pem", csr2.ExportSigningRequest(PkiEncodingFormat.Pem));
            File.WriteAllBytes(saveOut + "2b.pem", csr2.ExportSigningRequest(PkiEncodingFormat.Pem));

            Assert.AreEqual(csr.SubjectName, csr2.SubjectName);
            Assert.AreEqual(csr.HashAlgorithm, csr2.HashAlgorithm);
            CollectionAssert.AreEqual(
                csr.PublicKey.Export(PkiEncodingFormat.Der),
                csr2.PublicKey.Export(PkiEncodingFormat.Der));
            CollectionAssert.AreEqual(
                csr.CertificateExtensions,
                csr2.CertificateExtensions, CertExtComparerInstance);

            Assert.AreEqual(csr.PublicKey.IsPrivate, csr2.PublicKey.IsPrivate);
            Assert.AreEqual(csr.PublicKey.Algorithm, csr2.PublicKey.Algorithm);
            CollectionAssert.AreEqual(
                csr.PublicKey.Export(PkiEncodingFormat.Der),
                csr2.PublicKey.Export(PkiEncodingFormat.Der));
        }
Пример #2
0
        public void ExportSignedCert(PkiAsymmetricAlgorithm algor, int bits)
        {
            var hashAlgor = PkiHashAlgorithm.Sha256;

            var isurName = "CN=SelfSigned";
            var isurKeys = PkiKeyTests.GenerateKeyPair(algor, bits);
            var subjName = "CN=foo.example.com";
            var subjKeys = PkiKeyTests.GenerateKeyPair(algor, bits);
            var isurCsr  = new PkiCertificateSigningRequest(isurName, isurKeys, hashAlgor);
            var subjCsr  = new PkiCertificateSigningRequest(subjName, subjKeys, hashAlgor);

            subjCsr.CertificateExtensions.Add(
                PkiCertificateExtension.CreateDnsSubjectAlternativeNames(
                    new[] {
                "foo-alt1.example.com",
                "foo-alt2.example.com",
            }));

            var pemOut = Path.Combine(_testTemp,
                                      $"cert-{algor}-{bits}-{hashAlgor}.pem");
            var derOut = Path.Combine(_testTemp,
                                      $"cert-{algor}-{bits}-{hashAlgor}.der");

            var isurCert = isurCsr.CreateCa(
                DateTime.Now.AddMonths(-5),
                DateTime.Now.AddMonths(5));

            Assert.AreEqual(isurName, isurCert.SubjectName,
                            "Issuer Name on Issuer Certificate");

            var subjCert = subjCsr.Create(isurCert, isurKeys.PrivateKey,
                                          DateTime.Now.AddMonths(-1),
                                          DateTime.Now.AddMonths(1), new[] { (byte)0x2b });

            Assert.AreEqual(isurName, isurCert.SubjectName,
                            "Subject Name on Subject Certificate");

            File.WriteAllBytes(pemOut, subjCert.Export(PkiEncodingFormat.Pem));
            File.WriteAllBytes(derOut, subjCert.Export(PkiEncodingFormat.Der));

            using (var proc = OpenSsl.Start($"x509 -text -noout -in {pemOut}"))
            {
                proc.WaitForExit();
                Assert.AreEqual(0, proc.ExitCode);
            }

            using (var proc = OpenSsl.Start($"x509 -text -noout -inform DER -in {derOut}"))
            {
                proc.WaitForExit();
                Assert.AreEqual(0, proc.ExitCode);
            }
        }
Пример #3
0
        private (byte[] csr, PkiKeyPair keys) GenerateCertificateRequest(IEnumerable <string> hostnames)
        {
            using var ms = new MemoryStream();
            var keyPair = PkiKeyPair.GenerateRsaKeyPair(2048);

            var firstDns = hostnames.First();
            var csr      = new PkiCertificateSigningRequest($"CN={firstDns}", keyPair, PkiHashAlgorithm.Sha256);

            csr.CertificateExtensions.Add(PkiCertificateExtension.CreateDnsSubjectAlternativeNames(hostnames));
            var certCsr = csr.ExportSigningRequest(PkiEncodingFormat.Der);

            return(certCsr, keyPair);
        }
        public void EcdsaCaCertificateSignsImportedPemCsr()
        {
            var caKpr = PkiKeyPair.GenerateEcdsaKeyPair(384);
            var caCsr = new PkiCertificateSigningRequest("cn=test-ca",
                                                         caKpr, PkiHashAlgorithm.Sha256);

            var caCrt = caCsr.CreateCa(
                DateTimeOffset.Now.AddDays(-1),
                DateTimeOffset.Now.AddDays(30));

            var kpr  = PkiKeyPair.GenerateEcdsaKeyPair(384);
            var csr1 = new PkiCertificateSigningRequest("cn=foo.mock.acme2.zyborg.io", kpr,
                                                        PkiHashAlgorithm.Sha256);

            var bytes = csr1.ExportSigningRequest(PkiEncodingFormat.Pem);
            var csr2  = new PkiCertificateSigningRequest(PkiEncodingFormat.Pem, bytes,
                                                         PkiHashAlgorithm.Sha256);

            csr2.CertificateExtensions.Add(
                PkiCertificateExtension.CreateDnsSubjectAlternativeNames(new[] {
                "foo-alt1.mock.acme2.zyborg.io",
                "foo-alt2.mock.acme2.zyborg.io",
                "foo-alt3.mock.acme2.zyborg.io",
            }));

            var serNum      = DateTime.Now.Ticks;
            var serNumBytes = BitConverter.GetBytes(serNum);

            if (BitConverter.IsLittleEndian)
            {
                serNumBytes = serNumBytes.Reverse().ToArray();
            }

            var crt = csr2.Create(caCrt, caKpr.PrivateKey,
                                  DateTimeOffset.Now.AddHours(-1),
                                  DateTimeOffset.Now.AddHours(24),
                                  serNumBytes);

            var crtDer = crt.Export(PkiEncodingFormat.Der);
            var crtPem = crt.Export(PkiEncodingFormat.Pem);

            var pth = @"C:\local\prj\bek\ACMESharp\ACMESharpCore\test\ACMESharp.MockServer.UnitTests";

            File.WriteAllBytes(pth + "\\pem_imported-ecdsa_signed.der.crt", crtDer);
            File.WriteAllBytes(pth + "\\pem_imported-ecdsa_signed.pem.crt", crtPem);
        }
Пример #5
0
        public void CreateAndExportRsaSansCsr(int bits, PkiHashAlgorithm hashAlgor)
        {
            var sn   = "CN=foo.example.com";
            var sans = new[] {
                "foo-alt1.example.com",
                "foo-alt2.example.com",
            };
            var keys = PkiKeyPair.GenerateRsaKeyPair(bits);
            var csr  = new PkiCertificateSigningRequest(sn, keys, hashAlgor);

            csr.CertificateExtensions.Add(
                PkiCertificateExtension.CreateDnsSubjectAlternativeNames(sans));

            var pemOut = Path.Combine(_testTemp,
                                      $"csr-rsa-{bits}-{hashAlgor}-sans.pem");
            var derOut = Path.Combine(_testTemp,
                                      $"csr-rsa-{bits}-{hashAlgor}-sans.der");

            Assert.AreEqual(sn, csr.SubjectName);
            Assert.AreSame(keys.PublicKey, keys.PublicKey);
            Assert.AreEqual(hashAlgor, csr.HashAlgorithm);
            Assert.AreEqual(1, csr.CertificateExtensions.Count);

            File.WriteAllBytes(pemOut, csr.ExportSigningRequest(PkiEncodingFormat.Pem));
            File.WriteAllBytes(derOut, csr.ExportSigningRequest(PkiEncodingFormat.Der));

            using (var proc = OpenSsl.Start($"req -text -noout -verify -in {pemOut}"))
            {
                proc.WaitForExit();
                Assert.AreEqual(0, proc.ExitCode);
            }

            using (var proc = OpenSsl.Start($"req -text -noout -verify -inform DER -in {derOut}"))
            {
                proc.WaitForExit();
                Assert.AreEqual(0, proc.ExitCode);
            }
        }
        public async Task FinalizeOrder()
        {
            using (var http = _server.CreateClient())
            {
                var dir = await GetDir();

                var signer = new Crypto.JOSE.Impl.RSJwsTool();
                signer.Init();
                using (var acme = new AcmeProtocolClient(http, dir,
                                                         signer: signer))
                {
                    await acme.GetNonceAsync();

                    var acct = await acme.CreateAccountAsync(new[] { "mailto:[email protected]" });

                    acme.Account = acct;

                    var dnsIds = new[] {
                        "foo.mock.acme2.zyborg.io",
                        "foo-alt-1.mock.acme2.zyborg.io",
                        "foo-alt-2.mock.acme2.zyborg.io",
                        "foo-alt-3.mock.acme2.zyborg.io",
                    };
                    var order = await acme.CreateOrderAsync(dnsIds);

                    Assert.IsNotNull(order?.OrderUrl);
                    Assert.AreEqual(dnsIds.Length, order.Payload.Authorizations?.Length);
                    Assert.AreEqual(dnsIds.Length, order.Payload.Identifiers?.Length);

                    var authzUrl = order.Payload.Authorizations[0];
                    var authz    = await acme.GetAuthorizationDetailsAsync(authzUrl);

                    Assert.IsNotNull(authz);
                    Assert.IsFalse(authz.Wildcard ?? false);
                    Assert.AreEqual(dnsIds[0], authz.Identifier.Value);

                    foreach (var chlng in authz.Challenges)
                    {
                        var chlng2 = await acme.AnswerChallengeAsync(chlng.Url);

                        Assert.IsNotNull(chlng2);
                        Assert.AreEqual("valid", chlng2.Status);
                    }

                    var kpr = PkiKeyPair.GenerateRsaKeyPair(2048);
                    var csr = new PkiCertificateSigningRequest($"cn={dnsIds[0]}", kpr,
                                                               PkiHashAlgorithm.Sha256);
                    csr.CertificateExtensions.Add(
                        PkiCertificateExtension.CreateDnsSubjectAlternativeNames(dnsIds.Skip(1)));
                    var csrDer = csr.ExportSigningRequest(PkiEncodingFormat.Der);

                    var finalizedOrder = await acme.FinalizeOrderAsync(order.Payload.Finalize, csrDer);

                    Assert.AreEqual("valid", finalizedOrder.Payload.Status);
                    Assert.IsNotNull(finalizedOrder.Payload.Certificate);

                    var getResp = await acme.GetAsync(finalizedOrder.Payload.Certificate);

                    getResp.EnsureSuccessStatusCode();

                    using (var fs = new FileStream(
                               @"C:\local\prj\bek\ACMESharp\ACMESharpCore\test\ACMESharp.MockServer.UnitTests\finalize-cert.pem",
                               FileMode.Create))
                    {
                        await getResp.Content.CopyToAsync(fs);
                    }
                }
            }
        }
        public async Task Test_Finalize_Order_ForMultiDns()
        {
            if (Clients?.Acme == null)
            {
                await base.InitAcmeClient();

                //Clients.Acme.GetNonceAsync();
            }

            var testCtx = SetTestContext();

            var oldOrder = testCtx.GroupLoadObject <OrderDetails>("order.json");

            var rsaKeys = PkiKeyPair.GenerateRsaKeyPair(2048);

            using (var ms = new MemoryStream())
            {
                rsaKeys.Save(ms);
                testCtx.GroupWriteTo("order-csr-keys.ser", ms.ToArray());
            }

            var dnsNames = oldOrder.Payload.Identifiers.Select(x => x.Value).ToArray();
            var csr      = new PkiCertificateSigningRequest($"CN={dnsNames[0]}", rsaKeys, PkiHashAlgorithm.Sha256);

            csr.CertificateExtensions.Add(PkiCertificateExtension.CreateDnsSubjectAlternativeNames(dnsNames));
            var derEncodedCsr = csr.ExportSigningRequest(PkiEncodingFormat.Der);

            testCtx.GroupWriteTo("order-csr.der", derEncodedCsr);

            var updatedOrder = await Clients.Acme.FinalizeOrderAsync(
                oldOrder.Payload.Finalize, derEncodedCsr);

            int maxTry   = 20;
            int trySleep = 5 * 1000;
            var valid    = false;

            for (var tryCount = 0; tryCount < maxTry; ++tryCount)
            {
                if (tryCount > 0)
                {
                    // Wait just a bit for
                    // subsequent queries
                    Thread.Sleep(trySleep);

                    // Only need to refresh
                    // after the first check
                    Log.LogInformation($"  Retry #{tryCount} refreshing Order");
                    updatedOrder = await Clients.Acme.GetOrderDetailsAsync(oldOrder.OrderUrl);

                    testCtx.GroupSaveObject("order-updated.json", updatedOrder);
                }

                if (!valid)
                {
                    // The Order is either Valid, still Pending or some other UNEXPECTED state

                    if ("valid" == updatedOrder.Payload.Status)
                    {
                        valid = true;
                        Log.LogInformation("Order is VALID!");
                    }
                    else if ("pending" != updatedOrder.Payload.Status)
                    {
                        Log.LogInformation("Order in **UNEXPECTED STATUS**: {@UpdateChallengeDetails}", updatedOrder);
                        throw new InvalidOperationException("Unexpected status for Order: " + updatedOrder.Payload.Status);
                    }
                }

                if (valid)
                {
                    // Once it's valid, then we need to wait for the Cert

                    if (!string.IsNullOrEmpty(updatedOrder.Payload.Certificate))
                    {
                        Log.LogInformation("Certificate URL is ready!");
                        break;
                    }
                }
            }

            Assert.NotNull(updatedOrder.Payload.Certificate);
            var certBytes = await Clients.Acme.GetOrderCertificateAsync(updatedOrder);

            testCtx.GroupWriteTo("order-cert.crt", certBytes);
        }
Пример #8
0
        public void SaveLoadCertificate(PkiAsymmetricAlgorithm algor, int bits)
        {
            var hashAlgor = PkiHashAlgorithm.Sha256;

            var isurName = "CN=SelfSigned";
            var isurKeys = PkiKeyTests.GenerateKeyPair(algor, bits);
            var subjName = "CN=foo.example.com";
            var subjKeys = PkiKeyTests.GenerateKeyPair(algor, bits);
            var isurCsr  = new PkiCertificateSigningRequest(isurName, isurKeys, hashAlgor);
            var subjCsr  = new PkiCertificateSigningRequest(subjName, subjKeys, hashAlgor);

            subjCsr.CertificateExtensions.Add(PkiCertificateExtension.CreateDnsSubjectAlternativeNames(
                                                  new[] {
                "foo-alt1.example.com",
                "foo-alt2.example.com",
            }
                                                  ));

            var selfOut = Path.Combine(_testTemp,
                                       $"certsave-{algor}-{bits}-{hashAlgor}-self.ser");
            var signedOut = Path.Combine(_testTemp,
                                         $"certsave-{algor}-{bits}-{hashAlgor}-signed.ser");

            var isurCert = isurCsr.CreateCa(
                DateTime.Now.AddMonths(-5),
                DateTime.Now.AddMonths(5));

            var subjCert = subjCsr.Create(isurCert, isurKeys.PrivateKey,
                                          DateTime.Now.AddMonths(-1),
                                          DateTime.Now.AddMonths(1), new[] { (byte)0x2b });

            using (var ms = new MemoryStream())
            {
                isurCert.Save(ms);
                File.WriteAllBytes(selfOut, ms.ToArray());
            }
            using (var ms = new MemoryStream())
            {
                subjCert.Save(ms);
                File.WriteAllBytes(signedOut, ms.ToArray());
            }

            PkiCertificate isurCert2;
            PkiCertificate subjCert2;

            using (var fs = new FileStream(selfOut, FileMode.Open))
                isurCert2 = PkiCertificate.Load(fs);
            using (var fs = new FileStream(signedOut, FileMode.Open))
                subjCert2 = PkiCertificate.Load(fs);

            var bclIsur  = isurCert.ToBclCertificate();
            var bclSubj  = subjCert.ToBclCertificate();
            var bclIsur2 = isurCert2.ToBclCertificate();
            var bclSubj2 = subjCert2.ToBclCertificate();

            Assert.AreEqual(bclIsur.GetSerialNumberString(),
                            bclIsur2.GetSerialNumberString(), "Issuer Serial Number");
            Assert.AreEqual(bclIsur.GetCertHashString(),
                            bclIsur2.GetCertHashString(), "Issuer Hash");
            Assert.AreEqual(bclIsur.GetRawCertDataString(),
                            bclIsur2.GetRawCertDataString(), "Issuer Raw Data");

            Assert.AreEqual(bclSubj.GetSerialNumberString(),
                            bclSubj2.GetSerialNumberString(), "Subject Serial Number");
            Assert.AreEqual(bclSubj.GetCertHashString(),
                            bclSubj2.GetCertHashString(), "Subject Hash");
            Assert.AreEqual(bclSubj.GetRawCertDataString(),
                            bclSubj2.GetRawCertDataString(), "Subject Raw Data");
        }
Пример #9
0
        public void ExportSignedPkcs12(PkiAsymmetricAlgorithm algor, int bits)
        {
            var hashAlgor = PkiHashAlgorithm.Sha256;

            var isurName = "CN=SelfSigned";
            var isurKeys = PkiKeyTests.GenerateKeyPair(algor, bits);
            var subjName = "CN=foo.example.com";
            var subjKeys = PkiKeyTests.GenerateKeyPair(algor, bits);
            var isurCsr  = new PkiCertificateSigningRequest(isurName, isurKeys, hashAlgor);
            var subjCsr  = new PkiCertificateSigningRequest(subjName, subjKeys, hashAlgor);

            subjCsr.CertificateExtensions.Add(
                PkiCertificateExtension.CreateDnsSubjectAlternativeNames(
                    new[] {
                "foo-alt1.example.com",
                "foo-alt2.example.com",
            }));

            var pfxSansKey = Path.Combine(_testTemp,
                                          $"certexp-{algor}-{bits}-{hashAlgor}-sanskey.pfx");
            var pfxWithKey = Path.Combine(_testTemp,
                                          $"certexp-{algor}-{bits}-{hashAlgor}-withkey.pfx");

            var isurCert = isurCsr.CreateCa(
                DateTime.Now.AddMonths(-5),
                DateTime.Now.AddMonths(5));

            Assert.AreEqual(isurName, isurCert.SubjectName,
                            "Issuer Name on Issuer Certificate");

            var subjCert = subjCsr.Create(isurCert, isurKeys.PrivateKey,
                                          DateTime.Now.AddMonths(-1),
                                          DateTime.Now.AddMonths(1), new[] { (byte)0x2b });

            Assert.AreEqual(isurName, isurCert.SubjectName,
                            "Subject Name on Subject Certificate");

            File.WriteAllBytes(pfxSansKey, subjCert.Export(PkiArchiveFormat.Pkcs12,
                                                           chain: new[] { isurCert }));
            File.WriteAllBytes(pfxWithKey, subjCert.Export(PkiArchiveFormat.Pkcs12,
                                                           subjKeys.PrivateKey, new[] { isurCert }));

            using (var proc = OpenSsl.Start($"pkcs12 -info -in {pfxSansKey} -passin pass:"******"pkcs12 -info -in {pfxWithKey} -passin pass: -nokeys"))
            {
                proc.WaitForExit();
                Assert.AreEqual(0, proc.ExitCode);
            }

            var certSansKey = new System.Security.Cryptography.X509Certificates.X509Certificate2(File.ReadAllBytes(pfxSansKey));

            Assert.IsFalse(certSansKey.HasPrivateKey);
            Assert.IsNull(certSansKey.PrivateKey);
            var certWithKey = new System.Security.Cryptography.X509Certificates.X509Certificate2(File.ReadAllBytes(pfxWithKey));

            Assert.IsTrue(certWithKey.HasPrivateKey);
            if (algor != PkiAsymmetricAlgorithm.Ecdsa)
            {
                // This throws: System.NotSupportedException: The certificate key algorithm is not supported.
                Assert.IsNotNull(certWithKey.PrivateKey);
            }
        }