| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/chromeos/cros/certificate_pattern.h" | 5 #include "chrome/browser/chromeos/cros/certificate_pattern.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <list> | 8 #include <list> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include <cert.h> | 12 #include <cert.h> |
| 13 #include <pk11pub.h> | 13 #include <pk11pub.h> |
| 14 | 14 |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/values.h" | 16 #include "base/values.h" |
| 17 #include "net/base/cert_database.h" | 17 #include "net/base/cert_database.h" |
| 18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
| 19 #include "net/base/nss_cert_database.h" |
| 19 #include "net/base/x509_cert_types.h" | 20 #include "net/base/x509_cert_types.h" |
| 20 #include "net/base/x509_certificate.h" | 21 #include "net/base/x509_certificate.h" |
| 21 | 22 |
| 22 // To shorten some of those long lines below. | 23 // To shorten some of those long lines below. |
| 23 using base::DictionaryValue; | 24 using base::DictionaryValue; |
| 24 using base::ListValue; | 25 using base::ListValue; |
| 25 using std::find; | 26 using std::find; |
| 26 using std::list; | 27 using std::list; |
| 27 using std::string; | 28 using std::string; |
| 28 using std::vector; | 29 using std::vector; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 | 104 |
| 104 // Functor to filter out certs that don't have an issuer in the associated | 105 // Functor to filter out certs that don't have an issuer in the associated |
| 105 // IssuerCARef list. | 106 // IssuerCARef list. |
| 106 class IssuerCaRefFilter { | 107 class IssuerCaRefFilter { |
| 107 public: | 108 public: |
| 108 explicit IssuerCaRefFilter(const vector<string>& issuer_ca_ref_list) | 109 explicit IssuerCaRefFilter(const vector<string>& issuer_ca_ref_list) |
| 109 : issuer_ca_ref_list_(issuer_ca_ref_list) {} | 110 : issuer_ca_ref_list_(issuer_ca_ref_list) {} |
| 110 bool operator()(const scoped_refptr<net::X509Certificate>& cert) const { | 111 bool operator()(const scoped_refptr<net::X509Certificate>& cert) const { |
| 111 // Find the certificate issuer for each certificate. | 112 // Find the certificate issuer for each certificate. |
| 112 // TODO(gspencer): this functionality should be available from | 113 // TODO(gspencer): this functionality should be available from |
| 113 // X509Certificate or CertDatabase. | 114 // X509Certificate or NSSCertDatabase. |
| 114 CERTCertificate* issuer_cert = CERT_FindCertIssuer( | 115 CERTCertificate* issuer_cert = CERT_FindCertIssuer( |
| 115 cert.get()->os_cert_handle(), PR_Now(), certUsageAnyCA); | 116 cert.get()->os_cert_handle(), PR_Now(), certUsageAnyCA); |
| 116 | 117 |
| 117 if (issuer_cert && issuer_cert->nickname) { | 118 if (issuer_cert && issuer_cert->nickname) { |
| 118 // Separate the nickname stored in the certificate at the colon, since | 119 // Separate the nickname stored in the certificate at the colon, since |
| 119 // NSS likes to store it as token:nickname. | 120 // NSS likes to store it as token:nickname. |
| 120 const char* delimiter = ::strchr(issuer_cert->nickname, ':'); | 121 const char* delimiter = ::strchr(issuer_cert->nickname, ':'); |
| 121 if (delimiter) { | 122 if (delimiter) { |
| 122 delimiter++; // move past the colon. | 123 delimiter++; // move past the colon. |
| 123 vector<string>::const_iterator pat_iter = issuer_ca_ref_list_.begin(); | 124 vector<string>::const_iterator pat_iter = issuer_ca_ref_list_.begin(); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 subject_.Clear(); | 238 subject_.Clear(); |
| 238 enrollment_uri_list_.clear(); | 239 enrollment_uri_list_.clear(); |
| 239 } | 240 } |
| 240 | 241 |
| 241 scoped_refptr<net::X509Certificate> CertificatePattern::GetMatch() const { | 242 scoped_refptr<net::X509Certificate> CertificatePattern::GetMatch() const { |
| 242 typedef list<scoped_refptr<net::X509Certificate> > CertificateStlList; | 243 typedef list<scoped_refptr<net::X509Certificate> > CertificateStlList; |
| 243 | 244 |
| 244 // Start with all the certs, and narrow it down from there. | 245 // Start with all the certs, and narrow it down from there. |
| 245 net::CertificateList all_certs; | 246 net::CertificateList all_certs; |
| 246 CertificateStlList matching_certs; | 247 CertificateStlList matching_certs; |
| 247 net::CertDatabase cert_db; | 248 net::NSSCertDatabase nss_cert_db; |
| 248 cert_db.ListCerts(&all_certs); | 249 nss_cert_db.ListCerts(&all_certs); |
| 249 | 250 |
| 250 if (all_certs.empty()) | 251 if (all_certs.empty()) |
| 251 return NULL; | 252 return NULL; |
| 252 | 253 |
| 253 for (net::CertificateList::iterator iter = all_certs.begin(); | 254 for (net::CertificateList::iterator iter = all_certs.begin(); |
| 254 iter != all_certs.end(); ++iter) { | 255 iter != all_certs.end(); ++iter) { |
| 255 matching_certs.push_back(*iter); | 256 matching_certs.push_back(*iter); |
| 256 } | 257 } |
| 257 | 258 |
| 258 // Strip off any certs that don't have the right issuer and/or subject. | 259 // Strip off any certs that don't have the right issuer and/or subject. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 271 if (!issuer_ca_ref_list_.empty()) { | 272 if (!issuer_ca_ref_list_.empty()) { |
| 272 matching_certs.remove_if(IssuerCaRefFilter(issuer_ca_ref_list_)); | 273 matching_certs.remove_if(IssuerCaRefFilter(issuer_ca_ref_list_)); |
| 273 if (matching_certs.empty()) | 274 if (matching_certs.empty()) |
| 274 return NULL; | 275 return NULL; |
| 275 } | 276 } |
| 276 | 277 |
| 277 // Eliminate any certs that don't have private keys associated with | 278 // Eliminate any certs that don't have private keys associated with |
| 278 // them. The CheckUserCert call in the filter is a little slow (because of | 279 // them. The CheckUserCert call in the filter is a little slow (because of |
| 279 // underlying PKCS11 calls), so we do this last to reduce the number of times | 280 // underlying PKCS11 calls), so we do this last to reduce the number of times |
| 280 // we have to call it. | 281 // we have to call it. |
| 282 net::CertDatabase cert_db; |
| 281 PrivateKeyFilter private_filter(&cert_db); | 283 PrivateKeyFilter private_filter(&cert_db); |
| 282 matching_certs.remove_if(private_filter); | 284 matching_certs.remove_if(private_filter); |
| 283 | 285 |
| 284 if (matching_certs.empty()) | 286 if (matching_certs.empty()) |
| 285 return NULL; | 287 return NULL; |
| 286 | 288 |
| 287 // We now have a list of certificates that match the pattern we're | 289 // We now have a list of certificates that match the pattern we're |
| 288 // looking for. Now we find the one with the latest start date. | 290 // looking for. Now we find the one with the latest start date. |
| 289 scoped_refptr<net::X509Certificate> latest(NULL); | 291 scoped_refptr<net::X509Certificate> latest(NULL); |
| 290 | 292 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 // If we didn't copy anything from the dictionary, then it had better be | 345 // If we didn't copy anything from the dictionary, then it had better be |
| 344 // empty. | 346 // empty. |
| 345 DCHECK(dict.empty() == Empty()); | 347 DCHECK(dict.empty() == Empty()); |
| 346 if (dict.empty() != Empty()) | 348 if (dict.empty() != Empty()) |
| 347 return false; | 349 return false; |
| 348 | 350 |
| 349 return true; | 351 return true; |
| 350 } | 352 } |
| 351 | 353 |
| 352 } // namespace chromeos | 354 } // namespace chromeos |
| OLD | NEW |