| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |