OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_certificate.h" | 5 #include "net/base/x509_certificate.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/pickle.h" | 8 #include "base/pickle.h" |
9 #include "base/sha1.h" | 9 #include "base/sha1.h" |
10 #include "base/string_tokenizer.h" | 10 #include "base/string_tokenizer.h" |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
288 } | 288 } |
289 } | 289 } |
290 return false; | 290 return false; |
291 } | 291 } |
292 | 292 |
293 // Saves some information about the certificate chain chain_context in | 293 // Saves some information about the certificate chain chain_context in |
294 // *verify_result. The caller MUST initialize *verify_result before calling | 294 // *verify_result. The caller MUST initialize *verify_result before calling |
295 // this function. | 295 // this function. |
296 void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context, | 296 void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context, |
297 CertVerifyResult* verify_result) { | 297 CertVerifyResult* verify_result) { |
298 if (chain_context->cChain < 1) | |
299 return; | |
wtc
2011/07/26 00:16:35
Why don't you test chain_context->cChain == 0 here
Ryan Sleevi
2011/07/26 00:44:15
No, it's a DWORD, so it's unsigned. Updated to be
| |
300 | |
298 PCERT_SIMPLE_CHAIN first_chain = chain_context->rgpChain[0]; | 301 PCERT_SIMPLE_CHAIN first_chain = chain_context->rgpChain[0]; |
299 int num_elements = first_chain->cElement; | 302 int num_elements = first_chain->cElement; |
300 PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement; | 303 PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement; |
301 | 304 |
305 PCCERT_CONTEXT verified_cert = NULL; | |
306 std::vector<PCCERT_CONTEXT> verified_chain; | |
307 | |
302 // Each chain starts with the end entity certificate (i = 0) and ends with | 308 // Each chain starts with the end entity certificate (i = 0) and ends with |
303 // the root CA certificate (i = num_elements - 1). Do not inspect the | 309 // the root CA certificate (i = num_elements - 1). Do not inspect the |
304 // signature algorithm of the root CA certificate because the signature on | 310 // signature algorithm of the root CA certificate because the signature on |
305 // the trust anchor is not important. | 311 // the trust anchor is not important. |
306 for (int i = 0; i < num_elements - 1; ++i) { | 312 for (int i = 0; i < num_elements - 1; ++i) { |
307 PCCERT_CONTEXT cert = element[i]->pCertContext; | 313 PCCERT_CONTEXT cert = element[i]->pCertContext; |
314 if (i == 0) { | |
315 verified_cert = cert; | |
316 } else { | |
317 verified_chain.push_back(cert); | |
318 } | |
319 | |
308 const char* algorithm = cert->pCertInfo->SignatureAlgorithm.pszObjId; | 320 const char* algorithm = cert->pCertInfo->SignatureAlgorithm.pszObjId; |
309 if (strcmp(algorithm, szOID_RSA_MD5RSA) == 0) { | 321 if (strcmp(algorithm, szOID_RSA_MD5RSA) == 0) { |
310 // md5WithRSAEncryption: 1.2.840.113549.1.1.4 | 322 // md5WithRSAEncryption: 1.2.840.113549.1.1.4 |
311 verify_result->has_md5 = true; | 323 verify_result->has_md5 = true; |
312 if (i != 0) | 324 if (i != 0) |
313 verify_result->has_md5_ca = true; | 325 verify_result->has_md5_ca = true; |
314 } else if (strcmp(algorithm, szOID_RSA_MD2RSA) == 0) { | 326 } else if (strcmp(algorithm, szOID_RSA_MD2RSA) == 0) { |
315 // md2WithRSAEncryption: 1.2.840.113549.1.1.2 | 327 // md2WithRSAEncryption: 1.2.840.113549.1.1.2 |
316 verify_result->has_md2 = true; | 328 verify_result->has_md2 = true; |
317 if (i != 0) | 329 if (i != 0) |
318 verify_result->has_md2_ca = true; | 330 verify_result->has_md2_ca = true; |
319 } else if (strcmp(algorithm, szOID_RSA_MD4RSA) == 0) { | 331 } else if (strcmp(algorithm, szOID_RSA_MD4RSA) == 0) { |
320 // md4WithRSAEncryption: 1.2.840.113549.1.1.3 | 332 // md4WithRSAEncryption: 1.2.840.113549.1.1.3 |
321 verify_result->has_md4 = true; | 333 verify_result->has_md4 = true; |
322 } | 334 } |
323 } | 335 } |
336 | |
337 if (verified_cert) { | |
338 // Add the root certificate, if present, as it was not added above. | |
339 if (num_elements > 1) | |
340 verified_chain.push_back(element[num_elements - 1]->pCertContext); | |
341 verify_result->verified_cert = | |
342 X509Certificate::CreateFromHandle(verified_cert, verified_chain); | |
343 } | |
324 } | 344 } |
325 | 345 |
326 // Decodes the cert's certificatePolicies extension into a CERT_POLICIES_INFO | 346 // Decodes the cert's certificatePolicies extension into a CERT_POLICIES_INFO |
327 // structure and stores it in *output. | 347 // structure and stores it in *output. |
328 void GetCertPoliciesInfo(PCCERT_CONTEXT cert, | 348 void GetCertPoliciesInfo(PCCERT_CONTEXT cert, |
329 scoped_ptr_malloc<CERT_POLICIES_INFO>* output) { | 349 scoped_ptr_malloc<CERT_POLICIES_INFO>* output) { |
330 PCERT_EXTENSION extension = CertFindExtension(szOID_CERT_POLICIES, | 350 PCERT_EXTENSION extension = CertFindExtension(szOID_CERT_POLICIES, |
331 cert->pCertInfo->cExtension, | 351 cert->pCertInfo->cExtension, |
332 cert->pCertInfo->rgExtension); | 352 cert->pCertInfo->rgExtension); |
333 if (!extension) | 353 if (!extension) |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
667 } | 687 } |
668 } | 688 } |
669 | 689 |
670 return cert_list; | 690 return cert_list; |
671 } | 691 } |
672 | 692 |
673 int X509Certificate::Verify(const std::string& hostname, | 693 int X509Certificate::Verify(const std::string& hostname, |
674 int flags, | 694 int flags, |
675 CertVerifyResult* verify_result) const { | 695 CertVerifyResult* verify_result) const { |
676 verify_result->Reset(); | 696 verify_result->Reset(); |
677 if (!cert_handle_) | 697 verify_result->verified_cert = |
678 return ERR_UNEXPECTED; | 698 CreateFromHandle(cert_handle_, GetIntermediateCertificates()); |
679 | 699 |
680 if (IsBlacklisted()) { | 700 if (IsBlacklisted()) { |
681 verify_result->cert_status |= CERT_STATUS_REVOKED; | 701 verify_result->cert_status |= CERT_STATUS_REVOKED; |
682 return ERR_CERT_REVOKED; | 702 return ERR_CERT_REVOKED; |
683 } | 703 } |
684 | 704 |
685 // Build and validate certificate chain. | 705 // Build and validate certificate chain. |
686 | 706 |
687 CERT_CHAIN_PARA chain_para; | 707 CERT_CHAIN_PARA chain_para; |
688 memset(&chain_para, 0, sizeof(chain_para)); | 708 memset(&chain_para, 0, sizeof(chain_para)); |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1057 if (!CertSerializeCertificateStoreElement(cert_handle, 0, &buffer[0], | 1077 if (!CertSerializeCertificateStoreElement(cert_handle, 0, &buffer[0], |
1058 &length)) { | 1078 &length)) { |
1059 return false; | 1079 return false; |
1060 } | 1080 } |
1061 | 1081 |
1062 return pickle->WriteData(reinterpret_cast<const char*>(&buffer[0]), | 1082 return pickle->WriteData(reinterpret_cast<const char*>(&buffer[0]), |
1063 length); | 1083 length); |
1064 } | 1084 } |
1065 | 1085 |
1066 } // namespace net | 1086 } // namespace net |
OLD | NEW |