summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorrsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-30 08:47:47 +0000
committerrsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-30 08:47:47 +0000
commiteb8414e82812f8847a9eb7ab90fd191632ad3e8a (patch)
tree26970431a27bead05c2bbc82ece3a50f78224c74 /net
parentf4f8ed0a5e96e5020b302d66b6866e9ae97b478b (diff)
downloadchromium_src-eb8414e82812f8847a9eb7ab90fd191632ad3e8a.zip
chromium_src-eb8414e82812f8847a9eb7ab90fd191632ad3e8a.tar.gz
chromium_src-eb8414e82812f8847a9eb7ab90fd191632ad3e8a.tar.bz2
Return the constructed certificate chain in X509Certificate::Verify()
BUG=65540 TEST=net_unittests --gtest_filter=X509CertificateTest.VerifyReturn* Review URL: http://codereview.chromium.org/6874039 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94832 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/base/cert_verify_result.cc3
-rw-r--r--net/base/cert_verify_result.h19
-rw-r--r--net/base/x509_certificate.cc1
-rw-r--r--net/base/x509_certificate_mac.cc17
-rw-r--r--net/base/x509_certificate_nss.cc20
-rw-r--r--net/base/x509_certificate_openssl.cc13
-rw-r--r--net/base/x509_certificate_unittest.cc142
-rw-r--r--net/base/x509_certificate_win.cc20
-rw-r--r--net/data/ssl/certificates/README5
-rw-r--r--net/data/ssl/certificates/x509_verify_results.chain.pem50
-rw-r--r--net/socket/ssl_client_socket_mac.cc5
-rw-r--r--net/socket/ssl_client_socket_nss.cc3
-rw-r--r--net/socket/ssl_client_socket_openssl.cc1
-rw-r--r--net/socket/ssl_client_socket_win.cc2
14 files changed, 290 insertions, 11 deletions
diff --git a/net/base/cert_verify_result.cc b/net/base/cert_verify_result.cc
index 54e15f5..d51566b 100644
--- a/net/base/cert_verify_result.cc
+++ b/net/base/cert_verify_result.cc
@@ -4,6 +4,8 @@
#include "net/base/cert_verify_result.h"
+#include "net/base/x509_certificate.h"
+
namespace net {
CertVerifyResult::CertVerifyResult() {
@@ -14,6 +16,7 @@ CertVerifyResult::~CertVerifyResult() {
}
void CertVerifyResult::Reset() {
+ verified_cert = NULL;
cert_status = 0;
has_md5 = false;
has_md2 = false;
diff --git a/net/base/cert_verify_result.h b/net/base/cert_verify_result.h
index e4fb84a..2e4c250 100644
--- a/net/base/cert_verify_result.h
+++ b/net/base/cert_verify_result.h
@@ -9,12 +9,14 @@
#include <vector>
#include "net/base/net_api.h"
+#include "base/memory/ref_counted.h"
#include "net/base/x509_cert_types.h"
namespace net {
-// The result of certificate verification. Eventually this may contain the
-// certificate chain that was constructed during certificate verification.
+class X509Certificate;
+
+// The result of certificate verification.
class NET_API CertVerifyResult {
public:
CertVerifyResult();
@@ -22,7 +24,18 @@ class NET_API CertVerifyResult {
void Reset();
- // Bitmask of CERT_STATUS_* from net/base/cert_status_flags.h
+ // The certificate and chain that was constructed during verification.
+ // Note that the though the verified certificate will match the originally
+ // supplied certificate, the intermediate certificates stored within may
+ // be substantially different. In the event of a verification failure, this
+ // will contain the chain as supplied by the server. This may be NULL if
+ // running within the sandbox.
+ scoped_refptr<X509Certificate> verified_cert;
+
+ // Bitmask of CERT_STATUS_* from net/base/cert_status_flags.h. Note that
+ // these status flags apply to the certificate chain returned in
+ // |verified_cert|, rather than the originally supplied certificate
+ // chain.
int cert_status;
// Properties of the certificate chain.
diff --git a/net/base/x509_certificate.cc b/net/base/x509_certificate.cc
index 9fbf702..0c52de7 100644
--- a/net/base/x509_certificate.cc
+++ b/net/base/x509_certificate.cc
@@ -592,6 +592,7 @@ bool X509Certificate::VerifyHostname(
int X509Certificate::Verify(const std::string& hostname, int flags,
CertVerifyResult* verify_result) const {
verify_result->Reset();
+ verify_result->verified_cert = const_cast<X509Certificate*>(this);
if (IsBlacklisted()) {
verify_result->cert_status |= CERT_STATUS_REVOKED;
diff --git a/net/base/x509_certificate_mac.cc b/net/base/x509_certificate_mac.cc
index 88ff95f..ef69748 100644
--- a/net/base/x509_certificate_mac.cc
+++ b/net/base/x509_certificate_mac.cc
@@ -832,6 +832,23 @@ int X509Certificate::VerifyInternal(const std::string& hostname,
return NetErrorFromOSStatus(status);
ScopedCFTypeRef<CFArrayRef> scoped_completed_chain(completed_chain);
+ SecCertificateRef verified_cert = NULL;
+ std::vector<SecCertificateRef> verified_chain;
+ for (CFIndex i = 0, count = CFArrayGetCount(completed_chain);
+ i < count; ++i) {
+ SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>(
+ const_cast<void*>(CFArrayGetValueAtIndex(completed_chain, i)));
+ if (i == 0) {
+ verified_cert = chain_cert;
+ } else {
+ verified_chain.push_back(chain_cert);
+ }
+ }
+ if (verified_cert) {
+ verify_result->verified_cert = CreateFromHandle(verified_cert,
+ verified_chain);
+ }
+
// Evaluate the results
OSStatus cssm_result;
switch (trust_result) {
diff --git a/net/base/x509_certificate_nss.cc b/net/base/x509_certificate_nss.cc
index 0162663..7224020 100644
--- a/net/base/x509_certificate_nss.cc
+++ b/net/base/x509_certificate_nss.cc
@@ -168,19 +168,27 @@ int MapCertErrorToCertStatus(int err) {
// Saves some information about the certificate chain cert_list in
// *verify_result. The caller MUST initialize *verify_result before calling
// this function.
-// Note that cert_list[0] is the end entity certificate and cert_list doesn't
-// contain the root CA certificate.
+// Note that cert_list[0] is the end entity certificate.
void GetCertChainInfo(CERTCertList* cert_list,
+ CERTCertificate* root_cert,
CertVerifyResult* verify_result) {
// NOTE: Using a NSS library before 3.12.3.1 will crash below. To see the
// NSS version currently in use:
// 1. use ldd on the chrome executable for NSS's location (ie. libnss3.so*)
// 2. use ident libnss3.so* for the library's version
DCHECK(cert_list);
+
+ CERTCertificate* verified_cert = NULL;
+ std::vector<CERTCertificate*> verified_chain;
int i = 0;
for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
!CERT_LIST_END(node, cert_list);
- node = CERT_LIST_NEXT(node), i++) {
+ node = CERT_LIST_NEXT(node), ++i) {
+ if (i == 0) {
+ verified_cert = node->cert;
+ } else {
+ verified_chain.push_back(node->cert);
+ }
SECAlgorithmID& signature = node->cert->signature;
SECOidTag oid_tag = SECOID_FindOIDTag(&signature.algorithm);
switch (oid_tag) {
@@ -201,6 +209,11 @@ void GetCertChainInfo(CERTCertList* cert_list,
break;
}
}
+
+ if (root_cert)
+ verified_chain.push_back(root_cert);
+ verify_result->verified_cert =
+ X509Certificate::CreateFromHandle(verified_cert, verified_chain);
}
// IsKnownRoot returns true if the given certificate is one that we believe
@@ -811,6 +824,7 @@ int X509Certificate::VerifyInternal(const std::string& hostname,
}
GetCertChainInfo(cvout[cvout_cert_list_index].value.pointer.chain,
+ cvout[cvout_trust_anchor_index].value.pointer.cert,
verify_result);
if (IsCertStatusError(verify_result->cert_status))
return MapCertStatusToNetError(verify_result->cert_status);
diff --git a/net/base/x509_certificate_openssl.cc b/net/base/x509_certificate_openssl.cc
index d3cad61..5416a76 100644
--- a/net/base/x509_certificate_openssl.cc
+++ b/net/base/x509_certificate_openssl.cc
@@ -462,8 +462,16 @@ int X509Certificate::VerifyInternal(const std::string& hostname,
return MapCertStatusToNetError(verify_result->cert_status);
STACK_OF(X509)* chain = X509_STORE_CTX_get_chain(ctx.get());
+ X509* verified_cert = NULL;
+ std::vector<X509*> verified_chain;
for (int i = 0; i < sk_X509_num(chain); ++i) {
X509* cert = sk_X509_value(chain, i);
+ if (i == 0) {
+ verified_cert = cert;
+ } else {
+ verified_chain.push_back(verified_cert);
+ }
+
DERCache der_cache;
if (!GetDERAndCacheIfNeeded(cert, &der_cache))
continue;
@@ -480,6 +488,11 @@ int X509Certificate::VerifyInternal(const std::string& hostname,
verify_result->public_key_hashes.push_back(hash);
}
+ if (verified_cert) {
+ verify_result->verified_cert = CreateFromHandle(verified_cert,
+ verified_chain);
+ }
+
// Currently we only ues OpenSSL's default root CA paths, so treat all
// correctly verified certs as being from a known root. TODO(joth): if the
// motivations described in http://src.chromium.org/viewvc/chrome?view=rev&revision=80778
diff --git a/net/base/x509_certificate_unittest.cc b/net/base/x509_certificate_unittest.cc
index 7adad4f..32417ac 100644
--- a/net/base/x509_certificate_unittest.cc
+++ b/net/base/x509_certificate_unittest.cc
@@ -820,6 +820,148 @@ TEST(X509CertificateTest, IntermediateCertificates) {
X509Certificate::FreeOSCertHandle(google_handle);
}
+// Basic test for returning the chain in CertVerifyResult. Note that the
+// returned chain may just be a reflection of the originally supplied chain;
+// that is, if any errors occur, the default chain returned is an exact copy
+// of the certificate to be verified. The remaining VerifyReturn* tests are
+// used to ensure that the actual, verified chain is being returned by
+// Verify().
+TEST(X509CertificateTest, VerifyReturnChainBasic) {
+ FilePath certs_dir = GetTestCertsDirectory();
+ CertificateList certs = CreateCertificateListFromFile(
+ certs_dir, "x509_verify_results.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());
+
+ TestRootCerts::GetInstance()->Add(certs[2]);
+
+ 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());
+
+ CertVerifyResult verify_result;
+ EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
+ int error = google_full_chain->Verify("127.0.0.1", 0, &verify_result);
+ EXPECT_EQ(OK, error);
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
+
+ EXPECT_NE(google_full_chain, verify_result.verified_cert);
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(
+ google_full_chain->os_cert_handle(),
+ verify_result.verified_cert->os_cert_handle()));
+ const X509Certificate::OSCertHandles& return_intermediates =
+ verify_result.verified_cert->GetIntermediateCertificates();
+ ASSERT_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()));
+
+ TestRootCerts::GetInstance()->Clear();
+}
+
+// Test that the certificate returned in CertVerifyResult is able to reorder
+// certificates that are not ordered from end-entity to root. While this is
+// a protocol violation if sent during a TLS handshake, if multiple sources
+// of intermediate certificates are combined, it's possible that order may
+// not be maintained.
+TEST(X509CertificateTest, VerifyReturnChainProperlyOrdered) {
+ FilePath certs_dir = GetTestCertsDirectory();
+ CertificateList certs = CreateCertificateListFromFile(
+ certs_dir, "x509_verify_results.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());
+
+ TestRootCerts::GetInstance()->Add(certs[2]);
+
+ 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());
+
+ CertVerifyResult verify_result;
+ EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
+ int error = google_full_chain->Verify("127.0.0.1", 0, &verify_result);
+ EXPECT_EQ(OK, error);
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
+
+ EXPECT_NE(google_full_chain, verify_result.verified_cert);
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(
+ google_full_chain->os_cert_handle(),
+ verify_result.verified_cert->os_cert_handle()));
+ const X509Certificate::OSCertHandles& return_intermediates =
+ verify_result.verified_cert->GetIntermediateCertificates();
+ ASSERT_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()));
+
+ TestRootCerts::GetInstance()->Clear();
+}
+
+// Test that Verify() filters out certificates which are not related to
+// or part of the certificate chain being verified.
+TEST(X509CertificateTest, VerifyReturnChainFiltersUnrelatedCerts) {
+ FilePath certs_dir = GetTestCertsDirectory();
+ CertificateList certs = CreateCertificateListFromFile(
+ certs_dir, "x509_verify_results.chain.pem",
+ X509Certificate::FORMAT_AUTO);
+ ASSERT_EQ(3U, certs.size());
+ TestRootCerts::GetInstance()->Add(certs[2]);
+
+ 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());
+
+ CertVerifyResult verify_result;
+ EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
+ int error = google_full_chain->Verify("127.0.0.1", 0, &verify_result);
+ EXPECT_EQ(OK, error);
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
+
+ EXPECT_NE(google_full_chain, verify_result.verified_cert);
+ EXPECT_TRUE(X509Certificate::IsSameOSCert(
+ google_full_chain->os_cert_handle(),
+ verify_result.verified_cert->os_cert_handle()));
+ const X509Certificate::OSCertHandles& return_intermediates =
+ verify_result.verified_cert->GetIntermediateCertificates();
+ ASSERT_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()));
+ TestRootCerts::GetInstance()->Clear();
+}
+
#if defined(OS_MACOSX)
TEST(X509CertificateTest, IsIssuedBy) {
FilePath certs_dir = GetTestCertsDirectory();
diff --git a/net/base/x509_certificate_win.cc b/net/base/x509_certificate_win.cc
index 306bd28..5dfc285 100644
--- a/net/base/x509_certificate_win.cc
+++ b/net/base/x509_certificate_win.cc
@@ -296,16 +296,28 @@ bool CertSubjectCommonNameHasNull(PCCERT_CONTEXT cert) {
// this function.
void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context,
CertVerifyResult* verify_result) {
+ if (chain_context->cChain == 0)
+ return;
+
PCERT_SIMPLE_CHAIN first_chain = chain_context->rgpChain[0];
int num_elements = first_chain->cElement;
PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement;
+ PCCERT_CONTEXT verified_cert = NULL;
+ std::vector<PCCERT_CONTEXT> verified_chain;
+
// Each chain starts with the end entity certificate (i = 0) and ends with
// the root CA certificate (i = num_elements - 1). Do not inspect the
// signature algorithm of the root CA certificate because the signature on
// the trust anchor is not important.
for (int i = 0; i < num_elements - 1; ++i) {
PCCERT_CONTEXT cert = element[i]->pCertContext;
+ if (i == 0) {
+ verified_cert = cert;
+ } else {
+ verified_chain.push_back(cert);
+ }
+
const char* algorithm = cert->pCertInfo->SignatureAlgorithm.pszObjId;
if (strcmp(algorithm, szOID_RSA_MD5RSA) == 0) {
// md5WithRSAEncryption: 1.2.840.113549.1.1.4
@@ -322,6 +334,14 @@ void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context,
verify_result->has_md4 = true;
}
}
+
+ if (verified_cert) {
+ // Add the root certificate, if present, as it was not added above.
+ if (num_elements > 1)
+ verified_chain.push_back(element[num_elements - 1]->pCertContext);
+ verify_result->verified_cert =
+ X509Certificate::CreateFromHandle(verified_cert, verified_chain);
+ }
}
// Decodes the cert's certificatePolicies extension into a CERT_POLICIES_INFO
diff --git a/net/data/ssl/certificates/README b/net/data/ssl/certificates/README
index 1793476..07e3f36 100644
--- a/net/data/ssl/certificates/README
+++ b/net/data/ssl/certificates/README
@@ -39,3 +39,8 @@ unit tests.
key in unittest.key.bin. The common name is "unittest".
- unittest.key.bin : private key stored unencrypted.
+
+- x509_verify_results.chain.pem : A simple certificate chain used to test that
+ the correctly ordered, filtered certificate chain is returned during
+ verification, regardless of the order in which the intermediate/root CA
+ certificates are provided. \ No newline at end of file
diff --git a/net/data/ssl/certificates/x509_verify_results.chain.pem b/net/data/ssl/certificates/x509_verify_results.chain.pem
new file mode 100644
index 0000000..11c3187
--- /dev/null
+++ b/net/data/ssl/certificates/x509_verify_results.chain.pem
@@ -0,0 +1,50 @@
+-----BEGIN CERTIFICATE-----
+MIICwjCCAiugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHVGVzdCBDQTEdMBsGA1UEAwwUVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcN
+MTEwNDE4MDA1MzE4WhcNMjAxMTE2MDA1MzE4WjBgMQswCQYDVQQGEwJVUzETMBEG
+A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UE
+CgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4xMIGfMA0GCSqGSIb3DQEBAQUA
+A4GNADCBiQKBgQCmXYTWf2ivhIc3uf3qdg8u9c8EobXlXHSGq2iYJBedlGwyFUa1
+lijbi4OhP53pVv/gP9rZJXKACWDI4ZryAa2La1CiTAgesewzPIIVzrJ2KaNUFpvO
+e7YLZVqa0AnMNv1LNVp8eT05rcvN0XxFqvOdaFASBKnjOTqdvdkLtqwYawIDAQAB
+o4GAMH4wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUhEM3aeclNoZ1e/vksAaYOkCW
+txUwHwYDVR0jBBgwFoAUlJpwHgPeLEqeOAaz6Y7gch7YeCgwHQYDVR0lBBYwFAYI
+KwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZIhvcNAQEF
+BQADgYEAFMILenxcrqHu6+a77HDjZQ1TUHZcVnokdhbCR8n+jxO+QdrQcJuu9VPa
+0XpYR+x5VzN26Tbf88jGyCGEkDrtr7sBsw+YzUvDx18Rl9SfE4jFNuvNRCY+/oMH
+eq4v35gB0tHOH2As3QGywnp2zEAA8eVMJzSFHS18WR/vBUGpvzo=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICpzCCAhCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTExMDQxNzIy
+MjU1OFoXDTIxMDIyMzIyMjU1OFowazELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
+bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg
+Q0ExHTAbBgNVBAMMFFRlc3QgSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQCdrVeFppenZ20T6f76yHp+qIOuWpA9ojNKJW+p93kY/2wC
+bUxVndJ+YYQ2/HGHURRGwBs/1yYCaeyCeVF3Ckr3Ei65fDAHqZFpZ/IsjUT9eRBO
+BODSaKFfvCF7Iv+521PZq5QaIPZOA99CaL5nqlEUbtas+4ziEg76Ngc2KxII1QID
+AQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSUmnAeA94sSp44BrPp
+juByHth4KDAfBgNVHSMEGDAWgBRqsJiqdonmw+gkmvYOysT9lJgj2zAOBgNVHQ8B
+Af8EBAMCAQYwDQYJKoZIhvcNAQEFBQADgYEAzGgopGXKvuBlz04KEFMu46fUrxYe
+O6B6csR7Rt7elDvIMu2+rdkaP9Ccv0PqtXv4DRFCxdrG8+LhL3B4SofYxCqTtq9e
+rNtFRIR5Xad07djNBshor9PjNeKHnrGc1rXesqCfILpg2fq/Qv1OM1yrpLjbcuM6
+eCG7aIfsh9LwP3o=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIChjCCAe+gAwIBAgIJAOa+aXDInZR1MA0GCSqGSIb3DQEBBQUAMGMxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3MRAwDgYDVQQKDAdUZXN0IENBMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0EwHhcN
+MTEwNDE3MjIzMTEzWhcNMjEwNDE0MjIzMTEzWjBjMQswCQYDVQQGEwJVUzETMBEG
+A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UE
+CgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQD0pusirvvLaxBXtAu7kE9X7q4K/iOjIQIBNIbGdKtPDZus
+9I7SCNa3ZWcvTKTOp1biFCuXLJ404cxSOqo6YB7s4hcyHVEMz+EHhxHUYQmmZb0P
+12QwWVteJd2MZvkwupPeaNJhlyR0Vf51m9kpPVuFLrMb4Smvgcx9jbwOut1ACwID
+AQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
+FgQUarCYqnaJ5sPoJJr2DsrE/ZSYI9swDQYJKoZIhvcNAQEFBQADgYEAck/rD/Vy
+vD53HXph/Bc7+qo9t3Nmyy9rbgl0dQq9h5+6Ria4Btw3Uj8iaQZTeyyFvGP0NHR2
+ek2hgX7fDwD3fRKEJus4shs16BzuSCBmYKw/G5PehEC9trIly52pMuUGphczbpzp
+6RdYOT3pG713l25Kt436hDnCoonwUqB6mhs=
+-----END CERTIFICATE-----
diff --git a/net/socket/ssl_client_socket_mac.cc b/net/socket/ssl_client_socket_mac.cc
index de70ab0..96bae2d 100644
--- a/net/socket/ssl_client_socket_mac.cc
+++ b/net/socket/ssl_client_socket_mac.cc
@@ -722,10 +722,8 @@ bool SSLClientSocketMac::SetSendBufferSize(int32 size) {
void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) {
ssl_info->Reset();
- if (!server_cert_) {
- NOTREACHED();
+ if (!server_cert_)
return;
- }
ssl_info->cert = server_cert_;
ssl_info->cert_status = server_cert_verify_result_.cert_status;
@@ -1148,6 +1146,7 @@ int SSLClientSocketMac::DoVerifyCert() {
VLOG(1) << "Received an expected bad cert with status: " << cert_status;
server_cert_verify_result_.Reset();
server_cert_verify_result_.cert_status = cert_status;
+ server_cert_verify_result_.verified_cert = server_cert_;
return OK;
}
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index 42acb81..de39c55 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -477,7 +477,6 @@ void SSLClientSocketNSS::ClearSessionCache() {
void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
EnterFunction("");
ssl_info->Reset();
-
if (!server_cert_nss_)
return;
@@ -1527,6 +1526,7 @@ int SSLClientSocketNSS::DoVerifyDNSSEC(int result) {
host_and_port_.port());
if (r == DNSVR_SUCCESS) {
local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC;
+ local_server_cert_verify_result_.verified_cert = server_cert_;
server_cert_verify_result_ = &local_server_cert_verify_result_;
GotoState(STATE_VERIFY_CERT_COMPLETE);
return OK;
@@ -1557,6 +1557,7 @@ int SSLClientSocketNSS::DoVerifyCert(int result) {
server_cert_verify_result_ = &local_server_cert_verify_result_;
local_server_cert_verify_result_.Reset();
local_server_cert_verify_result_.cert_status = cert_status;
+ local_server_cert_verify_result_.verified_cert = server_cert_;
return OK;
}
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index 0801bf4..c0efab5 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -826,6 +826,7 @@ int SSLClientSocketOpenSSL::DoVerifyCert(int result) {
VLOG(1) << "Received an expected bad cert with status: " << cert_status;
server_cert_verify_result_.Reset();
server_cert_verify_result_.cert_status = cert_status;
+ server_cert_verify_result_.verified_cert = server_cert_;
return OK;
}
diff --git a/net/socket/ssl_client_socket_win.cc b/net/socket/ssl_client_socket_win.cc
index 729d76e..f970068 100644
--- a/net/socket/ssl_client_socket_win.cc
+++ b/net/socket/ssl_client_socket_win.cc
@@ -427,7 +427,6 @@ SSLClientSocketWin::~SSLClientSocketWin() {
void SSLClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) {
ssl_info->Reset();
-
if (!server_cert_)
return;
@@ -1163,6 +1162,7 @@ int SSLClientSocketWin::DoVerifyCert() {
VLOG(1) << "Received an expected bad cert with status: " << cert_status;
server_cert_verify_result_.Reset();
server_cert_verify_result_.cert_status = cert_status;
+ server_cert_verify_result_.verified_cert = server_cert_;
return OK;
}