Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: chrome/browser/chromeos/cros/onc_network_parser.cc

Issue 8566056: This applies GUIDs to certificate and key nicknames when (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: minor fixes Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/chromeos/cros/onc_network_parser.h" 5 #include "chrome/browser/chromeos/cros/onc_network_parser.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/json/json_value_serializer.h" 8 #include "base/json/json_value_serializer.h"
9 #include "base/stringprintf.h" 9 #include "base/stringprintf.h"
10 #include "base/values.h" 10 #include "base/values.h"
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 } 101 }
102 102
103 int OncNetworkParser::GetNetworkConfigsSize() const { 103 int OncNetworkParser::GetNetworkConfigsSize() const {
104 return network_configs_ ? network_configs_->GetSize() : 0; 104 return network_configs_ ? network_configs_->GetSize() : 0;
105 } 105 }
106 106
107 int OncNetworkParser::GetCertificatesSize() const { 107 int OncNetworkParser::GetCertificatesSize() const {
108 return certificates_ ? certificates_->GetSize() : 0; 108 return certificates_ ? certificates_->GetSize() : 0;
109 } 109 }
110 110
111 bool OncNetworkParser::ParseCertificate(int cert_index) { 111 scoped_refptr<net::X509Certificate> OncNetworkParser::ParseCertificate(
112 int cert_index) {
112 CHECK(certificates_); 113 CHECK(certificates_);
113 CHECK(static_cast<size_t>(cert_index) < certificates_->GetSize()); 114 CHECK(static_cast<size_t>(cert_index) < certificates_->GetSize());
114 CHECK(cert_index >= 0); 115 CHECK(cert_index >= 0);
115 base::DictionaryValue* certificate = NULL; 116 base::DictionaryValue* certificate = NULL;
116 certificates_->GetDictionary(cert_index, &certificate); 117 certificates_->GetDictionary(cert_index, &certificate);
117 CHECK(certificate); 118 CHECK(certificate);
118 119
119 // Get out the attributes of the given cert. 120 // Get out the attributes of the given certificate.
120 std::string guid; 121 std::string guid;
121 bool remove = false; 122 bool remove = false;
122 if (!certificate->GetString("GUID", &guid) || guid.empty()) { 123 if (!certificate->GetString("GUID", &guid) || guid.empty()) {
123 LOG(WARNING) << "ONC File: certificate missing identifier at index" 124 LOG(WARNING) << "ONC File: certificate missing identifier at index"
124 << cert_index; 125 << cert_index;
125 return false; 126 return NULL;
126 } 127 }
127 128
128 if (!certificate->GetBoolean("Remove", &remove)) 129 if (!certificate->GetBoolean("Remove", &remove))
129 remove = false; 130 remove = false;
130 131
131 net::CertDatabase cert_database; 132 net::CertDatabase cert_database;
132 if (remove) 133 if (remove) {
133 return cert_database.DeleteCertAndKeyByLabel(guid); 134 bool success = cert_database.DeleteCertAndKeyByLabel(guid);
135 DCHECK(success);
136 // TODO(gspencer): return removed certificate?
137 return NULL;
138 }
134 139
135 // Not removing, so let's get the data we need to add this cert. 140 // Not removing, so let's get the data we need to add this certificate.
136 std::string cert_type; 141 std::string cert_type;
137 certificate->GetString("Type", &cert_type); 142 certificate->GetString("Type", &cert_type);
138 if (cert_type == "Server" || cert_type == "Authority") { 143 if (cert_type == "Server" || cert_type == "Authority") {
139 return ParseServerOrCaCertificate(cert_index, cert_type, certificate); 144 return ParseServerOrCaCertificate(cert_index, cert_type, guid, certificate);
140 } 145 }
141 if (cert_type == "Client") { 146 if (cert_type == "Client") {
142 return ParseClientCertificate(cert_index, certificate); 147 return ParseClientCertificate(cert_index, guid, certificate);
143 } 148 }
144 149
145 LOG(WARNING) << "ONC File: certificate of unknown type: " << cert_type 150 LOG(WARNING) << "ONC File: certificate of unknown type: " << cert_type
146 << " at index " << cert_index; 151 << " at index " << cert_index;
147 return false; 152 return NULL;
148 } 153 }
149 154
150 Network* OncNetworkParser::ParseNetwork(int n) { 155 Network* OncNetworkParser::ParseNetwork(int n) {
151 // TODO(chocobo): Change this to parse network into a dictionary. 156 // TODO(chocobo): Change this to parse network into a dictionary.
152 if (!network_configs_) 157 if (!network_configs_)
153 return NULL; 158 return NULL;
154 DictionaryValue* info = NULL; 159 DictionaryValue* info = NULL;
155 if (!network_configs_->GetDictionary(n, &info)) 160 if (!network_configs_->GetDictionary(n, &info))
156 return NULL; 161 return NULL;
157 // Parse Open Network Configuration blob into a temporary Network object. 162 // Parse Open Network Configuration blob into a temporary Network object.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 return ParseType(GetTypeFromDictionary(info)); 205 return ParseType(GetTypeFromDictionary(info));
201 } 206 }
202 207
203 std::string OncNetworkParser::GetTypeFromDictionary( 208 std::string OncNetworkParser::GetTypeFromDictionary(
204 const base::DictionaryValue& info) { 209 const base::DictionaryValue& info) {
205 std::string type_string; 210 std::string type_string;
206 info.GetString("Type", &type_string); 211 info.GetString("Type", &type_string);
207 return type_string; 212 return type_string;
208 } 213 }
209 214
210 bool OncNetworkParser::ParseServerOrCaCertificate( 215 scoped_refptr<net::X509Certificate>
216 OncNetworkParser::ParseServerOrCaCertificate(
211 int cert_index, 217 int cert_index,
212 const std::string& cert_type, 218 const std::string& cert_type,
219 const std::string& guid,
213 base::DictionaryValue* certificate) { 220 base::DictionaryValue* certificate) {
214 net::CertDatabase cert_database; 221 net::CertDatabase cert_database;
215 bool web_trust = false; 222 bool web_trust = false;
216 base::ListValue* trust_list = NULL; 223 base::ListValue* trust_list = NULL;
217 if (certificate->GetList("Trust", &trust_list)) { 224 if (certificate->GetList("Trust", &trust_list)) {
218 for (size_t i = 0; i < trust_list->GetSize(); ++i) { 225 for (size_t i = 0; i < trust_list->GetSize(); ++i) {
219 std::string trust_type; 226 std::string trust_type;
220 if (!trust_list->GetString(i, &trust_type)) { 227 if (!trust_list->GetString(i, &trust_type)) {
221 LOG(WARNING) << "ONC File: certificate trust is invalid at index " 228 LOG(WARNING) << "ONC File: certificate trust is invalid at index "
222 << cert_index; 229 << cert_index;
223 return false; 230 return NULL;
224 } 231 }
225 if (trust_type == "Web") { 232 if (trust_type == "Web") {
226 web_trust = true; 233 web_trust = true;
227 } else { 234 } else {
228 LOG(WARNING) << "ONC File: certificate contains unknown " 235 LOG(WARNING) << "ONC File: certificate contains unknown "
229 << "trust type: " << trust_type 236 << "trust type: " << trust_type
230 << " at index " << cert_index; 237 << " at index " << cert_index;
231 return false; 238 return NULL;
232 } 239 }
233 } 240 }
234 } 241 }
235 242
236 std::string x509_data; 243 std::string x509_data;
237 if (!certificate->GetString("X509", &x509_data) || x509_data.empty()) { 244 if (!certificate->GetString("X509", &x509_data) || x509_data.empty()) {
238 LOG(WARNING) << "ONC File: certificate missing appropriate " 245 LOG(WARNING) << "ONC File: certificate missing appropriate "
239 << "certificate data for type: " << cert_type 246 << "certificate data for type: " << cert_type
240 << " at index " << cert_index; 247 << " at index " << cert_index;
241 return false; 248 return NULL;
242 } 249 }
243 250
244 std::string decoded_x509; 251 std::string decoded_x509;
245 if (!base::Base64Decode(x509_data, &decoded_x509)) { 252 if (!base::Base64Decode(x509_data, &decoded_x509)) {
246 LOG(WARNING) << "Unable to base64 decode X509 data: \"" 253 LOG(WARNING) << "Unable to base64 decode X509 data: \""
247 << x509_data << "\"."; 254 << x509_data << "\".";
248 return false; 255 return NULL;
249 } 256 }
250 257
251 scoped_refptr<net::X509Certificate> x509_cert( 258 scoped_refptr<net::X509Certificate> x509_cert =
252 net::X509Certificate::CreateFromBytes(decoded_x509.c_str(), 259 net::X509Certificate::CreateFromBytesWithNickname(
253 decoded_x509.size())); 260 decoded_x509.c_str(),
261 decoded_x509.size(),
262 guid.c_str());
254 if (!x509_cert.get()) { 263 if (!x509_cert.get()) {
255 LOG(WARNING) << "Unable to create X509 certificate from bytes."; 264 LOG(WARNING) << "Unable to create X509 certificate from bytes.";
256 return false; 265 return NULL;
257 } 266 }
267
268 if (!x509_cert->SetLabel(guid))
269 return NULL;
270
258 net::CertificateList cert_list; 271 net::CertificateList cert_list;
259 cert_list.push_back(x509_cert); 272 cert_list.push_back(x509_cert);
260 net::CertDatabase::ImportCertFailureList failures; 273 net::CertDatabase::ImportCertFailureList failures;
261 bool success = false; 274 bool success = false;
262 if (cert_type == "Server") { 275 if (cert_type == "Server") {
263 success = cert_database.ImportServerCert(cert_list, &failures); 276 success = cert_database.ImportServerCert(cert_list, &failures);
264 } else { // Authority cert 277 } else { // Authority cert
265 net::CertDatabase::TrustBits trust = web_trust ? 278 net::CertDatabase::TrustBits trust = web_trust ?
266 net::CertDatabase::TRUSTED_SSL : 279 net::CertDatabase::TRUSTED_SSL :
267 net::CertDatabase::UNTRUSTED; 280 net::CertDatabase::UNTRUSTED;
268 success = cert_database.ImportCACerts(cert_list, trust, &failures); 281 success = cert_database.ImportCACerts(cert_list, trust, &failures);
269 } 282 }
270 if (!failures.empty()) { 283 if (!failures.empty()) {
271 LOG(WARNING) << "ONC File: Error (" 284 LOG(WARNING) << "ONC File: Error ("
272 << net::ErrorToString(failures[0].net_error) 285 << net::ErrorToString(failures[0].net_error)
273 << ") importing " << cert_type << " certificate at index " 286 << ") importing " << cert_type << " certificate at index "
274 << cert_index; 287 << cert_index;
275 return false; 288 return NULL;
276 } 289 }
277 if (!success) { 290 if (!success) {
278 LOG(WARNING) << "ONC File: Unknown error importing " << cert_type 291 LOG(WARNING) << "ONC File: Unknown error importing " << cert_type
279 << " certificate at index " << cert_index; 292 << " certificate at index " << cert_index;
280 return false; 293 return NULL;
281 } 294 }
282 return true; 295
296 // Have to set the label again, because PKCS#11 seems to want to set
297 // it to token:nickname. We have to set it the first time so that
298 // it gets properly imported into the low-level token inside of
299 // ImportCACerts or ImportServerCert.
300 if (!x509_cert->SetLabel(guid))
301 return NULL;
302
303 return x509_cert;
283 } 304 }
284 305
285 bool OncNetworkParser::ParseClientCertificate( 306 scoped_refptr<net::X509Certificate> OncNetworkParser::ParseClientCertificate(
286 int cert_index, 307 int cert_index,
308 const std::string& guid,
287 base::DictionaryValue* certificate) { 309 base::DictionaryValue* certificate) {
288 net::CertDatabase cert_database; 310 net::CertDatabase cert_database;
289 std::string pkcs12_data; 311 std::string pkcs12_data;
290 if (!certificate->GetString("PKCS12", &pkcs12_data) || 312 if (!certificate->GetString("PKCS12", &pkcs12_data) ||
291 pkcs12_data.empty()) { 313 pkcs12_data.empty()) {
292 LOG(WARNING) << "ONC File: PKCS12 data is missing for Client " 314 LOG(WARNING) << "ONC File: PKCS12 data is missing for Client "
293 << "certificate at index " << cert_index; 315 << "certificate at index " << cert_index;
294 return false; 316 return NULL;
295 } 317 }
296 318
297 std::string decoded_pkcs12; 319 std::string decoded_pkcs12;
298 if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) { 320 if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) {
299 LOG(WARNING) << "Unable to base64 decode PKCS#12 data: \"" 321 LOG(WARNING) << "Unable to base64 decode PKCS#12 data: \""
300 << pkcs12_data << "\"."; 322 << pkcs12_data << "\".";
301 return false; 323 return NULL;
302 } 324 }
303 325
304 // Since this has a private key, always use the private module. 326 // Since this has a private key, always use the private module.
305 scoped_refptr<net::CryptoModule> module(cert_database.GetPrivateModule()); 327 scoped_refptr<net::CryptoModule> module(cert_database.GetPrivateModule());
328 net::CertificateList imported_certs;
306 int result = cert_database.ImportFromPKCS12( 329 int result = cert_database.ImportFromPKCS12(
307 module.get(), decoded_pkcs12, string16(), false); 330 module.get(), decoded_pkcs12, string16(), false, &imported_certs);
308 if (result != net::OK) { 331 if (result != net::OK) {
309 LOG(WARNING) << "ONC File: Unable to import Client certificate at index " 332 LOG(WARNING) << "ONC File: Unable to import Client certificate at index "
310 << cert_index 333 << cert_index
311 << " (error " << net::ErrorToString(result) << ")."; 334 << " (error " << net::ErrorToString(result) << ").";
312 return false; 335 return NULL;
313 } 336 }
314 return true; 337
338 if (imported_certs.size() == 0ul) {
339 LOG(WARNING) << "ONC File: PKCS12 data contains no importable certificates"
340 << " at index " << cert_index;
341 return NULL;
342 }
343
344 if (imported_certs.size() != 1ul) {
345 LOG(WARNING) << "ONC File: PKCS12 data at index " << cert_index
346 << " contains more than one certificate. Only the first one will"
347 << " be imported.";
348 }
349
350 scoped_refptr<net::X509Certificate> cert_result = imported_certs[0];
351 if (!cert_result->SetLabel(guid))
352 return NULL;
353
354 return cert_result;
315 } 355 }
316 356
317 // -------------------- OncWirelessNetworkParser -------------------- 357 // -------------------- OncWirelessNetworkParser --------------------
318 358
319 OncWirelessNetworkParser::OncWirelessNetworkParser() {} 359 OncWirelessNetworkParser::OncWirelessNetworkParser() {}
320 OncWirelessNetworkParser::~OncWirelessNetworkParser() {} 360 OncWirelessNetworkParser::~OncWirelessNetworkParser() {}
321 361
322 bool OncWirelessNetworkParser::ParseValue(PropertyIndex index, 362 bool OncWirelessNetworkParser::ParseValue(PropertyIndex index,
323 const base::Value& value, 363 const base::Value& value,
324 Network* network) { 364 Network* network) {
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 static EnumMapper<ProviderType>::Pair table[] = { 672 static EnumMapper<ProviderType>::Pair table[] = {
633 { flimflam::kProviderL2tpIpsec, PROVIDER_TYPE_L2TP_IPSEC_PSK }, 673 { flimflam::kProviderL2tpIpsec, PROVIDER_TYPE_L2TP_IPSEC_PSK },
634 { flimflam::kProviderOpenVpn, PROVIDER_TYPE_OPEN_VPN }, 674 { flimflam::kProviderOpenVpn, PROVIDER_TYPE_OPEN_VPN },
635 }; 675 };
636 static EnumMapper<ProviderType> parser( 676 static EnumMapper<ProviderType> parser(
637 table, arraysize(table), PROVIDER_TYPE_MAX); 677 table, arraysize(table), PROVIDER_TYPE_MAX);
638 return parser.Get(type); 678 return parser.Get(type);
639 } 679 }
640 680
641 } // namespace chromeos 681 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698