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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 return IMPORT_FAILED; | 63 return IMPORT_FAILED; |
64 } else { | 64 } else { |
65 return IMPORT_INCOMPLETE; | 65 return IMPORT_INCOMPLETE; |
66 } | 66 } |
67 } | 67 } |
68 | 68 |
69 bool CertificateImporter::ParseAndStoreCertificate( | 69 bool CertificateImporter::ParseAndStoreCertificate( |
70 const base::DictionaryValue& certificate) { | 70 const base::DictionaryValue& certificate) { |
71 // Get out the attributes of the given certificate. | 71 // Get out the attributes of the given certificate. |
72 std::string guid; | 72 std::string guid; |
73 certificate.GetString(certificate::kGUID, &guid); | 73 certificate.GetStringWithoutPathExpansion(certificate::kGUID, &guid); |
74 DCHECK(!guid.empty()); | 74 DCHECK(!guid.empty()); |
75 | 75 |
76 bool remove = false; | 76 bool remove = false; |
77 if (certificate.GetBoolean(kRemove, &remove) && remove) { | 77 if (certificate.GetBooleanWithoutPathExpansion(kRemove, &remove) && remove) { |
78 if (!DeleteCertAndKeyByNickname(guid)) { | 78 if (!DeleteCertAndKeyByNickname(guid)) { |
79 ONC_LOG_ERROR("Unable to delete certificate"); | 79 ONC_LOG_ERROR("Unable to delete certificate"); |
80 return false; | 80 return false; |
81 } else { | 81 } else { |
82 return true; | 82 return true; |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
86 // Not removing, so let's get the data we need to add this certificate. | 86 // Not removing, so let's get the data we need to add this certificate. |
87 std::string cert_type; | 87 std::string cert_type; |
88 certificate.GetString(certificate::kType, &cert_type); | 88 certificate.GetStringWithoutPathExpansion(certificate::kType, &cert_type); |
89 if (cert_type == certificate::kServer || | 89 if (cert_type == certificate::kServer || |
90 cert_type == certificate::kAuthority) { | 90 cert_type == certificate::kAuthority) { |
91 return ParseServerOrCaCertificate(cert_type, guid, certificate); | 91 return ParseServerOrCaCertificate(cert_type, guid, certificate); |
92 } else if (cert_type == certificate::kClient) { | 92 } else if (cert_type == certificate::kClient) { |
93 return ParseClientCertificate(guid, certificate); | 93 return ParseClientCertificate(guid, certificate); |
94 } | 94 } |
95 | 95 |
96 NOTREACHED(); | 96 NOTREACHED(); |
97 return false; | 97 return false; |
98 } | 98 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 } | 154 } |
155 return result; | 155 return result; |
156 } | 156 } |
157 | 157 |
158 bool CertificateImporter::ParseServerOrCaCertificate( | 158 bool CertificateImporter::ParseServerOrCaCertificate( |
159 const std::string& cert_type, | 159 const std::string& cert_type, |
160 const std::string& guid, | 160 const std::string& guid, |
161 const base::DictionaryValue& certificate) { | 161 const base::DictionaryValue& certificate) { |
162 bool web_trust = false; | 162 bool web_trust = false; |
163 const base::ListValue* trust_list = NULL; | 163 const base::ListValue* trust_list = NULL; |
164 if (certificate.GetList(certificate::kTrust, &trust_list)) { | 164 if (certificate.GetListWithoutPathExpansion(certificate::kTrustBits, |
165 for (size_t i = 0; i < trust_list->GetSize(); ++i) { | 165 &trust_list)) { |
166 for (base::ListValue::const_iterator it = trust_list->begin(); | |
167 it != trust_list->end(); ++it) { | |
166 std::string trust_type; | 168 std::string trust_type; |
167 if (!trust_list->GetString(i, &trust_type)) | 169 if (!(*it)->GetAsString(&trust_type)) |
168 NOTREACHED(); | 170 NOTREACHED(); |
169 | 171 |
170 if (trust_type == certificate::kWeb) { | 172 if (trust_type == certificate::kWeb) { |
171 // "Web" implies that the certificate is to be trusted for SSL | 173 // "Web" implies that the certificate is to be trusted for SSL |
172 // identification. | 174 // identification. |
173 web_trust = true; | 175 web_trust = true; |
174 } else { | 176 } else { |
175 ONC_LOG_ERROR("Certificate contains unknown trust type " + trust_type); | 177 ONC_LOG_WARNING("Certificate contains unknown trust type " + |
Joao da Silva
2013/04/02 15:06:02
Please confirm this change: new flags that are not
pneubeck (no reviews)
2013/04/03 08:13:07
Clarified here and in the ONC spec.
| |
176 return false; | 178 trust_type); |
177 } | 179 } |
178 } | 180 } |
179 } | 181 } |
180 | 182 |
181 if (web_trust && !allow_web_trust_) { | 183 if (web_trust && !allow_web_trust_) { |
182 LOG(WARNING) << "Web trust not granted for certificate: " << guid; | 184 ONC_LOG_WARNING("Web trust not granted for certificate: " + guid); |
183 web_trust = false; | 185 web_trust = false; |
184 } | 186 } |
185 | 187 |
186 std::string x509_data; | 188 std::string x509_data; |
187 if (!certificate.GetString(certificate::kX509, &x509_data) || | 189 if (!certificate.GetStringWithoutPathExpansion(certificate::kX509, |
190 &x509_data) || | |
188 x509_data.empty()) { | 191 x509_data.empty()) { |
189 ONC_LOG_ERROR( | 192 ONC_LOG_ERROR( |
190 "Certificate missing appropriate certificate data for type: " + | 193 "Certificate missing appropriate certificate data for type: " + |
191 cert_type); | 194 cert_type); |
192 return false; | 195 return false; |
193 } | 196 } |
194 | 197 |
195 // Parse PEM certificate, and get the decoded data for use in creating | 198 // Parse PEM certificate, and get the decoded data for use in creating |
196 // certificate below. | 199 // certificate below. |
197 std::vector<std::string> pem_headers; | 200 std::vector<std::string> pem_headers; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 // keep our own database for mapping GUIDs to certs in order to enable several | 246 // keep our own database for mapping GUIDs to certs in order to enable several |
244 // GUIDs to map to the same cert. See http://crosbug.com/26073. | 247 // GUIDs to map to the same cert. See http://crosbug.com/26073. |
245 net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance(); | 248 net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance(); |
246 if (x509_cert->os_cert_handle()->isperm) { | 249 if (x509_cert->os_cert_handle()->isperm) { |
247 if (!cert_database->DeleteCertAndKey(x509_cert.get())) { | 250 if (!cert_database->DeleteCertAndKey(x509_cert.get())) { |
248 ONC_LOG_ERROR("Unable to delete X509 certificate."); | 251 ONC_LOG_ERROR("Unable to delete X509 certificate."); |
249 return false; | 252 return false; |
250 } | 253 } |
251 | 254 |
252 // Reload the cert here to get an actual temporary cert instance. | 255 // Reload the cert here to get an actual temporary cert instance. |
253 x509_cert = | 256 x509_cert = net::X509Certificate::CreateFromBytesWithNickname( |
254 net::X509Certificate::CreateFromBytesWithNickname( | 257 decoded_x509.data(), |
255 decoded_x509.data(), | 258 decoded_x509.size(), |
256 decoded_x509.size(), | 259 guid.c_str()); |
257 guid.c_str()); | |
258 if (!x509_cert.get()) { | 260 if (!x509_cert.get()) { |
259 ONC_LOG_ERROR("Unable to create X509 certificate from bytes."); | 261 ONC_LOG_ERROR("Unable to create X509 certificate from bytes."); |
260 return false; | 262 return false; |
261 } | 263 } |
262 DCHECK(!x509_cert->os_cert_handle()->isperm); | 264 DCHECK(!x509_cert->os_cert_handle()->isperm); |
263 DCHECK(x509_cert->os_cert_handle()->istemp); | 265 DCHECK(x509_cert->os_cert_handle()->istemp); |
264 } | 266 } |
265 | 267 |
266 // Make sure the GUID is not already taken. Note that for the reimport case we | 268 // Make sure the GUID is not already taken. Note that for the reimport case we |
267 // have removed the existing cert above. | 269 // have removed the existing cert above. |
(...skipping 27 matching lines...) Expand all Loading... | |
295 return false; | 297 return false; |
296 } | 298 } |
297 | 299 |
298 return true; | 300 return true; |
299 } | 301 } |
300 | 302 |
301 bool CertificateImporter::ParseClientCertificate( | 303 bool CertificateImporter::ParseClientCertificate( |
302 const std::string& guid, | 304 const std::string& guid, |
303 const base::DictionaryValue& certificate) { | 305 const base::DictionaryValue& certificate) { |
304 std::string pkcs12_data; | 306 std::string pkcs12_data; |
305 if (!certificate.GetString(certificate::kPKCS12, &pkcs12_data) || | 307 if (!certificate.GetStringWithoutPathExpansion(certificate::kPKCS12, |
308 &pkcs12_data) || | |
306 pkcs12_data.empty()) { | 309 pkcs12_data.empty()) { |
307 ONC_LOG_ERROR("PKCS12 data is missing for client certificate."); | 310 ONC_LOG_ERROR("PKCS12 data is missing for client certificate."); |
308 return false; | 311 return false; |
309 } | 312 } |
310 | 313 |
311 std::string decoded_pkcs12; | 314 std::string decoded_pkcs12; |
312 if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) { | 315 if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) { |
313 ONC_LOG_ERROR( | 316 ONC_LOG_ERROR( |
314 "Unable to base64 decode PKCS#12 data: \"" + pkcs12_data + "\"."); | 317 "Unable to base64 decode PKCS#12 data: \"" + pkcs12_data + "\"."); |
315 return false; | 318 return false; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
350 PK11_SetPrivateKeyNickname(private_key, const_cast<char*>(guid.c_str())); | 353 PK11_SetPrivateKeyNickname(private_key, const_cast<char*>(guid.c_str())); |
351 SECKEY_DestroyPrivateKey(private_key); | 354 SECKEY_DestroyPrivateKey(private_key); |
352 } else { | 355 } else { |
353 ONC_LOG_WARNING("Unable to find private key for certificate."); | 356 ONC_LOG_WARNING("Unable to find private key for certificate."); |
354 } | 357 } |
355 return true; | 358 return true; |
356 } | 359 } |
357 | 360 |
358 } // namespace onc | 361 } // namespace onc |
359 } // namespace chromeos | 362 } // namespace chromeos |
OLD | NEW |