| OLD | NEW | 
|---|
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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 | 
| OLD | NEW | 
|---|