OLD | NEW |
---|---|
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 "net/cert/x509_util.h" | 5 #include "net/cert/x509_util.h" |
6 #include "net/cert/x509_util_nss.h" | 6 #include "net/cert/x509_util_nss.h" |
7 | 7 |
8 #include <cert.h> // Must be included before certdb.h | 8 #include <cert.h> // Must be included before certdb.h |
9 #include <certdb.h> | 9 #include <certdb.h> |
10 #include <cryptohi.h> | 10 #include <cryptohi.h> |
11 #include <nss.h> | 11 #include <nss.h> |
12 #include <pk11pub.h> | 12 #include <pk11pub.h> |
13 #include <prerror.h> | 13 #include <prerror.h> |
14 #include <secder.h> | 14 #include <secder.h> |
15 #include <secmod.h> | 15 #include <secmod.h> |
16 #include <secport.h> | 16 #include <secport.h> |
17 | 17 |
18 #include "base/base64.h" | |
18 #include "base/debug/leak_annotations.h" | 19 #include "base/debug/leak_annotations.h" |
19 #include "base/logging.h" | 20 #include "base/logging.h" |
20 #include "base/memory/scoped_ptr.h" | 21 #include "base/memory/scoped_ptr.h" |
21 #include "base/memory/singleton.h" | 22 #include "base/memory/singleton.h" |
22 #include "base/pickle.h" | 23 #include "base/pickle.h" |
23 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
25 #include "base/values.h" | |
24 #include "crypto/ec_private_key.h" | 26 #include "crypto/ec_private_key.h" |
25 #include "crypto/nss_util.h" | 27 #include "crypto/nss_util.h" |
26 #include "crypto/nss_util_internal.h" | 28 #include "crypto/nss_util_internal.h" |
27 #include "crypto/rsa_private_key.h" | 29 #include "crypto/rsa_private_key.h" |
28 #include "crypto/scoped_nss_types.h" | 30 #include "crypto/scoped_nss_types.h" |
29 #include "crypto/third_party/nss/chromium-nss.h" | 31 #include "crypto/third_party/nss/chromium-nss.h" |
30 #include "net/cert/x509_certificate.h" | 32 #include "net/cert/x509_certificate.h" |
31 | 33 |
32 namespace net { | 34 namespace net { |
33 | 35 |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
347 | 349 |
348 DCHECK(cert->derCert.len); | 350 DCHECK(cert->derCert.len); |
349 // XXX copied from X509Certificate::GetDEREncoded | 351 // XXX copied from X509Certificate::GetDEREncoded |
350 der_cert->clear(); | 352 der_cert->clear(); |
351 der_cert->append(reinterpret_cast<char*>(cert->derCert.data), | 353 der_cert->append(reinterpret_cast<char*>(cert->derCert.data), |
352 cert->derCert.len); | 354 cert->derCert.len); |
353 CERT_DestroyCertificate(cert); | 355 CERT_DestroyCertificate(cert); |
354 return true; | 356 return true; |
355 } | 357 } |
356 | 358 |
359 static bool ConvertEcPrime256v1PublicKeyInfoToJwk( | |
Ryan Sleevi
2013/08/02 23:08:43
Chromium prefers the unnamed namespace, especially
| |
360 CERTSubjectPublicKeyInfo* spki, | |
361 base::DictionaryValue* public_key_jwk) { | |
362 static const int kPrime256v1EncodingType = 4; | |
363 static const int kPrime256v1PublicKeyLength = 64; | |
364 // The public key value is encoded as 0x04 + 64 bytes of public key. | |
365 // For some reason NSS gives us a bogus, overly long length for the public | |
366 // key, but as long as there are at least enough bytes and the first byte has | |
Ryan Sleevi
2013/08/02 23:08:43
It's only bogus until you realize that for BIT_STR
| |
367 // the correct value, treat the remaining 64 bytes as the public key. | |
368 // | |
369 if (spki->subjectPublicKey.len < kPrime256v1PublicKeyLength + 1 || | |
370 spki->subjectPublicKey.data[0] != kPrime256v1EncodingType) | |
371 return false; | |
372 | |
373 public_key_jwk->SetString(std::string("alg"), std::string("EC")); | |
374 public_key_jwk->SetString(std::string("crv"), std::string("P-256")); | |
Ryan Sleevi
2013/08/02 23:08:43
Remove the explicit std::string constructors - let
| |
375 | |
376 base::StringPiece x( | |
377 reinterpret_cast<char*>(spki->subjectPublicKey.data + 1), | |
378 kPrime256v1PublicKeyLength / 2); | |
379 std::string x_b64; | |
380 base::Base64Encode(x, &x_b64); | |
381 public_key_jwk->SetString(std::string("x"), x_b64); | |
382 | |
383 base::StringPiece y( | |
384 reinterpret_cast<char*>(spki->subjectPublicKey.data + 1 + | |
385 kPrime256v1PublicKeyLength / 2), | |
386 kPrime256v1PublicKeyLength / 2); | |
387 std::string y_b64; | |
388 base::Base64Encode(y, &y_b64); | |
389 public_key_jwk->SetString(std::string("y"), y_b64); | |
390 return true; | |
391 } | |
392 | |
393 static bool ConvertEcPublicKeyInfoToJwk( | |
394 CERTSubjectPublicKeyInfo* spki, | |
395 base::DictionaryValue* public_key_jwk) { | |
396 // 1.2.840.10045.3.1.7 | |
397 // (iso.member-body.us.ansi-x9-62.ellipticCurve.primeCurve.prime256v1) | |
398 // (This includes the DER-encoded type (OID) and length: parameters can be | |
399 // anything, so the DER type isn't implied, and NSS includes it.) | |
400 static const uint8_t kPrime256v1[] = { | |
401 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 | |
402 }; | |
403 if (spki->algorithm.parameters.len == sizeof(kPrime256v1) && | |
404 !memcmp(spki->algorithm.parameters.data, kPrime256v1, | |
405 sizeof(kPrime256v1))) { | |
406 return ConvertEcPrime256v1PublicKeyInfoToJwk(spki, public_key_jwk); | |
407 } | |
408 // TODO(juanlang): other curves | |
409 return false; | |
410 } | |
411 | |
412 bool ConvertSPKIFromDERToJWK( | |
413 base::StringPiece spki_der, | |
414 base::DictionaryValue* public_key_jwk) { | |
415 public_key_jwk->Clear(); | |
416 | |
417 SECItem sec_item; | |
418 sec_item.data = const_cast<unsigned char*>( | |
419 reinterpret_cast<const unsigned char*>(spki_der.data())); | |
420 sec_item.len = spki_der.size(); | |
421 CERTSubjectPublicKeyInfo* spki = | |
422 SECKEY_DecodeDERSubjectPublicKeyInfo(&sec_item); | |
423 if (!spki) | |
424 return false; | |
425 | |
426 // 1.2.840.10045.2 | |
427 // (iso.member-body.us.ansi-x9-62.id-ecPublicKey) | |
428 // (This omits the ASN.1 encoding of the type (OID) and length: the fact that | |
429 // this is an OID is already clear, and NSS omits it here.) | |
430 static const uint8 kIdEcPublicKey[] = { | |
431 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 | |
432 }; | |
433 bool rv = false; | |
434 if (spki->algorithm.algorithm.len == sizeof(kIdEcPublicKey) && | |
435 !memcmp(spki->algorithm.algorithm.data, kIdEcPublicKey, | |
436 sizeof(kIdEcPublicKey))) { | |
437 rv = ConvertEcPublicKeyInfoToJwk(spki, public_key_jwk); | |
438 } | |
439 // TODO(juanlang): other algorithms | |
440 SECKEY_DestroySubjectPublicKeyInfo(spki); | |
441 return rv; | |
442 } | |
443 | |
357 #if defined(USE_NSS) || defined(OS_IOS) | 444 #if defined(USE_NSS) || defined(OS_IOS) |
358 void ParsePrincipal(CERTName* name, CertPrincipal* principal) { | 445 void ParsePrincipal(CERTName* name, CertPrincipal* principal) { |
359 // Starting in NSS 3.15, CERTGetNameFunc takes a const CERTName* argument. | 446 // Starting in NSS 3.15, CERTGetNameFunc takes a const CERTName* argument. |
360 #if NSS_VMINOR >= 15 | 447 #if NSS_VMINOR >= 15 |
361 typedef char* (*CERTGetNameFunc)(const CERTName* name); | 448 typedef char* (*CERTGetNameFunc)(const CERTName* name); |
362 #else | 449 #else |
363 typedef char* (*CERTGetNameFunc)(CERTName* name); | 450 typedef char* (*CERTGetNameFunc)(CERTName* name); |
364 #endif | 451 #endif |
365 | 452 |
366 // TODO(jcampan): add business_category and serial_number. | 453 // TODO(jcampan): add business_category and serial_number. |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
615 } | 702 } |
616 | 703 |
617 return new_name; | 704 return new_name; |
618 } | 705 } |
619 | 706 |
620 #endif // defined(USE_NSS) || defined(OS_IOS) | 707 #endif // defined(USE_NSS) || defined(OS_IOS) |
621 | 708 |
622 } // namespace x509_util | 709 } // namespace x509_util |
623 | 710 |
624 } // namespace net | 711 } // namespace net |
OLD | NEW |