Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Unified Diff: net/base/x509_certificate_win.cc

Issue 4040: Refactoring out common code in the X.509 cert handling (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698