Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: net/base/x509_chain_nss.cc

Issue 3146034: Allow the constructed certificate chain to be returned in CertVerifyResult (Closed)
Patch Set: Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/base/x509_chain_mac.cc ('k') | net/base/x509_chain_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/x509_chain.h" 5 #include "net/base/x509_chain.h"
6 6
7 #include <cert.h> 7 #include <cert.h>
8 #include <nss.h> 8 #include <nss.h>
9 #include <prerror.h> 9 #include <prerror.h>
10 #include <secerr.h> 10 #include <secerr.h>
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 case SEC_ERROR_POLICY_VALIDATION_FAILED: 135 case SEC_ERROR_POLICY_VALIDATION_FAILED:
136 return CERT_STATUS_INVALID; 136 return CERT_STATUS_INVALID;
137 default: 137 default:
138 return 0; 138 return 0;
139 } 139 }
140 } 140 }
141 141
142 // Saves some information about the certificate chain cert_list in 142 // Saves some information about the certificate chain cert_list in
143 // *verify_result. The caller MUST initialize *verify_result before calling 143 // *verify_result. The caller MUST initialize *verify_result before calling
144 // this function. 144 // this function.
145 // Note that cert_list[0] is the end entity certificate and cert_list doesn't 145 // Note that cert_list[0] is the end entity certificate
146 // contain the root CA certificate. 146 void GetCertChainInfo(int flags,
147 void GetCertChainInfo(CERTCertList* cert_list, 147 CERTCertList* cert_list,
148 CERTCertificate* trust_anchor,
148 CertVerifyResult* verify_result) { 149 CertVerifyResult* verify_result) {
149 // NOTE: Using a NSS library before 3.12.3.1 will crash below. To see the 150 // NOTE: Using a NSS library before 3.12.3.1 will crash below. To see the
150 // NSS version currently in use: 151 // NSS version currently in use:
151 // 1. use ldd on the chrome executable for NSS's location (ie. libnss3.so*) 152 // 1. use ldd on the chrome executable for NSS's location (ie. libnss3.so*)
152 // 2. use ident libnss3.so* for the library's version 153 // 2. use ident libnss3.so* for the library's version
153 DCHECK(cert_list); 154 DCHECK(cert_list);
155 bool return_chain = !!(flags & x509_chain::VERIFY_RETURN_CHAIN);
156 X509Certificate::OSCertHandles intermediates;
154 int i = 0; 157 int i = 0;
155 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); 158 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
156 !CERT_LIST_END(node, cert_list); 159 !CERT_LIST_END(node, cert_list);
157 node = CERT_LIST_NEXT(node), i++) { 160 node = CERT_LIST_NEXT(node), i++) {
158 SECAlgorithmID& signature = node->cert->signature; 161 SECAlgorithmID& signature = node->cert->signature;
159 SECOidTag oid_tag = SECOID_FindOIDTag(&signature.algorithm); 162 SECOidTag oid_tag = SECOID_FindOIDTag(&signature.algorithm);
160 switch (oid_tag) { 163 switch (oid_tag) {
161 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: 164 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
162 verify_result->has_md5 = true; 165 verify_result->has_md5 = true;
163 if (i != 0) 166 if (i != 0)
164 verify_result->has_md5_ca = true; 167 verify_result->has_md5_ca = true;
165 break; 168 break;
166 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: 169 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
167 verify_result->has_md2 = true; 170 verify_result->has_md2 = true;
168 if (i != 0) 171 if (i != 0)
169 verify_result->has_md2_ca = true; 172 verify_result->has_md2_ca = true;
170 break; 173 break;
171 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: 174 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
172 verify_result->has_md4 = true; 175 verify_result->has_md4 = true;
173 break; 176 break;
174 default: 177 default:
175 break; 178 break;
176 } 179 }
180
181 if (return_chain && i != 0)
182 intermediates.push_back(node->cert);
183 }
184
185 if (return_chain) {
186 if (trust_anchor)
187 intermediates.push_back(trust_anchor);
188 verify_result->certificate = X509Certificate::CreateFromHandle(
189 CERT_LIST_HEAD(cert_list)->cert, intermediates);
177 } 190 }
178 } 191 }
179 192
180 // Forward declarations. 193 // Forward declarations.
181 SECStatus RetryPKIXVerifyCertWithWorkarounds( 194 SECStatus RetryPKIXVerifyCertWithWorkarounds(
182 X509Certificate::OSCertHandle cert_handle, int num_policy_oids, 195 X509Certificate::OSCertHandle cert_handle, int num_policy_oids,
183 std::vector<CERTValInParam>* cvin, CERTValOutParam* cvout); 196 std::vector<CERTValInParam>* cvin, CERTValOutParam* cvout);
184 SECOidTag GetFirstCertPolicy(X509Certificate::OSCertHandle cert_handle); 197 SECOidTag GetFirstCertPolicy(X509Certificate::OSCertHandle cert_handle);
185 198
186 // Call CERT_PKIXVerifyCert for the cert_handle. 199 // Call CERT_PKIXVerifyCert for the cert_handle.
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 hostname.c_str()); 497 hostname.c_str());
485 if (status != SECSuccess) 498 if (status != SECSuccess)
486 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; 499 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
487 500
488 // Make sure that the cert is valid now. 501 // Make sure that the cert is valid now.
489 SECCertTimeValidity validity = CERT_CheckCertValidTimes( 502 SECCertTimeValidity validity = CERT_CheckCertValidTimes(
490 certificate->os_cert_handle(), PR_Now(), PR_TRUE); 503 certificate->os_cert_handle(), PR_Now(), PR_TRUE);
491 if (validity != secCertTimeValid) 504 if (validity != secCertTimeValid)
492 verify_result->cert_status |= CERT_STATUS_DATE_INVALID; 505 verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
493 506
494 CERTValOutParam cvout[3]; 507 CERTValOutParam cvout[4];
495 int cvout_index = 0; 508 int cvout_index = 0;
496 // We don't need the trust anchor for the first PKIXVerifyCert call.
497 cvout[cvout_index].type = cert_po_certList; 509 cvout[cvout_index].type = cert_po_certList;
498 cvout[cvout_index].value.pointer.chain = NULL; 510 cvout[cvout_index].value.pointer.chain = NULL;
499 int cvout_cert_list_index = cvout_index; 511 int cvout_cert_list_index = cvout_index;
500 cvout_index++; 512 cvout_index++;
513 cvout[cvout_index].type = cert_po_trustAnchor;
514 cvout[cvout_index].value.pointer.cert = NULL;
515 int cvout_trust_anchor_index = cvout_index;
516 cvout_index++;
501 cvout[cvout_index].type = cert_po_end; 517 cvout[cvout_index].type = cert_po_end;
502 ScopedCERTValOutParam scoped_cvout(cvout); 518 ScopedCERTValOutParam scoped_cvout(cvout);
503 519
504 bool check_revocation = (flags & VERIFY_REV_CHECKING_ENABLED); 520 bool check_revocation = (flags & VERIFY_REV_CHECKING_ENABLED);
505 if (check_revocation) { 521 if (check_revocation) {
506 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 522 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
507 } else { 523 } else {
508 // EV requires revocation checking. 524 // EV requires revocation checking.
509 flags &= ~VERIFY_EV_CERT; 525 flags &= ~VERIFY_EV_CERT;
510 } 526 }
(...skipping 10 matching lines...) Expand all
521 err = SEC_ERROR_EXPIRED_CERTIFICATE; 537 err = SEC_ERROR_EXPIRED_CERTIFICATE;
522 int cert_status = MapCertErrorToCertStatus(err); 538 int cert_status = MapCertErrorToCertStatus(err);
523 if (cert_status) { 539 if (cert_status) {
524 verify_result->cert_status |= cert_status; 540 verify_result->cert_status |= cert_status;
525 return MapCertStatusToNetError(verify_result->cert_status); 541 return MapCertStatusToNetError(verify_result->cert_status);
526 } 542 }
527 // |err| is not a certificate error. 543 // |err| is not a certificate error.
528 return MapSecurityError(err); 544 return MapSecurityError(err);
529 } 545 }
530 546
531 GetCertChainInfo(cvout[cvout_cert_list_index].value.pointer.chain, 547 GetCertChainInfo(flags, cvout[cvout_cert_list_index].value.pointer.chain,
548 cvout[cvout_trust_anchor_index].value.pointer.cert,
532 verify_result); 549 verify_result);
533 if (IsCertStatusError(verify_result->cert_status)) 550 if (IsCertStatusError(verify_result->cert_status))
534 return MapCertStatusToNetError(verify_result->cert_status); 551 return MapCertStatusToNetError(verify_result->cert_status);
535 552
536 if ((flags & VERIFY_EV_CERT) && VerifyEV(certificate)) 553 if ((flags & VERIFY_EV_CERT) && VerifyEV(certificate))
537 verify_result->cert_status |= CERT_STATUS_IS_EV; 554 verify_result->cert_status |= CERT_STATUS_IS_EV;
538 return OK; 555 return OK;
539 } 556 }
540 557
541 } // namespace x509_chain 558 } // namespace x509_chain
542 559
543 } // namespace net 560 } // namespace net
OLDNEW
« no previous file with comments | « net/base/x509_chain_mac.cc ('k') | net/base/x509_chain_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698