Index: net/base/x509_certificate_win.cc |
=================================================================== |
--- net/base/x509_certificate_win.cc (revision 2483) |
+++ net/base/x509_certificate_win.cc (working copy) |
@@ -4,12 +4,9 @@ |
#include "net/base/x509_certificate.h" |
-#include <map> |
- |
#include "base/histogram.h" |
-#include "base/lock.h" |
+#include "base/logging.h" |
#include "base/pickle.h" |
-#include "base/singleton.h" |
#include "base/string_tokenizer.h" |
#include "base/string_util.h" |
#include "net/base/cert_status_flags.h" |
@@ -21,16 +18,6 @@ |
namespace { |
-// 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 (size_t i = 0; i < arraysize(fingerprint.data); ++i) { |
- if (fingerprint.data[i] != 0) |
- return false; |
- } |
- return true; |
-} |
- |
// Calculates the SHA-1 fingerprint of the certificate. Returns an empty |
// (all zero) fingerprint on failure. |
X509Certificate::Fingerprint CalculateFingerprint(PCCERT_CONTEXT cert) { |
@@ -182,92 +169,68 @@ |
typedef scoped_ptr_malloc<const CERT_CHAIN_CONTEXT, |
ScopedPtrMallocFreeCertChain> ScopedCertChainContext; |
-} // namespace |
+// Helper function to parse a principal from a WinInet description of that |
+// principal. |
+void ParsePrincipal(const std::string& description, |
+ X509Certificate::Principal* principal) { |
+ // The description of the principal is a string with each LDAP value on |
+ // a separate line. |
+ const std::string kDelimiters("\r\n"); |
-bool X509Certificate::FingerprintLessThan::operator()( |
- const Fingerprint& lhs, |
- const Fingerprint& rhs) const { |
- 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]) |
- return false; |
- } |
- return false; |
-} |
+ std::vector<std::string> common_names, locality_names, state_names, |
+ country_names; |
-bool X509Certificate::LessThan::operator()(X509Certificate* lhs, |
- X509Certificate* rhs) const { |
- if (lhs == rhs) |
- return false; |
+ // TODO(jcampan): add business_category and serial_number. |
+ const std::string kPrefixes[] = { std::string("CN="), |
+ std::string("L="), |
+ std::string("S="), |
+ std::string("C="), |
+ std::string("STREET="), |
+ std::string("O="), |
+ std::string("OU="), |
+ std::string("DC=") }; |
- X509Certificate::FingerprintLessThan fingerprint_functor; |
- return fingerprint_functor(lhs->fingerprint_, rhs->fingerprint_); |
-} |
+ std::vector<std::string>* values[] = { |
+ &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)); |
-// A thread-safe cache for X509Certificate objects. |
-// |
-// The cache does not hold a reference to the certificate objects. The objects |
-// must |Remove| themselves from the cache upon destruction (or else the cache |
-// will be holding dead pointers to the objects). |
-class X509Certificate::Cache { |
- public: |
- // Get the singleton object for the cache. |
- static X509Certificate::Cache* GetInstance() { |
- return Singleton<X509Certificate::Cache>::get(); |
+ 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; |
+ } |
+ } |
} |
- // Insert |cert| into the cache. The cache does NOT AddRef |cert|. The cache |
- // must not already contain a certificate with the same fingerprint. |
- void Insert(X509Certificate* cert) { |
- AutoLock lock(lock_); |
+ // 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]; |
+ } |
+} |
- DCHECK(!IsNullFingerprint(cert->fingerprint())) << |
- "Only insert certs with real fingerprints."; |
- DCHECK(cache_.find(cert->fingerprint()) == cache_.end()); |
- cache_[cert->fingerprint()] = cert; |
- }; |
+} // namespace |
- // Remove |cert| from the cache. The cache does not assume that |cert| is |
- // already in the cache. |
- void Remove(X509Certificate* cert) { |
- AutoLock lock(lock_); |
- |
- CertMap::iterator pos(cache_.find(cert->fingerprint())); |
- if (pos == cache_.end()) |
- return; // It is not an error to remove a cert that is not in the cache. |
- cache_.erase(pos); |
- }; |
- |
- // Find a certificate in the cache with the given fingerprint. If one does |
- // not exist, this method returns NULL. |
- X509Certificate* Find(const Fingerprint& fingerprint) { |
- AutoLock lock(lock_); |
- |
- CertMap::iterator pos(cache_.find(fingerprint)); |
- if (pos == cache_.end()) |
- return NULL; |
- |
- return pos->second; |
- }; |
- |
- private: |
- typedef std::map<Fingerprint, X509Certificate*, FingerprintLessThan> CertMap; |
- |
- // Obtain an instance of X509Certificate::Cache via GetInstance(). |
- Cache() { } |
- friend struct DefaultSingletonTraits<X509Certificate::Cache>; |
- |
- // You must acquire this lock before using any private data of this object. |
- // You must not block while holding this lock. |
- Lock lock_; |
- |
- // The certificate cache. You must acquire |lock_| before using |cache_|. |
- CertMap cache_; |
- |
- DISALLOW_COPY_AND_ASSIGN(X509Certificate::Cache); |
-}; |
- |
void X509Certificate::Initialize() { |
std::wstring subject_info; |
std::wstring issuer_info; |
@@ -319,7 +282,8 @@ |
} |
// static |
-X509Certificate* X509Certificate::CreateFromBytes(const char* data, int length) { |
+X509Certificate* X509Certificate::CreateFromBytes(const char* data, |
+ int length) { |
OSCertHandle cert_handle = NULL; |
if (!CertAddEncodedCertificateToStore( |
NULL, // the cert won't be persisted in any cert store |
@@ -467,97 +431,5 @@ |
return ContainsPolicy(policies_info.get(), ev_policy_oid.c_str()); |
} |
-// 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; |
- |
- // TODO(jcampan): add business_category and serial_number. |
- const std::string kPrefixes[] = { 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[] = { |
- &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( |
- X509Certificate* cert) const { |
- // It shouldn't matter which set we check first, but we check denied first |
- // in case something strange has happened. |
- |
- if (denied_.find(cert->fingerprint()) != denied_.end()) { |
- // DCHECK that the order didn't matter. |
- DCHECK(allowed_.find(cert->fingerprint()) == allowed_.end()); |
- return DENIED; |
- } |
- |
- if (allowed_.find(cert->fingerprint()) != allowed_.end()) { |
- // DCHECK that the order didn't matter. |
- DCHECK(denied_.find(cert->fingerprint()) == denied_.end()); |
- return ALLOWED; |
- } |
- |
- // We don't have a policy for this cert. |
- return UNKNOWN; |
-} |
- |
-void X509Certificate::Policy::Allow(X509Certificate* cert) { |
- // Put the cert in the allowed set and (maybe) remove it from the denied set. |
- denied_.erase(cert->fingerprint()); |
- allowed_.insert(cert->fingerprint()); |
-} |
- |
-void X509Certificate::Policy::Deny(X509Certificate* cert) { |
- // Put the cert in the denied set and (maybe) remove it from the allowed set. |
- allowed_.erase(cert->fingerprint()); |
- denied_.insert(cert->fingerprint()); |
-} |
- |
} // namespace net |