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

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

Issue 17471005: Move PEM certificate decoding to onc_utils. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments. 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
« no previous file with comments | « no previous file | chromeos/network/onc/onc_utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_certificate_importer.h" 5 #include "chromeos/network/onc/onc_certificate_importer.h"
6 6
7 #include <cert.h> 7 #include <cert.h>
8 #include <keyhi.h> 8 #include <keyhi.h>
9 #include <pk11pub.h> 9 #include <pk11pub.h>
10 10
11 #include "base/base64.h" 11 #include "base/base64.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/values.h" 13 #include "base/values.h"
14 #include "chromeos/network/network_event_log.h" 14 #include "chromeos/network/network_event_log.h"
15 #include "chromeos/network/onc/onc_constants.h" 15 #include "chromeos/network/onc/onc_constants.h"
16 #include "chromeos/network/onc/onc_utils.h"
16 #include "net/base/crypto_module.h" 17 #include "net/base/crypto_module.h"
17 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
18 #include "net/cert/nss_cert_database.h" 19 #include "net/cert/nss_cert_database.h"
19 #include "net/cert/pem_tokenizer.h"
20 #include "net/cert/x509_certificate.h" 20 #include "net/cert/x509_certificate.h"
21 21
22 #define ONC_LOG_WARNING(message) \ 22 #define ONC_LOG_WARNING(message) \
23 NET_LOG_DEBUG("ONC Certificate Import Warning", message) 23 NET_LOG_DEBUG("ONC Certificate Import Warning", message)
24 #define ONC_LOG_ERROR(message) \ 24 #define ONC_LOG_ERROR(message) \
25 NET_LOG_ERROR("ONC Certificate Import Error", message) 25 NET_LOG_ERROR("ONC Certificate Import Error", message)
26 26
27 namespace {
28
29 // The PEM block header used for DER certificates
30 const char kCertificateHeader[] = "CERTIFICATE";
31 // This is an older PEM marker for DER certificates.
32 const char kX509CertificateHeader[] = "X509 CERTIFICATE";
33
34 } // namespace
35
36 namespace chromeos { 27 namespace chromeos {
37 namespace onc { 28 namespace onc {
38 29
39 CertificateImporter::CertificateImporter(bool allow_trust_imports) 30 CertificateImporter::CertificateImporter(bool allow_trust_imports)
40 : allow_trust_imports_(allow_trust_imports) { 31 : allow_trust_imports_(allow_trust_imports) {
41 } 32 }
42 33
43 CertificateImporter::ParseResult CertificateImporter::ParseAndStoreCertificates( 34 CertificateImporter::ParseResult CertificateImporter::ParseAndStoreCertificates(
44 const base::ListValue& certificates, 35 const base::ListValue& certificates,
45 net::CertificateList* onc_trusted_certificates) { 36 net::CertificateList* onc_trusted_certificates) {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 std::string x509_data; 190 std::string x509_data;
200 if (!certificate.GetStringWithoutPathExpansion(certificate::kX509, 191 if (!certificate.GetStringWithoutPathExpansion(certificate::kX509,
201 &x509_data) || 192 &x509_data) ||
202 x509_data.empty()) { 193 x509_data.empty()) {
203 ONC_LOG_ERROR( 194 ONC_LOG_ERROR(
204 "Certificate missing appropriate certificate data for type: " + 195 "Certificate missing appropriate certificate data for type: " +
205 cert_type); 196 cert_type);
206 return false; 197 return false;
207 } 198 }
208 199
209 // Parse PEM certificate, and get the decoded data for use in creating
210 // certificate below.
211 std::vector<std::string> pem_headers;
212 pem_headers.push_back(kCertificateHeader);
213 pem_headers.push_back(kX509CertificateHeader);
214
215 net::PEMTokenizer pem_tokenizer(x509_data, pem_headers);
216 std::string decoded_x509;
217 if (!pem_tokenizer.GetNext()) {
218 // If we failed to read the data as a PEM file, then let's just try plain
219 // base64 decode: some versions of Spigots didn't apply the PEM marker
220 // strings. For this to work, there has to be no white space, and it has to
221 // only contain the base64-encoded data.
222 if (!base::Base64Decode(x509_data, &decoded_x509)) {
223 ONC_LOG_ERROR("Unable to base64 decode X509 data: " + x509_data);
224 return false;
225 }
226 } else {
227 decoded_x509 = pem_tokenizer.data();
228 }
229
230 scoped_refptr<net::X509Certificate> x509_cert = 200 scoped_refptr<net::X509Certificate> x509_cert =
231 net::X509Certificate::CreateFromBytesWithNickname( 201 DecodePEMCertificate(x509_data, guid);
232 decoded_x509.data(),
233 decoded_x509.size(),
234 guid.c_str());
235 if (!x509_cert.get()) { 202 if (!x509_cert.get()) {
236 ONC_LOG_ERROR("Unable to create X509 certificate from bytes."); 203 ONC_LOG_ERROR("Unable to create certificate from PEM encoding, type: " +
204 cert_type);
237 return false; 205 return false;
238 } 206 }
239 207
240 // Due to a mismatch regarding cert identity between NSS (cert identity is 208 // Due to a mismatch regarding cert identity between NSS (cert identity is
241 // determined by the raw bytes) and ONC (cert identity is determined by 209 // determined by the raw bytes) and ONC (cert identity is determined by
242 // GUIDs), we have to special-case a number of situations here: 210 // GUIDs), we have to special-case a number of situations here:
243 // 211 //
244 // a) The cert bits we're trying to insert are already present in the NSS cert 212 // a) The cert bits we're trying to insert are already present in the NSS cert
245 // store. This is indicated by the isperm bit in CERTCertificateStr. Since 213 // store. This is indicated by the isperm bit in CERTCertificateStr. Since
246 // we might have to update the nick name, we just delete the existing cert 214 // we might have to update the nick name, we just delete the existing cert
(...skipping 10 matching lines...) Expand all
257 // keep our own database for mapping GUIDs to certs in order to enable several 225 // keep our own database for mapping GUIDs to certs in order to enable several
258 // GUIDs to map to the same cert. See http://crosbug.com/26073. 226 // GUIDs to map to the same cert. See http://crosbug.com/26073.
259 net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance(); 227 net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance();
260 if (x509_cert->os_cert_handle()->isperm) { 228 if (x509_cert->os_cert_handle()->isperm) {
261 if (!cert_database->DeleteCertAndKey(x509_cert.get())) { 229 if (!cert_database->DeleteCertAndKey(x509_cert.get())) {
262 ONC_LOG_ERROR("Unable to delete X509 certificate."); 230 ONC_LOG_ERROR("Unable to delete X509 certificate.");
263 return false; 231 return false;
264 } 232 }
265 233
266 // Reload the cert here to get an actual temporary cert instance. 234 // Reload the cert here to get an actual temporary cert instance.
267 x509_cert = net::X509Certificate::CreateFromBytesWithNickname( 235 x509_cert = DecodePEMCertificate(x509_data, guid);
268 decoded_x509.data(),
269 decoded_x509.size(),
270 guid.c_str());
271 if (!x509_cert.get()) { 236 if (!x509_cert.get()) {
272 ONC_LOG_ERROR("Unable to create X509 certificate from bytes."); 237 ONC_LOG_ERROR("Unable to create X509 certificate from bytes.");
273 return false; 238 return false;
274 } 239 }
275 DCHECK(!x509_cert->os_cert_handle()->isperm); 240 DCHECK(!x509_cert->os_cert_handle()->isperm);
276 DCHECK(x509_cert->os_cert_handle()->istemp); 241 DCHECK(x509_cert->os_cert_handle()->istemp);
277 } 242 }
278 243
279 // Make sure the GUID is not already taken. Note that for the reimport case we 244 // Make sure the GUID is not already taken. Note that for the reimport case we
280 // have removed the existing cert above. 245 // have removed the existing cert above.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 PK11_SetPrivateKeyNickname(private_key, const_cast<char*>(guid.c_str())); 334 PK11_SetPrivateKeyNickname(private_key, const_cast<char*>(guid.c_str()));
370 SECKEY_DestroyPrivateKey(private_key); 335 SECKEY_DestroyPrivateKey(private_key);
371 } else { 336 } else {
372 ONC_LOG_WARNING("Unable to find private key for certificate."); 337 ONC_LOG_WARNING("Unable to find private key for certificate.");
373 } 338 }
374 return true; 339 return true;
375 } 340 }
376 341
377 } // namespace onc 342 } // namespace onc
378 } // namespace chromeos 343 } // namespace chromeos
OLDNEW
« no previous file with comments | « no previous file | chromeos/network/onc/onc_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698