| Index: net/base/x509_chain_nss.cc
|
| diff --git a/net/base/x509_chain_nss.cc b/net/base/x509_chain_nss.cc
|
| index c5ffe9354310de019d76a2a04ad804e310aac66f..6a8a15f3a12e59241365a533a869862b00882edc 100644
|
| --- a/net/base/x509_chain_nss.cc
|
| +++ b/net/base/x509_chain_nss.cc
|
| @@ -142,15 +142,18 @@ 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.
|
| -void GetCertChainInfo(CERTCertList* cert_list,
|
| +// Note that cert_list[0] is the end entity certificate
|
| +void GetCertChainInfo(int flags,
|
| + CERTCertList* cert_list,
|
| + CERTCertificate* trust_anchor,
|
| 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);
|
| + bool return_chain = !!(flags & x509_chain::VERIFY_RETURN_CHAIN);
|
| + X509Certificate::OSCertHandles intermediates;
|
| int i = 0;
|
| for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
|
| !CERT_LIST_END(node, cert_list);
|
| @@ -174,6 +177,16 @@ void GetCertChainInfo(CERTCertList* cert_list,
|
| default:
|
| break;
|
| }
|
| +
|
| + if (return_chain && i != 0)
|
| + intermediates.push_back(node->cert);
|
| + }
|
| +
|
| + if (return_chain) {
|
| + if (trust_anchor)
|
| + intermediates.push_back(trust_anchor);
|
| + verify_result->certificate = X509Certificate::CreateFromHandle(
|
| + CERT_LIST_HEAD(cert_list)->cert, intermediates);
|
| }
|
| }
|
|
|
| @@ -491,13 +504,16 @@ int VerifySSLServer(X509Certificate* certificate, const std::string& hostname,
|
| if (validity != secCertTimeValid)
|
| verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
|
|
|
| - CERTValOutParam cvout[3];
|
| + CERTValOutParam cvout[4];
|
| int cvout_index = 0;
|
| - // We don't need the trust anchor for the first PKIXVerifyCert call.
|
| cvout[cvout_index].type = cert_po_certList;
|
| cvout[cvout_index].value.pointer.chain = NULL;
|
| int cvout_cert_list_index = cvout_index;
|
| cvout_index++;
|
| + cvout[cvout_index].type = cert_po_trustAnchor;
|
| + cvout[cvout_index].value.pointer.cert = NULL;
|
| + int cvout_trust_anchor_index = cvout_index;
|
| + cvout_index++;
|
| cvout[cvout_index].type = cert_po_end;
|
| ScopedCERTValOutParam scoped_cvout(cvout);
|
|
|
| @@ -528,7 +544,8 @@ int VerifySSLServer(X509Certificate* certificate, const std::string& hostname,
|
| return MapSecurityError(err);
|
| }
|
|
|
| - GetCertChainInfo(cvout[cvout_cert_list_index].value.pointer.chain,
|
| + GetCertChainInfo(flags, 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);
|
|
|