Chromium Code Reviews| 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 |