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

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

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

Powered by Google App Engine
This is Rietveld 408576698