Exemplo n.º 1
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()));
                            }
            }
        }