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

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

Issue 243433006: [webcrypto] Set the error type for failures. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase and try to fix android build... Created 6 years, 8 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 <vector> 7 #include <vector>
8 #include <openssl/aes.h> 8 #include <openssl/aes.h>
9 #include <openssl/evp.h> 9 #include <openssl/evp.h>
10 #include <openssl/hmac.h> 10 #include <openssl/hmac.h>
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // now it doesn't make much difference since the one-shot API would end up 92 // now it doesn't make much difference since the one-shot API would end up
93 // blowing out the memory and crashing anyway. 93 // blowing out the memory and crashing anyway.
94 return Status::ErrorDataTooLarge(); 94 return Status::ErrorDataTooLarge();
95 } 95 }
96 96
97 // Note: PKCS padding is enabled by default 97 // Note: PKCS padding is enabled by default
98 crypto::ScopedOpenSSL<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> context( 98 crypto::ScopedOpenSSL<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> context(
99 EVP_CIPHER_CTX_new()); 99 EVP_CIPHER_CTX_new());
100 100
101 if (!context.get()) 101 if (!context.get())
102 return Status::Error(); 102 return Status::OperationError();
103 103
104 const EVP_CIPHER* const cipher = GetAESCipherByKeyLength(key->key().size()); 104 const EVP_CIPHER* const cipher = GetAESCipherByKeyLength(key->key().size());
105 DCHECK(cipher); 105 DCHECK(cipher);
106 106
107 if (!EVP_CipherInit_ex(context.get(), 107 if (!EVP_CipherInit_ex(context.get(),
108 cipher, 108 cipher,
109 NULL, 109 NULL,
110 &key->key()[0], 110 &key->key()[0],
111 iv.bytes(), 111 iv.bytes(),
112 cipher_operation)) { 112 cipher_operation)) {
113 return Status::Error(); 113 return Status::OperationError();
114 } 114 }
115 115
116 // According to the openssl docs, the amount of data written may be as large 116 // According to the openssl docs, the amount of data written may be as large
117 // as (data_size + cipher_block_size - 1), constrained to a multiple of 117 // as (data_size + cipher_block_size - 1), constrained to a multiple of
118 // cipher_block_size. 118 // cipher_block_size.
119 unsigned int output_max_len = data.byte_length() + AES_BLOCK_SIZE - 1; 119 unsigned int output_max_len = data.byte_length() + AES_BLOCK_SIZE - 1;
120 const unsigned remainder = output_max_len % AES_BLOCK_SIZE; 120 const unsigned remainder = output_max_len % AES_BLOCK_SIZE;
121 if (remainder != 0) 121 if (remainder != 0)
122 output_max_len += AES_BLOCK_SIZE - remainder; 122 output_max_len += AES_BLOCK_SIZE - remainder;
123 DCHECK_GT(output_max_len, data.byte_length()); 123 DCHECK_GT(output_max_len, data.byte_length());
124 124
125 *buffer = blink::WebArrayBuffer::create(output_max_len, 1); 125 *buffer = blink::WebArrayBuffer::create(output_max_len, 1);
126 126
127 unsigned char* const buffer_data = 127 unsigned char* const buffer_data =
128 reinterpret_cast<unsigned char*>(buffer->data()); 128 reinterpret_cast<unsigned char*>(buffer->data());
129 129
130 int output_len = 0; 130 int output_len = 0;
131 if (!EVP_CipherUpdate(context.get(), 131 if (!EVP_CipherUpdate(context.get(),
132 buffer_data, 132 buffer_data,
133 &output_len, 133 &output_len,
134 data.bytes(), 134 data.bytes(),
135 data.byte_length())) 135 data.byte_length()))
136 return Status::Error(); 136 return Status::OperationError();
137 int final_output_chunk_len = 0; 137 int final_output_chunk_len = 0;
138 if (!EVP_CipherFinal_ex( 138 if (!EVP_CipherFinal_ex(
139 context.get(), buffer_data + output_len, &final_output_chunk_len)) { 139 context.get(), buffer_data + output_len, &final_output_chunk_len)) {
140 return Status::Error(); 140 return Status::OperationError();
141 } 141 }
142 142
143 const unsigned int final_output_len = 143 const unsigned int final_output_len =
144 static_cast<unsigned int>(output_len) + 144 static_cast<unsigned int>(output_len) +
145 static_cast<unsigned int>(final_output_chunk_len); 145 static_cast<unsigned int>(final_output_chunk_len);
146 DCHECK_LE(final_output_len, output_max_len); 146 DCHECK_LE(final_output_len, output_max_len);
147 147
148 ShrinkBuffer(buffer, final_output_len); 148 ShrinkBuffer(buffer, final_output_len);
149 149
150 return Status::Success(); 150 return Status::Success();
(...skipping 12 matching lines...) Expand all
163 return ConsumeWithStatus(data, size).IsSuccess(); 163 return ConsumeWithStatus(data, size).IsSuccess();
164 } 164 }
165 165
166 Status ConsumeWithStatus(const unsigned char* data, unsigned int size) { 166 Status ConsumeWithStatus(const unsigned char* data, unsigned int size) {
167 crypto::OpenSSLErrStackTracer(FROM_HERE); 167 crypto::OpenSSLErrStackTracer(FROM_HERE);
168 Status error = Init(); 168 Status error = Init();
169 if (!error.IsSuccess()) 169 if (!error.IsSuccess())
170 return error; 170 return error;
171 171
172 if (!EVP_DigestUpdate(digest_context_.get(), data, size)) 172 if (!EVP_DigestUpdate(digest_context_.get(), data, size))
173 return Status::Error(); 173 return Status::OperationError();
174 174
175 return Status::Success(); 175 return Status::Success();
176 } 176 }
177 177
178 virtual bool finish(unsigned char*& result_data, 178 virtual bool finish(unsigned char*& result_data,
179 unsigned int& result_data_size) { 179 unsigned int& result_data_size) {
180 Status error = FinishInternal(result_, &result_data_size); 180 Status error = FinishInternal(result_, &result_data_size);
181 if (!error.IsSuccess()) 181 if (!error.IsSuccess())
182 return false; 182 return false;
183 result_data = result_; 183 result_data = result_;
(...skipping 15 matching lines...) Expand all
199 private: 199 private:
200 Status Init() { 200 Status Init() {
201 if (initialized_) 201 if (initialized_)
202 return Status::Success(); 202 return Status::Success();
203 203
204 const EVP_MD* digest_algorithm = GetDigest(algorithm_id_); 204 const EVP_MD* digest_algorithm = GetDigest(algorithm_id_);
205 if (!digest_algorithm) 205 if (!digest_algorithm)
206 return Status::ErrorUnexpected(); 206 return Status::ErrorUnexpected();
207 207
208 if (!digest_context_.get()) 208 if (!digest_context_.get())
209 return Status::Error(); 209 return Status::OperationError();
210 210
211 if (!EVP_DigestInit_ex(digest_context_.get(), digest_algorithm, NULL)) 211 if (!EVP_DigestInit_ex(digest_context_.get(), digest_algorithm, NULL))
212 return Status::Error(); 212 return Status::OperationError();
213 213
214 initialized_ = true; 214 initialized_ = true;
215 return Status::Success(); 215 return Status::Success();
216 } 216 }
217 217
218 Status FinishInternal(unsigned char* result, unsigned int* result_size) { 218 Status FinishInternal(unsigned char* result, unsigned int* result_size) {
219 crypto::OpenSSLErrStackTracer(FROM_HERE); 219 crypto::OpenSSLErrStackTracer(FROM_HERE);
220 Status error = Init(); 220 Status error = Init();
221 if (!error.IsSuccess()) 221 if (!error.IsSuccess())
222 return error; 222 return error;
223 223
224 const int hash_expected_size = EVP_MD_CTX_size(digest_context_.get()); 224 const int hash_expected_size = EVP_MD_CTX_size(digest_context_.get());
225 if (hash_expected_size <= 0) 225 if (hash_expected_size <= 0)
226 return Status::ErrorUnexpected(); 226 return Status::ErrorUnexpected();
227 DCHECK_LE(hash_expected_size, EVP_MAX_MD_SIZE); 227 DCHECK_LE(hash_expected_size, EVP_MAX_MD_SIZE);
228 228
229 if (!EVP_DigestFinal_ex(digest_context_.get(), result, result_size) || 229 if (!EVP_DigestFinal_ex(digest_context_.get(), result, result_size) ||
230 static_cast<int>(*result_size) != hash_expected_size) 230 static_cast<int>(*result_size) != hash_expected_size)
231 return Status::Error(); 231 return Status::OperationError();
232 232
233 return Status::Success(); 233 return Status::Success();
234 } 234 }
235 235
236 bool initialized_; 236 bool initialized_;
237 crypto::ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> digest_context_; 237 crypto::ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> digest_context_;
238 blink::WebCryptoAlgorithmId algorithm_id_; 238 blink::WebCryptoAlgorithmId algorithm_id_;
239 unsigned char result_[EVP_MAX_MD_SIZE]; 239 unsigned char result_[EVP_MAX_MD_SIZE];
240 }; 240 };
241 241
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 unsigned keylen_bytes, 277 unsigned keylen_bytes,
278 blink::WebCryptoKey* key) { 278 blink::WebCryptoKey* key) {
279 // TODO(eroman): Is this right? 279 // TODO(eroman): Is this right?
280 if (keylen_bytes == 0) 280 if (keylen_bytes == 0)
281 return Status::ErrorGenerateKeyLength(); 281 return Status::ErrorGenerateKeyLength();
282 282
283 crypto::OpenSSLErrStackTracer(FROM_HERE); 283 crypto::OpenSSLErrStackTracer(FROM_HERE);
284 284
285 std::vector<unsigned char> random_bytes(keylen_bytes, 0); 285 std::vector<unsigned char> random_bytes(keylen_bytes, 0);
286 if (!(RAND_bytes(&random_bytes[0], keylen_bytes))) 286 if (!(RAND_bytes(&random_bytes[0], keylen_bytes)))
287 return Status::Error(); 287 return Status::OperationError();
288 288
289 blink::WebCryptoKeyAlgorithm key_algorithm; 289 blink::WebCryptoKeyAlgorithm key_algorithm;
290 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm)) 290 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm))
291 return Status::ErrorUnexpected(); 291 return Status::ErrorUnexpected();
292 292
293 *key = blink::WebCryptoKey::create(new SymKey(CryptoData(random_bytes)), 293 *key = blink::WebCryptoKey::create(new SymKey(CryptoData(random_bytes)),
294 blink::WebCryptoKeyTypeSecret, 294 blink::WebCryptoKeyTypeSecret,
295 extractable, 295 extractable,
296 key_algorithm, 296 key_algorithm,
297 usage_mask); 297 usage_mask);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 361
362 unsigned int hmac_actual_length; 362 unsigned int hmac_actual_length;
363 unsigned char* const success = HMAC(digest_algorithm, 363 unsigned char* const success = HMAC(digest_algorithm,
364 raw_key_voidp, 364 raw_key_voidp,
365 raw_key.size(), 365 raw_key.size(),
366 data.bytes(), 366 data.bytes(),
367 data.byte_length(), 367 data.byte_length(),
368 hmac_result.safe_buffer(), 368 hmac_result.safe_buffer(),
369 &hmac_actual_length); 369 &hmac_actual_length);
370 if (!success || hmac_actual_length != hmac_expected_length) 370 if (!success || hmac_actual_length != hmac_expected_length)
371 return Status::Error(); 371 return Status::OperationError();
372 372
373 *buffer = result; 373 *buffer = result;
374 return Status::Success(); 374 return Status::Success();
375 } 375 }
376 376
377 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, 377 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
378 bool extractable, 378 bool extractable,
379 blink::WebCryptoKeyUsageMask usage_mask, 379 blink::WebCryptoKeyUsageMask usage_mask,
380 const CryptoData& modulus_data, 380 const CryptoData& modulus_data,
381 const CryptoData& exponent_data, 381 const CryptoData& exponent_data,
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 blink::WebCryptoKey* key) { 505 blink::WebCryptoKey* key) {
506 // TODO(eroman): http://crbug.com/267888 506 // TODO(eroman): http://crbug.com/267888
507 return Status::ErrorUnsupported(); 507 return Status::ErrorUnsupported();
508 } 508 }
509 509
510 } // namespace platform 510 } // namespace platform
511 511
512 } // namespace webcrypto 512 } // namespace webcrypto
513 513
514 } // namespace content 514 } // namespace content
OLDNEW
« no previous file with comments | « content/child/webcrypto/platform_crypto_nss.cc ('k') | content/child/webcrypto/shared_crypto.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698