public async Task RevokeRSAIssuersTest()
        {
            using (var mock = AutoMock.GetLoose()) {
                // Setup
                Setup(mock, HandleQuery);
                ICertificateIssuer service = mock.Create <CertificateIssuer>();
                var rootca = await service.NewRootCertificateAsync("rootca",
                                                                   X500DistinguishedNameEx.Create("CN=rootca"), DateTime.UtcNow, TimeSpan.FromDays(5),
                                                                   new CreateKeyParams { KeySize = 2048, Type = KeyType.RSA },
                                                                   new IssuerPolicies { IssuedLifetime = TimeSpan.FromHours(3) });

                var intca = await service.NewIssuerCertificateAsync("rootca", "intca",
                                                                    X500DistinguishedNameEx.Create("CN=intca"), DateTime.UtcNow,
                                                                    new CreateKeyParams { KeySize = 2048, Type = KeyType.RSA },
                                                                    new IssuerPolicies { IssuedLifetime = TimeSpan.FromHours(2) });

                var footca1 = await service.NewIssuerCertificateAsync("intca", "footca1",
                                                                      X500DistinguishedNameEx.Create("CN=footca"), DateTime.UtcNow,
                                                                      new CreateKeyParams { KeySize = 2048, Type = KeyType.RSA },
                                                                      new IssuerPolicies { IssuedLifetime = TimeSpan.FromHours(1) });

                var footca2 = await service.NewIssuerCertificateAsync("intca", "footca2",
                                                                      X500DistinguishedNameEx.Create("CN=footca"), DateTime.UtcNow,
                                                                      new CreateKeyParams { KeySize = 2048, Type = KeyType.RSA },
                                                                      new IssuerPolicies { IssuedLifetime = TimeSpan.FromHours(1) });

                // Run
                ICertificateRevoker revoker = mock.Create <CertificateRevoker>();
                await revoker.RevokeCertificateAsync(footca1.SerialNumber);

                await revoker.RevokeCertificateAsync(footca2.SerialNumber);

                ICertificateStore store = mock.Create <CertificateDatabase>();
                var foundi = await store.FindLatestCertificateAsync("intca");

                var found1 = await store.FindLatestCertificateAsync("footca1");

                var found2 = await store.FindLatestCertificateAsync("footca2");

                ICrlEndpoint crls = mock.Create <CrlDatabase>();
                // Get crl chain for intca and rootca
                var chainr = await crls.GetCrlChainAsync(intca.SerialNumber);

                // Assert
                Assert.NotNull(foundi);
                Assert.NotNull(found1);
                Assert.NotNull(found2);
                Assert.Null(foundi.Revoked);
                Assert.NotNull(found1.Revoked);
                Assert.NotNull(found2.Revoked);
                Assert.NotNull(chainr);
                Assert.NotEmpty(chainr);
                Assert.Equal(2, chainr.Count());
                Assert.True(chainr.ToArray()[1].HasValidSignature(intca));
                Assert.True(chainr.ToArray()[0].HasValidSignature(rootca));
                Assert.True(chainr.Last().IsRevoked(footca1));
                Assert.True(chainr.Last().IsRevoked(footca2));
                Assert.False(chainr.First().IsRevoked(intca));
            }
        }
        public async Task RevokeECCIssuerAndECCIssuersTestAsync()
        {
            using (var mock = Setup(HandleQuery)) {
                ICertificateIssuer service = mock.Create <CertificateIssuer>();
                var rootca = await service.NewRootCertificateAsync("rootca",
                                                                   X500DistinguishedNameEx.Create("CN=rootca"), DateTime.UtcNow, TimeSpan.FromDays(5),
                                                                   new CreateKeyParams { KeySize = 2048, Type = KeyType.ECC, Curve = CurveType.P384 },
                                                                   new IssuerPolicies { IssuedLifetime = TimeSpan.FromHours(3) });

                var intca = await service.NewIssuerCertificateAsync("rootca", "intca",
                                                                    X500DistinguishedNameEx.Create("CN=intca"), DateTime.UtcNow,
                                                                    new CreateKeyParams { KeySize = 2048, Type = KeyType.ECC, Curve = CurveType.P384 },
                                                                    new IssuerPolicies { IssuedLifetime = TimeSpan.FromHours(2) });

                var footca1 = await service.NewIssuerCertificateAsync("intca", "footca1",
                                                                      X500DistinguishedNameEx.Create("CN=footca"), DateTime.UtcNow,
                                                                      new CreateKeyParams { KeySize = 2048, Type = KeyType.ECC, Curve = CurveType.P384 },
                                                                      new IssuerPolicies { IssuedLifetime = TimeSpan.FromHours(1) });

                var footca2 = await service.NewIssuerCertificateAsync("intca", "footca2",
                                                                      X500DistinguishedNameEx.Create("CN=footca"), DateTime.UtcNow,
                                                                      new CreateKeyParams { KeySize = 2048, Type = KeyType.ECC, Curve = CurveType.P384 },
                                                                      new IssuerPolicies { IssuedLifetime = TimeSpan.FromHours(1) });

                // Run
                ICertificateRevoker revoker = mock.Create <CertificateRevoker>();
                await revoker.RevokeCertificateAsync(intca.SerialNumber);

                ICertificateStore store = mock.Create <CertificateDatabase>();
                var foundi = await store.FindLatestCertificateAsync("intca");

                var found1 = await store.FindLatestCertificateAsync("footca1");

                var found2 = await store.FindLatestCertificateAsync("footca2");

                ICrlEndpoint crls = mock.Create <CrlDatabase>();
                // Get crl for root
                var chainr = await crls.GetCrlChainAsync(rootca.SerialNumber);

                // Assert
                Assert.NotNull(foundi);
                Assert.NotNull(found1);
                Assert.NotNull(found2);
                Assert.NotNull(foundi.Revoked);
                Assert.NotNull(found1.Revoked);
                Assert.NotNull(found2.Revoked);
                Assert.NotNull(chainr);
                Assert.Single(chainr);
                Assert.True(chainr.Single().HasValidSignature(rootca));
                Assert.True(chainr.Single().IsRevoked(intca));
            }
        }
Beispiel #3
0
        public async Task ImportCertificateWithoutKeyTest()
        {
            using (var mock = AutoMock.GetLoose()) {
                // Setup
                var(service, client) = Setup(mock, (v, q) => {
                    var expected = "SELECT TOP 1 * FROM Certificates c " +
                                   "WHERE c.Type = 'Certificate' " +
                                   "AND c.CertificateName = 'rootca' " +
                                   "ORDER BY c.Version DESC";
                    if (q == expected)
                    {
                        return(v
                               .Where(o => ((dynamic)o.Value).Type == "Certificate")
                               .Where(o => ((dynamic)o.Value).CertificateName == "rootca")
                               .OrderByDescending(o => ((dynamic)o.Value).Version));
                    }
                    throw new AssertActualExpectedException(expected, q, "Query");
                });

                ICertificateStore store = mock.Create <CertificateDatabase>();

                var now = DateTime.UtcNow;
                using (var rkey = SignatureType.RS256.CreateCsr("CN=me", true, out var request))
                    using (var cert = request.CreateSelfSigned(now, now + TimeSpan.FromDays(5))) {
                        // Run
                        var rootca = await service.ImportCertificateAsync("rootca",
                                                                          cert.ToCertificate(new IssuerPolicies {
                            SignatureType  = SignatureType.RS256,
                            IssuedLifetime = TimeSpan.FromHours(1)
                        }));

                        var found = await store.FindLatestCertificateAsync("rootca");

                        // Assert
                        Assert.NotNull(rootca);
                        Assert.NotNull(found);
                        Assert.Null(rootca.KeyHandle); // no key
                        Assert.Null(rootca.Revoked);
                        Assert.Equal(TimeSpan.FromDays(5), rootca.NotAfterUtc - rootca.NotBeforeUtc);
                        // Cannot issue without private key
                        Assert.Null(rootca.IssuerPolicies);
                        Assert.False(rootca.IsIssuer());
                        Assert.True(rootca.IsValidChain());
                        rootca.Verify(rootca);
                        Assert.True(rootca.IsSelfSigned());
                        Assert.True(rootca.SameAs(found));
                        Assert.NotNull(rootca.GetIssuerSerialNumberAsString());
                        Assert.Equal(rootca.GetSubjectName(), rootca.GetIssuerSubjectName());
                        Assert.True(rootca.Subject.SameAs(rootca.Issuer));
                        using (var rcert = rootca.ToX509Certificate2()) {
                            Assert.Equal(rcert.GetSerialNumber(), rootca.GetSerialNumberAsBytesLE());
                            Assert.Equal(rcert.SerialNumber, rootca.GetSerialNumberAsString());
                            Assert.Equal(rcert.Thumbprint, rootca.Thumbprint);
                        }
                        Assert.Equal(rootca.GetSerialNumberAsString(), rootca.GetIssuerSerialNumberAsString());
                    }
            }
        }
Beispiel #4
0
        public async Task ImportCertificateWithKeyTestAsync()
        {
            using (var mock = Setup((v, q) => {
                var expected = "SELECT TOP 1 * FROM Certificates c " +
                               "WHERE c.Type = 'Certificate' " +
                               "AND c.CertificateName = 'rootca' " +
                               "ORDER BY c.Version DESC";
                if (q == expected)
                {
                    return(v
                           .Where(o => o.Value["Type"] == "Certificate")
                           .Where(o => o.Value["CertificateName"] == "rootca")
                           .OrderByDescending(o => o.Value["Version"]));
                }
                throw new AssertActualExpectedException(expected, q, "Query");
            }, out var service, out var client)) {
                ICertificateStore store = mock.Create <CertificateDatabase>();

                var now  = DateTime.UtcNow;
                var rkey = SignatureType.RS256.CreateCsr("CN=me", true, out var request);
                var cert = request.CreateSelfSigned(now, now + TimeSpan.FromDays(5));

                client.Setup(o => o.ImportCertificateWithHttpMessagesAsync(
                                 It.Is <string>(a => a == kTestVaultUri),
                                 It.Is <string>(a => a == "rootca"),
                                 It.IsNotNull <string>(),
                                 It.IsNotNull <string>(),
                                 It.Is <CertificatePolicy>(p => !p.KeyProperties.Exportable.Value),
                                 It.IsNotNull <CertificateAttributes>(),
                                 It.Is <IDictionary <string, string> >(d => d == null),
                                 It.IsAny <Dictionary <string, List <string> > >(),
                                 It.IsAny <CancellationToken>())).Returns(() => {
                    var result = new CertificateBundle(
                        kTestVaultUri + "/certificates/rootca",
                        kTestVaultUri + "/keys/kid",
                        null,     // not exportable
                        null, null, cert.ToPfx(rkey.ToKey()),
                        null, null, null);
                    return(Task.FromResult(new AzureOperationResponse <CertificateBundle> {
                        Body = result
                    }));
                });

                // Run
                var rootca = await service.ImportCertificateAsync("rootca",
                                                                  cert.ToCertificate(new IssuerPolicies {
                    SignatureType  = SignatureType.RS256,
                    IssuedLifetime = TimeSpan.FromHours(1)
                }), rkey.ToKey());

                var found = await store.FindLatestCertificateAsync("rootca");

                var export = ((IKeyStore)service).ExportKeyAsync(found.KeyHandle);

                // Assert
                Assert.NotNull(rootca);
                Assert.NotNull(found);
                Assert.NotNull(rootca.IssuerPolicies);
                Assert.NotNull(rootca.KeyHandle);
                await Assert.ThrowsAsync <InvalidOperationException>(() => export);

                Assert.Null(rootca.Revoked);
                Assert.Equal(TimeSpan.FromDays(5), rootca.NotAfterUtc - rootca.NotBeforeUtc);
                Assert.Equal(TimeSpan.FromHours(1), rootca.IssuerPolicies.IssuedLifetime);
                Assert.Equal(SignatureType.RS256, rootca.IssuerPolicies.SignatureType);
                Assert.True(rootca.IsValidChain());
                rootca.Verify(rootca);
                Assert.True(rootca.IsSelfSigned());
                Assert.True(rootca.IsIssuer());
                Assert.True(rootca.SameAs(found));
                Assert.NotNull(rootca.GetIssuerSerialNumberAsString());
                Assert.Equal(rootca.GetSubjectName(), rootca.GetIssuerSubjectName());
                Assert.True(rootca.Subject.SameAs(rootca.Issuer));
                using (var rcert = rootca.ToX509Certificate2()) {
                    Assert.Equal(rcert.GetSerialNumber(), rootca.GetSerialNumberAsBytesLE());
                    Assert.Equal(rcert.SerialNumber, rootca.GetSerialNumberAsString());
                    Assert.Equal(rcert.Thumbprint, rootca.Thumbprint);
                }
                Assert.Equal(rootca.GetSerialNumberAsString(), rootca.GetIssuerSerialNumberAsString());
            }
        }
Beispiel #5
0
        public async Task CreateRSARootAndRSAIssuerTestAsync()
        {
            using (var mock = Setup((v, q) => {
                var expected = "SELECT TOP 1 * FROM Certificates c " +
                               "WHERE c.Type = 'Certificate' " +
                               "AND c.CertificateName = 'footca' " +
                               "ORDER BY c.Version DESC";
                if (q == expected)
                {
                    return(v
                           .Where(o => o.Value["Type"] == "Certificate")
                           .Where(o => o.Value["CertificateName"] == "footca")
                           .OrderByDescending(o => o.Value["Version"]));
                }
                expected = "SELECT TOP 1 * FROM Certificates c " +
                           "WHERE c.Type = 'Certificate' " +
                           "AND c.CertificateName = 'rootca' " +
                           "ORDER BY c.Version DESC";
                if (q == expected)
                {
                    return(v
                           .Where(o => o.Value["Type"] == "Certificate")
                           .Where(o => o.Value["CertificateName"] == "rootca")
                           .OrderByDescending(o => o.Value["Version"]));
                }
                expected = "SELECT TOP 1 * FROM Certificates c " +
                           "WHERE c.Type = 'Certificate' " +
                           "AND c.CertificateId = '" + kTestVaultUri + "/certificates/rootca' " +
                           "ORDER BY c.Version DESC";
                if (q == expected)
                {
                    return(v
                           .Where(o => o.Value["Type"] == "Certificate")
                           .Where(o => o.Value["CertificateName"] == "rootca")
                           .OrderByDescending(o => o.Value["Version"]));
                }
                throw new AssertActualExpectedException(expected, q, "Query");
            }, out var service, out var client)) {
                ICertificateStore      store = mock.Create <CertificateDatabase>();
                ICertificateRepository repo  = mock.Create <CertificateDatabase>();

                var now = DateTime.UtcNow;
                using (var rkey = SignatureType.RS256.CreateCsr("CN=thee", true, out var rootcsr))
                    using (var rootca = rootcsr.CreateSelfSigned(now, now + TimeSpan.FromDays(5)))
                        using (var ikey = SignatureType.RS256.CreateCsr("CN=me", true, out var issuercsr))
                            using (var issuer = issuercsr.Create(rootca, now, now + TimeSpan.FromHours(3),
                                                                 Guid.NewGuid().ToByteArray())) {
                                await repo.AddCertificateAsync("rootca",
                                                               rootca.ToCertificate(new IssuerPolicies {
                                    SignatureType  = SignatureType.RS256,
                                    IssuedLifetime = TimeSpan.FromHours(3)
                                },
                                                                                    KeyVaultKeyHandle.Create(kTestVaultUri + "/keys/rkid", null)),
                                                               kTestVaultUri + "/certificates/rootca");

                                client.Setup(o => o.GetCertificateWithHttpMessagesAsync(
                                                 It.Is <string>(a => a == kTestVaultUri),
                                                 It.Is <string>(a => a == "rootca"),
                                                 It.IsAny <string>(),
                                                 It.IsAny <Dictionary <string, List <string> > >(),
                                                 It.IsAny <CancellationToken>())).Returns(() => {
                                    var result = new CertificateBundle(
                                        kTestVaultUri + "/certificates/rootca",
                                        kTestVaultUri + "/keys/rkid",
                                        null, // not exportable
                                        null, null, rootca.ToPfx(rkey.ToKey()),
                                        null, null, null);
                                    return(Task.FromResult(new AzureOperationResponse <CertificateBundle> {
                                        Body = result
                                    }));
                                });

                                client.Setup(o => o.CreateCertificateWithHttpMessagesAsync(
                                                 It.Is <string>(a => a == kTestVaultUri),
                                                 It.Is <string>(a => a == "footca"),
                                                 It.IsNotNull <CertificatePolicy>(),
                                                 It.IsNotNull <CertificateAttributes>(),
                                                 It.IsAny <IDictionary <string, string> >(),
                                                 It.IsAny <Dictionary <string, List <string> > >(),
                                                 It.IsAny <CancellationToken>())).Returns(() => {
                                    var result = new CertificateOperation {
                                        Status = "InProgress"
                                    };
                                    return(Task.FromResult(new AzureOperationResponse <CertificateOperation> {
                                        Body = result
                                    }));
                                });

                                client.Setup(o => o.GetCertificateOperationWithHttpMessagesAsync(
                                                 It.Is <string>(a => a == kTestVaultUri),
                                                 It.IsAny <string>(),
                                                 It.IsAny <Dictionary <string, List <string> > >(),
                                                 It.IsAny <CancellationToken>())).Returns(() => {
                                    var result = new CertificateOperation {
                                        Csr    = issuercsr.CreateSigningRequest(),
                                        Status = "Completed"
                                    };
                                    return(Task.FromResult(new AzureOperationResponse <CertificateOperation> {
                                        Body = result
                                    }));
                                });

                                client.Setup(o => o.GetCertificateWithHttpMessagesAsync(
                                                 It.Is <string>(a => a == kTestVaultUri),
                                                 It.Is <string>(a => a == "footca"),
                                                 It.IsAny <string>(),
                                                 It.IsAny <Dictionary <string, List <string> > >(),
                                                 It.IsAny <CancellationToken>())).Returns(() => {
                                    var result = new CertificateBundle(
                                        kTestVaultUri + "/certificates/footca",
                                        kTestVaultUri + "/keys/fkid",
                                        null, // not exportable
                                        null, null, issuer.ToPfx(ikey.ToKey()),
                                        null, null, null);
                                    return(Task.FromResult(new AzureOperationResponse <CertificateBundle> {
                                        Body = result
                                    }));
                                });

                                client.Setup(o => o.MergeCertificateWithHttpMessagesAsync(
                                                 It.Is <string>(a => a == kTestVaultUri),
                                                 It.Is <string>(a => a == "footca"),
                                                 It.IsAny <IList <byte[]> >(),
                                                 It.IsAny <CertificateAttributes>(),
                                                 It.IsAny <IDictionary <string, string> >(),
                                                 It.IsAny <Dictionary <string, List <string> > >(),
                                                 It.IsAny <CancellationToken>())).Returns(() => {
                                    var result = new CertificateBundle(
                                        kTestVaultUri + "/certificates/footca",
                                        kTestVaultUri + "/keys/fkid",
                                        null, // not exportable
                                        null, null, issuer.ToPfx(ikey.ToKey()),
                                        null, null, null);
                                    return(Task.FromResult(new AzureOperationResponse <CertificateBundle> {
                                        Body = result
                                    }));
                                });

                                client.Setup(o => o.SignWithHttpMessagesAsync(
                                                 It.Is <string>(a => a == kTestVaultUri),
                                                 // It.Is<string>(a => a == kTestVaultUri + "/keys/rkid"),
                                                 It.IsAny <string>(),
                                                 It.IsAny <string>(),
                                                 It.IsAny <string>(),
                                                 // It.Is<string>(a => a == "RS256"),
                                                 It.IsAny <byte[]>(),
                                                 It.IsAny <Dictionary <string, List <string> > >(),
                                                 It.IsAny <CancellationToken>())).Returns(() => {
                                    var result = new KeyOperationResult(
                                        kTestVaultUri + "/keys/rkid",
                                        new byte[32]);
                                    return(Task.FromResult(new AzureOperationResponse <KeyOperationResult> {
                                        Body = result
                                    }));
                                });


                                // Run
                                var footca = await service.NewIssuerCertificateAsync("rootca", "footca",
                                                                                     X500DistinguishedNameEx.Create("CN=me"), DateTime.UtcNow,
                                                                                     new CreateKeyParams { KeySize = 2048, Type = KeyType.RSA },
                                                                                     new IssuerPolicies { IssuedLifetime = TimeSpan.FromHours(1) });

                                var found = await store.FindLatestCertificateAsync("footca");

                                // Assert
                                Assert.NotNull(footca);
                                Assert.NotNull(found);
                                Assert.NotNull(footca.IssuerPolicies);
                                Assert.NotNull(footca.KeyHandle);
                                Assert.Null(footca.Revoked);
                                Assert.Equal(TimeSpan.FromHours(3), footca.NotAfterUtc - footca.NotBeforeUtc);
                                Assert.Equal(TimeSpan.FromHours(1), footca.IssuerPolicies.IssuedLifetime);
                                Assert.Equal(SignatureType.RS256, footca.IssuerPolicies.SignatureType);
                                Assert.False(footca.IsSelfSigned());
                                Assert.True(footca.IsIssuer());
                                Assert.True(footca.SameAs(found));
                                Assert.Equal(rootca.Subject, footca.GetIssuerSubjectName());
                                Assert.True(rootca.SubjectName.SameAs(footca.Issuer));
                                using (var cert = footca.ToX509Certificate2()) {
                                    Assert.Equal(cert.GetSerialNumber(), footca.GetSerialNumberAsBytesLE());
                                    Assert.Equal(cert.SerialNumber, footca.GetSerialNumberAsString());
                                    Assert.Equal(cert.Thumbprint, footca.Thumbprint);
                                }
                                Assert.True(footca.IsValidChain(rootca.ToCertificate().YieldReturn()));
                            }
            }
        }
Beispiel #6
0
        public async Task NewRootCertificateTest()
        {
            using (var mock = AutoMock.GetLoose()) {
                // Setup
                var(service, client) = Setup(mock, (v, q) => {
                    var expected = "SELECT TOP 1 * FROM Certificates c " +
                                   "WHERE c.Type = 'Certificate' " +
                                   "AND c.CertificateName = 'rootca' " +
                                   "ORDER BY c.Version DESC";
                    if (q == expected)
                    {
                        return(v
                               .Where(o => ((dynamic)o.Value).Type == "Certificate")
                               .Where(o => ((dynamic)o.Value).CertificateName == "rootca")
                               .OrderByDescending(o => ((dynamic)o.Value).Version));
                    }
                    throw new AssertActualExpectedException(expected, q, "Query");
                });

                ICertificateStore store = mock.Create <CertificateDatabase>();

                var now = DateTime.UtcNow;
                using (var rkey = SignatureType.RS256.CreateCsr("CN=me", true, out var request))
                    using (var cert = request.CreateSelfSigned(now, now + TimeSpan.FromDays(5))) {
                        client.Setup(o => o.CreateCertificateWithHttpMessagesAsync(
                                         It.Is <string>(a => a == kTestVaultUri),
                                         It.Is <string>(a => a == "rootca"),
                                         It.IsNotNull <CertificatePolicy>(),
                                         It.IsNotNull <CertificateAttributes>(),
                                         It.IsAny <IDictionary <string, string> >(),
                                         It.IsAny <Dictionary <string, List <string> > >(),
                                         It.IsAny <CancellationToken>())).Returns(() => {
                            var result = new CertificateOperation {
                                Status = "InProgress"
                            };
                            return(Task.FromResult(new AzureOperationResponse <CertificateOperation> {
                                Body = result
                            }));
                        });

                        client.Setup(o => o.GetCertificateOperationWithHttpMessagesAsync(
                                         It.Is <string>(a => a == kTestVaultUri),
                                         It.Is <string>(a => a == "rootca"),
                                         It.IsAny <Dictionary <string, List <string> > >(),
                                         It.IsAny <CancellationToken>())).Returns(() => {
                            var result = new CertificateOperation {
                                Csr    = request.CreateSigningRequest(),
                                Status = "Completed"
                            };
                            return(Task.FromResult(new AzureOperationResponse <CertificateOperation> {
                                Body = result
                            }));
                        });

                        client.Setup(o => o.GetCertificateWithHttpMessagesAsync(
                                         It.Is <string>(a => a == kTestVaultUri),
                                         It.Is <string>(a => a == "rootca"),
                                         It.IsAny <string>(),
                                         It.IsAny <Dictionary <string, List <string> > >(),
                                         It.IsAny <CancellationToken>())).Returns(() => {
                            var result = new CertificateBundle(
                                kTestVaultUri + "/certificates/rootca",
                                kTestVaultUri + "/keys/kid",
                                null, // not exportable
                                null, null, cert.ToPfx(rkey.ToKey()),
                                null, null, null);
                            return(Task.FromResult(new AzureOperationResponse <CertificateBundle> {
                                Body = result
                            }));
                        });

                        client.Setup(o => o.MergeCertificateWithHttpMessagesAsync(
                                         It.Is <string>(a => a == kTestVaultUri),
                                         It.Is <string>(a => a == "rootca"),
                                         It.IsAny <IList <byte[]> >(),
                                         It.IsAny <CertificateAttributes>(),
                                         It.IsAny <IDictionary <string, string> >(),
                                         It.IsAny <Dictionary <string, List <string> > >(),
                                         It.IsAny <CancellationToken>())).Returns(() => {
                            var result = new CertificateBundle(
                                kTestVaultUri + "/certificates/rootca",
                                kTestVaultUri + "/keys/kid",
                                null, // not exportable
                                null, null, cert.ToPfx(rkey.ToKey()),
                                null, null, null);
                            return(Task.FromResult(new AzureOperationResponse <CertificateBundle> {
                                Body = result
                            }));
                        });

                        client.Setup(o => o.SignWithHttpMessagesAsync(
                                         It.Is <string>(a => a == kTestVaultUri),
                                         // It.Is<string>(a => a == kTestVaultUri + "/keys/kid"),
                                         It.IsAny <string>(),
                                         It.IsAny <string>(),
                                         It.IsAny <string>(),
                                         // It.Is<string>(a => a == "RS256"),
                                         It.IsAny <byte[]>(),
                                         It.IsAny <Dictionary <string, List <string> > >(),
                                         It.IsAny <CancellationToken>())).Returns(() => {
                            var result = new KeyOperationResult(
                                kTestVaultUri + "/keys/kid",
                                new byte[32]);
                            return(Task.FromResult(new AzureOperationResponse <KeyOperationResult> {
                                Body = result
                            }));
                        });

                        // Run
                        var rootca = await service.NewRootCertificateAsync("rootca",
                                                                           X500DistinguishedNameEx.Create("CN=me"), DateTime.UtcNow, TimeSpan.FromDays(5),
                                                                           new CreateKeyParams { KeySize = 4096, Type = KeyType.RSA },
                                                                           new IssuerPolicies {
                            SignatureType  = SignatureType.RS256,
                            IssuedLifetime = TimeSpan.FromHours(1)
                        });

                        var found = await store.FindLatestCertificateAsync("rootca");

                        var export = ((IKeyStore)service).ExportKeyAsync(found.KeyHandle);

                        // Assert
                        Assert.NotNull(rootca);
                        Assert.NotNull(found);
                        Assert.NotNull(rootca.IssuerPolicies);
                        Assert.NotNull(rootca.KeyHandle);
                        await Assert.ThrowsAsync <InvalidOperationException>(() => export);

                        Assert.Null(rootca.Revoked);
                        Assert.Equal(TimeSpan.FromDays(5), rootca.NotAfterUtc - rootca.NotBeforeUtc);
                        Assert.Equal(TimeSpan.FromHours(1), rootca.IssuerPolicies.IssuedLifetime);
                        Assert.Equal(SignatureType.RS256, rootca.IssuerPolicies.SignatureType);
                        Assert.True(rootca.IsValidChain());
                        rootca.Verify(rootca);
                        Assert.True(rootca.IsSelfSigned());
                        Assert.True(rootca.IsIssuer());
                        Assert.True(rootca.SameAs(found));
                        Assert.NotNull(rootca.GetIssuerSerialNumberAsString());
                        Assert.Equal(rootca.GetSubjectName(), rootca.GetIssuerSubjectName());
                        Assert.True(rootca.Subject.SameAs(rootca.Issuer));
                        using (var rcert = rootca.ToX509Certificate2()) {
                            Assert.Equal(rcert.GetSerialNumber(), rootca.GetSerialNumberAsBytesLE());
                            Assert.Equal(rcert.SerialNumber, rootca.GetSerialNumberAsString());
                            Assert.Equal(rcert.Thumbprint, rootca.Thumbprint);
                        }
                        Assert.Equal(rootca.GetSerialNumberAsString(), rootca.GetIssuerSerialNumberAsString());
                    }
            }
        }