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

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

Powered by Google App Engine
This is Rietveld 408576698