diff options
author | gspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-11 23:17:14 +0000 |
---|---|---|
committer | gspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-11 23:17:14 +0000 |
commit | 2c9f0def901b383bb003c4d10c198cabec1277f6 (patch) | |
tree | b151b0f99cf928e3aaf4eeddf39a98bf301313db | |
parent | 98a4a4fedccd40287db03233947f48c02906b74d (diff) | |
download | chromium_src-2c9f0def901b383bb003c4d10c198cabec1277f6.zip chromium_src-2c9f0def901b383bb003c4d10c198cabec1277f6.tar.gz chromium_src-2c9f0def901b383bb003c4d10c198cabec1277f6.tar.bz2 |
This adds support for encrypted ONC import to Chrome.
We now can import standalone ONC files that are encrypted by the
Spigots management app.
TBR=joaodasilva@chromium.org
BUG=chromium-os:19397
TEST=Ran new unit tests, imported encrypted ONC on device.
Review URL: http://codereview.chromium.org/8949056
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117321 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 15 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros/network_library.cc | 7 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros/onc_network_parser.cc | 132 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros/onc_network_parser.h | 4 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros/onc_network_parser_unittest.cc | 73 | ||||
-rw-r--r-- | chrome/browser/policy/configuration_policy_handler_chromeos.cc | 5 | ||||
-rw-r--r-- | crypto/hmac.cc | 12 | ||||
-rw-r--r-- | crypto/hmac.h | 7 |
8 files changed, 228 insertions, 27 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 482ab4a..ed480bd 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -11777,6 +11777,21 @@ Some features may be unavailable. Please check that the profile exists and you <message name="IDS_NETWORK_CONFIG_ERROR_CERT_IMPORT" desc="Error for network configuration: Certificate import error."> Certificate import error </message> + <message name="IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_MALFORMED" desc="Displayed when importing an encrypted ONC file and the ONC file is malformed."> + Encrypted ONC file is malformed. + </message> + <message name="IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNSUPPORTED_ENCRYPTION" desc="Displayed when importing an encrypted ONC file and the ONC file uses an encryption protocol that is not supported."> + Encrypted ONC file uses an unsupported encryption scheme. + </message> + <message name="IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNABLE_TO_DECODE" desc="Displayed when importing an encrypted ONC file and the encryption parameters are not able to be parsed."> + Unable to parse some parameters in the encrypted ONC file. + </message> + <message name="IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNABLE_TO_DECRYPT" desc="Displayed when importing an encrypted ONC file and it is not able to be decrypted."> + Unable to decrypt the encrypted ONC file. + </message> + <message name="IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_TOO_MANY_ITERATIONS" desc="Displayed when importing an encrypted ONC file and the iteration count is too large."> + Passphrase iteration count is too large. + </message> <message name="IDS_NETWORK_PURCHASE_MORE_MESSAGE" desc="Message for purchase more link on notification when there is no cellular plan"> Buy plan... </message> diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc index a1e4052..2fbff69 100644 --- a/chrome/browser/chromeos/cros/network_library.cc +++ b/chrome/browser/chromeos/cros/network_library.cc @@ -1773,7 +1773,7 @@ class NetworkLibraryImplBase : public NetworkLibrary { // virtual SetIPConfig implemented in derived classes. virtual void SwitchToPreferredNetwork() OVERRIDE; virtual bool LoadOncNetworks(const std::string& onc_blob, - const std::string& passcode, + const std::string& passphrase, NetworkUIData::ONCSource source, std::string* error) OVERRIDE; virtual bool SetActiveNetwork(ConnectionType type, @@ -2891,11 +2891,10 @@ void NetworkLibraryImplBase::SwitchToPreferredNetwork() { } bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, - const std::string& passcode, + const std::string& passphrase, NetworkUIData::ONCSource source, std::string* error) { - // TODO(gspencer): Add support for decrypting onc files. crbug.com/19397 - OncNetworkParser parser(onc_blob, source); + OncNetworkParser parser(onc_blob, passphrase, source); if (!parser.parse_error().empty()) { if (error) diff --git a/chrome/browser/chromeos/cros/onc_network_parser.cc b/chrome/browser/chromeos/cros/onc_network_parser.cc index 7b4c224..6a0f577 100644 --- a/chrome/browser/chromeos/cros/onc_network_parser.cc +++ b/chrome/browser/chromeos/cros/onc_network_parser.cc @@ -17,6 +17,10 @@ #include "chrome/browser/chromeos/cros/network_library.h" #include "chrome/browser/chromeos/cros/onc_constants.h" #include "chrome/common/net/x509_certificate_model.h" +#include "crypto/encryptor.h" +#include "crypto/hmac.h" +#include "crypto/scoped_nss_types.h" +#include "crypto/symmetric_key.h" #include "grit/generated_resources.h" #include "net/base/cert_database.h" #include "net/base/crypto_module.h" @@ -199,6 +203,7 @@ std::string ConvertValueToString(const base::Value& value) { // -------------------- OncNetworkParser -------------------- OncNetworkParser::OncNetworkParser(const std::string& onc_blob, + const std::string& passphrase, NetworkUIData::ONCSource onc_source) : NetworkParser(get_onc_mapper()), onc_source_(onc_source), @@ -213,15 +218,25 @@ OncNetworkParser::OncNetworkParser(const std::string& onc_blob, LOG(WARNING) << "OncNetworkParser received bad ONC file: " << parse_error_; } else { root_dict_.reset(static_cast<DictionaryValue*>(root.release())); + + // Check and see if this is an encrypted ONC file. If so, decrypt it. + std::string ciphertext_test; + if (root_dict_->GetString("Ciphertext", &ciphertext_test)) + root_dict_.reset(Decrypt(passphrase, root_dict_.get())); + + // Decryption failed, errors will be in parse_error_; + if (!root_dict_.get()) + return; + // At least one of NetworkConfigurations or Certificates is required. bool has_network_configurations = - root_dict_->GetList("NetworkConfigurations", &network_configs_); + root_dict_->GetList("NetworkConfigurations", &network_configs_); bool has_certificates = - root_dict_->GetList("Certificates", &certificates_); + root_dict_->GetList("Certificates", &certificates_); VLOG(2) << "ONC file has " << GetNetworkConfigsSize() << " networks and " << GetCertificatesSize() << " certificates"; LOG_IF(WARNING, (!has_network_configurations && !has_certificates)) - << "ONC file has no NetworkConfigurations or Certificates."; + << "ONC file has no NetworkConfigurations or Certificates."; } } @@ -239,6 +254,117 @@ const EnumMapper<PropertyIndex>* OncNetworkParser::property_mapper() { return get_onc_mapper(); } +base::DictionaryValue* OncNetworkParser::Decrypt( + const std::string& passphrase, + base::DictionaryValue* root) { + const int kKeySizeInBits = 256; + const int kMaxIterationCount = 500000; + std::string onc_type; + std::string initial_vector; + std::string salt; + std::string cipher; + std::string stretch_method; + std::string hmac_method; + std::string hmac; + int iterations; + std::string ciphertext; + + if (!root->GetString("Ciphertext", &ciphertext) || + !root->GetString("Cipher", &cipher) || + !root->GetString("HMAC", &hmac) || + !root->GetString("HMACMethod", &hmac_method) || + !root->GetString("IV", &initial_vector) || + !root->GetInteger("Iterations", &iterations) || + !root->GetString("Salt", &salt) || + !root->GetString("Stretch", &stretch_method) || + !root->GetString("Type", &onc_type) || + onc_type != "EncryptedConfiguration") { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_MALFORMED); + return NULL; + } + + if (hmac_method != "SHA1" || + cipher != "AES256" || + stretch_method != "PBKDF2") { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNSUPPORTED_ENCRYPTION); + return NULL; + } + + // Simply a sanity check to make sure we can't lock up the machine + // for too long with a huge number. + if (iterations > kMaxIterationCount) { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_TOO_MANY_ITERATIONS); + return NULL; + } + + if (!base::Base64Decode(salt, &salt)) { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNABLE_TO_DECODE); + return NULL; + } + + scoped_ptr<crypto::SymmetricKey> key( + crypto::SymmetricKey::DeriveKeyFromPassword(crypto::SymmetricKey::AES, + passphrase, + salt, + iterations, + kKeySizeInBits)); + + if (!base::Base64Decode(initial_vector, &initial_vector)) { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNABLE_TO_DECODE); + return NULL; + } + if (!base::Base64Decode(ciphertext, &ciphertext)) { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNABLE_TO_DECODE); + return NULL; + } + if (!base::Base64Decode(hmac, &hmac)) { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNABLE_TO_DECODE); + return NULL; + } + + crypto::HMAC hmac_verifier(crypto::HMAC::SHA1); + if (!hmac_verifier.Init(key.get()) || + !hmac_verifier.Verify(ciphertext, hmac)) { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNABLE_TO_DECRYPT); + return NULL; + } + + crypto::Encryptor decryptor; + if (!decryptor.Init(key.get(), crypto::Encryptor::CBC, initial_vector)) { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNABLE_TO_DECRYPT); + return NULL; + } + + std::string plaintext; + if (!decryptor.Decrypt(ciphertext, &plaintext)) { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_ENCRYPTED_ONC_UNABLE_TO_DECRYPT); + return NULL; + } + + // Now we've decrypted it, let's deserialize the decrypted data. + JSONStringValueSerializer deserializer(plaintext); + deserializer.set_allow_trailing_comma(true); + scoped_ptr<base::Value> new_root(deserializer.Deserialize(NULL, + &parse_error_)); + if (!new_root.get() || !new_root->IsType(base::Value::TYPE_DICTIONARY)) { + if (parse_error_.empty()) + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); + return NULL; + } + return static_cast<base::DictionaryValue*>(new_root.release()); +} + int OncNetworkParser::GetNetworkConfigsSize() const { return network_configs_ ? network_configs_->GetSize() : 0; } diff --git a/chrome/browser/chromeos/cros/onc_network_parser.h b/chrome/browser/chromeos/cros/onc_network_parser.h index af55c27..1e9cc30 100644 --- a/chrome/browser/chromeos/cros/onc_network_parser.h +++ b/chrome/browser/chromeos/cros/onc_network_parser.h @@ -53,6 +53,7 @@ class OncNetworkParser : public NetworkParser { Network*); OncNetworkParser(const std::string& onc_blob, + const std::string& passphrase, NetworkUIData::ONCSource onc_source); virtual ~OncNetworkParser(); static const EnumMapper<PropertyIndex>* property_mapper(); @@ -147,6 +148,9 @@ class OncNetworkParser : public NetworkParser { const std::string& guid, base::DictionaryValue* certificate); + base::DictionaryValue* Decrypt(const std::string& passphrase, + base::DictionaryValue* root); + // Error message from the JSON parser, if applicable. std::string parse_error_; diff --git a/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc b/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc index fb63bb4..696bbc3 100644 --- a/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc +++ b/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc @@ -469,7 +469,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkWifi1) { " }" " }]" "}"); - OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); + OncNetworkParser parser(test_blob, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetNetworkConfigsSize()); EXPECT_EQ(0, parser.GetCertificatesSize()); @@ -487,6 +487,46 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkWifi1) { CheckStringProperty(wifi, PROPERTY_INDEX_PASSPHRASE, "pass"); } +TEST_F(OncNetworkParserTest, TestLoadEncryptedOnc) { + std::string test_blob( + "{" + " \"Cipher\": \"AES256\"," + " \"Ciphertext\": \"eQ9/r6v29/83M745aa0JllEj4lklt3Nfy4kPPvXgjBt1eTBy" + "xXB+FnsdvL6Uca5JBU5aROxfiol2+ZZOkxPmUNNIFZj70pkdqOGVe09ncf0aVBDsAa27" + "veGIG8rG/VQTTbAo7d8QaxdNNbZvwQVkdsAXawzPCu7zSh4NF/hDnDbYjbN/JEm1NzvW" + "gEjeOfqnnw3PnGUYCArIaRsKq9uD0a1NccU+16ZSzyDhX724JNrJjsuxohotk5YXsCK0" + "lP7ZXuXj+nSR0aRIETSQ+eqGhrew2octLXq8cXK05s6ZuVAc0mFKPkntSI/fzBACuPi4" + "ZaGd3YEYiKzNOgKJ+qEwgoE39xp0EXMZOZyjMOAtA6e1ZZDQGWG7vKdTLmLKNztHGrXv" + "lZkyEf1RDs10YgkwwLgUhm0yBJ+eqbxO/RiBXz7O2/UVOkkkVcmeI6yh3BdL6HIYsMMy" + "gnZa5WRkd/2/EudoqEnjcqUyGsL+YUqV6KRTC0PH+z7zSwvFs2KygrSM7SIAZM2yiQHT" + "QACkA/YCJDwACkkQOBFnRWTWiX0xmN55WMbgrs/wqJ4zGC9LgdAInOBlc3P+76+i7QLa" + "NjMovQ==\"," + " \"HMAC\": \"3ylRy5InlhVzFGakJ/9lvGSyVH0=\"," + " \"HMACMethod\": \"SHA1\"," + " \"IV\": \"hcm6OENfqG6C/TVO6p5a8g==\"," + " \"Iterations\": 20000," + " \"Salt\": \"/3O73QadCzA=\"," + " \"Stretch\": \"PBKDF2\"," + " \"Type\": \"EncryptedConfiguration\"" + "}"); + OncNetworkParser parser(test_blob, + "test0000", + NetworkUIData::ONC_SOURCE_USER_IMPORT); + ASSERT_TRUE(parser.parse_error().empty()); + EXPECT_EQ(1, parser.GetNetworkConfigsSize()); + EXPECT_EQ(0, parser.GetCertificatesSize()); + scoped_ptr<Network> network(parser.ParseNetwork(0)); + ASSERT_TRUE(network.get()); + + EXPECT_EQ(network->type(), chromeos::TYPE_WIFI); + WifiNetwork* wifi = static_cast<WifiNetwork*>(network.get()); + EXPECT_EQ(wifi->encryption(), chromeos::SECURITY_NONE); + EXPECT_EQ(wifi->name(), "WirelessNetwork"); + EXPECT_EQ(wifi->auto_connect(), false); + EXPECT_EQ(wifi->passphrase(), ""); +} + + TEST_F(OncNetworkParserTest, TestCreateNetworkWifiEAP1) { std::string test_blob( "{" @@ -504,7 +544,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkWifiEAP1) { " }" " }]" "}"); - OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); + OncNetworkParser parser(test_blob, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetNetworkConfigsSize()); EXPECT_EQ(0, parser.GetCertificatesSize()); @@ -543,7 +583,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkWifiEAP2) { " }" " }]" "}"); - OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); + OncNetworkParser parser(test_blob, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetNetworkConfigsSize()); EXPECT_EQ(0, parser.GetCertificatesSize()); @@ -582,7 +622,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkUnknownFields) { " }," " }]" "}"); - OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); + OncNetworkParser parser(test_blob, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); scoped_ptr<Network> network(parser.ParseNetwork(0)); ASSERT_TRUE(network.get()); @@ -599,7 +639,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkOpenVPN) { " \"NetworkConfigurations\": [") + std::string(kNetworkConfigurationOpenVPN) + std::string( " ]}")); - OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); + OncNetworkParser parser(test_blob, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetNetworkConfigsSize()); EXPECT_EQ(0, parser.GetCertificatesSize()); @@ -678,7 +718,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkL2TPIPsec) { " ]," " \"Certificates\": []" "}"); - OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); + OncNetworkParser parser(test_blob, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetNetworkConfigsSize()); EXPECT_EQ(0, parser.GetCertificatesSize()); @@ -709,7 +749,7 @@ TEST_F(OncNetworkParserTest, TestAddClientCertificate) { " ]," "}"); std::string test_guid("{f998f760-272b-6939-4c2beffe428697ac}"); - OncNetworkParser parser(certificate_json, + OncNetworkParser parser(certificate_json, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); @@ -774,7 +814,7 @@ TEST_F(OncNetworkParserTest, TestReplaceClientCertificate) { std::string test_guid("{f998f760-272b-6939-4c2beffe428697ac}"); { // First we import a certificate. - OncNetworkParser parser(certificate_json, + OncNetworkParser parser(certificate_json, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); @@ -793,7 +833,7 @@ TEST_F(OncNetworkParserTest, TestReplaceClientCertificate) { { // Now we import a new certificate with the same GUID as the // first. It should replace the old one. - OncNetworkParser parser(certificate_alternate_json, + OncNetworkParser parser(certificate_alternate_json, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); scoped_refptr<net::X509Certificate> cert = parser.ParseCertificate(0).get(); @@ -815,7 +855,7 @@ TEST_F(OncNetworkParserTest, TestAddServerCertificate) { " ]," "}"); std::string test_guid("{f998f760-272b-6939-4c2beffe428697aa}"); - OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); + OncNetworkParser parser(test_blob, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); scoped_refptr<net::X509Certificate> cert = parser.ParseCertificate(0).get(); @@ -856,7 +896,7 @@ TEST_F(OncNetworkParserTest, TestReplaceServerCertificate) { std::string test_guid("{f998f760-272b-6939-4c2beffe428697aa}"); { // First we import a certificate. - OncNetworkParser parser(certificate_json, + OncNetworkParser parser(certificate_json, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); @@ -875,7 +915,7 @@ TEST_F(OncNetworkParserTest, TestReplaceServerCertificate) { { // Now we import a new certificate with the same GUID as the // first. It should replace the old one. - OncNetworkParser parser(certificate_alternate_json, + OncNetworkParser parser(certificate_alternate_json, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); scoped_refptr<net::X509Certificate> cert = parser.ParseCertificate(0).get(); @@ -898,7 +938,7 @@ TEST_F(OncNetworkParserTest, TestAddAuthorityCertificate) { " ]," "}"); std::string test_guid("{f998f760-272b-6939-4c2beffe428697ab}"); - OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); + OncNetworkParser parser(test_blob, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); scoped_refptr<net::X509Certificate> cert = parser.ParseCertificate(0).get(); @@ -938,7 +978,7 @@ TEST_F(OncNetworkParserTest, TestReplaceAuthorityCertificate) { { // First we import an authority certificate. - OncNetworkParser parser(authority_json, + OncNetworkParser parser(authority_json, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); @@ -957,7 +997,7 @@ TEST_F(OncNetworkParserTest, TestReplaceAuthorityCertificate) { { // Now we import a new authority certificate with the same GUID as the // first. It should replace the old one. - OncNetworkParser parser(authority_alternate_json, + OncNetworkParser parser(authority_alternate_json, "", NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); scoped_refptr<net::X509Certificate> cert = parser.ParseCertificate(0).get(); @@ -982,7 +1022,8 @@ TEST_F(OncNetworkParserTest, TestNetworkAndCertificate) { std::string(kCertificateWebAuthority) + " ]," "}"); - OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); + OncNetworkParser parser(test_blob, "", + NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetCertificatesSize()); EXPECT_TRUE(parser.ParseCertificate(0)); diff --git a/chrome/browser/policy/configuration_policy_handler_chromeos.cc b/chrome/browser/policy/configuration_policy_handler_chromeos.cc index 8c0f1d8..ac74293b 100644 --- a/chrome/browser/policy/configuration_policy_handler_chromeos.cc +++ b/chrome/browser/policy/configuration_policy_handler_chromeos.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -35,7 +35,8 @@ bool NetworkConfigurationPolicyHandler::CheckPolicySettings( if (value) { std::string onc_blob; value->GetAsString(&onc_blob); - chromeos::OncNetworkParser parser(onc_blob, onc_source_); + // Policy-based ONC blobs cannot have a passphrase. + chromeos::OncNetworkParser parser(onc_blob, "", onc_source_); if (!parser.parse_error().empty()) { errors->AddError(policy_type(), IDS_POLICY_NETWORK_CONFIG_PARSE_ERROR, diff --git a/crypto/hmac.cc b/crypto/hmac.cc index 9131313..7176248 100644 --- a/crypto/hmac.cc +++ b/crypto/hmac.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,9 +8,19 @@ #include "base/logging.h" #include "crypto/secure_util.h" +#include "crypto/symmetric_key.h" namespace crypto { +bool HMAC::Init(SymmetricKey* key) { + std::string raw_key; + bool result = key->GetRawKey(&raw_key) && Init(raw_key); + // Zero out key copy. This might get optimized away, but one can hope. + // Using std::string to store key info at all is a larger problem. + std::fill(raw_key.begin(), raw_key.end(), 0); + return result; +} + size_t HMAC::DigestLength() const { switch (hash_alg_) { case SHA1: diff --git a/crypto/hmac.h b/crypto/hmac.h index b170ce7..2e22a15 100644 --- a/crypto/hmac.h +++ b/crypto/hmac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -19,6 +19,7 @@ namespace crypto { // Simplify the interface and reduce includes by abstracting out the internals. struct HMACPlatformData; +class SymmetricKey; class CRYPTO_EXPORT HMAC { public: @@ -41,6 +42,10 @@ class CRYPTO_EXPORT HMAC { // TODO(abarth): key_length should be a size_t. bool Init(const unsigned char* key, int key_length) WARN_UNUSED_RESULT; + // Initializes this instance using |key|. Call Init + // only once. It returns false on the second or later calls. + bool Init(SymmetricKey* key) WARN_UNUSED_RESULT; + // Initializes this instance using |key|. Call Init only once. It returns // false on the second or later calls. bool Init(const base::StringPiece& key) WARN_UNUSED_RESULT { |