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/onc/onc_certificate_importer.h" | 5 #include "chromeos/network/onc/onc_certificate_importer.h" |
6 | 6 |
7 #include <cert.h> | 7 #include <cert.h> |
8 #include <keyhi.h> | 8 #include <keyhi.h> |
9 #include <pk11pub.h> | 9 #include <pk11pub.h> |
10 | 10 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 result = false; | 123 result = false; |
124 } | 124 } |
125 return result; | 125 return result; |
126 } | 126 } |
127 | 127 |
128 bool CertificateImporter::ParseAndStoreCertificate( | 128 bool CertificateImporter::ParseAndStoreCertificate( |
129 const base::DictionaryValue& certificate, | 129 const base::DictionaryValue& certificate, |
130 net::CertificateList* onc_trusted_certificates) { | 130 net::CertificateList* onc_trusted_certificates) { |
131 // Get out the attributes of the given certificate. | 131 // Get out the attributes of the given certificate. |
132 std::string guid; | 132 std::string guid; |
133 certificate.GetString(certificate::kGUID, &guid); | 133 certificate.GetStringWithoutPathExpansion(certificate::kGUID, &guid); |
134 DCHECK(!guid.empty()); | 134 DCHECK(!guid.empty()); |
135 | 135 |
136 bool remove = false; | 136 bool remove = false; |
137 if (certificate.GetBoolean(kRemove, &remove) && remove) { | 137 if (certificate.GetBooleanWithoutPathExpansion(kRemove, &remove) && remove) { |
138 if (!DeleteCertAndKeyByNickname(guid)) { | 138 if (!DeleteCertAndKeyByNickname(guid)) { |
139 ONC_LOG_ERROR("Unable to delete certificate"); | 139 ONC_LOG_ERROR("Unable to delete certificate"); |
140 return false; | 140 return false; |
141 } else { | 141 } else { |
142 return true; | 142 return true; |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 // Not removing, so let's get the data we need to add this certificate. | 146 // Not removing, so let's get the data we need to add this certificate. |
147 std::string cert_type; | 147 std::string cert_type; |
148 certificate.GetString(certificate::kType, &cert_type); | 148 certificate.GetStringWithoutPathExpansion(certificate::kType, &cert_type); |
149 if (cert_type == certificate::kServer || | 149 if (cert_type == certificate::kServer || |
150 cert_type == certificate::kAuthority) { | 150 cert_type == certificate::kAuthority) { |
151 return ParseServerOrCaCertificate( | 151 return ParseServerOrCaCertificate( |
152 cert_type, guid, certificate, onc_trusted_certificates); | 152 cert_type, guid, certificate, onc_trusted_certificates); |
153 } else if (cert_type == certificate::kClient) { | 153 } else if (cert_type == certificate::kClient) { |
154 return ParseClientCertificate(guid, certificate); | 154 return ParseClientCertificate(guid, certificate); |
155 } | 155 } |
156 | 156 |
157 NOTREACHED(); | 157 NOTREACHED(); |
158 return false; | 158 return false; |
159 } | 159 } |
160 | 160 |
161 bool CertificateImporter::ParseServerOrCaCertificate( | 161 bool CertificateImporter::ParseServerOrCaCertificate( |
162 const std::string& cert_type, | 162 const std::string& cert_type, |
163 const std::string& guid, | 163 const std::string& guid, |
164 const base::DictionaryValue& certificate, | 164 const base::DictionaryValue& certificate, |
165 net::CertificateList* onc_trusted_certificates) { | 165 net::CertificateList* onc_trusted_certificates) { |
166 bool web_trust_flag = false; | 166 bool web_trust_flag = false; |
167 const base::ListValue* trust_list = NULL; | 167 const base::ListValue* trust_list = NULL; |
168 if (certificate.GetList(certificate::kTrust, &trust_list)) { | 168 if (certificate.GetListWithoutPathExpansion(certificate::kTrustBits, |
169 for (size_t i = 0; i < trust_list->GetSize(); ++i) { | 169 &trust_list)) { |
| 170 for (base::ListValue::const_iterator it = trust_list->begin(); |
| 171 it != trust_list->end(); ++it) { |
170 std::string trust_type; | 172 std::string trust_type; |
171 if (!trust_list->GetString(i, &trust_type)) | 173 if (!(*it)->GetAsString(&trust_type)) |
172 NOTREACHED(); | 174 NOTREACHED(); |
173 | 175 |
174 if (trust_type == certificate::kWeb) { | 176 if (trust_type == certificate::kWeb) { |
175 // "Web" implies that the certificate is to be trusted for SSL | 177 // "Web" implies that the certificate is to be trusted for SSL |
176 // identification. | 178 // identification. |
177 web_trust_flag = true; | 179 web_trust_flag = true; |
178 } else { | 180 } else { |
179 ONC_LOG_ERROR("Certificate contains unknown trust type " + trust_type); | 181 // Trust bits should only increase trust and never restrict. Thus, |
180 return false; | 182 // ignoring unknown bits should be safe. |
| 183 ONC_LOG_WARNING("Certificate contains unknown trust type " + |
| 184 trust_type); |
181 } | 185 } |
182 } | 186 } |
183 } | 187 } |
184 | 188 |
185 bool import_with_ssl_trust = false; | 189 bool import_with_ssl_trust = false; |
186 if (web_trust_flag) { | 190 if (web_trust_flag) { |
187 if (!allow_trust_imports_) | 191 if (!allow_trust_imports_) |
188 LOG(WARNING) << "Web trust not granted for certificate: " << guid; | 192 ONC_LOG_WARNING("Web trust not granted for certificate: " + guid); |
189 else | 193 else |
190 import_with_ssl_trust = true; | 194 import_with_ssl_trust = true; |
191 } | 195 } |
192 | 196 |
193 std::string x509_data; | 197 std::string x509_data; |
194 if (!certificate.GetString(certificate::kX509, &x509_data) || | 198 if (!certificate.GetStringWithoutPathExpansion(certificate::kX509, |
| 199 &x509_data) || |
195 x509_data.empty()) { | 200 x509_data.empty()) { |
196 ONC_LOG_ERROR( | 201 ONC_LOG_ERROR( |
197 "Certificate missing appropriate certificate data for type: " + | 202 "Certificate missing appropriate certificate data for type: " + |
198 cert_type); | 203 cert_type); |
199 return false; | 204 return false; |
200 } | 205 } |
201 | 206 |
202 // Parse PEM certificate, and get the decoded data for use in creating | 207 // Parse PEM certificate, and get the decoded data for use in creating |
203 // certificate below. | 208 // certificate below. |
204 std::vector<std::string> pem_headers; | 209 std::vector<std::string> pem_headers; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 // keep our own database for mapping GUIDs to certs in order to enable several | 255 // keep our own database for mapping GUIDs to certs in order to enable several |
251 // GUIDs to map to the same cert. See http://crosbug.com/26073. | 256 // GUIDs to map to the same cert. See http://crosbug.com/26073. |
252 net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance(); | 257 net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance(); |
253 if (x509_cert->os_cert_handle()->isperm) { | 258 if (x509_cert->os_cert_handle()->isperm) { |
254 if (!cert_database->DeleteCertAndKey(x509_cert.get())) { | 259 if (!cert_database->DeleteCertAndKey(x509_cert.get())) { |
255 ONC_LOG_ERROR("Unable to delete X509 certificate."); | 260 ONC_LOG_ERROR("Unable to delete X509 certificate."); |
256 return false; | 261 return false; |
257 } | 262 } |
258 | 263 |
259 // Reload the cert here to get an actual temporary cert instance. | 264 // Reload the cert here to get an actual temporary cert instance. |
260 x509_cert = | 265 x509_cert = net::X509Certificate::CreateFromBytesWithNickname( |
261 net::X509Certificate::CreateFromBytesWithNickname( | 266 decoded_x509.data(), |
262 decoded_x509.data(), | 267 decoded_x509.size(), |
263 decoded_x509.size(), | 268 guid.c_str()); |
264 guid.c_str()); | |
265 if (!x509_cert.get()) { | 269 if (!x509_cert.get()) { |
266 ONC_LOG_ERROR("Unable to create X509 certificate from bytes."); | 270 ONC_LOG_ERROR("Unable to create X509 certificate from bytes."); |
267 return false; | 271 return false; |
268 } | 272 } |
269 DCHECK(!x509_cert->os_cert_handle()->isperm); | 273 DCHECK(!x509_cert->os_cert_handle()->isperm); |
270 DCHECK(x509_cert->os_cert_handle()->istemp); | 274 DCHECK(x509_cert->os_cert_handle()->istemp); |
271 } | 275 } |
272 | 276 |
273 // Make sure the GUID is not already taken. Note that for the reimport case we | 277 // Make sure the GUID is not already taken. Note that for the reimport case we |
274 // have removed the existing cert above. | 278 // have removed the existing cert above. |
(...skipping 30 matching lines...) Expand all Loading... |
305 if (web_trust_flag && onc_trusted_certificates) | 309 if (web_trust_flag && onc_trusted_certificates) |
306 onc_trusted_certificates->push_back(x509_cert); | 310 onc_trusted_certificates->push_back(x509_cert); |
307 | 311 |
308 return true; | 312 return true; |
309 } | 313 } |
310 | 314 |
311 bool CertificateImporter::ParseClientCertificate( | 315 bool CertificateImporter::ParseClientCertificate( |
312 const std::string& guid, | 316 const std::string& guid, |
313 const base::DictionaryValue& certificate) { | 317 const base::DictionaryValue& certificate) { |
314 std::string pkcs12_data; | 318 std::string pkcs12_data; |
315 if (!certificate.GetString(certificate::kPKCS12, &pkcs12_data) || | 319 if (!certificate.GetStringWithoutPathExpansion(certificate::kPKCS12, |
| 320 &pkcs12_data) || |
316 pkcs12_data.empty()) { | 321 pkcs12_data.empty()) { |
317 ONC_LOG_ERROR("PKCS12 data is missing for client certificate."); | 322 ONC_LOG_ERROR("PKCS12 data is missing for client certificate."); |
318 return false; | 323 return false; |
319 } | 324 } |
320 | 325 |
321 std::string decoded_pkcs12; | 326 std::string decoded_pkcs12; |
322 if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) { | 327 if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) { |
323 ONC_LOG_ERROR( | 328 ONC_LOG_ERROR( |
324 "Unable to base64 decode PKCS#12 data: \"" + pkcs12_data + "\"."); | 329 "Unable to base64 decode PKCS#12 data: \"" + pkcs12_data + "\"."); |
325 return false; | 330 return false; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 PK11_SetPrivateKeyNickname(private_key, const_cast<char*>(guid.c_str())); | 365 PK11_SetPrivateKeyNickname(private_key, const_cast<char*>(guid.c_str())); |
361 SECKEY_DestroyPrivateKey(private_key); | 366 SECKEY_DestroyPrivateKey(private_key); |
362 } else { | 367 } else { |
363 ONC_LOG_WARNING("Unable to find private key for certificate."); | 368 ONC_LOG_WARNING("Unable to find private key for certificate."); |
364 } | 369 } |
365 return true; | 370 return true; |
366 } | 371 } |
367 | 372 |
368 } // namespace onc | 373 } // namespace onc |
369 } // namespace chromeos | 374 } // namespace chromeos |
OLD | NEW |