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

Side by Side Diff: content/renderer/webcrypto/webcrypto_impl_nss.cc

Issue 34583010: [webcrypto] Add RSA key generation using NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixes for eroman Created 7 years, 1 month 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/renderer/webcrypto/webcrypto_impl.h" 5 #include "content/renderer/webcrypto/webcrypto_impl.h"
6 6
7 #include <cryptohi.h> 7 #include <cryptohi.h>
8 #include <pk11pub.h> 8 #include <pk11pub.h>
9 #include <sechash.h> 9 #include <sechash.h>
10 10
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "crypto/nss_util.h" 14 #include "crypto/nss_util.h"
15 #include "crypto/scoped_nss_types.h" 15 #include "crypto/scoped_nss_types.h"
16 #include "crypto/secure_util.h" 16 #include "crypto/secure_util.h"
17 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" 17 #include "third_party/WebKit/public/platform/WebArrayBuffer.h"
18 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" 18 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
19 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" 19 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
20 20
21 namespace content { 21 namespace content {
22 22
23 namespace { 23 namespace {
24 24
25 class SymKeyHandle : public WebKit::WebCryptoKeyHandle { 25 class SymKeyHandle : public WebKit::WebCryptoKeyHandle {
26 public: 26 public:
27 explicit SymKeyHandle(crypto::ScopedPK11SymKey key) { 27 explicit SymKeyHandle(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {}
28 DCHECK(!key_.get());
29 key_ = key.Pass();
30 }
31 28
32 PK11SymKey* key() { return key_.get(); } 29 PK11SymKey* key() { return key_.get(); }
33 30
34 private: 31 private:
35 crypto::ScopedPK11SymKey key_; 32 crypto::ScopedPK11SymKey key_;
36 33
37 DISALLOW_COPY_AND_ASSIGN(SymKeyHandle); 34 DISALLOW_COPY_AND_ASSIGN(SymKeyHandle);
38 }; 35 };
39 36
37 class PublicKeyHandle : public WebKit::WebCryptoKeyHandle {
38 public:
39 explicit PublicKeyHandle(crypto::ScopedSECKEYPublicKey key)
40 : key_(key.Pass()) {}
41
42 SECKEYPublicKey* key() { return key_.get(); }
43
44 private:
45 crypto::ScopedSECKEYPublicKey key_;
46
47 DISALLOW_COPY_AND_ASSIGN(PublicKeyHandle);
48 };
49
50 class PrivateKeyHandle : public WebKit::WebCryptoKeyHandle {
51 public:
52 explicit PrivateKeyHandle(crypto::ScopedSECKEYPrivateKey key)
53 : key_(key.Pass()) {}
54
55 SECKEYPrivateKey* key() { return key_.get(); }
56
57 private:
58 crypto::ScopedSECKEYPrivateKey key_;
59
60 DISALLOW_COPY_AND_ASSIGN(PrivateKeyHandle);
61 };
62
40 HASH_HashType WebCryptoAlgorithmToNSSHashType( 63 HASH_HashType WebCryptoAlgorithmToNSSHashType(
41 const WebKit::WebCryptoAlgorithm& algorithm) { 64 const WebKit::WebCryptoAlgorithm& algorithm) {
42 switch (algorithm.id()) { 65 switch (algorithm.id()) {
43 case WebKit::WebCryptoAlgorithmIdSha1: 66 case WebKit::WebCryptoAlgorithmIdSha1:
44 return HASH_AlgSHA1; 67 return HASH_AlgSHA1;
45 case WebKit::WebCryptoAlgorithmIdSha224: 68 case WebKit::WebCryptoAlgorithmIdSha224:
46 return HASH_AlgSHA224; 69 return HASH_AlgSHA224;
47 case WebKit::WebCryptoAlgorithmIdSha256: 70 case WebKit::WebCryptoAlgorithmIdSha256:
48 return HASH_AlgSHA256; 71 return HASH_AlgSHA256;
49 case WebKit::WebCryptoAlgorithmIdSha384: 72 case WebKit::WebCryptoAlgorithmIdSha384:
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 switch (params->hash().id()) { 209 switch (params->hash().id()) {
187 case WebKit::WebCryptoAlgorithmIdSha1: 210 case WebKit::WebCryptoAlgorithmIdSha1:
188 return 512; 211 return 512;
189 case WebKit::WebCryptoAlgorithmIdSha256: 212 case WebKit::WebCryptoAlgorithmIdSha256:
190 return 512; 213 return 512;
191 default: 214 default:
192 return 0; 215 return 0;
193 } 216 }
194 } 217 }
195 218
219 // Convert a (big-endian) WebCrypto BigInteger, with or without leading zeros,
eroman 2013/10/28 20:00:47 minor nit: "Convert" --> "Converts". Google C++ s
padolph 2013/10/28 21:08:53 Done.
220 // to unsigned long.
221 bool BigIntegerToLong(const uint8* data,
222 unsigned data_size,
223 unsigned long* result) {
224 if (data_size == 0)
225 return false; // TODO(padolph): Is this correct?
eroman 2013/10/28 20:00:47 You can link to https://www.w3.org/Bugs/Public/sho
padolph 2013/10/28 21:08:53 Done.
226
227 *result = 0;
228 for (size_t i = 0; i < data_size; ++i) {
229 size_t reverse_i = data_size - i - 1;
230
231 if (reverse_i >= sizeof(unsigned long) && data[i])
232 return false; // Too large for a long.
233
234 *result |= data[i] << 8 * reverse_i;
235 }
236 return true;
237 }
238
196 } // namespace 239 } // namespace
197 240
198 void WebCryptoImpl::Init() { 241 void WebCryptoImpl::Init() {
199 crypto::EnsureNSSInit(); 242 crypto::EnsureNSSInit();
200 } 243 }
201 244
202 bool WebCryptoImpl::EncryptInternal( 245 bool WebCryptoImpl::EncryptInternal(
203 const WebKit::WebCryptoAlgorithm& algorithm, 246 const WebKit::WebCryptoAlgorithm& algorithm,
204 const WebKit::WebCryptoKey& key, 247 const WebKit::WebCryptoKey& key,
205 const unsigned char* data, 248 const unsigned char* data,
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 if (!pk11_key) { 359 if (!pk11_key) {
317 return false; 360 return false;
318 } 361 }
319 362
320 key->reset(new SymKeyHandle(pk11_key.Pass())); 363 key->reset(new SymKeyHandle(pk11_key.Pass()));
321 *type = key_type; 364 *type = key_type;
322 365
323 return true; 366 return true;
324 } 367 }
325 368
369 bool WebCryptoImpl::GenerateKeyPairInternal(
370 const WebKit::WebCryptoAlgorithm& algorithm,
371 scoped_ptr<WebKit::WebCryptoKeyHandle>* public_key_handle,
372 scoped_ptr<WebKit::WebCryptoKeyHandle>* private_key_handle) {
373
374 // TODO(padolph) Handle other asymmetric algorithm key generation
eroman 2013/10/28 20:00:47 minor nit: put colon after closing paren.
padolph 2013/10/28 21:08:53 Done.
375 switch (algorithm.id()) {
376 case WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
377 case WebKit::WebCryptoAlgorithmIdRsaOaep:
378 case WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: {
379 const WebKit::WebCryptoRsaKeyGenParams* const params =
380 algorithm.rsaKeyGenParams();
381 DCHECK(params);
382
383 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
384 unsigned long public_exponent;
385 if (!slot || !params->modulusLength() ||
386 !params->publicExponent().size() ||
eroman 2013/10/28 20:00:47 This check is not needed, since it is OK to call .
padolph 2013/10/28 21:08:53 Done.
387 !BigIntegerToLong(params->publicExponent().data(),
388 params->publicExponent().size(),
389 &public_exponent) ||
390 !public_exponent) {
eroman 2013/10/28 20:00:47 Is this check necessary, or will NSS fail later wi
padolph 2013/10/28 21:08:53 NSS fails correctly in this case, but I thought it
391 return false;
392 }
393
394 PK11RSAGenParams rsa_gen_params;
395 rsa_gen_params.keySizeInBits = params->modulusLength();
396 rsa_gen_params.pe = public_exponent;
397
398 // Flags are verified at the Blink layer; here the flags are set to all
399 // possible operations for the given key type.
400 CK_FLAGS operation_flags;
401 switch (algorithm.id()) {
402 case WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
403 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP;
404 break;
405 case WebKit::WebCryptoAlgorithmIdRsaOaep:
406 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP;
eroman 2013/10/28 20:00:47 [optional]: since this line is the same as above,
padolph 2013/10/28 21:08:53 Done.
407 break;
408 case WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
409 operation_flags = CKF_SIGN | CKF_VERIFY;
410 break;
411 default:
412 NOTREACHED();
413 return false;
414 }
415 const CK_FLAGS operation_flags_mask = CKF_ENCRYPT | CKF_DECRYPT |
416 CKF_SIGN | CKF_VERIFY | CKF_WRAP |
417 CKF_UNWRAP;
418 const PK11AttrFlags attribute_flags = 0; // default all PK11_ATTR_ flags
419
420 SECKEYPublicKey* sec_public_key;
421 crypto::ScopedSECKEYPrivateKey private_key(
422 PK11_GenerateKeyPairWithOpFlags(slot.get(),
423 CKM_RSA_PKCS_KEY_PAIR_GEN,
424 &rsa_gen_params,
425 &sec_public_key,
426 attribute_flags,
427 operation_flags,
428 operation_flags_mask,
429 NULL));
430 if (!private_key) {
431 return false;
432 }
433 crypto::ScopedSECKEYPublicKey public_key(sec_public_key);
434
435 public_key_handle->reset(new PublicKeyHandle(public_key.Pass()));
436 private_key_handle->reset(new PrivateKeyHandle(private_key.Pass()));
437
438 return true;
439 }
440 default:
441 return false;
442 }
443 }
326 444
327 bool WebCryptoImpl::ImportKeyInternal( 445 bool WebCryptoImpl::ImportKeyInternal(
328 WebKit::WebCryptoKeyFormat format, 446 WebKit::WebCryptoKeyFormat format,
329 const unsigned char* key_data, 447 const unsigned char* key_data,
330 unsigned key_data_size, 448 unsigned key_data_size,
331 const WebKit::WebCryptoAlgorithm& algorithm, 449 const WebKit::WebCryptoAlgorithm& algorithm,
332 WebKit::WebCryptoKeyUsageMask usage_mask, 450 WebKit::WebCryptoKeyUsageMask usage_mask,
333 scoped_ptr<WebKit::WebCryptoKeyHandle>* handle, 451 scoped_ptr<WebKit::WebCryptoKeyHandle>* handle,
334 WebKit::WebCryptoKeyType* type) { 452 WebKit::WebCryptoKeyType* type) {
335 switch (algorithm.id()) { 453 switch (algorithm.id()) {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 break; 617 break;
500 } 618 }
501 default: 619 default:
502 return false; 620 return false;
503 } 621 }
504 622
505 return true; 623 return true;
506 } 624 }
507 625
508 } // namespace content 626 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698