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 |