| 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 |