| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/string_tokenizer.h" | 9 #include "base/string_tokenizer.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 *(single_values[i]) = (*(single_value_lists[i]))[0]; | 429 *(single_values[i]) = (*(single_value_lists[i]))[0]; |
| 430 } | 430 } |
| 431 } | 431 } |
| 432 | 432 |
| 433 } // namespace | 433 } // namespace |
| 434 | 434 |
| 435 void X509Certificate::Initialize() { | 435 void X509Certificate::Initialize() { |
| 436 std::wstring subject_info; | 436 std::wstring subject_info; |
| 437 std::wstring issuer_info; | 437 std::wstring issuer_info; |
| 438 DWORD name_size; | 438 DWORD name_size; |
| 439 DCHECK(cert_handle_); |
| 439 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, | 440 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, |
| 440 &cert_handle_->pCertInfo->Subject, | 441 &cert_handle_->pCertInfo->Subject, |
| 441 CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, | 442 CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, |
| 442 NULL, 0); | 443 NULL, 0); |
| 443 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, | 444 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, |
| 444 &cert_handle_->pCertInfo->Subject, | 445 &cert_handle_->pCertInfo->Subject, |
| 445 CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, | 446 CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, |
| 446 WriteInto(&subject_info, name_size), name_size); | 447 WriteInto(&subject_info, name_size), name_size); |
| 447 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, | 448 name_size = CertNameToStr(cert_handle_->dwCertEncodingType, |
| 448 &cert_handle_->pCertInfo->Issuer, | 449 &cert_handle_->pCertInfo->Issuer, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 477 NULL, // the cert won't be persisted in any cert store | 478 NULL, // the cert won't be persisted in any cert store |
| 478 reinterpret_cast<const BYTE*>(data), length, | 479 reinterpret_cast<const BYTE*>(data), length, |
| 479 CERT_STORE_ADD_USE_EXISTING, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, | 480 CERT_STORE_ADD_USE_EXISTING, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, |
| 480 NULL, reinterpret_cast<const void **>(&cert_handle))) | 481 NULL, reinterpret_cast<const void **>(&cert_handle))) |
| 481 return NULL; | 482 return NULL; |
| 482 | 483 |
| 483 return CreateFromHandle(cert_handle, SOURCE_LONE_CERT_IMPORT); | 484 return CreateFromHandle(cert_handle, SOURCE_LONE_CERT_IMPORT); |
| 484 } | 485 } |
| 485 | 486 |
| 486 void X509Certificate::Persist(Pickle* pickle) { | 487 void X509Certificate::Persist(Pickle* pickle) { |
| 488 DCHECK(cert_handle_); |
| 487 DWORD length; | 489 DWORD length; |
| 488 if (!CertSerializeCertificateStoreElement(cert_handle_, 0, | 490 if (!CertSerializeCertificateStoreElement(cert_handle_, 0, |
| 489 NULL, &length)) { | 491 NULL, &length)) { |
| 490 NOTREACHED(); | 492 NOTREACHED(); |
| 491 return; | 493 return; |
| 492 } | 494 } |
| 493 BYTE* data = reinterpret_cast<BYTE*>(pickle->BeginWriteData(length)); | 495 BYTE* data = reinterpret_cast<BYTE*>(pickle->BeginWriteData(length)); |
| 494 if (!CertSerializeCertificateStoreElement(cert_handle_, 0, | 496 if (!CertSerializeCertificateStoreElement(cert_handle_, 0, |
| 495 data, &length)) { | 497 data, &length)) { |
| 496 NOTREACHED(); | 498 NOTREACHED(); |
| 497 length = 0; | 499 length = 0; |
| 498 } | 500 } |
| 499 pickle->TrimWriteData(length); | 501 pickle->TrimWriteData(length); |
| 500 } | 502 } |
| 501 | 503 |
| 502 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { | 504 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { |
| 503 dns_names->clear(); | 505 dns_names->clear(); |
| 504 scoped_ptr_malloc<CERT_ALT_NAME_INFO> alt_name_info; | 506 if (cert_handle_) { |
| 505 GetCertSubjectAltName(cert_handle_, &alt_name_info); | 507 scoped_ptr_malloc<CERT_ALT_NAME_INFO> alt_name_info; |
| 506 CERT_ALT_NAME_INFO* alt_name = alt_name_info.get(); | 508 GetCertSubjectAltName(cert_handle_, &alt_name_info); |
| 507 if (alt_name) { | 509 CERT_ALT_NAME_INFO* alt_name = alt_name_info.get(); |
| 508 int num_entries = alt_name->cAltEntry; | 510 if (alt_name) { |
| 509 for (int i = 0; i < num_entries; i++) { | 511 int num_entries = alt_name->cAltEntry; |
| 510 // dNSName is an ASN.1 IA5String representing a string of ASCII | 512 for (int i = 0; i < num_entries; i++) { |
| 511 // characters, so we can use WideToASCII here. | 513 // dNSName is an ASN.1 IA5String representing a string of ASCII |
| 512 if (alt_name->rgAltEntry[i].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME) | 514 // characters, so we can use WideToASCII here. |
| 513 dns_names->push_back(WideToASCII(alt_name->rgAltEntry[i].pwszDNSName)); | 515 if (alt_name->rgAltEntry[i].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME) |
| 516 dns_names->push_back( |
| 517 WideToASCII(alt_name->rgAltEntry[i].pwszDNSName)); |
| 518 } |
| 514 } | 519 } |
| 515 } | 520 } |
| 516 if (dns_names->empty()) | 521 if (dns_names->empty()) |
| 517 dns_names->push_back(subject_.common_name); | 522 dns_names->push_back(subject_.common_name); |
| 518 } | 523 } |
| 519 | 524 |
| 520 int X509Certificate::Verify(const std::string& hostname, | 525 int X509Certificate::Verify(const std::string& hostname, |
| 521 int flags, | 526 int flags, |
| 522 CertVerifyResult* verify_result) const { | 527 CertVerifyResult* verify_result) const { |
| 523 verify_result->Reset(); | 528 verify_result->Reset(); |
| 529 if (!cert_handle_) |
| 530 return ERR_UNEXPECTED; |
| 524 | 531 |
| 525 // Build and validate certificate chain. | 532 // Build and validate certificate chain. |
| 526 | 533 |
| 527 CERT_CHAIN_PARA chain_para; | 534 CERT_CHAIN_PARA chain_para; |
| 528 memset(&chain_para, 0, sizeof(chain_para)); | 535 memset(&chain_para, 0, sizeof(chain_para)); |
| 529 chain_para.cbSize = sizeof(chain_para); | 536 chain_para.cbSize = sizeof(chain_para); |
| 530 // TODO(wtc): consider requesting the usage szOID_PKIX_KP_SERVER_AUTH | 537 // TODO(wtc): consider requesting the usage szOID_PKIX_KP_SERVER_AUTH |
| 531 // or szOID_SERVER_GATED_CRYPTO or szOID_SGC_NETSCAPE | 538 // or szOID_SERVER_GATED_CRYPTO or szOID_SGC_NETSCAPE |
| 532 chain_para.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND; | 539 chain_para.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND; |
| 533 chain_para.RequestedUsage.Usage.cUsageIdentifier = 0; | 540 chain_para.RequestedUsage.Usage.cUsageIdentifier = 0; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 return OK; | 671 return OK; |
| 665 } | 672 } |
| 666 | 673 |
| 667 // Returns true if the certificate is an extended-validation certificate. | 674 // Returns true if the certificate is an extended-validation certificate. |
| 668 // | 675 // |
| 669 // This function checks the certificatePolicies extensions of the | 676 // This function checks the certificatePolicies extensions of the |
| 670 // certificates in the certificate chain according to Section 7 (pp. 11-12) | 677 // certificates in the certificate chain according to Section 7 (pp. 11-12) |
| 671 // of the EV Certificate Guidelines Version 1.0 at | 678 // of the EV Certificate Guidelines Version 1.0 at |
| 672 // http://cabforum.org/EV_Certificate_Guidelines.pdf. | 679 // http://cabforum.org/EV_Certificate_Guidelines.pdf. |
| 673 bool X509Certificate::VerifyEV() const { | 680 bool X509Certificate::VerifyEV() const { |
| 681 DCHECK(cert_handle_); |
| 674 net::EVRootCAMetadata* metadata = net::EVRootCAMetadata::GetInstance(); | 682 net::EVRootCAMetadata* metadata = net::EVRootCAMetadata::GetInstance(); |
| 675 | 683 |
| 676 PCCERT_CHAIN_CONTEXT chain_context = ConstructCertChain(cert_handle_, | 684 PCCERT_CHAIN_CONTEXT chain_context = ConstructCertChain(cert_handle_, |
| 677 metadata->GetPolicyOIDs(), metadata->NumPolicyOIDs()); | 685 metadata->GetPolicyOIDs(), metadata->NumPolicyOIDs()); |
| 678 if (!chain_context) | 686 if (!chain_context) |
| 679 return false; | 687 return false; |
| 680 ScopedCertChainContext scoped_chain_context(chain_context); | 688 ScopedCertChainContext scoped_chain_context(chain_context); |
| 681 | 689 |
| 682 DCHECK(chain_context->cChain != 0); | 690 DCHECK(chain_context->cChain != 0); |
| 683 // If the cert doesn't match any of the policies, the | 691 // If the cert doesn't match any of the policies, the |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 DWORD sha1_size = sizeof(sha1.data); | 753 DWORD sha1_size = sizeof(sha1.data); |
| 746 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, | 754 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, |
| 747 cert->cbCertEncoded, sha1.data, &sha1_size); | 755 cert->cbCertEncoded, sha1.data, &sha1_size); |
| 748 DCHECK(rv && sha1_size == sizeof(sha1.data)); | 756 DCHECK(rv && sha1_size == sizeof(sha1.data)); |
| 749 if (!rv) | 757 if (!rv) |
| 750 memset(sha1.data, 0, sizeof(sha1.data)); | 758 memset(sha1.data, 0, sizeof(sha1.data)); |
| 751 return sha1; | 759 return sha1; |
| 752 } | 760 } |
| 753 | 761 |
| 754 } // namespace net | 762 } // namespace net |
| OLD | NEW |