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

Side by Side Diff: chrome/browser/chromeos/cros/onc_network_parser.cc

Issue 10916094: Move the NSS functions out of CertDatabase into a new NSSCertDatabase class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 8 years, 3 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 "chrome/browser/chromeos/cros/onc_network_parser.h" 5 #include "chrome/browser/chromeos/cros/onc_network_parser.h"
6 6
7 #include <keyhi.h> 7 #include <keyhi.h>
8 #include <pk11pub.h> 8 #include <pk11pub.h>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
(...skipping 10 matching lines...) Expand all
21 #include "chrome/browser/chromeos/cros/onc_constants.h" 21 #include "chrome/browser/chromeos/cros/onc_constants.h"
22 #include "chrome/browser/chromeos/proxy_config_service_impl.h" 22 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
23 #include "chrome/browser/prefs/proxy_config_dictionary.h" 23 #include "chrome/browser/prefs/proxy_config_dictionary.h"
24 #include "chrome/common/net/x509_certificate_model.h" 24 #include "chrome/common/net/x509_certificate_model.h"
25 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
26 #include "crypto/encryptor.h" 26 #include "crypto/encryptor.h"
27 #include "crypto/hmac.h" 27 #include "crypto/hmac.h"
28 #include "crypto/scoped_nss_types.h" 28 #include "crypto/scoped_nss_types.h"
29 #include "crypto/symmetric_key.h" 29 #include "crypto/symmetric_key.h"
30 #include "grit/generated_resources.h" 30 #include "grit/generated_resources.h"
31 #include "net/base/cert_database.h"
32 #include "net/base/crypto_module.h" 31 #include "net/base/crypto_module.h"
33 #include "net/base/net_errors.h" 32 #include "net/base/net_errors.h"
33 #include "net/base/nss_cert_database.h"
34 #include "net/base/pem_tokenizer.h" 34 #include "net/base/pem_tokenizer.h"
35 #include "net/base/x509_certificate.h" 35 #include "net/base/x509_certificate.h"
36 #include "net/proxy/proxy_bypass_rules.h" 36 #include "net/proxy/proxy_bypass_rules.h"
37 #include "third_party/cros_system_api/dbus/service_constants.h" 37 #include "third_party/cros_system_api/dbus/service_constants.h"
38 #include "ui/base/l10n/l10n_util.h" 38 #include "ui/base/l10n/l10n_util.h"
39 39
40 namespace chromeos { 40 namespace chromeos {
41 41
42 // Local constants. 42 // Local constants.
43 namespace { 43 namespace {
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 LOG(WARNING) << "ONC File: certificate missing identifier at index" 519 LOG(WARNING) << "ONC File: certificate missing identifier at index"
520 << cert_index; 520 << cert_index;
521 parse_error_ = l10n_util::GetStringUTF8( 521 parse_error_ = l10n_util::GetStringUTF8(
522 IDS_NETWORK_CONFIG_ERROR_CERT_GUID_MISSING); 522 IDS_NETWORK_CONFIG_ERROR_CERT_GUID_MISSING);
523 return NULL; 523 return NULL;
524 } 524 }
525 525
526 if (!certificate->GetBoolean("Remove", &remove)) 526 if (!certificate->GetBoolean("Remove", &remove))
527 remove = false; 527 remove = false;
528 528
529 net::CertDatabase cert_database;
530 if (remove) { 529 if (remove) {
531 if (!DeleteCertAndKeyByNickname(guid)) { 530 if (!DeleteCertAndKeyByNickname(guid)) {
532 parse_error_ = l10n_util::GetStringUTF8( 531 parse_error_ = l10n_util::GetStringUTF8(
533 IDS_NETWORK_CONFIG_ERROR_CERT_DELETE); 532 IDS_NETWORK_CONFIG_ERROR_CERT_DELETE);
534 } 533 }
535 return NULL; 534 return NULL;
536 } 535 }
537 536
538 // Not removing, so let's get the data we need to add this certificate. 537 // Not removing, so let's get the data we need to add this certificate.
539 std::string cert_type; 538 std::string cert_type;
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 // identical certificate known to NSS, so we can safely import the 922 // identical certificate known to NSS, so we can safely import the
924 // certificate. The GUID being imported may still be on a different 923 // certificate. The GUID being imported may still be on a different
925 // certificate, and we could jump through hoops to reimport the existing 924 // certificate, and we could jump through hoops to reimport the existing
926 // certificate with a different nickname. However, that would mean lots of 925 // certificate with a different nickname. However, that would mean lots of
927 // effort for a case that's pretty much illegal (reusing GUIDs contradicts 926 // effort for a case that's pretty much illegal (reusing GUIDs contradicts
928 // the intention of GUIDs), so we just report an error. 927 // the intention of GUIDs), so we just report an error.
929 // 928 //
930 // TODO(mnissler, gspencer): We should probably switch to a mode where we 929 // TODO(mnissler, gspencer): We should probably switch to a mode where we
931 // keep our own database for mapping GUIDs to certs in order to enable several 930 // keep our own database for mapping GUIDs to certs in order to enable several
932 // GUIDs to map to the same cert. See http://crosbug.com/26073. 931 // GUIDs to map to the same cert. See http://crosbug.com/26073.
933 net::CertDatabase cert_database; 932 net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance();
934 if (x509_cert->os_cert_handle()->isperm) { 933 if (x509_cert->os_cert_handle()->isperm) {
935 if (!cert_database.DeleteCertAndKey(x509_cert.get())) { 934 if (!cert_database->DeleteCertAndKey(x509_cert.get())) {
936 parse_error_ = l10n_util::GetStringUTF8( 935 parse_error_ = l10n_util::GetStringUTF8(
937 IDS_NETWORK_CONFIG_ERROR_CERT_DELETE); 936 IDS_NETWORK_CONFIG_ERROR_CERT_DELETE);
938 return NULL; 937 return NULL;
939 } 938 }
940 939
941 // Reload the cert here to get an actual temporary cert instance. 940 // Reload the cert here to get an actual temporary cert instance.
942 x509_cert = 941 x509_cert =
943 net::X509Certificate::CreateFromBytesWithNickname( 942 net::X509Certificate::CreateFromBytesWithNickname(
944 decoded_x509.data(), 943 decoded_x509.data(),
945 decoded_x509.size(), 944 decoded_x509.size(),
(...skipping 14 matching lines...) Expand all
960 ListCertsWithNickname(guid, &certs); 959 ListCertsWithNickname(guid, &certs);
961 if (!certs.empty()) { 960 if (!certs.empty()) {
962 LOG(WARNING) << "Cert GUID is already in use: " << guid; 961 LOG(WARNING) << "Cert GUID is already in use: " << guid;
963 parse_error_ = l10n_util::GetStringUTF8( 962 parse_error_ = l10n_util::GetStringUTF8(
964 IDS_NETWORK_CONFIG_ERROR_CERT_GUID_COLLISION); 963 IDS_NETWORK_CONFIG_ERROR_CERT_GUID_COLLISION);
965 return NULL; 964 return NULL;
966 } 965 }
967 966
968 net::CertificateList cert_list; 967 net::CertificateList cert_list;
969 cert_list.push_back(x509_cert); 968 cert_list.push_back(x509_cert);
970 net::CertDatabase::ImportCertFailureList failures; 969 net::NSSCertDatabase::ImportCertFailureList failures;
971 bool success = false; 970 bool success = false;
972 net::CertDatabase::TrustBits trust = web_trust ? 971 net::NSSCertDatabase::TrustBits trust = web_trust ?
973 net::CertDatabase::TRUSTED_SSL : 972 net::NSSCertDatabase::TRUSTED_SSL :
974 net::CertDatabase::TRUST_DEFAULT; 973 net::NSSCertDatabase::TRUST_DEFAULT;
975 if (cert_type == "Server") { 974 if (cert_type == "Server") {
976 success = cert_database.ImportServerCert(cert_list, trust, &failures); 975 success = cert_database->ImportServerCert(cert_list, trust, &failures);
977 } else { // Authority cert 976 } else { // Authority cert
978 success = cert_database.ImportCACerts(cert_list, trust, &failures); 977 success = cert_database->ImportCACerts(cert_list, trust, &failures);
979 } 978 }
980 if (!failures.empty()) { 979 if (!failures.empty()) {
981 LOG(WARNING) << "ONC File: Error (" 980 LOG(WARNING) << "ONC File: Error ("
982 << net::ErrorToString(failures[0].net_error) 981 << net::ErrorToString(failures[0].net_error)
983 << ") importing " << cert_type << " certificate at index " 982 << ") importing " << cert_type << " certificate at index "
984 << cert_index; 983 << cert_index;
985 parse_error_ = l10n_util::GetStringUTF8( 984 parse_error_ = l10n_util::GetStringUTF8(
986 IDS_NETWORK_CONFIG_ERROR_CERT_IMPORT); 985 IDS_NETWORK_CONFIG_ERROR_CERT_IMPORT);
987 return NULL; 986 return NULL;
988 } 987 }
989 if (!success) { 988 if (!success) {
990 LOG(WARNING) << "ONC File: Unknown error importing " << cert_type 989 LOG(WARNING) << "ONC File: Unknown error importing " << cert_type
991 << " certificate at index " << cert_index; 990 << " certificate at index " << cert_index;
992 parse_error_ = l10n_util::GetStringUTF8( 991 parse_error_ = l10n_util::GetStringUTF8(
993 IDS_NETWORK_CONFIG_ERROR_UNKNOWN); 992 IDS_NETWORK_CONFIG_ERROR_UNKNOWN);
994 return NULL; 993 return NULL;
995 } 994 }
996 VLOG(2) << "Successfully imported server/ca certificate at index " 995 VLOG(2) << "Successfully imported server/ca certificate at index "
997 << cert_index; 996 << cert_index;
998 997
999 return x509_cert; 998 return x509_cert;
1000 } 999 }
1001 1000
1002 scoped_refptr<net::X509Certificate> OncNetworkParser::ParseClientCertificate( 1001 scoped_refptr<net::X509Certificate> OncNetworkParser::ParseClientCertificate(
1003 int cert_index, 1002 int cert_index,
1004 const std::string& guid, 1003 const std::string& guid,
1005 base::DictionaryValue* certificate) { 1004 base::DictionaryValue* certificate) {
1006 net::CertDatabase cert_database;
1007 std::string pkcs12_data; 1005 std::string pkcs12_data;
1008 if (!certificate->GetString("PKCS12", &pkcs12_data) || 1006 if (!certificate->GetString("PKCS12", &pkcs12_data) ||
1009 pkcs12_data.empty()) { 1007 pkcs12_data.empty()) {
1010 LOG(WARNING) << "ONC File: PKCS12 data is missing for Client " 1008 LOG(WARNING) << "ONC File: PKCS12 data is missing for Client "
1011 << "certificate at index " << cert_index; 1009 << "certificate at index " << cert_index;
1012 parse_error_ = l10n_util::GetStringUTF8( 1010 parse_error_ = l10n_util::GetStringUTF8(
1013 IDS_NETWORK_CONFIG_ERROR_CERT_DATA_MISSING); 1011 IDS_NETWORK_CONFIG_ERROR_CERT_DATA_MISSING);
1014 return NULL; 1012 return NULL;
1015 } 1013 }
1016 1014
1017 std::string decoded_pkcs12; 1015 std::string decoded_pkcs12;
1018 if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) { 1016 if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) {
1019 LOG(WARNING) << "Unable to base64 decode PKCS#12 data: \"" 1017 LOG(WARNING) << "Unable to base64 decode PKCS#12 data: \""
1020 << pkcs12_data << "\"."; 1018 << pkcs12_data << "\".";
1021 parse_error_ = l10n_util::GetStringUTF8( 1019 parse_error_ = l10n_util::GetStringUTF8(
1022 IDS_NETWORK_CONFIG_ERROR_CERT_DATA_MALFORMED); 1020 IDS_NETWORK_CONFIG_ERROR_CERT_DATA_MALFORMED);
1023 return NULL; 1021 return NULL;
1024 } 1022 }
1025 1023
1026 // Since this has a private key, always use the private module. 1024 // Since this has a private key, always use the private module.
1027 scoped_refptr<net::CryptoModule> module(cert_database.GetPrivateModule()); 1025 net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance();
1026 scoped_refptr<net::CryptoModule> module(cert_database->GetPrivateModule());
1028 net::CertificateList imported_certs; 1027 net::CertificateList imported_certs;
1029 1028
1030 int result = cert_database.ImportFromPKCS12( 1029 int result = cert_database->ImportFromPKCS12(
1031 module.get(), decoded_pkcs12, string16(), false, &imported_certs); 1030 module.get(), decoded_pkcs12, string16(), false, &imported_certs);
1032 if (result != net::OK) { 1031 if (result != net::OK) {
1033 LOG(WARNING) << "ONC File: Unable to import Client certificate at index " 1032 LOG(WARNING) << "ONC File: Unable to import Client certificate at index "
1034 << cert_index 1033 << cert_index
1035 << " (error " << net::ErrorToString(result) << ")."; 1034 << " (error " << net::ErrorToString(result) << ").";
1036 parse_error_ = l10n_util::GetStringUTF8( 1035 parse_error_ = l10n_util::GetStringUTF8(
1037 IDS_NETWORK_CONFIG_ERROR_CERT_IMPORT); 1036 IDS_NETWORK_CONFIG_ERROR_CERT_IMPORT);
1038 return NULL; 1037 return NULL;
1039 } 1038 }
1040 1039
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 }; 1080 };
1082 CR_DEFINE_STATIC_LOCAL(EnumMapper<ClientCertType>, parser, 1081 CR_DEFINE_STATIC_LOCAL(EnumMapper<ClientCertType>, parser,
1083 (table, arraysize(table), CLIENT_CERT_TYPE_NONE)); 1082 (table, arraysize(table), CLIENT_CERT_TYPE_NONE));
1084 return parser.Get(type); 1083 return parser.Get(type);
1085 } 1084 }
1086 1085
1087 // static 1086 // static
1088 void OncNetworkParser::ListCertsWithNickname(const std::string& label, 1087 void OncNetworkParser::ListCertsWithNickname(const std::string& label,
1089 net::CertificateList* result) { 1088 net::CertificateList* result) {
1090 net::CertificateList all_certs; 1089 net::CertificateList all_certs;
1091 net::CertDatabase cert_db; 1090 net::NSSCertDatabase::GetInstance()->ListCerts(&all_certs);
1092 cert_db.ListCerts(&all_certs);
1093 result->clear(); 1091 result->clear();
1094 for (net::CertificateList::iterator iter = all_certs.begin(); 1092 for (net::CertificateList::iterator iter = all_certs.begin();
1095 iter != all_certs.end(); ++iter) { 1093 iter != all_certs.end(); ++iter) {
1096 if (iter->get()->os_cert_handle()->nickname) { 1094 if (iter->get()->os_cert_handle()->nickname) {
1097 // Separate the nickname stored in the certificate at the colon, since 1095 // Separate the nickname stored in the certificate at the colon, since
1098 // NSS likes to store it as token:nickname. 1096 // NSS likes to store it as token:nickname.
1099 const char* delimiter = 1097 const char* delimiter =
1100 ::strchr(iter->get()->os_cert_handle()->nickname, ':'); 1098 ::strchr(iter->get()->os_cert_handle()->nickname, ':');
1101 if (delimiter) { 1099 if (delimiter) {
1102 delimiter++; // move past the colon. 1100 delimiter++; // move past the colon.
(...skipping 17 matching lines...) Expand all
1120 PORT_Free(private_key_nickname); 1118 PORT_Free(private_key_nickname);
1121 SECKEY_DestroyPrivateKey(private_key); 1119 SECKEY_DestroyPrivateKey(private_key);
1122 } 1120 }
1123 } 1121 }
1124 } 1122 }
1125 1123
1126 // static 1124 // static
1127 bool OncNetworkParser::DeleteCertAndKeyByNickname(const std::string& label) { 1125 bool OncNetworkParser::DeleteCertAndKeyByNickname(const std::string& label) {
1128 net::CertificateList cert_list; 1126 net::CertificateList cert_list;
1129 ListCertsWithNickname(label, &cert_list); 1127 ListCertsWithNickname(label, &cert_list);
1130 net::CertDatabase cert_db;
1131 bool result = true; 1128 bool result = true;
1132 for (net::CertificateList::iterator iter = cert_list.begin(); 1129 for (net::CertificateList::iterator iter = cert_list.begin();
1133 iter != cert_list.end(); ++iter) { 1130 iter != cert_list.end(); ++iter) {
1134 // If we fail, we try and delete the rest still. 1131 // If we fail, we try and delete the rest still.
1135 // TODO(gspencer): this isn't very "transactional". If we fail on some, but 1132 // TODO(gspencer): this isn't very "transactional". If we fail on some, but
1136 // not all, then it's possible to leave things in a weird state. 1133 // not all, then it's possible to leave things in a weird state.
1137 // Luckily there should only be one cert with a particular 1134 // Luckily there should only be one cert with a particular
1138 // label, and the cert not being found is one of the few reasons the 1135 // label, and the cert not being found is one of the few reasons the
1139 // delete could fail, but still... The other choice is to return 1136 // delete could fail, but still... The other choice is to return
1140 // failure immediately, but that doesn't seem to do what is intended. 1137 // failure immediately, but that doesn't seem to do what is intended.
1141 if (!cert_db.DeleteCertAndKey(iter->get())) 1138 if (!net::NSSCertDatabase::GetInstance()->DeleteCertAndKey(iter->get()))
1142 result = false; 1139 result = false;
1143 } 1140 }
1144 return result; 1141 return result;
1145 } 1142 }
1146 1143
1147 // static 1144 // static
1148 std::string OncNetworkParser::GetPkcs11IdFromCertGuid(const std::string& guid) { 1145 std::string OncNetworkParser::GetPkcs11IdFromCertGuid(const std::string& guid) {
1149 // We have to look up the GUID to find the PKCS#11 ID that is needed. 1146 // We have to look up the GUID to find the PKCS#11 ID that is needed.
1150 net::CertificateList cert_list; 1147 net::CertificateList cert_list;
1151 ListCertsWithNickname(guid, &cert_list); 1148 ListCertsWithNickname(guid, &cert_list);
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after
2027 // on the value of AuthenticationType. 2024 // on the value of AuthenticationType.
2028 { "L2TP-IPsec", PROVIDER_TYPE_L2TP_IPSEC_PSK }, 2025 { "L2TP-IPsec", PROVIDER_TYPE_L2TP_IPSEC_PSK },
2029 { "OpenVPN", PROVIDER_TYPE_OPEN_VPN }, 2026 { "OpenVPN", PROVIDER_TYPE_OPEN_VPN },
2030 }; 2027 };
2031 CR_DEFINE_STATIC_LOCAL(EnumMapper<ProviderType>, parser, 2028 CR_DEFINE_STATIC_LOCAL(EnumMapper<ProviderType>, parser,
2032 (table, arraysize(table), PROVIDER_TYPE_MAX)); 2029 (table, arraysize(table), PROVIDER_TYPE_MAX));
2033 return parser.Get(type); 2030 return parser.Get(type);
2034 } 2031 }
2035 2032
2036 } // namespace chromeos 2033 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698