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 |