OLD | NEW |
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/renderer/webcrypto/shared_crypto.h" | 5 #include "content/renderer/webcrypto/shared_crypto.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "content/renderer/webcrypto/crypto_data.h" | 8 #include "content/renderer/webcrypto/crypto_data.h" |
9 #include "content/renderer/webcrypto/platform_crypto.h" | 9 #include "content/renderer/webcrypto/platform_crypto.h" |
10 #include "content/renderer/webcrypto/webcrypto_util.h" | 10 #include "content/renderer/webcrypto/webcrypto_util.h" |
11 #include "crypto/secure_util.h" | 11 #include "crypto/secure_util.h" |
12 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 12 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
13 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 13 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
| 14 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| 15 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
| 16 #endif |
14 #include "third_party/WebKit/public/platform/WebCryptoKey.h" | 17 #include "third_party/WebKit/public/platform/WebCryptoKey.h" |
15 | 18 |
16 namespace content { | 19 namespace content { |
17 | 20 |
18 namespace webcrypto { | 21 namespace webcrypto { |
19 | 22 |
20 namespace { | 23 namespace { |
21 | 24 |
22 // TODO(eroman): Move this helper to WebCryptoKey. | 25 // TODO(eroman): Move this helper to WebCryptoKey. |
23 bool KeyUsageAllows(const blink::WebCryptoKey& key, | 26 bool KeyUsageAllows(const blink::WebCryptoKey& key, |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 | 150 |
148 Status SignHmac(const blink::WebCryptoAlgorithm& algorithm, | 151 Status SignHmac(const blink::WebCryptoAlgorithm& algorithm, |
149 const blink::WebCryptoKey& key, | 152 const blink::WebCryptoKey& key, |
150 const CryptoData& data, | 153 const CryptoData& data, |
151 blink::WebArrayBuffer* buffer) { | 154 blink::WebArrayBuffer* buffer) { |
152 platform::SymKey* sym_key; | 155 platform::SymKey* sym_key; |
153 Status status = ToPlatformSymKey(key, &sym_key); | 156 Status status = ToPlatformSymKey(key, &sym_key); |
154 if (status.IsError()) | 157 if (status.IsError()) |
155 return status; | 158 return status; |
156 | 159 |
157 const blink::WebCryptoHmacParams* params = algorithm.hmacParams(); | 160 return platform::SignHmac( |
158 if (!params) | 161 sym_key, key.algorithm().hmacParams()->hash(), data, buffer); |
159 return Status::ErrorUnexpected(); | |
160 | |
161 if (!IsHashAlgorithm(params->hash().id())) | |
162 return Status::ErrorUnexpected(); | |
163 | |
164 if (params->hash().id() != GetInnerHashAlgorithm(key.algorithm()).id()) | |
165 return Status::ErrorUnexpected(); | |
166 | |
167 return platform::SignHmac(sym_key, params->hash(), data, buffer); | |
168 } | 162 } |
169 | 163 |
170 Status VerifyHmac(const blink::WebCryptoAlgorithm& algorithm, | 164 Status VerifyHmac(const blink::WebCryptoAlgorithm& algorithm, |
171 const blink::WebCryptoKey& key, | 165 const blink::WebCryptoKey& key, |
172 const CryptoData& signature, | 166 const CryptoData& signature, |
173 const CryptoData& data, | 167 const CryptoData& data, |
174 bool* signature_match) { | 168 bool* signature_match) { |
175 blink::WebArrayBuffer result; | 169 blink::WebArrayBuffer result; |
176 Status status = SignHmac(algorithm, key, data, &result); | 170 Status status = SignHmac(algorithm, key, data, &result); |
177 if (status.IsError()) | 171 if (status.IsError()) |
(...skipping 10 matching lines...) Expand all Loading... |
188 | 182 |
189 Status SignRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, | 183 Status SignRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, |
190 const blink::WebCryptoKey& key, | 184 const blink::WebCryptoKey& key, |
191 const CryptoData& data, | 185 const CryptoData& data, |
192 blink::WebArrayBuffer* buffer) { | 186 blink::WebArrayBuffer* buffer) { |
193 platform::PrivateKey* private_key; | 187 platform::PrivateKey* private_key; |
194 Status status = ToPlatformPrivateKey(key, &private_key); | 188 Status status = ToPlatformPrivateKey(key, &private_key); |
195 if (status.IsError()) | 189 if (status.IsError()) |
196 return status; | 190 return status; |
197 | 191 |
198 const blink::WebCryptoRsaSsaParams* params = algorithm.rsaSsaParams(); | 192 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
199 if (!params) | |
200 return Status::ErrorUnexpected(); | |
201 | |
202 if (!IsHashAlgorithm(params->hash().id())) | |
203 return Status::ErrorUnexpected(); | |
204 | |
205 // TODO(eroman): Verify the key has not been used with any other hash. | |
206 | |
207 return platform::SignRsaSsaPkcs1v1_5( | 193 return platform::SignRsaSsaPkcs1v1_5( |
208 private_key, params->hash(), data, buffer); | 194 private_key, key.algorithm().rsaHashedParams()->hash(), data, buffer); |
| 195 #else |
| 196 return platform::SignRsaSsaPkcs1v1_5( |
| 197 private_key, algorithm.rsaSsaParams()->hash(), data, buffer); |
| 198 #endif |
209 } | 199 } |
210 | 200 |
211 Status VerifyRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, | 201 Status VerifyRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, |
212 const blink::WebCryptoKey& key, | 202 const blink::WebCryptoKey& key, |
213 const CryptoData& signature, | 203 const CryptoData& signature, |
214 const CryptoData& data, | 204 const CryptoData& data, |
215 bool* signature_match) { | 205 bool* signature_match) { |
216 platform::PublicKey* public_key; | 206 platform::PublicKey* public_key; |
217 Status status = ToPlatformPublicKey(key, &public_key); | 207 Status status = ToPlatformPublicKey(key, &public_key); |
218 if (status.IsError()) | 208 if (status.IsError()) |
219 return status; | 209 return status; |
220 | 210 |
221 const blink::WebCryptoRsaSsaParams* params = algorithm.rsaSsaParams(); | 211 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
222 if (!params) | |
223 return Status::ErrorUnexpected(); | |
224 | |
225 if (!IsHashAlgorithm(params->hash().id())) | |
226 return Status::ErrorUnexpected(); | |
227 | |
228 // TODO(eroman): Verify the key has not been used with any other hash. | |
229 | |
230 return platform::VerifyRsaSsaPkcs1v1_5( | 212 return platform::VerifyRsaSsaPkcs1v1_5( |
231 public_key, params->hash(), signature, data, signature_match); | 213 public_key, |
| 214 key.algorithm().rsaHashedParams()->hash(), |
| 215 signature, |
| 216 data, |
| 217 signature_match); |
| 218 #else |
| 219 return platform::VerifyRsaSsaPkcs1v1_5(public_key, |
| 220 algorithm.rsaSsaParams()->hash(), |
| 221 signature, |
| 222 data, |
| 223 signature_match); |
| 224 #endif |
232 } | 225 } |
233 | 226 |
234 Status ImportKeyRaw(const CryptoData& key_data, | 227 Status ImportKeyRaw(const CryptoData& key_data, |
235 const blink::WebCryptoAlgorithm& algorithm_or_null, | 228 const blink::WebCryptoAlgorithm& algorithm_or_null, |
236 bool extractable, | 229 bool extractable, |
237 blink::WebCryptoKeyUsageMask usage_mask, | 230 blink::WebCryptoKeyUsageMask usage_mask, |
238 blink::WebCryptoKey* key) { | 231 blink::WebCryptoKey* key) { |
239 if (algorithm_or_null.isNull()) | 232 if (algorithm_or_null.isNull()) |
240 return Status::ErrorMissingAlgorithmImportRawKey(); | 233 return Status::ErrorMissingAlgorithmImportRawKey(); |
241 | 234 |
242 switch (algorithm_or_null.id()) { | 235 switch (algorithm_or_null.id()) { |
| 236 case blink::WebCryptoAlgorithmIdAesCtr: |
243 case blink::WebCryptoAlgorithmIdAesCbc: | 237 case blink::WebCryptoAlgorithmIdAesCbc: |
244 case blink::WebCryptoAlgorithmIdAesGcm: | 238 case blink::WebCryptoAlgorithmIdAesGcm: |
245 case blink::WebCryptoAlgorithmIdAesKw: | 239 case blink::WebCryptoAlgorithmIdAesKw: |
246 if (!IsValidAesKeyLengthBytes(key_data.byte_length())) | 240 if (!IsValidAesKeyLengthBytes(key_data.byte_length())) |
247 return Status::Error(); | 241 return Status::Error(); |
248 // Fallthrough intentional! | 242 // Fallthrough intentional! |
249 case blink::WebCryptoAlgorithmIdHmac: | 243 case blink::WebCryptoAlgorithmIdHmac: |
250 return platform::ImportKeyRaw( | 244 return platform::ImportKeyRaw( |
251 algorithm_or_null, key_data, extractable, usage_mask, key); | 245 algorithm_or_null, key_data, extractable, usage_mask, key); |
252 | |
253 default: | 246 default: |
254 return Status::ErrorUnsupported(); | 247 return Status::ErrorUnsupported(); |
255 } | 248 } |
256 } | 249 } |
257 | 250 |
258 } // namespace | 251 } // namespace |
259 | 252 |
260 void Init() { platform::Init(); } | 253 void Init() { platform::Init(); } |
261 | 254 |
262 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, | 255 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 switch (algorithm.id()) { | 320 switch (algorithm.id()) { |
328 case blink::WebCryptoAlgorithmIdAesCbc: | 321 case blink::WebCryptoAlgorithmIdAesCbc: |
329 case blink::WebCryptoAlgorithmIdAesGcm: | 322 case blink::WebCryptoAlgorithmIdAesGcm: |
330 case blink::WebCryptoAlgorithmIdAesKw: { | 323 case blink::WebCryptoAlgorithmIdAesKw: { |
331 if (!IsValidAesKeyLengthBits(algorithm.aesKeyGenParams()->lengthBits())) | 324 if (!IsValidAesKeyLengthBits(algorithm.aesKeyGenParams()->lengthBits())) |
332 return Status::ErrorGenerateKeyLength(); | 325 return Status::ErrorGenerateKeyLength(); |
333 keylen_bytes = algorithm.aesKeyGenParams()->lengthBits() / 8; | 326 keylen_bytes = algorithm.aesKeyGenParams()->lengthBits() / 8; |
334 break; | 327 break; |
335 } | 328 } |
336 case blink::WebCryptoAlgorithmIdHmac: { | 329 case blink::WebCryptoAlgorithmIdHmac: { |
| 330 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| 331 const blink::WebCryptoHmacKeyGenParams* params = |
| 332 algorithm.hmacKeyGenParams(); |
| 333 #else |
337 const blink::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); | 334 const blink::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); |
| 335 #endif |
338 DCHECK(params); | 336 DCHECK(params); |
339 if (params->hasLengthBytes()) { | 337 if (params->hasLengthBytes()) { |
340 keylen_bytes = params->optionalLengthBytes(); | 338 keylen_bytes = params->optionalLengthBytes(); |
341 } else { | 339 } else { |
342 keylen_bytes = ShaBlockSizeBytes(params->hash().id()); | 340 keylen_bytes = ShaBlockSizeBytes(params->hash().id()); |
343 if (keylen_bytes == 0) | 341 if (keylen_bytes == 0) |
344 return Status::ErrorUnsupported(); | 342 return Status::ErrorUnsupported(); |
345 } | 343 } |
346 break; | 344 break; |
347 } | 345 } |
(...skipping 10 matching lines...) Expand all Loading... |
358 return platform::GenerateSecretKey( | 356 return platform::GenerateSecretKey( |
359 algorithm, extractable, usage_mask, keylen_bytes, key); | 357 algorithm, extractable, usage_mask, keylen_bytes, key); |
360 } | 358 } |
361 | 359 |
362 Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm, | 360 Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm, |
363 bool extractable, | 361 bool extractable, |
364 blink::WebCryptoKeyUsageMask usage_mask, | 362 blink::WebCryptoKeyUsageMask usage_mask, |
365 blink::WebCryptoKey* public_key, | 363 blink::WebCryptoKey* public_key, |
366 blink::WebCryptoKey* private_key) { | 364 blink::WebCryptoKey* private_key) { |
367 // TODO(padolph): Handle other asymmetric algorithm key generation. | 365 // TODO(padolph): Handle other asymmetric algorithm key generation. |
368 switch (algorithm.id()) { | 366 switch (algorithm.paramsType()) { |
369 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 367 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
370 case blink::WebCryptoAlgorithmIdRsaOaep: | 368 case blink::WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams: |
371 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | 369 case blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams: { |
372 if (!algorithm.rsaKeyGenParams()) | 370 const blink::WebCryptoRsaKeyGenParams* params = NULL; |
373 return Status::ErrorUnexpected(); | 371 blink::WebCryptoAlgorithm hash_or_null = |
374 return platform::GenerateRsaKeyPair( | 372 blink::WebCryptoAlgorithm::createNull(); |
375 algorithm, extractable, usage_mask, public_key, private_key); | 373 if (algorithm.rsaHashedKeyGenParams()) { |
| 374 params = algorithm.rsaHashedKeyGenParams(); |
| 375 hash_or_null = algorithm.rsaHashedKeyGenParams()->hash(); |
| 376 } else { |
| 377 params = algorithm.rsaKeyGenParams(); |
| 378 } |
| 379 #else |
| 380 case blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams: { |
| 381 const blink::WebCryptoRsaKeyGenParams* params = |
| 382 algorithm.rsaKeyGenParams(); |
| 383 blink::WebCryptoAlgorithm hash_or_null = |
| 384 blink::WebCryptoAlgorithm::createNull(); |
| 385 #endif |
| 386 |
| 387 if (!params->modulusLengthBits()) |
| 388 return Status::ErrorGenerateRsaZeroModulus(); |
| 389 |
| 390 CryptoData publicExponent(params->publicExponent()); |
| 391 if (!publicExponent.byte_length()) |
| 392 return Status::ErrorGenerateKeyPublicExponent(); |
| 393 |
| 394 return platform::GenerateRsaKeyPair(algorithm, |
| 395 extractable, |
| 396 usage_mask, |
| 397 params->modulusLengthBits(), |
| 398 publicExponent, |
| 399 hash_or_null, |
| 400 public_key, |
| 401 private_key); |
| 402 } |
376 default: | 403 default: |
377 return Status::ErrorUnsupported(); | 404 return Status::ErrorUnsupported(); |
378 } | 405 } |
379 } | 406 } |
380 | 407 |
381 Status ImportKey(blink::WebCryptoKeyFormat format, | 408 Status ImportKey(blink::WebCryptoKeyFormat format, |
382 const CryptoData& key_data, | 409 const CryptoData& key_data, |
383 const blink::WebCryptoAlgorithm& algorithm_or_null, | 410 const blink::WebCryptoAlgorithm& algorithm_or_null, |
384 bool extractable, | 411 bool extractable, |
385 blink::WebCryptoKeyUsageMask usage_mask, | 412 blink::WebCryptoKeyUsageMask usage_mask, |
386 blink::WebCryptoKey* key) { | 413 blink::WebCryptoKey* key) { |
387 switch (format) { | 414 switch (format) { |
388 case blink::WebCryptoKeyFormatRaw: | 415 case blink::WebCryptoKeyFormatRaw: |
389 return ImportKeyRaw( | 416 return ImportKeyRaw( |
390 key_data, algorithm_or_null, extractable, usage_mask, key); | 417 key_data, algorithm_or_null, extractable, usage_mask, key); |
391 return platform::ImportKeyRaw( | 418 return platform::ImportKeyRaw( |
392 algorithm_or_null, key_data, extractable, usage_mask, key); | 419 algorithm_or_null, key_data, extractable, usage_mask, key); |
393 case blink::WebCryptoKeyFormatSpki: | 420 case blink::WebCryptoKeyFormatSpki: |
394 return platform::ImportKeySpki( | 421 return platform::ImportKeySpki( |
395 algorithm_or_null, key_data, extractable, usage_mask, key); | 422 algorithm_or_null, key_data, usage_mask, key); |
396 case blink::WebCryptoKeyFormatPkcs8: | 423 case blink::WebCryptoKeyFormatPkcs8: |
397 return platform::ImportKeyPkcs8( | 424 return platform::ImportKeyPkcs8( |
398 algorithm_or_null, key_data, extractable, usage_mask, key); | 425 algorithm_or_null, key_data, extractable, usage_mask, key); |
399 case blink::WebCryptoKeyFormatJwk: | 426 case blink::WebCryptoKeyFormatJwk: |
400 return ImportKeyJwk( | 427 return ImportKeyJwk( |
401 key_data, algorithm_or_null, extractable, usage_mask, key); | 428 key_data, algorithm_or_null, extractable, usage_mask, key); |
402 default: | 429 default: |
403 return Status::ErrorUnsupported(); | 430 return Status::ErrorUnsupported(); |
404 } | 431 } |
405 } | 432 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 return VerifyRsaSsaPkcs1v1_5( | 505 return VerifyRsaSsaPkcs1v1_5( |
479 algorithm, key, signature, data, signature_match); | 506 algorithm, key, signature, data, signature_match); |
480 default: | 507 default: |
481 return Status::ErrorUnsupported(); | 508 return Status::ErrorUnsupported(); |
482 } | 509 } |
483 } | 510 } |
484 | 511 |
485 } // namespace webcrypto | 512 } // namespace webcrypto |
486 | 513 |
487 } // namespace content | 514 } // namespace content |
OLD | NEW |