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/client_cert_util.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> |
11 #include <string> | 11 #include <string> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/values.h" | |
14 #include "chromeos/network/certificate_pattern.h" | 15 #include "chromeos/network/certificate_pattern.h" |
15 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
16 #include "net/cert/cert_database.h" | 17 #include "net/cert/cert_database.h" |
17 #include "net/cert/nss_cert_database.h" | 18 #include "net/cert/nss_cert_database.h" |
18 #include "net/cert/x509_cert_types.h" | 19 #include "net/cert/x509_cert_types.h" |
19 #include "net/cert/x509_certificate.h" | 20 #include "net/cert/x509_certificate.h" |
21 #include "third_party/cros_system_api/dbus/service_constants.h" | |
20 | 22 |
21 namespace chromeos { | 23 namespace chromeos { |
22 | 24 |
25 namespace client_cert { | |
26 | |
23 namespace { | 27 namespace { |
24 | 28 |
25 // Returns true only if any fields set in this pattern match exactly with | |
26 // similar fields in the principal. If organization_ or organizational_unit_ | |
27 // are set, then at least one of the organizations or units in the principal | |
28 // must match. | |
29 bool CertPrincipalMatches(const IssuerSubjectPattern& pattern, | |
30 const net::CertPrincipal& principal) { | |
31 if (!pattern.common_name().empty() && | |
32 pattern.common_name() != principal.common_name) { | |
33 return false; | |
34 } | |
35 | |
36 if (!pattern.locality().empty() && | |
37 pattern.locality() != principal.locality_name) { | |
38 return false; | |
39 } | |
40 | |
41 if (!pattern.organization().empty()) { | |
42 if (std::find(principal.organization_names.begin(), | |
43 principal.organization_names.end(), | |
44 pattern.organization()) == | |
45 principal.organization_names.end()) { | |
46 return false; | |
47 } | |
48 } | |
49 | |
50 if (!pattern.organizational_unit().empty()) { | |
51 if (std::find(principal.organization_unit_names.begin(), | |
52 principal.organization_unit_names.end(), | |
53 pattern.organizational_unit()) == | |
54 principal.organization_unit_names.end()) { | |
55 return false; | |
56 } | |
57 } | |
58 | |
59 return true; | |
60 } | |
61 | |
62 // Functor to filter out non-matching issuers. | 29 // Functor to filter out non-matching issuers. |
63 class IssuerFilter { | 30 class IssuerFilter { |
64 public: | 31 public: |
65 explicit IssuerFilter(const IssuerSubjectPattern& issuer) | 32 explicit IssuerFilter(const IssuerSubjectPattern& issuer) |
66 : issuer_(issuer) {} | 33 : issuer_(issuer) {} |
67 bool operator()(const scoped_refptr<net::X509Certificate>& cert) const { | 34 bool operator()(const scoped_refptr<net::X509Certificate>& cert) const { |
68 return !CertPrincipalMatches(issuer_, cert.get()->issuer()); | 35 return !CertPrincipalMatches(issuer_, cert.get()->issuer()); |
69 } | 36 } |
70 private: | 37 private: |
71 const IssuerSubjectPattern& issuer_; | 38 const IssuerSubjectPattern& issuer_; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
119 return (std::find(issuer_ca_pems_.begin(), issuer_ca_pems_.end(), | 86 return (std::find(issuer_ca_pems_.begin(), issuer_ca_pems_.end(), |
120 pem_encoded) == | 87 pem_encoded) == |
121 issuer_ca_pems_.end()); | 88 issuer_ca_pems_.end()); |
122 } | 89 } |
123 private: | 90 private: |
124 const std::vector<std::string>& issuer_ca_pems_; | 91 const std::vector<std::string>& issuer_ca_pems_; |
125 }; | 92 }; |
126 | 93 |
127 } // namespace | 94 } // namespace |
128 | 95 |
129 namespace certificate_pattern { | 96 // Returns true only if any fields set in this pattern match exactly with |
97 // similar fields in the principal. If organization_ or organizational_unit_ | |
98 // are set, then at least one of the organizations or units in the principal | |
99 // must match. | |
100 bool CertPrincipalMatches(const IssuerSubjectPattern& pattern, | |
101 const net::CertPrincipal& principal) { | |
102 if (!pattern.common_name().empty() && | |
103 pattern.common_name() != principal.common_name) { | |
104 return false; | |
105 } | |
106 | |
107 if (!pattern.locality().empty() && | |
108 pattern.locality() != principal.locality_name) { | |
109 return false; | |
110 } | |
111 | |
112 if (!pattern.organization().empty()) { | |
113 if (std::find(principal.organization_names.begin(), | |
114 principal.organization_names.end(), | |
115 pattern.organization()) == | |
116 principal.organization_names.end()) { | |
117 return false; | |
118 } | |
119 } | |
120 | |
121 if (!pattern.organizational_unit().empty()) { | |
122 if (std::find(principal.organization_unit_names.begin(), | |
123 principal.organization_unit_names.end(), | |
124 pattern.organizational_unit()) == | |
125 principal.organization_unit_names.end()) { | |
126 return false; | |
127 } | |
128 } | |
129 | |
130 return true; | |
131 } | |
130 | 132 |
131 scoped_refptr<net::X509Certificate> GetCertificateMatch( | 133 scoped_refptr<net::X509Certificate> GetCertificateMatch( |
132 const CertificatePattern& pattern) { | 134 const CertificatePattern& pattern) { |
133 typedef std::list<scoped_refptr<net::X509Certificate> > CertificateStlList; | 135 typedef std::list<scoped_refptr<net::X509Certificate> > CertificateStlList; |
134 | 136 |
135 // Start with all the certs, and narrow it down from there. | 137 // Start with all the certs, and narrow it down from there. |
136 net::CertificateList all_certs; | 138 net::CertificateList all_certs; |
137 CertificateStlList matching_certs; | 139 CertificateStlList matching_certs; |
138 net::NSSCertDatabase::GetInstance()->ListCerts(&all_certs); | 140 net::NSSCertDatabase::GetInstance()->ListCerts(&all_certs); |
139 | 141 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 // Iterate over the rest looking for the one that was issued latest. | 183 // Iterate over the rest looking for the one that was issued latest. |
182 for (CertificateStlList::iterator iter = matching_certs.begin(); | 184 for (CertificateStlList::iterator iter = matching_certs.begin(); |
183 iter != matching_certs.end(); ++iter) { | 185 iter != matching_certs.end(); ++iter) { |
184 if (!latest.get() || (*iter)->valid_start() > latest->valid_start()) | 186 if (!latest.get() || (*iter)->valid_start() > latest->valid_start()) |
185 latest = *iter; | 187 latest = *iter; |
186 } | 188 } |
187 | 189 |
188 return latest; | 190 return latest; |
189 } | 191 } |
190 | 192 |
191 } // namespace certificate_pattern | 193 void SetShillProperties(const client_cert::ConfigType cert_config_type, |
194 const std::string& tpm_slot, | |
195 const std::string& tpm_pin, | |
196 const std::string* pkcs11_id, | |
197 base::DictionaryValue* properties) { | |
198 const char* tpm_pin_property = NULL; | |
199 switch (cert_config_type) { | |
200 case CONFIG_TYPE_NONE: { | |
201 return; | |
202 } | |
203 case CONFIG_TYPE_OPENVPN: { | |
204 tpm_pin_property = flimflam::kOpenVPNPinProperty; | |
205 if (pkcs11_id) { | |
206 properties->SetStringWithoutPathExpansion( | |
207 flimflam::kOpenVPNClientCertIdProperty, *pkcs11_id); | |
208 } | |
209 break; | |
210 } | |
211 case CONFIG_TYPE_IPSEC: { | |
212 tpm_pin_property = flimflam::kL2tpIpsecPinProperty; | |
213 if (!tpm_slot.empty()) { | |
214 properties->SetStringWithoutPathExpansion( | |
215 flimflam::kL2tpIpsecClientCertSlotProperty, tpm_slot); | |
216 } | |
217 if (pkcs11_id) { | |
218 properties->SetStringWithoutPathExpansion( | |
219 flimflam::kL2tpIpsecClientCertIdProperty, *pkcs11_id); | |
220 } | |
221 break; | |
222 } | |
223 case CONFIG_TYPE_EAP: { | |
224 tpm_pin_property = flimflam::kEapPinProperty; | |
225 if (pkcs11_id) { | |
226 // Shill requires both CertID and KeyID for TLS connections, despite the | |
227 // fact that by convention they are the same ID. | |
228 properties->SetStringWithoutPathExpansion(flimflam::kEapCertIdProperty, | |
229 *pkcs11_id); | |
230 properties->SetStringWithoutPathExpansion(flimflam::kEapKeyIdProperty, | |
231 *pkcs11_id); | |
232 } | |
233 break; | |
234 } | |
235 } | |
236 DCHECK(tpm_pin_property); | |
237 if (!tpm_pin.empty()) | |
238 properties->SetStringWithoutPathExpansion(tpm_pin_property, tpm_pin); | |
stevenjb
2013/08/09 17:03:29
nit: I'm not sure using tpm_pin_property simplifie
pneubeck (no reviews)
2013/08/09 22:40:21
I know, i had that before. But I didn't like the a
| |
239 } | |
240 | |
241 } // namespace client_cert | |
192 | 242 |
193 } // namespace chromeos | 243 } // namespace chromeos |
OLD | NEW |