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

Side by Side Diff: net/base/x509_certificate_mac.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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <CommonCrypto/CommonDigest.h> 7 #include <CommonCrypto/CommonDigest.h>
8 #include <map>
9 #include <time.h> 8 #include <time.h>
10 9
11 #include "base/histogram.h" 10 #include "base/histogram.h"
12 #include "base/lock.h" 11 #include "base/logging.h"
13 #include "base/pickle.h" 12 #include "base/pickle.h"
14 #include "base/singleton.h"
15 #include "base/string_tokenizer.h"
16 #include "base/string_util.h"
17 #include "net/base/cert_status_flags.h" 13 #include "net/base/cert_status_flags.h"
18 #include "net/base/ev_root_ca_metadata.h" 14 #include "net/base/ev_root_ca_metadata.h"
19 15
20 namespace net { 16 namespace net {
21 17
22 namespace { 18 namespace {
23 19
24 // Returns true if this cert fingerprint is the null (all zero) fingerprint.
25 // We use this as a bogus fingerprint value.
26 bool IsNullFingerprint(const X509Certificate::Fingerprint& fingerprint) {
27 for (size_t i = 0; i < arraysize(fingerprint.data); ++i) {
28 if (fingerprint.data[i] != 0)
29 return false;
30 }
31 return true;
32 }
33
34 // Calculates the SHA-1 fingerprint of the certificate. Returns an empty 20 // Calculates the SHA-1 fingerprint of the certificate. Returns an empty
35 // (all zero) fingerprint on failure. 21 // (all zero) fingerprint on failure.
36 X509Certificate::Fingerprint CalculateFingerprint( 22 X509Certificate::Fingerprint CalculateFingerprint(
37 X509Certificate::OSCertHandle cert) { 23 X509Certificate::OSCertHandle cert) {
38 X509Certificate::Fingerprint sha1; 24 X509Certificate::Fingerprint sha1;
39 memset(sha1.data, 0, sizeof(sha1.data)); 25 memset(sha1.data, 0, sizeof(sha1.data));
40 26
41 CSSM_DATA cert_data; 27 CSSM_DATA cert_data;
42 OSStatus status = SecCertificateGetData(cert, &cert_data); 28 OSStatus status = SecCertificateGetData(cert, &cert_data);
43 if (status) 29 if (status)
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 exploded.second = time.tm_sec; 197 exploded.second = time.tm_sec;
212 exploded.millisecond = 0; 198 exploded.millisecond = 0;
213 199
214 *result = Time::FromUTCExploded(exploded); 200 *result = Time::FromUTCExploded(exploded);
215 } 201 }
216 } 202 }
217 } 203 }
218 204
219 } // namespace 205 } // namespace
220 206
221 bool X509Certificate::FingerprintLessThan::operator()(
222 const Fingerprint& lhs,
223 const Fingerprint& rhs) const {
224 for (size_t i = 0; i < sizeof(lhs.data); ++i) {
225 if (lhs.data[i] < rhs.data[i])
226 return true;
227 if (lhs.data[i] > rhs.data[i])
228 return false;
229 }
230 return false;
231 }
232
233 bool X509Certificate::LessThan::operator()(X509Certificate* lhs,
234 X509Certificate* rhs) const {
235 if (lhs == rhs)
236 return false;
237
238 X509Certificate::FingerprintLessThan fingerprint_functor;
239 return fingerprint_functor(lhs->fingerprint_, rhs->fingerprint_);
240 }
241
242 // A thread-safe cache for X509Certificate objects.
243 //
244 // The cache does not hold a reference to the certificate objects. The objects
245 // must |Remove| themselves from the cache upon destruction (or else the cache
246 // will be holding dead pointers to the objects).
247 class X509Certificate::Cache {
248 public:
249 // Get the singleton object for the cache.
250 static X509Certificate::Cache* GetInstance() {
251 return Singleton<X509Certificate::Cache>::get();
252 }
253
254 // Insert |cert| into the cache. The cache does NOT AddRef |cert|. The cache
255 // must not already contain a certificate with the same fingerprint.
256 void Insert(X509Certificate* cert) {
257 AutoLock lock(lock_);
258
259 DCHECK(!IsNullFingerprint(cert->fingerprint())) <<
260 "Only insert certs with real fingerprints.";
261 DCHECK(cache_.find(cert->fingerprint()) == cache_.end());
262 cache_[cert->fingerprint()] = cert;
263 };
264
265 // Remove |cert| from the cache. The cache does not assume that |cert| is
266 // already in the cache.
267 void Remove(X509Certificate* cert) {
268 AutoLock lock(lock_);
269
270 CertMap::iterator pos(cache_.find(cert->fingerprint()));
271 if (pos == cache_.end())
272 return; // It is not an error to remove a cert that is not in the cache.
273 cache_.erase(pos);
274 };
275
276 // Find a certificate in the cache with the given fingerprint. If one does
277 // not exist, this method returns NULL.
278 X509Certificate* Find(const Fingerprint& fingerprint) {
279 AutoLock lock(lock_);
280
281 CertMap::iterator pos(cache_.find(fingerprint));
282 if (pos == cache_.end())
283 return NULL;
284
285 return pos->second;
286 };
287
288 private:
289 typedef std::map<Fingerprint, X509Certificate*, FingerprintLessThan> CertMap;
290
291 // Obtain an instance of X509Certificate::Cache via GetInstance().
292 Cache() { }
293 friend struct DefaultSingletonTraits<X509Certificate::Cache>;
294
295 // You must acquire this lock before using any private data of this object.
296 // You must not block while holding this lock.
297 Lock lock_;
298
299 // The certificate cache. You must acquire |lock_| before using |cache_|.
300 CertMap cache_;
301
302 DISALLOW_COPY_AND_ASSIGN(Cache);
303 };
304
305 void X509Certificate::Initialize() { 207 void X509Certificate::Initialize() {
306 const CSSM_X509_NAME* name; 208 const CSSM_X509_NAME* name;
307 OSStatus status = SecCertificateGetSubject(cert_handle_, &name); 209 OSStatus status = SecCertificateGetSubject(cert_handle_, &name);
308 if (!status) { 210 if (!status) {
309 ParsePrincipal(name, &subject_); 211 ParsePrincipal(name, &subject_);
310 } 212 }
311 status = SecCertificateGetIssuer(cert_handle_, &name); 213 status = SecCertificateGetIssuer(cert_handle_, &name);
312 if (!status) { 214 if (!status) {
313 ParsePrincipal(name, &issuer_); 215 ParsePrincipal(name, &issuer_);
314 } 216 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 // additional checks of the certificatePolicies extensions of the certificates 323 // additional checks of the certificatePolicies extensions of the certificates
422 // in the certificate chain according to Section 7 (pp. 11-12) of the EV 324 // in the certificate chain according to Section 7 (pp. 11-12) of the EV
423 // Certificate Guidelines Version 1.0 at 325 // Certificate Guidelines Version 1.0 at
424 // http://cabforum.org/EV_Certificate_Guidelines.pdf. 326 // http://cabforum.org/EV_Certificate_Guidelines.pdf.
425 bool X509Certificate::IsEV(int cert_status) const { 327 bool X509Certificate::IsEV(int cert_status) const {
426 // TODO(avi): implement this 328 // TODO(avi): implement this
427 NOTIMPLEMENTED(); 329 NOTIMPLEMENTED();
428 return false; 330 return false;
429 } 331 }
430 332
431 X509Certificate::Policy::Judgment X509Certificate::Policy::Check(
432 X509Certificate* cert) const {
433 // It shouldn't matter which set we check first, but we check denied first
434 // in case something strange has happened.
435
436 if (denied_.find(cert->fingerprint()) != denied_.end()) {
437 // DCHECK that the order didn't matter.
438 DCHECK(allowed_.find(cert->fingerprint()) == allowed_.end());
439 return DENIED;
440 }
441
442 if (allowed_.find(cert->fingerprint()) != allowed_.end()) {
443 // DCHECK that the order didn't matter.
444 DCHECK(denied_.find(cert->fingerprint()) == denied_.end());
445 return ALLOWED;
446 }
447
448 // We don't have a policy for this cert.
449 return UNKNOWN;
450 }
451
452 void X509Certificate::Policy::Allow(X509Certificate* cert) {
453 // Put the cert in the allowed set and (maybe) remove it from the denied set.
454 denied_.erase(cert->fingerprint());
455 allowed_.insert(cert->fingerprint());
456 }
457
458 void X509Certificate::Policy::Deny(X509Certificate* cert) {
459 // Put the cert in the denied set and (maybe) remove it from the allowed set.
460 allowed_.erase(cert->fingerprint());
461 denied_.insert(cert->fingerprint());
462 }
463
464 } // namespace net 333 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698