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

Side by Side Diff: chromeos/network/onc/onc_utils.cc

Issue 16946002: Resolve certificate references in ONC by PEM. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: removed automation part. Created 7 years, 6 months 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chromeos/network/onc/onc_utils.h" 5 #include "chromeos/network/onc/onc_utils.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
12 #include "base/values.h" 13 #include "base/values.h"
13 #include "chromeos/network/network_event_log.h" 14 #include "chromeos/network/network_event_log.h"
14 #include "chromeos/network/onc/onc_mapper.h" 15 #include "chromeos/network/onc/onc_mapper.h"
15 #include "chromeos/network/onc/onc_normalizer.h" 16 #include "chromeos/network/onc/onc_normalizer.h"
16 #include "chromeos/network/onc/onc_signature.h" 17 #include "chromeos/network/onc/onc_signature.h"
17 #include "chromeos/network/onc/onc_utils.h" 18 #include "chromeos/network/onc/onc_utils.h"
18 #include "chromeos/network/onc/onc_validator.h" 19 #include "chromeos/network/onc/onc_validator.h"
19 #include "crypto/encryptor.h" 20 #include "crypto/encryptor.h"
20 #include "crypto/hmac.h" 21 #include "crypto/hmac.h"
21 #include "crypto/symmetric_key.h" 22 #include "crypto/symmetric_key.h"
23 #include "net/base/hash_value.h"
22 24
23 #define ONC_LOG_WARNING(message) NET_LOG_WARNING("ONC", message) 25 #define ONC_LOG_WARNING(message) NET_LOG_WARNING("ONC", message)
24 #define ONC_LOG_ERROR(message) NET_LOG_ERROR("ONC", message) 26 #define ONC_LOG_ERROR(message) NET_LOG_ERROR("ONC", message)
25 27
26 namespace chromeos { 28 namespace chromeos {
27 namespace onc { 29 namespace onc {
28 30
29 namespace { 31 namespace {
30 32
31 const char kUnableToDecrypt[] = "Unable to decrypt encrypted ONC"; 33 const char kUnableToDecrypt[] = "Unable to decrypt encrypted ONC";
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 349
348 base::ListValue* validated_networks = NULL; 350 base::ListValue* validated_networks = NULL;
349 if (toplevel_onc->GetListWithoutPathExpansion( 351 if (toplevel_onc->GetListWithoutPathExpansion(
350 toplevel_config::kNetworkConfigurations, &validated_networks)) { 352 toplevel_config::kNetworkConfigurations, &validated_networks)) {
351 network_configs->Swap(validated_networks); 353 network_configs->Swap(validated_networks);
352 } 354 }
353 355
354 return success; 356 return success;
355 } 357 }
356 358
359 std::string GetHexFingerprintOfCert(const net::X509Certificate& cert) {
360 net::SHA1HashValue fingerprint = cert.fingerprint();
361 return base::HexEncode(fingerprint.data, sizeof(fingerprint.data));
362 }
363
364 net::X509Certificate* FindCertByFingerprint(
365 const net::CertificateList& cert_list, const std::string& fingerprint) {
366 net::X509Certificate* found = NULL;
367 for (net::CertificateList::const_iterator it = cert_list.begin();
368 it != cert_list.end(); ++it) {
369 if (GetHexFingerprintOfCert(**it) != fingerprint)
370 continue;
371 if (found != NULL) {
372 LOG(ERROR) << "Certificate fingerprints collided.";
373 return NULL;
374 }
375 found = it->get();
376 }
377 return found;
378 }
379
380 std::string GetPEMEncodedCertFromFingerprint(
381 const net::CertificateList& cert_list,
382 const std::string& fingerprint) {
383 net::X509Certificate* cert = FindCertByFingerprint(cert_list, fingerprint);
384 if (!cert) {
385 LOG(ERROR) << "Couldn't find a certificate with fingerprint "
386 << fingerprint;
387 return std::string();
388 }
389
390 std::string pem_encoded_cert;
391 if (!cert->GetPEMEncoded(&pem_encoded_cert)) {
392 LOG(ERROR) << "Couldn't PEM-encode certificate with fingerprint "
393 << fingerprint;
394 return std::string();
395 }
396
397 return pem_encoded_cert;
398 }
399
400 namespace {
401
402 bool ResolveCertRef(
403 const std::map<std::string,
404 scoped_refptr<net::X509Certificate> >& certs_by_guid,
405 const std::string& key_guid_ref,
406 const std::string& key_fingerprint,
407 base::DictionaryValue* dict) {
408 std::string guid_ref;
409 if (!dict->GetStringWithoutPathExpansion(key_guid_ref, &guid_ref))
410 return true;
411 std::map<std::string, scoped_refptr<net::X509Certificate> >::const_iterator
412 it = certs_by_guid.find(guid_ref);
413 if (it == certs_by_guid.end()) {
414 LOG(ERROR) << "Couldn't resolve certificate reference " << guid_ref;
415 return false;
416 }
417
418 dict->SetStringWithoutPathExpansion(
419 key_fingerprint,
420 GetHexFingerprintOfCert(*it->second));
421 return true;
422 }
423
424 bool ResolveServerCertRefsInObject(
425 const std::map<std::string,
426 scoped_refptr<net::X509Certificate> >& certs_by_guid,
427 const OncValueSignature& signature,
428 base::DictionaryValue* onc_object) {
429 if (&signature == &kEAPSignature) {
430 if (!ResolveCertRef(certs_by_guid, eap::kServerCARef,
431 eap::kServerCAFingerprint, onc_object)) {
432 return false;
433 }
434 } else if (&signature == &kL2TPSignature ||
435 &signature == &kOpenVPNSignature) {
436 if (!ResolveCertRef(certs_by_guid, vpn::kServerCARef,
437 vpn::kServerCAFingerprint, onc_object) ||
438 !ResolveCertRef(certs_by_guid, vpn::kServerCertRef,
439 vpn::kServerCertFingerprint, onc_object)) {
440 return false;;
441 }
442 }
443
444 // Recurse into nested objects.
445 for (base::DictionaryValue::Iterator it(*onc_object); !it.IsAtEnd();
446 it.Advance()) {
447 base::DictionaryValue* inner_object = NULL;
448 if (!onc_object->GetDictionaryWithoutPathExpansion(it.key(), &inner_object))
449 continue;
450
451 const OncFieldSignature* field_signature =
452 GetFieldSignature(signature, it.key());
453 if (!field_signature)
454 continue;
455
456 if (!ResolveServerCertRefsInObject(certs_by_guid,
457 *field_signature->value_signature,
458 inner_object)) {
459 return false;
460 }
461 }
462 return true;
463 }
464
465 } // namespace
466
467 bool ResolveServerCertRefsInNetworks(
468 const std::map<std::string,
469 scoped_refptr<net::X509Certificate> >& certs_by_guid,
470 base::ListValue* network_configs) {
471 bool success = true;
472 for (base::ListValue::iterator it = network_configs->begin();
473 it != network_configs->end(); ) {
474 base::DictionaryValue* network = NULL;
475 (*it)->GetAsDictionary(&network);
476 if (!ResolveServerCertRefsInNetwork(certs_by_guid, network)) {
477 std::string guid;
478 network->GetStringWithoutPathExpansion(network_config::kGUID, &guid);
479 // This might happen even with correct validation, if the referenced
480 // certificate couldn't be imported.
481 LOG(ERROR) << "Couldn't resolve some certificate reference of network "
482 << guid;
483 it = network_configs->Erase(it, NULL);
484 success = false;
485 continue;
486 }
487 ++it;
488 }
489 return success;
490 }
491
492 bool ResolveServerCertRefsInNetwork(
493 const std::map<std::string,
494 scoped_refptr<net::X509Certificate> >& certs_by_guid,
495 base::DictionaryValue* network_config) {
496 return ResolveServerCertRefsInObject(certs_by_guid,
497 kNetworkConfigurationSignature,
498 network_config);
499 }
500
357 } // namespace onc 501 } // namespace onc
358 } // namespace chromeos 502 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698