Chromium Code Reviews| Index: net/base/x509_certificate_mac.cc |
| =================================================================== |
| --- net/base/x509_certificate_mac.cc (revision 2361) |
| +++ net/base/x509_certificate_mac.cc (working copy) |
| @@ -4,6 +4,7 @@ |
| #include "net/base/x509_certificate.h" |
| +#include <CommonCrypto/CommonDigest.h> |
| #include <map> |
| #include "base/histogram.h" |
| @@ -15,7 +16,11 @@ |
| #include "net/base/cert_status_flags.h" |
| #include "net/base/ev_root_ca_metadata.h" |
| -#pragma comment(lib, "crypt32.lib") |
| +// NOTE: This Mac implementation is almost entirely untested. TODO(avi): test |
| +// it to make sure it does what the docs imply it does. |
| +// NOTE: This implementation doesn't keep track of dates. Calling code is |
| +// expected to use SecTrustEvaluate(x509cert.os_cert_handle()) and look at the |
| +// result there. |
| namespace net { |
| @@ -24,7 +29,7 @@ |
| // Returns true if this cert fingerprint is the null (all zero) fingerprint. |
| // We use this as a bogus fingerprint value. |
| bool IsNullFingerprint(const X509Certificate::Fingerprint& fingerprint) { |
| - for (int i = 0; i < arraysize(fingerprint.data); ++i) { |
| + for (size_t i = 0; i < arraysize(fingerprint.data); ++i) { |
| if (fingerprint.data[i] != 0) |
| return false; |
| } |
| @@ -33,161 +38,130 @@ |
| // Calculates the SHA-1 fingerprint of the certificate. Returns an empty |
| // (all zero) fingerprint on failure. |
| -X509Certificate::Fingerprint CalculateFingerprint(PCCERT_CONTEXT cert) { |
| - DCHECK(NULL != cert->pbCertEncoded); |
| - DCHECK(0 != cert->cbCertEncoded); |
| - |
| - BOOL rv; |
| +X509Certificate::Fingerprint CalculateFingerprint( |
| + X509Certificate::OSCertHandle cert) { |
| + // The Windows code uses CryptHashCertificate, a function specially designed |
|
wtc
2008/09/18 20:37:55
I believe CryptHashCertificate is just a convenien
Avi (use Gerrit)
2008/09/18 20:48:17
Nice, thanks.
|
| + // to hash certificates. I'm not sure what the difference between using it and |
| + // just hashing the data is. WINE's implementation just hashes the data, and |
| + // so we'll do that. |
| + |
| X509Certificate::Fingerprint sha1; |
| - DWORD sha1_size = sizeof(sha1.data); |
| - rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, |
| - cert->cbCertEncoded, sha1.data, &sha1_size); |
| - DCHECK(rv && sha1_size == sizeof(sha1.data)); |
| - if (!rv) |
| - memset(sha1.data, 0, sizeof(sha1.data)); |
| + memset(sha1.data, 0, sizeof(sha1.data)); |
| + |
| + CSSM_DATA cert_data; |
| + OSStatus status = SecCertificateGetData(cert, &cert_data); |
| + if (status) |
| + return sha1; |
| + |
| + DCHECK(NULL != cert_data.Data); |
| + DCHECK(0 != cert_data.Length); |
| + |
| + CC_SHA1(cert_data.Data, cert_data.Length, sha1.data); |
| + |
| return sha1; |
| } |
| -// Wrappers of malloc and free for CRYPT_DECODE_PARA, which requires the |
| -// WINAPI calling convention. |
| -void* WINAPI MyCryptAlloc(size_t size) { |
| - return malloc(size); |
| +inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) { |
|
wtc
2008/09/18 20:37:55
I'm a little surprised that the Security Framework
Avi (use Gerrit)
2008/09/18 20:48:17
Me too, but I looked...
|
| + return oid1->Length == oid2->Length && |
| + (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0); |
| } |
| -void WINAPI MyCryptFree(void* p) { |
| - free(p); |
| -} |
| +void ParsePrincipal(const CSSM_X509_NAME* name, |
| + X509Certificate::Principal* principal) { |
| + std::vector<std::string> common_names, locality_names, state_names, |
| + country_names; |
| -// Decodes the cert's subjectAltName extension into a CERT_ALT_NAME_INFO |
| -// structure and stores it in *output. |
| -void GetCertSubjectAltName(PCCERT_CONTEXT cert, |
| - scoped_ptr_malloc<CERT_ALT_NAME_INFO>* output) { |
| - PCERT_EXTENSION extension = CertFindExtension(szOID_SUBJECT_ALT_NAME2, |
| - cert->pCertInfo->cExtension, |
| - cert->pCertInfo->rgExtension); |
| - if (!extension) |
| - return; |
| + // TODO(jcampan): add business_category and serial_number. |
| + const CSSM_OID* kOIDs[8] = { &CSSMOID_CommonName, |
|
Amanda Walker
2008/09/18 16:14:43
suggest using [] instead of [8] so that we don't n
|
| + &CSSMOID_LocalityName, |
| + &CSSMOID_StateProvinceName, |
| + &CSSMOID_CountryName, |
| + &CSSMOID_StreetAddress, |
| + &CSSMOID_OrganizationName, |
| + &CSSMOID_OrganizationalUnitName, |
| + &CSSMOID_DNQualifier }; // This should be "DC" |
|
wtc
2008/09/18 20:37:55
"DN" most likely stands for Distinguished Name, so
|
| + // but is undoubtedly |
| + // wrong. Find the right |
| + // OID. |
|
Amanda Walker
2008/09/18 16:14:43
Add TODO
|
| - CRYPT_DECODE_PARA decode_para; |
| - decode_para.cbSize = sizeof(decode_para); |
| - decode_para.pfnAlloc = MyCryptAlloc; |
| - decode_para.pfnFree = MyCryptFree; |
| - CERT_ALT_NAME_INFO* alt_name_info = NULL; |
| - DWORD alt_name_info_size = 0; |
| - BOOL rv; |
| - rv = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, |
| - szOID_SUBJECT_ALT_NAME2, |
| - extension->Value.pbData, |
| - extension->Value.cbData, |
| - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, |
| - &decode_para, |
| - &alt_name_info, |
| - &alt_name_info_size); |
| - if (rv) |
| - output->reset(alt_name_info); |
| -} |
| + std::vector<std::string>* values[8] = { |
|
Amanda Walker
2008/09/18 16:14:43
suggest using [] instead of [8] so that we don't n
|
| + &common_names, &locality_names, |
| + &state_names, &country_names, |
| + &(principal->street_addresses), |
| + &(principal->organization_names), |
| + &(principal->organization_unit_names), |
| + &(principal->domain_components) }; |
| + DCHECK(arraysize(kOIDs) == arraysize(values)); |
| -/////////////////////////////////////////////////////////////////////////// |
| -// |
| -// Functions used by X509Certificate::IsEV |
| -// |
| -/////////////////////////////////////////////////////////////////////////// |
| + for (size_t rdn = 0; rdn < name->numberOfRDNs; ++rdn) { |
| + CSSM_X509_RDN rdn_struct = name->RelativeDistinguishedName[rdn]; |
| + for (size_t pair = 0; pair < rdn_struct.numberOfPairs; ++pair) { |
| + CSSM_X509_TYPE_VALUE_PAIR pair_struct = |
| + rdn_struct.AttributeTypeAndValue[pair]; |
| + for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { |
| + if (CSSMOIDEqual(&pair_struct.type, kOIDs[oid])) { |
| + std::string value = |
| + std::string(reinterpret_cast<std::string::value_type*> |
| + (pair_struct.value.Data), |
| + pair_struct.value.Length); |
| + values[oid]->push_back(value); |
| + break; |
| + } |
| + } |
| + } |
| + } |
| -// Constructs a certificate chain starting from the end certificate |
| -// 'cert_context', matching any of the certificate policies. |
| -// |
| -// Returns the certificate chain context on success, or NULL on failure. |
| -// The caller is responsible for freeing the certificate chain context with |
| -// CertFreeCertificateChain. |
| -PCCERT_CHAIN_CONTEXT ConstructCertChain( |
| - PCCERT_CONTEXT cert_context, |
| - const char* const* policies, |
| - int num_policies) { |
| - CERT_CHAIN_PARA chain_para; |
| - memset(&chain_para, 0, sizeof(chain_para)); |
| - chain_para.cbSize = sizeof(chain_para); |
| - chain_para.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND; |
| - chain_para.RequestedUsage.Usage.cUsageIdentifier = 0; |
| - chain_para.RequestedUsage.Usage.rgpszUsageIdentifier = NULL; // LPSTR* |
| - chain_para.RequestedIssuancePolicy.dwType = USAGE_MATCH_TYPE_OR; |
| - chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = num_policies; |
| - chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = |
| - const_cast<char**>(policies); |
| - PCCERT_CHAIN_CONTEXT chain_context; |
| - if (!CertGetCertificateChain( |
| - NULL, // default chain engine, HCCE_CURRENT_USER |
| - cert_context, |
| - NULL, // current system time |
| - cert_context->hCertStore, // search this store |
| - &chain_para, |
| - CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT | |
| - CERT_CHAIN_CACHE_END_CERT, |
| - NULL, // reserved |
| - &chain_context)) { |
| - return NULL; |
| + // We don't expect to have more than one CN, L, S, and C. |
| + std::vector<std::string>* single_value_lists[4] = { |
| + &common_names, &locality_names, &state_names, &country_names }; |
| + std::string* single_values[4] = { |
| + &principal->common_name, &principal->locality_name, |
| + &principal->state_or_province_name, &principal->country_name }; |
| + for (size_t i = 0; i < arraysize(single_value_lists); ++i) { |
| + DCHECK(single_value_lists[i]->size() <= 1); |
| + if (single_value_lists[i]->size() > 0) |
| + *(single_values[i]) = (*(single_value_lists[i]))[0]; |
| } |
| - return chain_context; |
| } |
| -// Decodes the cert's certificatePolicies extension into a CERT_POLICIES_INFO |
| -// structure and stores it in *output. |
| -void GetCertPoliciesInfo(PCCERT_CONTEXT cert, |
| - scoped_ptr_malloc<CERT_POLICIES_INFO>* output) { |
| - PCERT_EXTENSION extension = CertFindExtension(szOID_CERT_POLICIES, |
| - cert->pCertInfo->cExtension, |
| - cert->pCertInfo->rgExtension); |
| - if (!extension) |
| +void GetCertFieldsForOID(X509Certificate::OSCertHandle cert_handle, |
|
wtc
2008/09/18 20:37:55
Use "Field", singular. You're returning only one
Avi (use Gerrit)
2008/09/18 20:48:17
The break is a mistake on my part, copied from the
|
| + CSSM_OID oid, |
| + std::vector<std::string>* result) { |
| + CSSM_DATA cert_data; |
| + OSStatus status = SecCertificateGetData(cert_handle, &cert_data); |
| + if (status) |
| return; |
| - |
| - CRYPT_DECODE_PARA decode_para; |
| - decode_para.cbSize = sizeof(decode_para); |
| - decode_para.pfnAlloc = MyCryptAlloc; |
| - decode_para.pfnFree = MyCryptFree; |
| - CERT_POLICIES_INFO* policies_info = NULL; |
| - DWORD policies_info_size = 0; |
| - BOOL rv; |
| - rv = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, |
| - szOID_CERT_POLICIES, |
| - extension->Value.pbData, |
| - extension->Value.cbData, |
| - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, |
| - &decode_para, |
| - &policies_info, |
| - &policies_info_size); |
| - if (rv) |
| - output->reset(policies_info); |
| -} |
| - |
| -// Returns true if the policy is in the array of CERT_POLICY_INFO in |
| -// the CERT_POLICIES_INFO structure. |
| -bool ContainsPolicy(const CERT_POLICIES_INFO* policies_info, |
| - const char* policy) { |
| - int num_policies = policies_info->cPolicyInfo; |
| - for (int i = 0; i < num_policies; i++) { |
| - if (!strcmp(policies_info->rgPolicyInfo[i].pszPolicyIdentifier, policy)) |
| - return true; |
| + |
| + CSSM_CL_HANDLE clHandle; |
|
wtc
2008/09/18 20:37:55
clHandle doesn't follow the naming convention in t
|
| + status = SecCertificateGetCLHandle(cert_handle, &clHandle); |
| + if (status) |
| + return; |
| + |
| + uint32 numOfFields; |
|
wtc
2008/09/18 20:37:55
numOfFields doesn't follow the naming convention i
|
| + CSSM_FIELD_PTR fields; |
| + status = CSSM_CL_CertGetAllFields(clHandle, &cert_data, &numOfFields, |
| + &fields); |
| + if (status) |
| + return; |
| + |
| + for (size_t field = 0; field < numOfFields; ++field) { |
| + if (CSSMOIDEqual(&fields[field].FieldOid, &oid)) { |
| + std::string value = |
| + std::string(reinterpret_cast<std::string::value_type*> |
| + (fields[field].FieldValue.Data), |
| + fields[field].FieldValue.Length); |
| + result->push_back(value); |
| + break; |
| + } |
| } |
| - return false; |
| } |
| -// This class wraps the CertFreeCertificateChain function in a class that can |
| -// be passed as a template argument to scoped_ptr_malloc. |
| -class ScopedPtrMallocFreeCertChain { |
| - public: |
| - void operator()(const CERT_CHAIN_CONTEXT* x) const { |
| - CertFreeCertificateChain(x); |
| - } |
| -}; |
| - |
| -typedef scoped_ptr_malloc<const CERT_CHAIN_CONTEXT, |
| - ScopedPtrMallocFreeCertChain> ScopedCertChainContext; |
| - |
| } // namespace |
| bool X509Certificate::FingerprintLessThan::operator()( |
| const Fingerprint& lhs, |
| const Fingerprint& rhs) const { |
| - for (int i = 0; i < sizeof(lhs.data); ++i) { |
| + for (size_t i = 0; i < sizeof(lhs.data); ++i) { |
| if (lhs.data[i] < rhs.data[i]) |
| return true; |
| if (lhs.data[i] > rhs.data[i]) |
| @@ -256,7 +230,7 @@ |
| // Obtain an instance of X509Certificate::Cache via GetInstance(). |
| Cache() { } |
| - friend DefaultSingletonTraits<X509Certificate::Cache>; |
| + friend class DefaultSingletonTraits<X509Certificate::Cache>; |
| // You must acquire this lock before using any private data of this object. |
| // You must not block while holding this lock. |
| @@ -265,35 +239,20 @@ |
| // The certificate cache. You must acquire |lock_| before using |cache_|. |
| CertMap cache_; |
| - DISALLOW_EVIL_CONSTRUCTORS(X509Certificate::Cache); |
| + DISALLOW_COPY_AND_ASSIGN(Cache); |
| }; |
| void X509Certificate::Initialize() { |
| - std::wstring subject_info; |
| - std::wstring issuer_info; |
| - DWORD name_size; |
| - name_size = CertNameToStr(cert_handle_->dwCertEncodingType, |
| - &cert_handle_->pCertInfo->Subject, |
| - CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, |
| - NULL, 0); |
| - name_size = CertNameToStr(cert_handle_->dwCertEncodingType, |
| - &cert_handle_->pCertInfo->Subject, |
| - CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, |
| - WriteInto(&subject_info, name_size), name_size); |
| - name_size = CertNameToStr(cert_handle_->dwCertEncodingType, |
| - &cert_handle_->pCertInfo->Issuer, |
| - CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, |
| - NULL, 0); |
| - name_size = CertNameToStr(cert_handle_->dwCertEncodingType, |
| - &cert_handle_->pCertInfo->Issuer, |
| - CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, |
| - WriteInto(&issuer_info, name_size), name_size); |
| - ParsePrincipal(WideToUTF8(subject_info), &subject_); |
| - ParsePrincipal(WideToUTF8(issuer_info), &issuer_); |
| - |
| - valid_start_ = Time::FromFileTime(cert_handle_->pCertInfo->NotBefore); |
| - valid_expiry_ = Time::FromFileTime(cert_handle_->pCertInfo->NotAfter); |
| - |
| + const CSSM_X509_NAME* name; |
| + OSStatus status = SecCertificateGetSubject(cert_handle_, &name); |
| + if (!status) { |
| + ParsePrincipal(name, &subject_); |
| + } |
| + status = SecCertificateGetIssuer(cert_handle_, &name); |
| + if (!status) { |
| + ParsePrincipal(name, &issuer_); |
| + } |
| + |
| fingerprint_ = CalculateFingerprint(cert_handle_); |
| // Store the certificate in the cache in case we need it later. |
| @@ -310,7 +269,7 @@ |
| if (cert) { |
| // We've found a certificate with the same fingerprint in our cache. We own |
| // the |cert_handle|, which makes it our job to free it. |
| - CertFreeCertificateContext(cert_handle); |
| + CFRelease(cert_handle); |
| DHISTOGRAM_COUNTS(L"X509CertificateReuseCount", 1); |
| return cert; |
| } |
| @@ -325,13 +284,16 @@ |
| int length; |
| if (!pickle.ReadData(pickle_iter, &data, &length)) |
| return NULL; |
| + CSSM_DATA cert_data; |
| + cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data)); |
| + cert_data.Length = length; |
| OSCertHandle cert_handle = NULL; |
| - if (!CertAddSerializedElementToStore( |
| - NULL, // the cert won't be persisted in any cert store |
| - reinterpret_cast<const BYTE*>(data), length, |
| - CERT_STORE_ADD_USE_EXISTING, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, |
| - NULL, reinterpret_cast<const void **>(&cert_handle))) |
| + OSStatus status = SecCertificateCreateFromData(&cert_data, |
| + CSSM_CERT_X_509v3, |
| + CSSM_CERT_ENCODING_BER, |
| + &cert_handle); |
| + if (status) |
| return NULL; |
| return CreateFromHandle(cert_handle); |
| @@ -343,60 +305,40 @@ |
| } |
| X509Certificate::X509Certificate(std::string subject, std::string issuer, |
| - Time start_date, Time expiration_date) |
| + Time, Time) |
| : subject_(subject), |
| issuer_(issuer), |
| - valid_start_(start_date), |
| - valid_expiry_(expiration_date), |
| cert_handle_(NULL) { |
| memset(fingerprint_.data, 0, sizeof(fingerprint_.data)); |
| } |
| void X509Certificate::Persist(Pickle* pickle) { |
| - DWORD length; |
| - if (!CertSerializeCertificateStoreElement(cert_handle_, 0, |
| - NULL, &length)) { |
| + CSSM_DATA cert_data; |
| + OSStatus status = SecCertificateGetData(cert_handle_, &cert_data); |
| + if (status) { |
| NOTREACHED(); |
| return; |
| } |
| - BYTE* data = reinterpret_cast<BYTE*>(pickle->BeginWriteData(length)); |
| - if (!CertSerializeCertificateStoreElement(cert_handle_, 0, |
| - data, &length)) { |
| - NOTREACHED(); |
| - length = 0; |
| - } |
| - pickle->TrimWriteData(length); |
| + |
| + pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), cert_data.Length); |
| } |
| X509Certificate::~X509Certificate() { |
| // We might not be in the cache, but it is safe to remove ourselves anyway. |
| X509Certificate::Cache::GetInstance()->Remove(this); |
| if (cert_handle_) |
| - CertFreeCertificateContext(cert_handle_); |
| + CFRelease(cert_handle_); |
| } |
| void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { |
| dns_names->clear(); |
| - scoped_ptr_malloc<CERT_ALT_NAME_INFO> alt_name_info; |
| - GetCertSubjectAltName(cert_handle_, &alt_name_info); |
| - CERT_ALT_NAME_INFO* alt_name = alt_name_info.get(); |
| - if (alt_name) { |
| - int num_entries = alt_name->cAltEntry; |
| - for (int i = 0; i < num_entries; i++) { |
| - // dNSName is an ASN.1 IA5String representing a string of ASCII |
| - // characters, so we can use WideToASCII here. |
| - if (alt_name->rgAltEntry[i].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME) |
| - dns_names->push_back(WideToASCII(alt_name->rgAltEntry[i].pwszDNSName)); |
| - } |
| - } |
| + |
| + GetCertFieldsForOID(cert_handle_, CSSMOID_SubjectAltName, dns_names); |
|
wtc
2008/09/18 20:37:55
Add a TODO comment to note that we still need to p
Avi (use Gerrit)
2008/09/18 20:48:17
OK; this is me coding not quite sure what needs to
|
| + |
| if (dns_names->empty()) |
| dns_names->push_back(subject_.common_name); |
| } |
| - |
| -bool X509Certificate::HasExpired() const { |
| - return Time::Now() > valid_expiry(); |
| -} |
| - |
| + |
| // Returns true if the certificate is an extended-validation certificate. |
| // |
| // The certificate has already been verified by the HTTP library. cert_status |
| @@ -406,112 +348,11 @@ |
| // Certificate Guidelines Version 1.0 at |
| // http://cabforum.org/EV_Certificate_Guidelines.pdf. |
| bool X509Certificate::IsEV(int cert_status) const { |
| - if (net::IsCertStatusError(cert_status) || |
| - (cert_status & net::CERT_STATUS_REV_CHECKING_ENABLED) == 0) |
| - return false; |
| - |
| - net::EVRootCAMetadata* metadata = net::EVRootCAMetadata::GetInstance(); |
| - |
| - PCCERT_CHAIN_CONTEXT chain_context = ConstructCertChain(cert_handle_, |
| - metadata->GetPolicyOIDs(), metadata->NumPolicyOIDs()); |
| - if (!chain_context) |
| - return false; |
| - ScopedCertChainContext scoped_chain_context(chain_context); |
| - |
| - DCHECK(chain_context->cChain != 0); |
| - // If the cert doesn't match any of the policies, the |
| - // CERT_TRUST_IS_NOT_VALID_FOR_USAGE bit (0x10) in |
| - // chain_context->TrustStatus.dwErrorStatus is set. |
| - DWORD error_status = chain_context->TrustStatus.dwErrorStatus; |
| - DWORD info_status = chain_context->TrustStatus.dwInfoStatus; |
| - if (!chain_context->cChain || error_status != CERT_TRUST_NO_ERROR) |
| - return false; |
| - |
| - // Check the end certificate simple chain (chain_context->rgpChain[0]). |
| - // If the end certificate's certificatePolicies extension contains the |
| - // EV policy OID of the root CA, return true. |
| - PCERT_CHAIN_ELEMENT* element = chain_context->rgpChain[0]->rgpElement; |
| - int num_elements = chain_context->rgpChain[0]->cElement; |
| - if (num_elements < 2) |
| - return false; |
| - |
| - // Look up the EV policy OID of the root CA. |
| - PCCERT_CONTEXT root_cert = element[num_elements - 1]->pCertContext; |
| - X509Certificate::Fingerprint fingerprint = CalculateFingerprint(root_cert); |
| - std::string ev_policy_oid; |
| - if (!metadata->GetPolicyOID(fingerprint, &ev_policy_oid)) |
| - return false; |
| - DCHECK(!ev_policy_oid.empty()); |
| - |
| - // Get the certificatePolicies extension of the end certificate. |
| - PCCERT_CONTEXT end_cert = element[0]->pCertContext; |
| - scoped_ptr_malloc<CERT_POLICIES_INFO> policies_info; |
| - GetCertPoliciesInfo(end_cert, &policies_info); |
| - if (!policies_info.get()) |
| - return false; |
| - |
| - return ContainsPolicy(policies_info.get(), ev_policy_oid.c_str()); |
| + // TODO(avi): implement this |
| + NOTIMPLEMENTED(); |
| + return false; |
| } |
| -// static |
| -void X509Certificate::ParsePrincipal(const std::string& description, |
| - Principal* principal) { |
| - // The description of the principal is a string with each LDAP value on |
| - // a separate line. |
| - const std::string kDelimiters("\r\n"); |
| - |
| - std::vector<std::string> common_names, locality_names, state_names, |
| - country_names, street_addresses; |
| - |
| - // TODO(jcampan): add business_category and serial_number. |
| - const std::string kPrefixes[8] = { std::string("CN="), |
| - std::string("L="), |
| - std::string("S="), |
| - std::string("C="), |
| - std::string("STREET="), |
| - std::string("O="), |
| - std::string("OU="), |
| - std::string("DC=") }; |
| - |
| - std::vector<std::string>* values[8] = { |
| - &common_names, &locality_names, |
| - &state_names, &country_names, |
| - &(principal->street_addresses), |
| - &(principal->organization_names), |
| - &(principal->organization_unit_names), |
| - &(principal->domain_components) }; |
| - DCHECK(arraysize(kPrefixes) == arraysize(values)); |
| - |
| - StringTokenizer str_tok(description, kDelimiters); |
| - while (str_tok.GetNext()) { |
| - std::string entry = str_tok.token(); |
| - for (int i = 0; i < arraysize(kPrefixes); i++) { |
| - if (!entry.compare(0, kPrefixes[i].length(), kPrefixes[i])) { |
| - std::string value = entry.substr(kPrefixes[i].length()); |
| - // Remove enclosing double-quotes if any. |
| - if (value.size() >= 2 && |
| - value[0] == '"' && value[value.size() - 1] == '"') |
| - value = value.substr(1, value.size() - 2); |
| - values[i]->push_back(value); |
| - break; |
| - } |
| - } |
| - } |
| - |
| - // We don't expect to have more than one CN, L, S, and C. |
| - std::vector<std::string>* single_value_lists[4] = { |
| - &common_names, &locality_names, &state_names, &country_names }; |
| - std::string* single_values[4] = { |
| - &principal->common_name, &principal->locality_name, |
| - &principal->state_or_province_name, &principal->country_name }; |
| - for (int i = 0; i < arraysize(single_value_lists); ++i) { |
| - int length = static_cast<int>(single_value_lists[i]->size()); |
| - DCHECK(single_value_lists[i]->size() <= 1); |
| - if (single_value_lists[i]->size() > 0) |
| - *(single_values[i]) = (*(single_value_lists[i]))[0]; |
| - } |
| -} |
| - |
| X509Certificate::Policy::Judgment X509Certificate::Policy::Check( |
|
Amanda Walker
2008/09/18 16:14:43
If X509Certificate::Policy has no platform depende
|
| X509Certificate* cert) const { |
| // It shouldn't matter which set we check first, but we check denied first |