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

Side by Side Diff: content/child/webcrypto/platform_crypto_nss.cc

Issue 233733004: [webcrypto] Make operations run on worker threads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix argument ordering bug Created 6 years, 7 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/child/webcrypto/platform_crypto.h" 5 #include "content/child/webcrypto/platform_crypto.h"
6 6
7 #include <cryptohi.h> 7 #include <cryptohi.h>
8 #include <pk11pub.h> 8 #include <pk11pub.h>
9 #include <secerr.h> 9 #include <secerr.h>
10 #include <sechash.h> 10 #include <sechash.h>
11 11
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/lazy_instance.h" 14 #include "base/lazy_instance.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
17 #include "content/child/webcrypto/crypto_data.h" 17 #include "content/child/webcrypto/crypto_data.h"
18 #include "content/child/webcrypto/status.h" 18 #include "content/child/webcrypto/status.h"
19 #include "content/child/webcrypto/webcrypto_util.h" 19 #include "content/child/webcrypto/webcrypto_util.h"
20 #include "crypto/nss_util.h" 20 #include "crypto/nss_util.h"
21 #include "crypto/scoped_nss_types.h" 21 #include "crypto/scoped_nss_types.h"
22 #include "third_party/WebKit/public/platform/WebArrayBuffer.h"
23 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" 22 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
24 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" 23 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
25 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" 24 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
26 25
27 #if defined(USE_NSS) 26 #if defined(USE_NSS)
28 #include <dlfcn.h> 27 #include <dlfcn.h>
29 #include <secoid.h> 28 #include <secoid.h>
30 #endif 29 #endif
31 30
32 // At the time of this writing: 31 // At the time of this writing:
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 112
114 base::LazyInstance<AesGcmSupport>::Leaky g_aes_gcm_support = 113 base::LazyInstance<AesGcmSupport>::Leaky g_aes_gcm_support =
115 LAZY_INSTANCE_INITIALIZER; 114 LAZY_INSTANCE_INITIALIZER;
116 115
117 namespace content { 116 namespace content {
118 117
119 namespace webcrypto { 118 namespace webcrypto {
120 119
121 namespace platform { 120 namespace platform {
122 121
122 // Each key maintains a copy of its serialized form
123 // in either 'raw', 'pkcs8', or 'spki' format. This is to allow
124 // structured cloning of keys synchronously from the target Blink
125 // thread without having to lock access to the key.
126 //
127 // TODO(eroman): Take advantage of this for implementing exportKey(): no need
128 // to call into NSS if the serialized form already exists.
129 // http://crubg.com/366836
123 class SymKey : public Key { 130 class SymKey : public Key {
124 public: 131 public:
125 explicit SymKey(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {} 132 static Status Create(crypto::ScopedPK11SymKey key, scoped_ptr<SymKey>* out) {
133 out->reset(new SymKey(key.Pass()));
134 return ExportKeyRaw(out->get(), &(*out)->serialized_key_);
135 }
126 136
127 PK11SymKey* key() { return key_.get(); } 137 PK11SymKey* key() { return key_.get(); }
128 138
129 virtual SymKey* AsSymKey() OVERRIDE { return this; } 139 virtual SymKey* AsSymKey() OVERRIDE { return this; }
130 virtual PublicKey* AsPublicKey() OVERRIDE { return NULL; } 140 virtual PublicKey* AsPublicKey() OVERRIDE { return NULL; }
131 virtual PrivateKey* AsPrivateKey() OVERRIDE { return NULL; } 141 virtual PrivateKey* AsPrivateKey() OVERRIDE { return NULL; }
132 142
143 virtual bool ThreadSafeSerializeForClone(
144 blink::WebVector<uint8>* key_data) OVERRIDE {
145 key_data->assign(Uint8VectorStart(serialized_key_), serialized_key_.size());
146 return true;
147 }
148
133 private: 149 private:
150 explicit SymKey(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {}
151
134 crypto::ScopedPK11SymKey key_; 152 crypto::ScopedPK11SymKey key_;
153 std::vector<uint8> serialized_key_;
135 154
136 DISALLOW_COPY_AND_ASSIGN(SymKey); 155 DISALLOW_COPY_AND_ASSIGN(SymKey);
137 }; 156 };
138 157
139 class PublicKey : public Key { 158 class PublicKey : public Key {
140 public: 159 public:
141 explicit PublicKey(crypto::ScopedSECKEYPublicKey key) : key_(key.Pass()) {} 160 static Status Create(crypto::ScopedSECKEYPublicKey key,
161 scoped_ptr<PublicKey>* out) {
162 out->reset(new PublicKey(key.Pass()));
163 return ExportKeySpki(out->get(), &(*out)->serialized_key_);
164 }
142 165
143 SECKEYPublicKey* key() { return key_.get(); } 166 SECKEYPublicKey* key() { return key_.get(); }
144 167
145 virtual SymKey* AsSymKey() OVERRIDE { return NULL; } 168 virtual SymKey* AsSymKey() OVERRIDE { return NULL; }
146 virtual PublicKey* AsPublicKey() OVERRIDE { return this; } 169 virtual PublicKey* AsPublicKey() OVERRIDE { return this; }
147 virtual PrivateKey* AsPrivateKey() OVERRIDE { return NULL; } 170 virtual PrivateKey* AsPrivateKey() OVERRIDE { return NULL; }
148 171
172 virtual bool ThreadSafeSerializeForClone(
173 blink::WebVector<uint8>* key_data) OVERRIDE {
174 key_data->assign(Uint8VectorStart(serialized_key_), serialized_key_.size());
175 return true;
176 }
177
149 private: 178 private:
179 explicit PublicKey(crypto::ScopedSECKEYPublicKey key) : key_(key.Pass()) {}
180
150 crypto::ScopedSECKEYPublicKey key_; 181 crypto::ScopedSECKEYPublicKey key_;
182 std::vector<uint8> serialized_key_;
151 183
152 DISALLOW_COPY_AND_ASSIGN(PublicKey); 184 DISALLOW_COPY_AND_ASSIGN(PublicKey);
153 }; 185 };
154 186
155 class PrivateKey : public Key { 187 class PrivateKey : public Key {
156 public: 188 public:
157 explicit PrivateKey(crypto::ScopedSECKEYPrivateKey key) : key_(key.Pass()) {} 189 static Status Create(crypto::ScopedSECKEYPrivateKey key,
190 const blink::WebCryptoKeyAlgorithm& algorithm,
191 scoped_ptr<PrivateKey>* out) {
192 out->reset(new PrivateKey(key.Pass()));
193 return ExportKeyPkcs8(out->get(), algorithm, &(*out)->serialized_key_);
194 }
158 195
159 SECKEYPrivateKey* key() { return key_.get(); } 196 SECKEYPrivateKey* key() { return key_.get(); }
160 197
161 virtual SymKey* AsSymKey() OVERRIDE { return NULL; } 198 virtual SymKey* AsSymKey() OVERRIDE { return NULL; }
162 virtual PublicKey* AsPublicKey() OVERRIDE { return NULL; } 199 virtual PublicKey* AsPublicKey() OVERRIDE { return NULL; }
163 virtual PrivateKey* AsPrivateKey() OVERRIDE { return this; } 200 virtual PrivateKey* AsPrivateKey() OVERRIDE { return this; }
164 201
202 virtual bool ThreadSafeSerializeForClone(
203 blink::WebVector<uint8>* key_data) OVERRIDE {
204 key_data->assign(Uint8VectorStart(serialized_key_), serialized_key_.size());
205 return true;
206 }
207
165 private: 208 private:
209 explicit PrivateKey(crypto::ScopedSECKEYPrivateKey key) : key_(key.Pass()) {}
210
166 crypto::ScopedSECKEYPrivateKey key_; 211 crypto::ScopedSECKEYPrivateKey key_;
212 std::vector<uint8> serialized_key_;
167 213
168 DISALLOW_COPY_AND_ASSIGN(PrivateKey); 214 DISALLOW_COPY_AND_ASSIGN(PrivateKey);
169 }; 215 };
170 216
171 namespace { 217 namespace {
172 218
173 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so 219 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so
174 // |buffer| should outlive the SECItem. 220 // |buffer| should outlive the SECItem.
175 SECItem MakeSECItemForBuffer(const CryptoData& buffer) { 221 SECItem MakeSECItemForBuffer(const CryptoData& buffer) {
176 SECItem item = { 222 SECItem item = {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 default: 257 default:
212 // Not a supported algorithm. 258 // Not a supported algorithm.
213 return CKM_INVALID_MECHANISM; 259 return CKM_INVALID_MECHANISM;
214 } 260 }
215 } 261 }
216 262
217 Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode, 263 Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode,
218 SymKey* key, 264 SymKey* key,
219 const CryptoData& iv, 265 const CryptoData& iv,
220 const CryptoData& data, 266 const CryptoData& data,
221 blink::WebArrayBuffer* buffer) { 267 std::vector<uint8>* buffer) {
222 CK_ATTRIBUTE_TYPE operation = (mode == ENCRYPT) ? CKA_ENCRYPT : CKA_DECRYPT; 268 CK_ATTRIBUTE_TYPE operation = (mode == ENCRYPT) ? CKA_ENCRYPT : CKA_DECRYPT;
223 269
224 SECItem iv_item = MakeSECItemForBuffer(iv); 270 SECItem iv_item = MakeSECItemForBuffer(iv);
225 271
226 crypto::ScopedSECItem param(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item)); 272 crypto::ScopedSECItem param(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item));
227 if (!param) 273 if (!param)
228 return Status::OperationError(); 274 return Status::OperationError();
229 275
230 crypto::ScopedPK11Context context(PK11_CreateContextBySymKey( 276 crypto::ScopedPK11Context context(PK11_CreateContextBySymKey(
231 CKM_AES_CBC_PAD, operation, key->key(), param.get())); 277 CKM_AES_CBC_PAD, operation, key->key(), param.get()));
(...skipping 16 matching lines...) Expand all
248 if (operation == CKA_DECRYPT && 294 if (operation == CKA_DECRYPT &&
249 (data.byte_length() == 0 || (data.byte_length() % AES_BLOCK_SIZE != 0))) { 295 (data.byte_length() == 0 || (data.byte_length() % AES_BLOCK_SIZE != 0))) {
250 return Status::OperationError(); 296 return Status::OperationError();
251 } 297 }
252 298
253 // TODO(eroman): Refine the output buffer size. It can be computed exactly for 299 // TODO(eroman): Refine the output buffer size. It can be computed exactly for
254 // encryption, and can be smaller for decryption. 300 // encryption, and can be smaller for decryption.
255 unsigned int output_max_len = data.byte_length() + AES_BLOCK_SIZE; 301 unsigned int output_max_len = data.byte_length() + AES_BLOCK_SIZE;
256 CHECK_GT(output_max_len, data.byte_length()); 302 CHECK_GT(output_max_len, data.byte_length());
257 303
258 *buffer = blink::WebArrayBuffer::create(output_max_len, 1); 304 buffer->resize(output_max_len);
259 305
260 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); 306 unsigned char* buffer_data = Uint8VectorStart(buffer);
261 307
262 int output_len; 308 int output_len;
263 if (SECSuccess != PK11_CipherOp(context.get(), 309 if (SECSuccess != PK11_CipherOp(context.get(),
264 buffer_data, 310 buffer_data,
265 &output_len, 311 &output_len,
266 buffer->byteLength(), 312 buffer->size(),
267 data.bytes(), 313 data.bytes(),
268 data.byte_length())) { 314 data.byte_length())) {
269 return Status::OperationError(); 315 return Status::OperationError();
270 } 316 }
271 317
272 unsigned int final_output_chunk_len; 318 unsigned int final_output_chunk_len;
273 if (SECSuccess != PK11_DigestFinal(context.get(), 319 if (SECSuccess != PK11_DigestFinal(context.get(),
274 buffer_data + output_len, 320 buffer_data + output_len,
275 &final_output_chunk_len, 321 &final_output_chunk_len,
276 output_max_len - output_len)) { 322 output_max_len - output_len)) {
277 return Status::OperationError(); 323 return Status::OperationError();
278 } 324 }
279 325
280 ShrinkBuffer(buffer, final_output_chunk_len + output_len); 326 buffer->resize(final_output_chunk_len + output_len);
281 return Status::Success(); 327 return Status::Success();
282 } 328 }
283 329
284 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is 330 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is
285 // the concatenation of the ciphertext and the authentication tag. Similarly, 331 // the concatenation of the ciphertext and the authentication tag. Similarly,
286 // this is the expectation for the input to decryption. 332 // this is the expectation for the input to decryption.
287 Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode, 333 Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
288 SymKey* key, 334 SymKey* key,
289 const CryptoData& data, 335 const CryptoData& data,
290 const CryptoData& iv, 336 const CryptoData& iv,
291 const CryptoData& additional_data, 337 const CryptoData& additional_data,
292 unsigned int tag_length_bits, 338 unsigned int tag_length_bits,
293 blink::WebArrayBuffer* buffer) { 339 std::vector<uint8>* buffer) {
294 if (!g_aes_gcm_support.Get().IsSupported()) 340 if (!g_aes_gcm_support.Get().IsSupported())
295 return Status::ErrorUnsupported(); 341 return Status::ErrorUnsupported();
296 342
297 unsigned int tag_length_bytes = tag_length_bits / 8; 343 unsigned int tag_length_bytes = tag_length_bits / 8;
298 344
299 CK_GCM_PARAMS gcm_params = {0}; 345 CK_GCM_PARAMS gcm_params = {0};
300 gcm_params.pIv = const_cast<unsigned char*>(iv.bytes()); 346 gcm_params.pIv = const_cast<unsigned char*>(iv.bytes());
301 gcm_params.ulIvLen = iv.byte_length(); 347 gcm_params.ulIvLen = iv.byte_length();
302 348
303 gcm_params.pAAD = const_cast<unsigned char*>(additional_data.bytes()); 349 gcm_params.pAAD = const_cast<unsigned char*>(additional_data.bytes());
(...skipping 22 matching lines...) Expand all
326 // not at least as large as the ciphertext: 372 // not at least as large as the ciphertext:
327 // 373 //
328 // https://bugzilla.mozilla.org/show_bug.cgi?id=%20853674 374 // https://bugzilla.mozilla.org/show_bug.cgi?id=%20853674
329 // 375 //
330 // From the analysis of that bug it looks like it might be safe to pass a 376 // From the analysis of that bug it looks like it might be safe to pass a
331 // correctly sized buffer but lie about its size. Since resizing the 377 // correctly sized buffer but lie about its size. Since resizing the
332 // WebCryptoArrayBuffer is expensive that hack may be worth looking into. 378 // WebCryptoArrayBuffer is expensive that hack may be worth looking into.
333 buffer_size = data.byte_length(); 379 buffer_size = data.byte_length();
334 } 380 }
335 381
336 *buffer = blink::WebArrayBuffer::create(buffer_size, 1); 382 buffer->resize(buffer_size);
337 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); 383 unsigned char* buffer_data = Uint8VectorStart(buffer);
338 384
339 PK11_EncryptDecryptFunction func = 385 PK11_EncryptDecryptFunction func =
340 (mode == ENCRYPT) ? g_aes_gcm_support.Get().pk11_encrypt_func() 386 (mode == ENCRYPT) ? g_aes_gcm_support.Get().pk11_encrypt_func()
341 : g_aes_gcm_support.Get().pk11_decrypt_func(); 387 : g_aes_gcm_support.Get().pk11_decrypt_func();
342 388
343 unsigned int output_len = 0; 389 unsigned int output_len = 0;
344 SECStatus result = func(key->key(), 390 SECStatus result = func(key->key(),
345 CKM_AES_GCM, 391 CKM_AES_GCM,
346 &param, 392 &param,
347 buffer_data, 393 buffer_data,
348 &output_len, 394 &output_len,
349 buffer->byteLength(), 395 buffer->size(),
350 data.bytes(), 396 data.bytes(),
351 data.byte_length()); 397 data.byte_length());
352 398
353 if (result != SECSuccess) 399 if (result != SECSuccess)
354 return Status::OperationError(); 400 return Status::OperationError();
355 401
356 // Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug 402 // Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug
357 // above). 403 // above).
358 ShrinkBuffer(buffer, output_len); 404 buffer->resize(output_len);
359 405
360 return Status::Success(); 406 return Status::Success();
361 } 407 }
362 408
363 CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( 409 CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism(
364 const blink::WebCryptoAlgorithm& algorithm) { 410 const blink::WebCryptoAlgorithm& algorithm) {
365 switch (algorithm.id()) { 411 switch (algorithm.id()) {
366 case blink::WebCryptoAlgorithmIdAesCbc: 412 case blink::WebCryptoAlgorithmIdAesCbc:
367 case blink::WebCryptoAlgorithmIdAesGcm: 413 case blink::WebCryptoAlgorithmIdAesGcm:
368 case blink::WebCryptoAlgorithmIdAesKw: 414 case blink::WebCryptoAlgorithmIdAesKw:
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 742
697 virtual bool finish(unsigned char*& result_data, 743 virtual bool finish(unsigned char*& result_data,
698 unsigned int& result_data_size) { 744 unsigned int& result_data_size) {
699 Status error = FinishInternal(result_, &result_data_size); 745 Status error = FinishInternal(result_, &result_data_size);
700 if (!error.IsSuccess()) 746 if (!error.IsSuccess())
701 return false; 747 return false;
702 result_data = result_; 748 result_data = result_;
703 return true; 749 return true;
704 } 750 }
705 751
706 Status FinishWithWebArrayAndStatus(blink::WebArrayBuffer* result) { 752 Status FinishWithVectorAndStatus(std::vector<uint8>* result) {
707 if (!hash_context_) 753 if (!hash_context_)
708 return Status::ErrorUnexpected(); 754 return Status::ErrorUnexpected();
709 755
710 unsigned int result_length = HASH_ResultLenContext(hash_context_); 756 unsigned int result_length = HASH_ResultLenContext(hash_context_);
711 *result = blink::WebArrayBuffer::create(result_length, 1); 757 result->resize(result_length);
712 unsigned char* digest = reinterpret_cast<unsigned char*>(result->data()); 758 unsigned char* digest = Uint8VectorStart(result);
713 unsigned int digest_size; // ignored 759 unsigned int digest_size; // ignored
714 return FinishInternal(digest, &digest_size); 760 return FinishInternal(digest, &digest_size);
715 } 761 }
716 762
717 private: 763 private:
718 Status Init() { 764 Status Init() {
719 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm_id_); 765 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm_id_);
720 766
721 if (hash_type == HASH_AlgNULL) 767 if (hash_type == HASH_AlgNULL)
722 return Status::ErrorUnsupported(); 768 return Status::ErrorUnsupported();
(...skipping 27 matching lines...) Expand all
750 HASHContext* hash_context_; 796 HASHContext* hash_context_;
751 blink::WebCryptoAlgorithmId algorithm_id_; 797 blink::WebCryptoAlgorithmId algorithm_id_;
752 unsigned char result_[HASH_LENGTH_MAX]; 798 unsigned char result_[HASH_LENGTH_MAX];
753 }; 799 };
754 800
755 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, 801 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm,
756 const CryptoData& key_data, 802 const CryptoData& key_data,
757 bool extractable, 803 bool extractable,
758 blink::WebCryptoKeyUsageMask usage_mask, 804 blink::WebCryptoKeyUsageMask usage_mask,
759 blink::WebCryptoKey* key) { 805 blink::WebCryptoKey* key) {
760
761 DCHECK(!algorithm.isNull()); 806 DCHECK(!algorithm.isNull());
762 807
763 CK_MECHANISM_TYPE mechanism; 808 CK_MECHANISM_TYPE mechanism;
764 CK_FLAGS flags; 809 CK_FLAGS flags;
765 Status status = 810 Status status =
766 WebCryptoAlgorithmToNssMechFlags(algorithm, &mechanism, &flags); 811 WebCryptoAlgorithmToNssMechFlags(algorithm, &mechanism, &flags);
767 if (status.IsError()) 812 if (status.IsError())
768 return status; 813 return status;
769 814
770 SECItem key_item = MakeSECItemForBuffer(key_data); 815 SECItem key_item = MakeSECItemForBuffer(key_data);
771 816
772 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); 817 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
773 crypto::ScopedPK11SymKey pk11_sym_key( 818 crypto::ScopedPK11SymKey pk11_sym_key(
774 PK11_ImportSymKeyWithFlags(slot.get(), 819 PK11_ImportSymKeyWithFlags(slot.get(),
775 mechanism, 820 mechanism,
776 PK11_OriginUnwrap, 821 PK11_OriginUnwrap,
777 CKA_FLAGS_ONLY, 822 CKA_FLAGS_ONLY,
778 &key_item, 823 &key_item,
779 flags, 824 flags,
780 false, 825 false,
781 NULL)); 826 NULL));
782 if (!pk11_sym_key.get()) 827 if (!pk11_sym_key.get())
783 return Status::OperationError(); 828 return Status::OperationError();
784 829
785 blink::WebCryptoKeyAlgorithm key_algorithm; 830 blink::WebCryptoKeyAlgorithm key_algorithm;
786 if (!CreateSecretKeyAlgorithm( 831 if (!CreateSecretKeyAlgorithm(
787 algorithm, key_data.byte_length(), &key_algorithm)) 832 algorithm, key_data.byte_length(), &key_algorithm))
788 return Status::ErrorUnexpected(); 833 return Status::ErrorUnexpected();
789 834
790 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), 835 scoped_ptr<SymKey> key_handle;
836 status = SymKey::Create(pk11_sym_key.Pass(), &key_handle);
837 if (status.IsError())
838 return status;
839
840 *key = blink::WebCryptoKey::create(key_handle.release(),
791 blink::WebCryptoKeyTypeSecret, 841 blink::WebCryptoKeyTypeSecret,
792 extractable, 842 extractable,
793 key_algorithm, 843 key_algorithm,
794 usage_mask); 844 usage_mask);
795 return Status::Success(); 845 return Status::Success();
796 } 846 }
797 847
798 Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) { 848 Status ExportKeyRaw(SymKey* key, std::vector<uint8>* buffer) {
799 if (PK11_ExtractKeyValue(key->key()) != SECSuccess) 849 if (PK11_ExtractKeyValue(key->key()) != SECSuccess)
800 return Status::OperationError(); 850 return Status::OperationError();
801 851
802 // http://crbug.com/366427: the spec does not define any other failures for 852 // http://crbug.com/366427: the spec does not define any other failures for
803 // exporting, so none of the subsequent errors are spec compliant. 853 // exporting, so none of the subsequent errors are spec compliant.
804 const SECItem* key_data = PK11_GetKeyData(key->key()); 854 const SECItem* key_data = PK11_GetKeyData(key->key());
805 if (!key_data) 855 if (!key_data)
806 return Status::OperationError(); 856 return Status::OperationError();
807 857
808 *buffer = CreateArrayBuffer(key_data->data, key_data->len); 858 buffer->assign(key_data->data, key_data->data + key_data->len);
809 859
810 return Status::Success(); 860 return Status::Success();
811 } 861 }
812 862
813 namespace { 863 namespace {
814 864
815 typedef scoped_ptr<CERTSubjectPublicKeyInfo, 865 typedef scoped_ptr<CERTSubjectPublicKeyInfo,
816 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, 866 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo,
817 SECKEY_DestroySubjectPublicKeyInfo> > 867 SECKEY_DestroySubjectPublicKeyInfo> >
818 ScopedCERTSubjectPublicKeyInfo; 868 ScopedCERTSubjectPublicKeyInfo;
(...skipping 17 matching lines...) Expand all
836 return false; 886 return false;
837 } 887 }
838 888
839 } // namespace 889 } // namespace
840 890
841 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm, 891 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm,
842 const CryptoData& key_data, 892 const CryptoData& key_data,
843 bool extractable, 893 bool extractable,
844 blink::WebCryptoKeyUsageMask usage_mask, 894 blink::WebCryptoKeyUsageMask usage_mask,
845 blink::WebCryptoKey* key) { 895 blink::WebCryptoKey* key) {
846
847 DCHECK(key); 896 DCHECK(key);
848 897
849 if (!key_data.byte_length()) 898 if (!key_data.byte_length())
850 return Status::ErrorImportEmptyKeyData(); 899 return Status::ErrorImportEmptyKeyData();
851 DCHECK(key_data.bytes()); 900 DCHECK(key_data.bytes());
852 901
853 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject 902 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject
854 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. 903 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo.
855 SECItem spki_item = MakeSECItemForBuffer(key_data); 904 SECItem spki_item = MakeSECItemForBuffer(key_data);
856 const ScopedCERTSubjectPublicKeyInfo spki( 905 const ScopedCERTSubjectPublicKeyInfo spki(
857 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); 906 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
858 if (!spki) 907 if (!spki)
859 return Status::DataError(); 908 return Status::DataError();
860 909
861 crypto::ScopedSECKEYPublicKey sec_public_key( 910 crypto::ScopedSECKEYPublicKey sec_public_key(
862 SECKEY_ExtractPublicKey(spki.get())); 911 SECKEY_ExtractPublicKey(spki.get()));
863 if (!sec_public_key) 912 if (!sec_public_key)
864 return Status::DataError(); 913 return Status::DataError();
865 914
866 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); 915 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get());
867 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) 916 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm))
868 return Status::DataError(); 917 return Status::DataError();
869 918
870 blink::WebCryptoKeyAlgorithm key_algorithm; 919 blink::WebCryptoKeyAlgorithm key_algorithm;
871 if (!CreatePublicKeyAlgorithm( 920 if (!CreatePublicKeyAlgorithm(
872 algorithm, sec_public_key.get(), &key_algorithm)) 921 algorithm, sec_public_key.get(), &key_algorithm))
873 return Status::ErrorUnexpected(); 922 return Status::ErrorUnexpected();
874 923
875 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), 924 scoped_ptr<PublicKey> key_handle;
925 Status status = PublicKey::Create(sec_public_key.Pass(), &key_handle);
926 if (status.IsError())
927 return status;
928
929 *key = blink::WebCryptoKey::create(key_handle.release(),
876 blink::WebCryptoKeyTypePublic, 930 blink::WebCryptoKeyTypePublic,
877 extractable, 931 extractable,
878 key_algorithm, 932 key_algorithm,
879 usage_mask); 933 usage_mask);
880 934
881 return Status::Success(); 935 return Status::Success();
882 } 936 }
883 937
884 Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) { 938 Status ExportKeySpki(PublicKey* key, std::vector<uint8>* buffer) {
885 const crypto::ScopedSECItem spki_der( 939 const crypto::ScopedSECItem spki_der(
886 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key())); 940 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key()));
887 // http://crbug.com/366427: the spec does not define any other failures for 941 // http://crbug.com/366427: the spec does not define any other failures for
888 // exporting, so none of the subsequent errors are spec compliant. 942 // exporting, so none of the subsequent errors are spec compliant.
889 if (!spki_der) 943 if (!spki_der)
890 return Status::OperationError(); 944 return Status::OperationError();
891 945
892 DCHECK(spki_der->data); 946 DCHECK(spki_der->data);
893 DCHECK(spki_der->len); 947 DCHECK(spki_der->len);
894 948
895 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); 949 buffer->assign(spki_der->data, spki_der->data + spki_der->len);
896 950
897 return Status::Success(); 951 return Status::Success();
898 } 952 }
899 953
900 Status ExportRsaPublicKey(PublicKey* key, 954 Status ExportRsaPublicKey(PublicKey* key,
901 std::vector<uint8>* modulus, 955 std::vector<uint8>* modulus,
902 std::vector<uint8>* public_exponent) { 956 std::vector<uint8>* public_exponent) {
903 DCHECK(key); 957 DCHECK(key);
904 DCHECK(key->key()); 958 DCHECK(key->key());
905 if (key->key()->keyType != rsaKey) 959 if (key->key()->keyType != rsaKey)
906 return Status::ErrorUnsupported(); 960 return Status::ErrorUnsupported();
907 CopySECItemToVector(key->key()->u.rsa.modulus, modulus); 961 CopySECItemToVector(key->key()->u.rsa.modulus, modulus);
908 CopySECItemToVector(key->key()->u.rsa.publicExponent, public_exponent); 962 CopySECItemToVector(key->key()->u.rsa.publicExponent, public_exponent);
909 if (modulus->empty() || public_exponent->empty()) 963 if (modulus->empty() || public_exponent->empty())
910 return Status::ErrorUnexpected(); 964 return Status::ErrorUnexpected();
911 return Status::Success(); 965 return Status::Success();
912 } 966 }
913 967
914 Status ExportKeyPkcs8(PrivateKey* key, 968 Status ExportKeyPkcs8(PrivateKey* key,
915 const blink::WebCryptoKeyAlgorithm& key_algorithm, 969 const blink::WebCryptoKeyAlgorithm& key_algorithm,
916 blink::WebArrayBuffer* buffer) { 970 std::vector<uint8>* buffer) {
917 // TODO(eroman): Support other RSA key types as they are added to Blink. 971 // TODO(eroman): Support other RSA key types as they are added to Blink.
918 if (key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 && 972 if (key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 &&
919 key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5) 973 key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5)
920 return Status::ErrorUnsupported(); 974 return Status::ErrorUnsupported();
921 975
922 #if defined(USE_NSS) 976 #if defined(USE_NSS)
923 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code. 977 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code.
924 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; 978 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
925 const int kPrivateKeyInfoVersion = 0; 979 const int kPrivateKeyInfoVersion = 0;
926 980
(...skipping 24 matching lines...) Expand all
951 1005
952 if (!SEC_ASN1EncodeInteger( 1006 if (!SEC_ASN1EncodeInteger(
953 arena.get(), &private_key_info.version, kPrivateKeyInfoVersion)) 1007 arena.get(), &private_key_info.version, kPrivateKeyInfoVersion))
954 return Status::OperationError(); 1008 return Status::OperationError();
955 1009
956 crypto::ScopedSECItem encoded_key( 1010 crypto::ScopedSECItem encoded_key(
957 SEC_ASN1EncodeItem(NULL, 1011 SEC_ASN1EncodeItem(NULL,
958 NULL, 1012 NULL,
959 &private_key_info, 1013 &private_key_info,
960 SEC_ASN1_GET(SECKEY_PrivateKeyInfoTemplate))); 1014 SEC_ASN1_GET(SECKEY_PrivateKeyInfoTemplate)));
961 #else // defined(USE_NSS) 1015 #else // defined(USE_NSS)
962 crypto::ScopedSECItem encoded_key( 1016 crypto::ScopedSECItem encoded_key(
963 PK11_ExportDERPrivateKeyInfo(key->key(), NULL)); 1017 PK11_ExportDERPrivateKeyInfo(key->key(), NULL));
964 #endif // defined(USE_NSS) 1018 #endif // defined(USE_NSS)
965 1019
966 if (!encoded_key.get()) 1020 if (!encoded_key.get())
967 return Status::OperationError(); 1021 return Status::OperationError();
968 1022
969 *buffer = CreateArrayBuffer(encoded_key->data, encoded_key->len); 1023 buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len);
970 return Status::Success(); 1024 return Status::Success();
971 } 1025 }
972 1026
973 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm, 1027 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
974 const CryptoData& key_data, 1028 const CryptoData& key_data,
975 bool extractable, 1029 bool extractable,
976 blink::WebCryptoKeyUsageMask usage_mask, 1030 blink::WebCryptoKeyUsageMask usage_mask,
977 blink::WebCryptoKey* key) { 1031 blink::WebCryptoKey* key) {
978
979 DCHECK(key); 1032 DCHECK(key);
980 1033
981 if (!key_data.byte_length()) 1034 if (!key_data.byte_length())
982 return Status::ErrorImportEmptyKeyData(); 1035 return Status::ErrorImportEmptyKeyData();
983 DCHECK(key_data.bytes()); 1036 DCHECK(key_data.bytes());
984 1037
985 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8 1038 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8
986 // private key info object. 1039 // private key info object.
987 SECItem pki_der = MakeSECItemForBuffer(key_data); 1040 SECItem pki_der = MakeSECItemForBuffer(key_data);
988 1041
(...skipping 14 matching lines...) Expand all
1003 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); 1056 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key);
1004 1057
1005 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); 1058 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get());
1006 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) 1059 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm))
1007 return Status::DataError(); 1060 return Status::DataError();
1008 1061
1009 blink::WebCryptoKeyAlgorithm key_algorithm; 1062 blink::WebCryptoKeyAlgorithm key_algorithm;
1010 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) 1063 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm))
1011 return Status::ErrorUnexpected(); 1064 return Status::ErrorUnexpected();
1012 1065
1013 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), 1066 scoped_ptr<PrivateKey> key_handle;
1067 Status status =
1068 PrivateKey::Create(private_key.Pass(), key_algorithm, &key_handle);
1069 if (status.IsError())
1070 return status;
1071
1072 *key = blink::WebCryptoKey::create(key_handle.release(),
1014 blink::WebCryptoKeyTypePrivate, 1073 blink::WebCryptoKeyTypePrivate,
1015 extractable, 1074 extractable,
1016 key_algorithm, 1075 key_algorithm,
1017 usage_mask); 1076 usage_mask);
1018 1077
1019 return Status::Success(); 1078 return Status::Success();
1020 } 1079 }
1021 1080
1022 // ----------------------------------- 1081 // -----------------------------------
1023 // Hmac 1082 // Hmac
1024 // ----------------------------------- 1083 // -----------------------------------
1025 1084
1026 Status SignHmac(SymKey* key, 1085 Status SignHmac(SymKey* key,
1027 const blink::WebCryptoAlgorithm& hash, 1086 const blink::WebCryptoAlgorithm& hash,
1028 const CryptoData& data, 1087 const CryptoData& data,
1029 blink::WebArrayBuffer* buffer) { 1088 std::vector<uint8>* buffer) {
1030 DCHECK_EQ(PK11_GetMechanism(key->key()), WebCryptoHashToHMACMechanism(hash)); 1089 DCHECK_EQ(PK11_GetMechanism(key->key()), WebCryptoHashToHMACMechanism(hash));
1031 1090
1032 SECItem param_item = {siBuffer, NULL, 0}; 1091 SECItem param_item = {siBuffer, NULL, 0};
1033 SECItem data_item = MakeSECItemForBuffer(data); 1092 SECItem data_item = MakeSECItemForBuffer(data);
1034 // First call is to figure out the length. 1093 // First call is to figure out the length.
1035 SECItem signature_item = {siBuffer, NULL, 0}; 1094 SECItem signature_item = {siBuffer, NULL, 0};
1036 1095
1037 if (PK11_SignWithSymKey(key->key(), 1096 if (PK11_SignWithSymKey(key->key(),
1038 PK11_GetMechanism(key->key()), 1097 PK11_GetMechanism(key->key()),
1039 &param_item, 1098 &param_item,
1040 &signature_item, 1099 &signature_item,
1041 &data_item) != SECSuccess) { 1100 &data_item) != SECSuccess) {
1042 return Status::OperationError(); 1101 return Status::OperationError();
1043 } 1102 }
1044 1103
1045 DCHECK_NE(0u, signature_item.len); 1104 DCHECK_NE(0u, signature_item.len);
1046 1105
1047 *buffer = blink::WebArrayBuffer::create(signature_item.len, 1); 1106 buffer->resize(signature_item.len);
1048 signature_item.data = reinterpret_cast<unsigned char*>(buffer->data()); 1107 signature_item.data = Uint8VectorStart(buffer);
1049 1108
1050 if (PK11_SignWithSymKey(key->key(), 1109 if (PK11_SignWithSymKey(key->key(),
1051 PK11_GetMechanism(key->key()), 1110 PK11_GetMechanism(key->key()),
1052 &param_item, 1111 &param_item,
1053 &signature_item, 1112 &signature_item,
1054 &data_item) != SECSuccess) { 1113 &data_item) != SECSuccess) {
1055 return Status::OperationError(); 1114 return Status::OperationError();
1056 } 1115 }
1057 1116
1058 DCHECK_EQ(buffer->byteLength(), signature_item.len); 1117 DCHECK_EQ(buffer->size(), signature_item.len);
1059 return Status::Success(); 1118 return Status::Success();
1060 } 1119 }
1061 1120
1062 // ----------------------------------- 1121 // -----------------------------------
1063 // RsaEsPkcs1v1_5 1122 // RsaEsPkcs1v1_5
1064 // ----------------------------------- 1123 // -----------------------------------
1065 1124
1066 Status EncryptRsaEsPkcs1v1_5(PublicKey* key, 1125 Status EncryptRsaEsPkcs1v1_5(PublicKey* key,
1067 const CryptoData& data, 1126 const CryptoData& data,
1068 blink::WebArrayBuffer* buffer) { 1127 std::vector<uint8>* buffer) {
1069 const unsigned int encrypted_length_bytes = 1128 const unsigned int encrypted_length_bytes =
1070 SECKEY_PublicKeyStrength(key->key()); 1129 SECKEY_PublicKeyStrength(key->key());
1071 1130
1072 // RSAES can operate on messages up to a length of k - 11, where k is the 1131 // RSAES can operate on messages up to a length of k - 11, where k is the
1073 // octet length of the RSA modulus. 1132 // octet length of the RSA modulus.
1074 if (encrypted_length_bytes < 11 || 1133 if (encrypted_length_bytes < 11 ||
1075 encrypted_length_bytes - 11 < data.byte_length()) 1134 encrypted_length_bytes - 11 < data.byte_length())
1076 return Status::ErrorDataTooLarge(); 1135 return Status::ErrorDataTooLarge();
1077 1136
1078 *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1); 1137 buffer->resize(encrypted_length_bytes);
1079 unsigned char* const buffer_data = 1138 unsigned char* const buffer_data = Uint8VectorStart(buffer);
1080 reinterpret_cast<unsigned char*>(buffer->data());
1081 1139
1082 if (PK11_PubEncryptPKCS1(key->key(), 1140 if (PK11_PubEncryptPKCS1(key->key(),
1083 buffer_data, 1141 buffer_data,
1084 const_cast<unsigned char*>(data.bytes()), 1142 const_cast<unsigned char*>(data.bytes()),
1085 data.byte_length(), 1143 data.byte_length(),
1086 NULL) != SECSuccess) { 1144 NULL) != SECSuccess) {
1087 return Status::OperationError(); 1145 return Status::OperationError();
1088 } 1146 }
1089 return Status::Success(); 1147 return Status::Success();
1090 } 1148 }
1091 1149
1092 Status DecryptRsaEsPkcs1v1_5(PrivateKey* key, 1150 Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
1093 const CryptoData& data, 1151 const CryptoData& data,
1094 blink::WebArrayBuffer* buffer) { 1152 std::vector<uint8>* buffer) {
1095 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key()); 1153 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key());
1096 if (modulus_length_bytes <= 0) 1154 if (modulus_length_bytes <= 0)
1097 return Status::ErrorUnexpected(); 1155 return Status::ErrorUnexpected();
1098 const unsigned int max_output_length_bytes = modulus_length_bytes; 1156 const unsigned int max_output_length_bytes = modulus_length_bytes;
1099 1157
1100 *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1); 1158 buffer->resize(max_output_length_bytes);
1101 unsigned char* const buffer_data = 1159 unsigned char* const buffer_data = Uint8VectorStart(buffer);
1102 reinterpret_cast<unsigned char*>(buffer->data());
1103 1160
1104 unsigned int output_length_bytes = 0; 1161 unsigned int output_length_bytes = 0;
1105 if (PK11_PrivDecryptPKCS1(key->key(), 1162 if (PK11_PrivDecryptPKCS1(key->key(),
1106 buffer_data, 1163 buffer_data,
1107 &output_length_bytes, 1164 &output_length_bytes,
1108 max_output_length_bytes, 1165 max_output_length_bytes,
1109 const_cast<unsigned char*>(data.bytes()), 1166 const_cast<unsigned char*>(data.bytes()),
1110 data.byte_length()) != SECSuccess) { 1167 data.byte_length()) != SECSuccess) {
1111 return Status::OperationError(); 1168 return Status::OperationError();
1112 } 1169 }
1113 DCHECK_LE(output_length_bytes, max_output_length_bytes); 1170 DCHECK_LE(output_length_bytes, max_output_length_bytes);
1114 ShrinkBuffer(buffer, output_length_bytes); 1171 buffer->resize(output_length_bytes);
1115 return Status::Success(); 1172 return Status::Success();
1116 } 1173 }
1117 1174
1118 // ----------------------------------- 1175 // -----------------------------------
1119 // RsaSsaPkcs1v1_5 1176 // RsaSsaPkcs1v1_5
1120 // ----------------------------------- 1177 // -----------------------------------
1121 1178
1122 Status SignRsaSsaPkcs1v1_5(PrivateKey* key, 1179 Status SignRsaSsaPkcs1v1_5(PrivateKey* key,
1123 const blink::WebCryptoAlgorithm& hash, 1180 const blink::WebCryptoAlgorithm& hash,
1124 const CryptoData& data, 1181 const CryptoData& data,
1125 blink::WebArrayBuffer* buffer) { 1182 std::vector<uint8>* buffer) {
1126 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the 1183 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the
1127 // inner hash of the input Web Crypto algorithm. 1184 // inner hash of the input Web Crypto algorithm.
1128 SECOidTag sign_alg_tag; 1185 SECOidTag sign_alg_tag;
1129 switch (hash.id()) { 1186 switch (hash.id()) {
1130 case blink::WebCryptoAlgorithmIdSha1: 1187 case blink::WebCryptoAlgorithmIdSha1:
1131 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 1188 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
1132 break; 1189 break;
1133 case blink::WebCryptoAlgorithmIdSha256: 1190 case blink::WebCryptoAlgorithmIdSha256:
1134 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; 1191 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
1135 break; 1192 break;
1136 case blink::WebCryptoAlgorithmIdSha384: 1193 case blink::WebCryptoAlgorithmIdSha384:
1137 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; 1194 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
1138 break; 1195 break;
1139 case blink::WebCryptoAlgorithmIdSha512: 1196 case blink::WebCryptoAlgorithmIdSha512:
1140 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; 1197 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
1141 break; 1198 break;
1142 default: 1199 default:
1143 return Status::ErrorUnsupported(); 1200 return Status::ErrorUnsupported();
1144 } 1201 }
1145 1202
1146 crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0)); 1203 crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0));
1147 if (SEC_SignData(signature_item.get(), 1204 if (SEC_SignData(signature_item.get(),
1148 data.bytes(), 1205 data.bytes(),
1149 data.byte_length(), 1206 data.byte_length(),
1150 key->key(), 1207 key->key(),
1151 sign_alg_tag) != SECSuccess) { 1208 sign_alg_tag) != SECSuccess) {
1152 return Status::OperationError(); 1209 return Status::OperationError();
1153 } 1210 }
1154 1211
1155 *buffer = CreateArrayBuffer(signature_item->data, signature_item->len); 1212 buffer->assign(signature_item->data,
1213 signature_item->data + signature_item->len);
1156 return Status::Success(); 1214 return Status::Success();
1157 } 1215 }
1158 1216
1159 Status VerifyRsaSsaPkcs1v1_5(PublicKey* key, 1217 Status VerifyRsaSsaPkcs1v1_5(PublicKey* key,
1160 const blink::WebCryptoAlgorithm& hash, 1218 const blink::WebCryptoAlgorithm& hash,
1161 const CryptoData& signature, 1219 const CryptoData& signature,
1162 const CryptoData& data, 1220 const CryptoData& data,
1163 bool* signature_match) { 1221 bool* signature_match) {
1164 const SECItem signature_item = MakeSECItemForBuffer(signature); 1222 const SECItem signature_item = MakeSECItemForBuffer(signature);
1165 1223
(...skipping 24 matching lines...) Expand all
1190 hash_alg_tag, 1248 hash_alg_tag,
1191 NULL, 1249 NULL,
1192 NULL); 1250 NULL);
1193 return Status::Success(); 1251 return Status::Success();
1194 } 1252 }
1195 1253
1196 Status EncryptDecryptAesCbc(EncryptOrDecrypt mode, 1254 Status EncryptDecryptAesCbc(EncryptOrDecrypt mode,
1197 SymKey* key, 1255 SymKey* key,
1198 const CryptoData& data, 1256 const CryptoData& data,
1199 const CryptoData& iv, 1257 const CryptoData& iv,
1200 blink::WebArrayBuffer* buffer) { 1258 std::vector<uint8>* buffer) {
1201 // TODO(eroman): Inline. 1259 // TODO(eroman): Inline.
1202 return AesCbcEncryptDecrypt(mode, key, iv, data, buffer); 1260 return AesCbcEncryptDecrypt(mode, key, iv, data, buffer);
1203 } 1261 }
1204 1262
1205 Status EncryptDecryptAesGcm(EncryptOrDecrypt mode, 1263 Status EncryptDecryptAesGcm(EncryptOrDecrypt mode,
1206 SymKey* key, 1264 SymKey* key,
1207 const CryptoData& data, 1265 const CryptoData& data,
1208 const CryptoData& iv, 1266 const CryptoData& iv,
1209 const CryptoData& additional_data, 1267 const CryptoData& additional_data,
1210 unsigned int tag_length_bits, 1268 unsigned int tag_length_bits,
1211 blink::WebArrayBuffer* buffer) { 1269 std::vector<uint8>* buffer) {
1212 // TODO(eroman): Inline. 1270 // TODO(eroman): Inline.
1213 return AesGcmEncryptDecrypt( 1271 return AesGcmEncryptDecrypt(
1214 mode, key, data, iv, additional_data, tag_length_bits, buffer); 1272 mode, key, data, iv, additional_data, tag_length_bits, buffer);
1215 } 1273 }
1216 1274
1217 // ----------------------------------- 1275 // -----------------------------------
1218 // Key generation 1276 // Key generation
1219 // ----------------------------------- 1277 // -----------------------------------
1220 1278
1221 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, 1279 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 operation_flags, 1335 operation_flags,
1278 operation_flags_mask, 1336 operation_flags_mask,
1279 NULL)); 1337 NULL));
1280 if (!private_key) 1338 if (!private_key)
1281 return Status::OperationError(); 1339 return Status::OperationError();
1282 1340
1283 blink::WebCryptoKeyAlgorithm key_algorithm; 1341 blink::WebCryptoKeyAlgorithm key_algorithm;
1284 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm)) 1342 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm))
1285 return Status::ErrorUnexpected(); 1343 return Status::ErrorUnexpected();
1286 1344
1287 *public_key = blink::WebCryptoKey::create( 1345 scoped_ptr<PublicKey> public_key_handle;
1288 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), 1346 Status status = PublicKey::Create(
1289 blink::WebCryptoKeyTypePublic, 1347 crypto::ScopedSECKEYPublicKey(sec_public_key), &public_key_handle);
1290 true, 1348 if (status.IsError())
1291 key_algorithm, 1349 return status;
1292 usage_mask); 1350
1293 *private_key = 1351 scoped_ptr<PrivateKey> private_key_handle;
1294 blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()), 1352 status = PrivateKey::Create(
1295 blink::WebCryptoKeyTypePrivate, 1353 scoped_sec_private_key.Pass(), key_algorithm, &private_key_handle);
1296 extractable, 1354 if (status.IsError())
1297 key_algorithm, 1355 return status;
1298 usage_mask); 1356
1357 *public_key = blink::WebCryptoKey::create(public_key_handle.release(),
1358 blink::WebCryptoKeyTypePublic,
1359 true,
1360 key_algorithm,
1361 usage_mask);
1362 *private_key = blink::WebCryptoKey::create(private_key_handle.release(),
1363 blink::WebCryptoKeyTypePrivate,
1364 extractable,
1365 key_algorithm,
1366 usage_mask);
1299 1367
1300 return Status::Success(); 1368 return Status::Success();
1301 } 1369 }
1302 1370
1303 void Init() { crypto::EnsureNSSInit(); } 1371 void Init() {
1372 crypto::EnsureNSSInit();
1373 }
1304 1374
1305 Status DigestSha(blink::WebCryptoAlgorithmId algorithm, 1375 Status DigestSha(blink::WebCryptoAlgorithmId algorithm,
1306 const CryptoData& data, 1376 const CryptoData& data,
1307 blink::WebArrayBuffer* buffer) { 1377 std::vector<uint8>* buffer) {
1308 DigestorNSS digestor(algorithm); 1378 DigestorNSS digestor(algorithm);
1309 Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length()); 1379 Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length());
1310 // http://crbug.com/366427: the spec does not define any other failures for 1380 // http://crbug.com/366427: the spec does not define any other failures for
1311 // digest, so none of the subsequent errors are spec compliant. 1381 // digest, so none of the subsequent errors are spec compliant.
1312 if (!error.IsSuccess()) 1382 if (!error.IsSuccess())
1313 return error; 1383 return error;
1314 return digestor.FinishWithWebArrayAndStatus(buffer); 1384 return digestor.FinishWithVectorAndStatus(buffer);
1315 } 1385 }
1316 1386
1317 scoped_ptr<blink::WebCryptoDigestor> CreateDigestor( 1387 scoped_ptr<blink::WebCryptoDigestor> CreateDigestor(
1318 blink::WebCryptoAlgorithmId algorithm_id) { 1388 blink::WebCryptoAlgorithmId algorithm_id) {
1319 return scoped_ptr<blink::WebCryptoDigestor>(new DigestorNSS(algorithm_id)); 1389 return scoped_ptr<blink::WebCryptoDigestor>(new DigestorNSS(algorithm_id));
1320 } 1390 }
1321 1391
1322 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, 1392 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
1323 bool extractable, 1393 bool extractable,
1324 blink::WebCryptoKeyUsageMask usage_mask, 1394 blink::WebCryptoKeyUsageMask usage_mask,
(...skipping 12 matching lines...) Expand all
1337 crypto::ScopedPK11SymKey pk11_key( 1407 crypto::ScopedPK11SymKey pk11_key(
1338 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); 1408 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL));
1339 1409
1340 if (!pk11_key) 1410 if (!pk11_key)
1341 return Status::OperationError(); 1411 return Status::OperationError();
1342 1412
1343 blink::WebCryptoKeyAlgorithm key_algorithm; 1413 blink::WebCryptoKeyAlgorithm key_algorithm;
1344 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm)) 1414 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm))
1345 return Status::ErrorUnexpected(); 1415 return Status::ErrorUnexpected();
1346 1416
1347 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), 1417 scoped_ptr<SymKey> key_handle;
1348 key_type, 1418 Status status = SymKey::Create(pk11_key.Pass(), &key_handle);
1349 extractable, 1419 if (status.IsError())
1350 key_algorithm, 1420 return status;
1351 usage_mask); 1421
1422 *key = blink::WebCryptoKey::create(
1423 key_handle.release(), key_type, extractable, key_algorithm, usage_mask);
1352 return Status::Success(); 1424 return Status::Success();
1353 } 1425 }
1354 1426
1355 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, 1427 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
1356 bool extractable, 1428 bool extractable,
1357 blink::WebCryptoKeyUsageMask usage_mask, 1429 blink::WebCryptoKeyUsageMask usage_mask,
1358 const CryptoData& modulus_data, 1430 const CryptoData& modulus_data,
1359 const CryptoData& exponent_data, 1431 const CryptoData& exponent_data,
1360 blink::WebCryptoKey* key) { 1432 blink::WebCryptoKey* key) {
1361
1362 if (!modulus_data.byte_length()) 1433 if (!modulus_data.byte_length())
1363 return Status::ErrorImportRsaEmptyModulus(); 1434 return Status::ErrorImportRsaEmptyModulus();
1364 1435
1365 if (!exponent_data.byte_length()) 1436 if (!exponent_data.byte_length())
1366 return Status::ErrorImportRsaEmptyExponent(); 1437 return Status::ErrorImportRsaEmptyExponent();
1367 1438
1368 DCHECK(modulus_data.bytes()); 1439 DCHECK(modulus_data.bytes());
1369 DCHECK(exponent_data.bytes()); 1440 DCHECK(exponent_data.bytes());
1370 1441
1371 // NSS does not provide a way to create an RSA public key directly from the 1442 // NSS does not provide a way to create an RSA public key directly from the
(...skipping 28 matching lines...) Expand all
1400 // Import the DER-encoded public key to create an RSA SECKEYPublicKey. 1471 // Import the DER-encoded public key to create an RSA SECKEYPublicKey.
1401 crypto::ScopedSECKEYPublicKey pubkey( 1472 crypto::ScopedSECKEYPublicKey pubkey(
1402 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA)); 1473 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA));
1403 if (!pubkey) 1474 if (!pubkey)
1404 return Status::OperationError(); 1475 return Status::OperationError();
1405 1476
1406 blink::WebCryptoKeyAlgorithm key_algorithm; 1477 blink::WebCryptoKeyAlgorithm key_algorithm;
1407 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm)) 1478 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm))
1408 return Status::ErrorUnexpected(); 1479 return Status::ErrorUnexpected();
1409 1480
1410 *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()), 1481 scoped_ptr<PublicKey> key_handle;
1482 Status status = PublicKey::Create(pubkey.Pass(), &key_handle);
1483 if (status.IsError())
1484 return status;
1485
1486 *key = blink::WebCryptoKey::create(key_handle.release(),
1411 blink::WebCryptoKeyTypePublic, 1487 blink::WebCryptoKeyTypePublic,
1412 extractable, 1488 extractable,
1413 key_algorithm, 1489 key_algorithm,
1414 usage_mask); 1490 usage_mask);
1415 return Status::Success(); 1491 return Status::Success();
1416 } 1492 }
1417 1493
1418 Status WrapSymKeyAesKw(SymKey* wrapping_key, 1494 Status WrapSymKeyAesKw(SymKey* wrapping_key,
1419 SymKey* key, 1495 SymKey* key,
1420 blink::WebArrayBuffer* buffer) { 1496 std::vector<uint8>* buffer) {
1421 // The data size must be at least 16 bytes and a multiple of 8 bytes. 1497 // The data size must be at least 16 bytes and a multiple of 8 bytes.
1422 // RFC 3394 does not specify a maximum allowed data length, but since only 1498 // RFC 3394 does not specify a maximum allowed data length, but since only
1423 // keys are being wrapped in this application (which are small), a reasonable 1499 // keys are being wrapped in this application (which are small), a reasonable
1424 // max limit is whatever will fit into an unsigned. For the max size test, 1500 // max limit is whatever will fit into an unsigned. For the max size test,
1425 // note that AES Key Wrap always adds 8 bytes to the input data size. 1501 // note that AES Key Wrap always adds 8 bytes to the input data size.
1426 const unsigned int input_length = PK11_GetKeyLength(key->key()); 1502 const unsigned int input_length = PK11_GetKeyLength(key->key());
1427 if (input_length < 16) 1503 if (input_length < 16)
1428 return Status::ErrorDataTooSmall(); 1504 return Status::ErrorDataTooSmall();
1429 if (input_length > UINT_MAX - 8) 1505 if (input_length > UINT_MAX - 8)
1430 return Status::ErrorDataTooLarge(); 1506 return Status::ErrorDataTooLarge();
1431 if (input_length % 8) 1507 if (input_length % 8)
1432 return Status::ErrorInvalidAesKwDataLength(); 1508 return Status::ErrorInvalidAesKwDataLength();
1433 1509
1434 SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv))); 1510 SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv)));
1435 crypto::ScopedSECItem param_item( 1511 crypto::ScopedSECItem param_item(
1436 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); 1512 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item));
1437 if (!param_item) 1513 if (!param_item)
1438 return Status::ErrorUnexpected(); 1514 return Status::ErrorUnexpected();
1439 1515
1440 const unsigned int output_length = input_length + 8; 1516 const unsigned int output_length = input_length + 8;
1441 *buffer = blink::WebArrayBuffer::create(output_length, 1); 1517 buffer->resize(output_length);
1442 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); 1518 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
1443 1519
1444 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, 1520 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP,
1445 param_item.get(), 1521 param_item.get(),
1446 wrapping_key->key(), 1522 wrapping_key->key(),
1447 key->key(), 1523 key->key(),
1448 &wrapped_key_item)) { 1524 &wrapped_key_item)) {
1449 return Status::OperationError(); 1525 return Status::OperationError();
1450 } 1526 }
1451 if (output_length != wrapped_key_item.len) 1527 if (output_length != wrapped_key_item.len)
(...skipping 20 matching lines...) Expand all
1472 status = DoUnwrapSymKeyAesKw( 1548 status = DoUnwrapSymKeyAesKw(
1473 wrapped_key_data, wrapping_key, mechanism, flags, &unwrapped_key); 1549 wrapped_key_data, wrapping_key, mechanism, flags, &unwrapped_key);
1474 if (status.IsError()) 1550 if (status.IsError())
1475 return status; 1551 return status;
1476 1552
1477 blink::WebCryptoKeyAlgorithm key_algorithm; 1553 blink::WebCryptoKeyAlgorithm key_algorithm;
1478 if (!CreateSecretKeyAlgorithm( 1554 if (!CreateSecretKeyAlgorithm(
1479 algorithm, PK11_GetKeyLength(unwrapped_key.get()), &key_algorithm)) 1555 algorithm, PK11_GetKeyLength(unwrapped_key.get()), &key_algorithm))
1480 return Status::ErrorUnexpected(); 1556 return Status::ErrorUnexpected();
1481 1557
1482 *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()), 1558 scoped_ptr<SymKey> key_handle;
1559 status = SymKey::Create(unwrapped_key.Pass(), &key_handle);
1560 if (status.IsError())
1561 return status;
1562
1563 *key = blink::WebCryptoKey::create(key_handle.release(),
1483 blink::WebCryptoKeyTypeSecret, 1564 blink::WebCryptoKeyTypeSecret,
1484 extractable, 1565 extractable,
1485 key_algorithm, 1566 key_algorithm,
1486 usage_mask); 1567 usage_mask);
1487 return Status::Success(); 1568 return Status::Success();
1488 } 1569 }
1489 1570
1490 Status DecryptAesKw(SymKey* wrapping_key, 1571 Status DecryptAesKw(SymKey* wrapping_key,
1491 const CryptoData& data, 1572 const CryptoData& data,
1492 blink::WebArrayBuffer* buffer) { 1573 std::vector<uint8>* buffer) {
1493 // Due to limitations in the NSS API for the AES-KW algorithm, |data| must be 1574 // Due to limitations in the NSS API for the AES-KW algorithm, |data| must be
1494 // temporarily viewed as a symmetric key to be unwrapped (decrypted). 1575 // temporarily viewed as a symmetric key to be unwrapped (decrypted).
1495 crypto::ScopedPK11SymKey decrypted; 1576 crypto::ScopedPK11SymKey decrypted;
1496 Status status = DoUnwrapSymKeyAesKw( 1577 Status status = DoUnwrapSymKeyAesKw(
1497 data, wrapping_key, CKK_GENERIC_SECRET, CKA_ENCRYPT, &decrypted); 1578 data, wrapping_key, CKK_GENERIC_SECRET, CKA_ENCRYPT, &decrypted);
1498 if (status.IsError()) 1579 if (status.IsError())
1499 return status; 1580 return status;
1500 1581
1501 // Once the decrypt is complete, extract the resultant raw bytes from NSS and 1582 // Once the decrypt is complete, extract the resultant raw bytes from NSS and
1502 // return them to the caller. 1583 // return them to the caller.
1503 if (PK11_ExtractKeyValue(decrypted.get()) != SECSuccess) 1584 if (PK11_ExtractKeyValue(decrypted.get()) != SECSuccess)
1504 return Status::OperationError(); 1585 return Status::OperationError();
1505 const SECItem* const key_data = PK11_GetKeyData(decrypted.get()); 1586 const SECItem* const key_data = PK11_GetKeyData(decrypted.get());
1506 if (!key_data) 1587 if (!key_data)
1507 return Status::OperationError(); 1588 return Status::OperationError();
1508 *buffer = webcrypto::CreateArrayBuffer(key_data->data, key_data->len); 1589 buffer->assign(key_data->data, key_data->data + key_data->len);
1509 1590
1510 return Status::Success(); 1591 return Status::Success();
1511 } 1592 }
1512 1593
1513 Status WrapSymKeyRsaEs(PublicKey* wrapping_key, 1594 Status WrapSymKeyRsaEs(PublicKey* wrapping_key,
1514 SymKey* key, 1595 SymKey* key,
1515 blink::WebArrayBuffer* buffer) { 1596 std::vector<uint8>* buffer) {
1516 // Check the raw length of the key to be wrapped against the max size allowed 1597 // Check the raw length of the key to be wrapped against the max size allowed
1517 // by the RSA wrapping key. With PKCS#1 v1.5 padding used in this function, 1598 // by the RSA wrapping key. With PKCS#1 v1.5 padding used in this function,
1518 // the maximum data length that can be encrypted is the wrapping_key's modulus 1599 // the maximum data length that can be encrypted is the wrapping_key's modulus
1519 // byte length minus eleven bytes. 1600 // byte length minus eleven bytes.
1520 const unsigned int input_length_bytes = PK11_GetKeyLength(key->key()); 1601 const unsigned int input_length_bytes = PK11_GetKeyLength(key->key());
1521 const unsigned int modulus_length_bytes = 1602 const unsigned int modulus_length_bytes =
1522 SECKEY_PublicKeyStrength(wrapping_key->key()); 1603 SECKEY_PublicKeyStrength(wrapping_key->key());
1523 if (modulus_length_bytes < 11 || 1604 if (modulus_length_bytes < 11 ||
1524 modulus_length_bytes - 11 < input_length_bytes) 1605 modulus_length_bytes - 11 < input_length_bytes)
1525 return Status::ErrorDataTooLarge(); 1606 return Status::ErrorDataTooLarge();
1526 1607
1527 *buffer = blink::WebArrayBuffer::create(modulus_length_bytes, 1); 1608 buffer->resize(modulus_length_bytes);
1528 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); 1609 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
1529 1610
1530 if (SECSuccess != 1611 if (SECSuccess !=
1531 PK11_PubWrapSymKey( 1612 PK11_PubWrapSymKey(
1532 CKM_RSA_PKCS, wrapping_key->key(), key->key(), &wrapped_key_item)) { 1613 CKM_RSA_PKCS, wrapping_key->key(), key->key(), &wrapped_key_item)) {
1533 return Status::OperationError(); 1614 return Status::OperationError();
1534 } 1615 }
1535 if (wrapped_key_item.len != modulus_length_bytes) 1616 if (wrapped_key_item.len != modulus_length_bytes)
1536 return Status::ErrorUnexpected(); 1617 return Status::ErrorUnexpected();
1537 1618
1538 return Status::Success(); 1619 return Status::Success();
1539 } 1620 }
1540 1621
1541 Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data, 1622 Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data,
1542 PrivateKey* wrapping_key, 1623 PrivateKey* wrapping_key,
1543 const blink::WebCryptoAlgorithm& algorithm, 1624 const blink::WebCryptoAlgorithm& algorithm,
1544 bool extractable, 1625 bool extractable,
1545 blink::WebCryptoKeyUsageMask usage_mask, 1626 blink::WebCryptoKeyUsageMask usage_mask,
1546 blink::WebCryptoKey* key) { 1627 blink::WebCryptoKey* key) {
1547
1548 // Verify wrapped_key_data size does not exceed the modulus of the RSA key. 1628 // Verify wrapped_key_data size does not exceed the modulus of the RSA key.
1549 const int modulus_length_bytes = 1629 const int modulus_length_bytes =
1550 PK11_GetPrivateModulusLen(wrapping_key->key()); 1630 PK11_GetPrivateModulusLen(wrapping_key->key());
1551 if (modulus_length_bytes <= 0) 1631 if (modulus_length_bytes <= 0)
1552 return Status::ErrorUnexpected(); 1632 return Status::ErrorUnexpected();
1553 if (wrapped_key_data.byte_length() > 1633 if (wrapped_key_data.byte_length() >
1554 static_cast<unsigned int>(modulus_length_bytes)) 1634 static_cast<unsigned int>(modulus_length_bytes))
1555 return Status::ErrorDataTooLarge(); 1635 return Status::ErrorDataTooLarge();
1556 1636
1557 // Determine the proper NSS key properties from the input algorithm. 1637 // Determine the proper NSS key properties from the input algorithm.
(...skipping 16 matching lines...) Expand all
1574 false)); 1654 false));
1575 if (!unwrapped_key) 1655 if (!unwrapped_key)
1576 return Status::OperationError(); 1656 return Status::OperationError();
1577 1657
1578 const unsigned int key_length = PK11_GetKeyLength(unwrapped_key.get()); 1658 const unsigned int key_length = PK11_GetKeyLength(unwrapped_key.get());
1579 1659
1580 blink::WebCryptoKeyAlgorithm key_algorithm; 1660 blink::WebCryptoKeyAlgorithm key_algorithm;
1581 if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm)) 1661 if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm))
1582 return Status::ErrorUnexpected(); 1662 return Status::ErrorUnexpected();
1583 1663
1584 *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()), 1664 scoped_ptr<SymKey> key_handle;
1665 status = SymKey::Create(unwrapped_key.Pass(), &key_handle);
1666 if (status.IsError())
1667 return status;
1668
1669 *key = blink::WebCryptoKey::create(key_handle.release(),
1585 blink::WebCryptoKeyTypeSecret, 1670 blink::WebCryptoKeyTypeSecret,
1586 extractable, 1671 extractable,
1587 key_algorithm, 1672 key_algorithm,
1588 usage_mask); 1673 usage_mask);
1589 return Status::Success(); 1674 return Status::Success();
1590 } 1675 }
1591 1676
1592 } // namespace platform 1677 } // namespace platform
1593 1678
1594 } // namespace webcrypto 1679 } // namespace webcrypto
1595 1680
1596 } // namespace content 1681 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698