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

Side by Side Diff: net/cert/x509_util_nss.cc

Issue 21561003: Add a utility method to convert SPKI from DER to JWK, so far implemented only for EC P256v1 (which … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@domain-bound-public-key
Patch Set: Created 7 years, 4 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
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 "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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698