Index: net/ssl/client_cert_store_nss_unittest.cc |
diff --git a/net/ssl/client_cert_store_nss_unittest.cc b/net/ssl/client_cert_store_nss_unittest.cc |
index dbf06660bb0eb64b1a8fe7de09404477283871af..bc222e87696cb7ae3cfacb263a31af9e3d711a4f 100644 |
--- a/net/ssl/client_cert_store_nss_unittest.cc |
+++ b/net/ssl/client_cert_store_nss_unittest.cc |
@@ -4,7 +4,21 @@ |
#include "net/ssl/client_cert_store_nss.h" |
+#include <cert.h> |
+#include <certt.h> |
+#include <pk11pub.h> |
+ |
+#include <memory> |
+#include <string> |
+ |
+#include "base/memory/ref_counted.h" |
+#include "base/run_loop.h" |
+#include "crypto/scoped_test_nss_db.h" |
+#include "net/cert/x509_certificate.h" |
#include "net/ssl/client_cert_store_unittest-inl.h" |
+#include "net/ssl/ssl_cert_request_info.h" |
+#include "net/test/cert_test_util.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
namespace net { |
@@ -27,4 +41,66 @@ INSTANTIATE_TYPED_TEST_CASE_P(NSS, |
ClientCertStoreTest, |
ClientCertStoreNSSTestDelegate); |
+// Tests that ClientCertStoreNSS attempts to build a certificate chain by |
+// querying NSS before return a certificate. |
+TEST(ClientCertStoreNSSTest, BuildsCertificateChain) { |
+ // Set up a test DB and import client_1.pem and client_1_ca.pem. |
+ crypto::ScopedTestNSSDB test_db; |
+ scoped_refptr<X509Certificate> client_1(ImportClientCertAndKeyFromFile( |
+ GetTestCertsDirectory(), "client_1.pem", "client_1.pk8", test_db.slot())); |
+ ASSERT_TRUE(client_1.get()); |
+ scoped_refptr<X509Certificate> client_1_ca( |
+ ImportCertFromFile(GetTestCertsDirectory(), "client_1_ca.pem")); |
+ ASSERT_TRUE(client_1_ca.get()); |
+ ASSERT_EQ(SECSuccess, |
+ PK11_ImportCert(test_db.slot(), client_1_ca->os_cert_handle(), |
+ CK_INVALID_HANDLE, "client_1_ca", |
+ PR_FALSE /* includeTrust (unused) */)); |
+ |
+ std::unique_ptr<ClientCertStoreNSS> store( |
+ new ClientCertStoreNSS(ClientCertStoreNSS::PasswordDelegateFactory())); |
+ |
+ { |
+ // Request certificates matching B CA, |client_1|'s issuer. |
+ scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo); |
+ request->cert_authorities.push_back(std::string( |
+ reinterpret_cast<const char*>(kAuthority1DN), sizeof(kAuthority1DN))); |
+ |
+ CertificateList selected_certs; |
+ base::RunLoop loop; |
+ store->GetClientCerts(*request.get(), &selected_certs, loop.QuitClosure()); |
+ loop.Run(); |
+ |
+ // The result be |client_1| with no intermediates. |
+ ASSERT_EQ(1u, selected_certs.size()); |
+ scoped_refptr<X509Certificate> selected_cert = selected_certs[0]; |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(client_1->os_cert_handle(), |
+ selected_cert->os_cert_handle())); |
+ ASSERT_EQ(0u, selected_cert->GetIntermediateCertificates().size()); |
+ } |
+ |
+ { |
+ // Request certificates matching C Root CA, |client_1_ca|'s issuer. |
+ scoped_refptr<SSLCertRequestInfo> request(new SSLCertRequestInfo); |
+ request->cert_authorities.push_back( |
+ std::string(reinterpret_cast<const char*>(kAuthorityRootDN), |
+ sizeof(kAuthorityRootDN))); |
+ |
+ CertificateList selected_certs; |
+ base::RunLoop loop; |
+ store->GetClientCerts(*request.get(), &selected_certs, loop.QuitClosure()); |
+ loop.Run(); |
+ |
+ // The result be |client_1| with |client_1_ca| as an intermediate. |
+ ASSERT_EQ(1u, selected_certs.size()); |
+ scoped_refptr<X509Certificate> selected_cert = selected_certs[0]; |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(client_1->os_cert_handle(), |
+ selected_cert->os_cert_handle())); |
+ ASSERT_EQ(1u, selected_cert->GetIntermediateCertificates().size()); |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert( |
+ client_1_ca->os_cert_handle(), |
+ selected_cert->GetIntermediateCertificates()[0])); |
+ } |
+} |
+ |
} // namespace net |