| 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 "chromeos/network/certificate_pattern_matcher.h" | 5 #include "chromeos/network/certificate_pattern_matcher.h" |
| 6 | 6 |
| 7 #include <cert.h> | 7 #include <cert.h> |
| 8 #include <pk11pub.h> | 8 #include <pk11pub.h> |
| 9 | 9 |
| 10 #include <list> | 10 #include <list> |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 public: | 88 public: |
| 89 explicit PrivateKeyFilter(net::CertDatabase* cert_db) : cert_db_(cert_db) {} | 89 explicit PrivateKeyFilter(net::CertDatabase* cert_db) : cert_db_(cert_db) {} |
| 90 bool operator()(const scoped_refptr<net::X509Certificate>& cert) const { | 90 bool operator()(const scoped_refptr<net::X509Certificate>& cert) const { |
| 91 return cert_db_->CheckUserCert(cert.get()) != net::OK; | 91 return cert_db_->CheckUserCert(cert.get()) != net::OK; |
| 92 } | 92 } |
| 93 private: | 93 private: |
| 94 net::CertDatabase* cert_db_; | 94 net::CertDatabase* cert_db_; |
| 95 }; | 95 }; |
| 96 | 96 |
| 97 // Functor to filter out certs that don't have an issuer in the associated | 97 // Functor to filter out certs that don't have an issuer in the associated |
| 98 // IssuerCARef list. | 98 // IssuerCAPEMs list. |
| 99 class IssuerCaRefFilter { | 99 class IssuerCaFilter { |
| 100 public: | 100 public: |
| 101 explicit IssuerCaRefFilter(const std::vector<std::string>& issuer_ca_ref_list) | 101 explicit IssuerCaFilter(const std::vector<std::string>& issuer_ca_pems) |
| 102 : issuer_ca_ref_list_(issuer_ca_ref_list) {} | 102 : issuer_ca_pems_(issuer_ca_pems) {} |
| 103 bool operator()(const scoped_refptr<net::X509Certificate>& cert) const { | 103 bool operator()(const scoped_refptr<net::X509Certificate>& cert) const { |
| 104 // Find the certificate issuer for each certificate. | 104 // Find the certificate issuer for each certificate. |
| 105 // TODO(gspencer): this functionality should be available from | 105 // TODO(gspencer): this functionality should be available from |
| 106 // X509Certificate or NSSCertDatabase. | 106 // X509Certificate or NSSCertDatabase. |
| 107 CERTCertificate* issuer_cert = CERT_FindCertIssuer( | 107 CERTCertificate* issuer_cert = CERT_FindCertIssuer( |
| 108 cert.get()->os_cert_handle(), PR_Now(), certUsageAnyCA); | 108 cert.get()->os_cert_handle(), PR_Now(), certUsageAnyCA); |
| 109 | 109 |
| 110 if (issuer_cert && issuer_cert->nickname) { | 110 if (!issuer_cert) |
| 111 // Separate the nickname stored in the certificate at the colon, since | 111 return true; |
| 112 // NSS likes to store it as token:nickname. | 112 |
| 113 const char* delimiter = ::strchr(issuer_cert->nickname, ':'); | 113 std::string pem_encoded; |
| 114 if (delimiter) { | 114 if (!net::X509Certificate::GetPEMEncoded(issuer_cert, &pem_encoded)) { |
| 115 delimiter++; // move past the colon. | 115 LOG(ERROR) << "Couldn't PEM-encode certificate."; |
| 116 std::vector<std::string>::const_iterator pat_iter = | 116 return true; |
| 117 issuer_ca_ref_list_.begin(); | |
| 118 while (pat_iter != issuer_ca_ref_list_.end()) { | |
| 119 if (*pat_iter == delimiter) | |
| 120 return false; | |
| 121 ++pat_iter; | |
| 122 } | |
| 123 } | |
| 124 } | 117 } |
| 125 return true; | 118 |
| 119 return (std::find(issuer_ca_pems_.begin(), issuer_ca_pems_.end(), |
| 120 pem_encoded) == |
| 121 issuer_ca_pems_.end()); |
| 126 } | 122 } |
| 127 private: | 123 private: |
| 128 const std::vector<std::string>& issuer_ca_ref_list_; | 124 const std::vector<std::string>& issuer_ca_pems_; |
| 129 }; | 125 }; |
| 130 | 126 |
| 131 } // namespace | 127 } // namespace |
| 132 | 128 |
| 133 namespace certificate_pattern { | 129 namespace certificate_pattern { |
| 134 | 130 |
| 135 scoped_refptr<net::X509Certificate> GetCertificateMatch( | 131 scoped_refptr<net::X509Certificate> GetCertificateMatch( |
| 136 const CertificatePattern& pattern) { | 132 const CertificatePattern& pattern) { |
| 137 typedef std::list<scoped_refptr<net::X509Certificate> > CertificateStlList; | 133 typedef std::list<scoped_refptr<net::X509Certificate> > CertificateStlList; |
| 138 | 134 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 155 if (matching_certs.empty()) | 151 if (matching_certs.empty()) |
| 156 return NULL; | 152 return NULL; |
| 157 } | 153 } |
| 158 | 154 |
| 159 if (!pattern.subject().Empty()) { | 155 if (!pattern.subject().Empty()) { |
| 160 matching_certs.remove_if(SubjectFilter(pattern.subject())); | 156 matching_certs.remove_if(SubjectFilter(pattern.subject())); |
| 161 if (matching_certs.empty()) | 157 if (matching_certs.empty()) |
| 162 return NULL; | 158 return NULL; |
| 163 } | 159 } |
| 164 | 160 |
| 165 if (!pattern.issuer_ca_ref_list().empty()) { | 161 if (!pattern.issuer_ca_pems().empty()) { |
| 166 matching_certs.remove_if(IssuerCaRefFilter(pattern.issuer_ca_ref_list())); | 162 matching_certs.remove_if(IssuerCaFilter(pattern.issuer_ca_pems())); |
| 167 if (matching_certs.empty()) | 163 if (matching_certs.empty()) |
| 168 return NULL; | 164 return NULL; |
| 169 } | 165 } |
| 170 | 166 |
| 171 // Eliminate any certs that don't have private keys associated with | 167 // Eliminate any certs that don't have private keys associated with |
| 172 // them. The CheckUserCert call in the filter is a little slow (because of | 168 // them. The CheckUserCert call in the filter is a little slow (because of |
| 173 // underlying PKCS11 calls), so we do this last to reduce the number of times | 169 // underlying PKCS11 calls), so we do this last to reduce the number of times |
| 174 // we have to call it. | 170 // we have to call it. |
| 175 PrivateKeyFilter private_filter(net::CertDatabase::GetInstance()); | 171 PrivateKeyFilter private_filter(net::CertDatabase::GetInstance()); |
| 176 matching_certs.remove_if(private_filter); | 172 matching_certs.remove_if(private_filter); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 188 if (!latest.get() || (*iter)->valid_start() > latest->valid_start()) | 184 if (!latest.get() || (*iter)->valid_start() > latest->valid_start()) |
| 189 latest = *iter; | 185 latest = *iter; |
| 190 } | 186 } |
| 191 | 187 |
| 192 return latest; | 188 return latest; |
| 193 } | 189 } |
| 194 | 190 |
| 195 } // namespace certificate_pattern | 191 } // namespace certificate_pattern |
| 196 | 192 |
| 197 } // namespace chromeos | 193 } // namespace chromeos |
| OLD | NEW |