Chromium Code Reviews| Index: chromeos/network/onc/onc_utils.cc |
| diff --git a/chromeos/network/onc/onc_utils.cc b/chromeos/network/onc/onc_utils.cc |
| index 4dbbfba75125a3a84f6de54c9476d982e3ae9920..9ca4c20657472fc434538f5d7735c739d7a808f5 100644 |
| --- a/chromeos/network/onc/onc_utils.cc |
| +++ b/chromeos/network/onc/onc_utils.cc |
| @@ -18,6 +18,7 @@ |
| #include "crypto/encryptor.h" |
| #include "crypto/hmac.h" |
| #include "crypto/symmetric_key.h" |
| +#include "net/cert/pem_tokenizer.h" |
| #define ONC_LOG_WARNING(message) NET_LOG_WARNING("ONC", message) |
| #define ONC_LOG_ERROR(message) NET_LOG_ERROR("ONC", message) |
| @@ -179,14 +180,14 @@ void ExpandField(const std::string fieldname, |
| std::string login_id; |
| if (substitution.GetSubstitute(substitutes::kLoginIDField, &login_id)) { |
| ReplaceSubstringsAfterOffset(&user_string, 0, |
| - onc::substitutes::kLoginIDField, |
| + substitutes::kLoginIDField, |
| login_id); |
| } |
| std::string email; |
| if (substitution.GetSubstitute(substitutes::kEmailField, &email)) { |
| ReplaceSubstringsAfterOffset(&user_string, 0, |
| - onc::substitutes::kEmailField, |
| + substitutes::kEmailField, |
| email); |
| } |
| @@ -224,10 +225,10 @@ void ExpandStringsInOncObject( |
| namespace { |
| -class OncMaskValues : public onc::Mapper { |
| +class OncMaskValues : public Mapper { |
| public: |
| static scoped_ptr<base::DictionaryValue> Mask( |
| - const onc::OncValueSignature& signature, |
| + const OncValueSignature& signature, |
| const base::DictionaryValue& onc_object, |
| const std::string& mask) { |
| OncMaskValues masker(mask); |
| @@ -242,15 +243,15 @@ class OncMaskValues : public onc::Mapper { |
| virtual scoped_ptr<base::Value> MapField( |
| const std::string& field_name, |
| - const onc::OncValueSignature& object_signature, |
| + const OncValueSignature& object_signature, |
| const base::Value& onc_value, |
| bool* found_unknown_field, |
| bool* error) OVERRIDE { |
| - if (onc::FieldIsCredential(object_signature, field_name)) { |
| + if (FieldIsCredential(object_signature, field_name)) { |
| return scoped_ptr<base::Value>(new base::StringValue(mask_)); |
| } else { |
| - return onc::Mapper::MapField(field_name, object_signature, onc_value, |
| - found_unknown_field, error); |
| + return Mapper::MapField(field_name, object_signature, onc_value, |
| + found_unknown_field, error); |
| } |
| } |
| @@ -261,92 +262,129 @@ class OncMaskValues : public onc::Mapper { |
| } // namespace |
| scoped_ptr<base::DictionaryValue> MaskCredentialsInOncObject( |
| - const onc::OncValueSignature& signature, |
| + const OncValueSignature& signature, |
| const base::DictionaryValue& onc_object, |
| const std::string& mask) { |
| return OncMaskValues::Mask(signature, onc_object, mask); |
| } |
| -bool ParseAndValidateOncForImport( |
| - const std::string& onc_blob, |
| - chromeos::onc::ONCSource onc_source, |
| - const std::string& passphrase, |
| - base::ListValue* network_configs, |
| - base::ListValue* certificates) { |
| +bool ParseAndValidateOncForImport(const std::string& onc_blob, |
| + ONCSource onc_source, |
| + const std::string& passphrase, |
| + base::ListValue* network_configs, |
| + base::ListValue* certificates) { |
| certificates->Clear(); |
| network_configs->Clear(); |
| if (onc_blob.empty()) |
| return true; |
| scoped_ptr<base::DictionaryValue> toplevel_onc = |
| - onc::ReadDictionaryFromJson(onc_blob); |
| + ReadDictionaryFromJson(onc_blob); |
| if (toplevel_onc.get() == NULL) { |
| - LOG(ERROR) << "ONC loaded from " << onc::GetSourceAsString(onc_source) |
| + LOG(ERROR) << "ONC loaded from " << GetSourceAsString(onc_source) |
| << " is not a valid JSON dictionary."; |
| return false; |
| } |
| // Check and see if this is an encrypted ONC file. If so, decrypt it. |
| std::string onc_type; |
| - toplevel_onc->GetStringWithoutPathExpansion(onc::toplevel_config::kType, |
| + toplevel_onc->GetStringWithoutPathExpansion(toplevel_config::kType, |
| &onc_type); |
| - if (onc_type == onc::toplevel_config::kEncryptedConfiguration) { |
| - toplevel_onc = onc::Decrypt(passphrase, *toplevel_onc); |
| + if (onc_type == toplevel_config::kEncryptedConfiguration) { |
| + toplevel_onc = Decrypt(passphrase, *toplevel_onc); |
| if (toplevel_onc.get() == NULL) { |
| LOG(ERROR) << "Couldn't decrypt the ONC from " |
| - << onc::GetSourceAsString(onc_source); |
| + << GetSourceAsString(onc_source); |
| return false; |
| } |
| } |
| - bool from_policy = (onc_source == onc::ONC_SOURCE_USER_POLICY || |
| - onc_source == onc::ONC_SOURCE_DEVICE_POLICY); |
| + bool from_policy = (onc_source == ONC_SOURCE_USER_POLICY || |
| + onc_source == ONC_SOURCE_DEVICE_POLICY); |
| // Validate the ONC dictionary. We are liberal and ignore unknown field |
| // names and ignore invalid field names in kRecommended arrays. |
| - onc::Validator validator(false, // Ignore unknown fields. |
| - false, // Ignore invalid recommended field names. |
| - true, // Fail on missing fields. |
| - from_policy); |
| + Validator validator(false, // Ignore unknown fields. |
| + false, // Ignore invalid recommended field names. |
| + true, // Fail on missing fields. |
| + from_policy); |
| validator.SetOncSource(onc_source); |
| - onc::Validator::Result validation_result; |
| + Validator::Result validation_result; |
| toplevel_onc = validator.ValidateAndRepairObject( |
| - &onc::kToplevelConfigurationSignature, |
| + &kToplevelConfigurationSignature, |
| *toplevel_onc, |
| &validation_result); |
| if (from_policy) { |
| UMA_HISTOGRAM_BOOLEAN("Enterprise.ONC.PolicyValidation", |
| - validation_result == onc::Validator::VALID); |
| + validation_result == Validator::VALID); |
| } |
| bool success = true; |
| - if (validation_result == onc::Validator::VALID_WITH_WARNINGS) { |
| - LOG(WARNING) << "ONC from " << onc::GetSourceAsString(onc_source) |
| + if (validation_result == Validator::VALID_WITH_WARNINGS) { |
| + LOG(WARNING) << "ONC from " << GetSourceAsString(onc_source) |
| << " produced warnings."; |
| success = false; |
| - } else if (validation_result == onc::Validator::INVALID || |
| - toplevel_onc == NULL) { |
| - LOG(ERROR) << "ONC from " << onc::GetSourceAsString(onc_source) |
| + } else if (validation_result == Validator::INVALID || toplevel_onc == NULL) { |
| + LOG(ERROR) << "ONC from " << GetSourceAsString(onc_source) |
| << " is invalid and couldn't be repaired."; |
| return false; |
| } |
| base::ListValue* validated_certs = NULL; |
| - if (toplevel_onc->GetListWithoutPathExpansion( |
| - onc::toplevel_config::kCertificates, &validated_certs)) { |
| + if (toplevel_onc->GetListWithoutPathExpansion(toplevel_config::kCertificates, |
| + &validated_certs)) { |
| certificates->Swap(validated_certs); |
| } |
| base::ListValue* validated_networks = NULL; |
| if (toplevel_onc->GetListWithoutPathExpansion( |
| - onc::toplevel_config::kNetworkConfigurations, &validated_networks)) { |
| + toplevel_config::kNetworkConfigurations, &validated_networks)) { |
| network_configs->Swap(validated_networks); |
| } |
| return success; |
| } |
| +namespace { |
|
Mattias Nissler (ping if slow)
2013/06/20 16:15:36
By convention, this should be at the top of the fi
pneubeck (no reviews)
2013/06/21 11:28:00
Done.
|
| + |
| +// The PEM block header used for DER certificates |
| +const char kCertificateHeader[] = "CERTIFICATE"; |
| +// This is an older PEM marker for DER certificates. |
| +const char kX509CertificateHeader[] = "X509 CERTIFICATE"; |
| + |
| +} // namespace |
| + |
| +scoped_refptr<net::X509Certificate> GetCertFromPEMEncoding( |
| + const std::string& pem_encoded, |
| + const std::string& nickname) { |
| + std::vector<std::string> pem_headers; |
| + pem_headers.push_back(kCertificateHeader); |
| + pem_headers.push_back(kX509CertificateHeader); |
| + |
| + net::PEMTokenizer pem_tokenizer(pem_encoded, pem_headers); |
| + std::string decoded; |
| + if (pem_tokenizer.GetNext()) { |
| + decoded = pem_tokenizer.data(); |
| + } else { |
| + // If we failed to read the data as a PEM file, then try plain base64 decode |
| + // in case the PEM marker strings are missing. For this to work, there has |
| + // to be no white space, and it has to only contain the base64-encoded data. |
| + if (!base::Base64Decode(pem_encoded, &decoded)) { |
| + LOG(ERROR) << "Unable to base64 decode X509 data: " << pem_encoded; |
| + return scoped_refptr<net::X509Certificate>(); |
| + } |
| + } |
| + |
| + scoped_refptr<net::X509Certificate> cert = |
| + net::X509Certificate::CreateFromBytesWithNickname(decoded.data(), |
| + decoded.size(), |
| + nickname.c_str()); |
| + LOG_IF(ERROR, !cert) << "Couldn't create certificate from X509 data: " |
| + << decoded; |
| + return cert; |
| +} |
| + |
| } // namespace onc |
| } // namespace chromeos |