Index: net/base/x509_certificate_unittest.cc |
diff --git a/net/base/x509_certificate_unittest.cc b/net/base/x509_certificate_unittest.cc |
index 90a60e3be58a1aec88f2f59a4e15146f06f51dea..056b1a4d901bfde89636853ede0770dfe561d4e0 100644 |
--- a/net/base/x509_certificate_unittest.cc |
+++ b/net/base/x509_certificate_unittest.cc |
@@ -625,6 +625,169 @@ TEST(X509CertificateTest, IntermediateCertificates) { |
X509Certificate::FreeOSCertHandle(google_handle); |
} |
+TEST(X509CertificateTest, VerifyReturnChainBasic) { |
+ FilePath certs_dir = GetTestCertsDirectory(); |
+ CertificateList certs = |
+ CreateCertificateListFromFile(certs_dir, "google.full_chain.pem", |
+ X509Certificate::FORMAT_AUTO); |
+ ASSERT_EQ(3U, certs.size()); |
+ |
+ X509Certificate::OSCertHandles intermediates; |
+ intermediates.push_back(certs[1]->os_cert_handle()); |
+ intermediates.push_back(certs[2]->os_cert_handle()); |
+ |
+ scoped_refptr<X509Certificate> google_full_chain = |
+ X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), |
+ intermediates); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain); |
+ ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size()); |
+ |
+ int flags = x509_chain::VERIFY_RETURN_CHAIN; |
+ CertVerifyResult verify_result; |
+ EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.certificate); |
+ int error = x509_chain::VerifySSLServer(google_full_chain, |
+ "www.google.com", flags, |
+ &verify_result); |
+ EXPECT_EQ(OK, error); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.certificate); |
+ |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert( |
+ google_full_chain->os_cert_handle(), |
+ verify_result.certificate->os_cert_handle())); |
+ const X509Certificate::OSCertHandles& return_intermediates = |
+ verify_result.certificate->GetIntermediateCertificates(); |
+ EXPECT_EQ(2U, return_intermediates.size()); |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], |
+ certs[1]->os_cert_handle())); |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], |
+ certs[2]->os_cert_handle())); |
+} |
+ |
+// Test that the certificate returned in CertVerifyResult is an actual |
+// certificate chain by supplying the original chain out of order, which |
+// will not properly validate unless the underlying crypto library reorders |
+// the certificates into a valid chain. |
+TEST(X509CertificateTest, VerifyReturnChainProperlyOrders) { |
+ FilePath certs_dir = GetTestCertsDirectory(); |
+ CertificateList certs = |
+ CreateCertificateListFromFile(certs_dir, "google.full_chain.pem", |
+ X509Certificate::FORMAT_AUTO); |
+ ASSERT_EQ(3U, certs.size()); |
+ |
+ // Construct the chain out of order. |
+ X509Certificate::OSCertHandles intermediates; |
+ intermediates.push_back(certs[2]->os_cert_handle()); |
+ intermediates.push_back(certs[1]->os_cert_handle()); |
+ |
+ scoped_refptr<X509Certificate> google_full_chain = |
+ X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), |
+ intermediates); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain); |
+ ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size()); |
+ |
+ int flags = x509_chain::VERIFY_RETURN_CHAIN; |
+ CertVerifyResult verify_result; |
+ EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.certificate); |
+ int error = x509_chain::VerifySSLServer(google_full_chain, |
+ "www.google.com", flags, |
+ &verify_result); |
+ EXPECT_EQ(OK, error); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.certificate); |
+ |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert( |
+ google_full_chain->os_cert_handle(), |
+ verify_result.certificate->os_cert_handle())); |
+ const X509Certificate::OSCertHandles& return_intermediates = |
+ verify_result.certificate->GetIntermediateCertificates(); |
+ EXPECT_EQ(2U, return_intermediates.size()); |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], |
+ certs[1]->os_cert_handle())); |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], |
+ certs[2]->os_cert_handle())); |
+} |
+ |
+// Test that certificates supplied, but that are unrelated to the |
+// certificate for which the chain is being constructed and verified, are |
+// properly filtered out in the return chain. |
+TEST(X509CertificateTest, VerifyReturnChainFiltersUnrelatedCerts) { |
+ FilePath certs_dir = GetTestCertsDirectory(); |
+ CertificateList certs = |
+ CreateCertificateListFromFile(certs_dir, "google.full_chain.pem", |
+ X509Certificate::FORMAT_AUTO); |
+ ASSERT_EQ(3U, certs.size()); |
+ scoped_refptr<X509Certificate> unrelated_dod_certificate = |
+ ImportCertFromFile(certs_dir, "dod_ca_17_cert.der"); |
+ scoped_refptr<X509Certificate> unrelated_dod_certificate2 = |
+ ImportCertFromFile(certs_dir, "dod_root_ca_2_cert.der"); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_dod_certificate); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_dod_certificate2); |
+ |
+ // Interject unrelated certificates into the list of intermediates. |
+ X509Certificate::OSCertHandles intermediates; |
+ intermediates.push_back(unrelated_dod_certificate->os_cert_handle()); |
+ intermediates.push_back(certs[1]->os_cert_handle()); |
+ intermediates.push_back(unrelated_dod_certificate2->os_cert_handle()); |
+ intermediates.push_back(certs[2]->os_cert_handle()); |
+ |
+ scoped_refptr<X509Certificate> google_full_chain = |
+ X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), |
+ intermediates); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain); |
+ ASSERT_EQ(4U, google_full_chain->GetIntermediateCertificates().size()); |
+ |
+ int flags = x509_chain::VERIFY_RETURN_CHAIN; |
+ CertVerifyResult verify_result; |
+ EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.certificate); |
+ int error = x509_chain::VerifySSLServer(google_full_chain, |
+ "www.google.com", flags, |
+ &verify_result); |
+ EXPECT_EQ(OK, error); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.certificate); |
+ |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert( |
+ google_full_chain->os_cert_handle(), |
+ verify_result.certificate->os_cert_handle())); |
+ const X509Certificate::OSCertHandles& return_intermediates = |
+ verify_result.certificate->GetIntermediateCertificates(); |
+ EXPECT_EQ(2U, return_intermediates.size()); |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], |
+ certs[1]->os_cert_handle())); |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], |
+ certs[2]->os_cert_handle())); |
+} |
+ |
+#if defined(ALLOW_EXTERNAL_ACCESS) |
+// Test verification using only an end entity certificate, but one which has |
+// an Authority Information Access extension containing a a location where |
+// the intermediate certificate can be downloaded. It is not guaranteed that |
+// the underlying crypto library will need to retrieve it using the AIA |
+// extension, as it may already have a local copy installed or cached. In |
+// order to keep this test reliable, however, and because it may make a |
+// request to an external resource, this test is guarded by the define. |
+TEST(X509CertificateTest, VerifyReturnsChainUsingAIA) { |
+ FilePath certs_dir = GetTestCertsDirectory(); |
+ scoped_refptr<X509Certificate> google_cert = |
+ ImportCertFromFile(certs_dir, "google.single.der"); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); |
+ EXPECT_EQ(0U, google_cert->GetIntermediateCertificates().size()); |
+ |
+ int flags = x509_chain::VERIFY_RETURN_CHAIN; |
+ CertVerifyResult verify_result; |
+ EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.certificate); |
+ int error = x509_chain::VerifySSLServer(google_cert, "www.google.com", |
+ flags, &verify_result); |
+ EXPECT_EQ(OK, error); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.certificate); |
+ |
+ EXPECT_TRUE(X509Certificate::IsSameOSCert( |
+ google_cert->os_cert_handle(), |
+ verify_result.certificate->os_cert_handle())); |
+ const X509Certificate::OSCertHandles& intermediates = |
+ verify_result.certificate->GetIntermediateCertificates(); |
+ EXPECT_EQ(2U, intermediates.size()); |
+} |
+#endif |
+ |
#if defined(OS_MACOSX) |
TEST(X509CertificateTest, IsIssuedBy) { |
FilePath certs_dir = GetTestCertsDirectory(); |