Chromium Code Reviews| Index: content/renderer/webcrypto/webcrypto_impl.cc |
| diff --git a/content/renderer/webcrypto/webcrypto_impl.cc b/content/renderer/webcrypto/webcrypto_impl.cc |
| index 5d5a1415bb13cf28d5255cd384496e166831419d..4d69f0750d596f10941d99b9ccfac007c1d657cf 100644 |
| --- a/content/renderer/webcrypto/webcrypto_impl.cc |
| +++ b/content/renderer/webcrypto/webcrypto_impl.cc |
| @@ -17,11 +17,19 @@ |
| #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
| #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
| #include "third_party/WebKit/public/platform/WebCryptoKey.h" |
| +#include "third_party/WebKit/public/platform/WebString.h" |
| namespace content { |
| +using webcrypto::Status; |
| + |
| namespace { |
| +void CompleteWithError(const Status& status, blink::WebCryptoResult* result) { |
| + DCHECK(status.IsError()); |
| + result->completeWithError(blink::WebString::fromUTF8(status.ToString())); |
| +} |
| + |
| bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) { |
| // TODO(padolph): include all other asymmetric algorithms once they are |
| // defined, e.g. EC and DH. |
| @@ -175,8 +183,9 @@ void WebCryptoImpl::encrypt( |
| blink::WebCryptoResult result) { |
| DCHECK(!algorithm.isNull()); |
| blink::WebArrayBuffer buffer; |
| - if (!EncryptInternal(algorithm, key, data, data_size, &buffer)) { |
| - result.completeWithError(); |
| + Status status = EncryptInternal(algorithm, key, data, data_size, &buffer); |
| + if (status.IsError()) { |
| + CompleteWithError(status, &result); |
| } else { |
| result.completeWithBuffer(buffer); |
| } |
| @@ -190,8 +199,9 @@ void WebCryptoImpl::decrypt( |
| blink::WebCryptoResult result) { |
| DCHECK(!algorithm.isNull()); |
| blink::WebArrayBuffer buffer; |
| - if (!DecryptInternal(algorithm, key, data, data_size, &buffer)) { |
| - result.completeWithError(); |
| + Status status = DecryptInternal(algorithm, key, data, data_size, &buffer); |
| + if (status.IsError()) { |
| + CompleteWithError(status, &result); |
| } else { |
| result.completeWithBuffer(buffer); |
| } |
| @@ -204,8 +214,9 @@ void WebCryptoImpl::digest( |
| blink::WebCryptoResult result) { |
| DCHECK(!algorithm.isNull()); |
| blink::WebArrayBuffer buffer; |
| - if (!DigestInternal(algorithm, data, data_size, &buffer)) { |
| - result.completeWithError(); |
| + Status status = DigestInternal(algorithm, data, data_size, &buffer); |
| + if (status.IsError()) { |
| + CompleteWithError(status, &result); |
| } else { |
| result.completeWithBuffer(buffer); |
| } |
| @@ -220,9 +231,10 @@ void WebCryptoImpl::generateKey( |
| if (IsAlgorithmAsymmetric(algorithm)) { |
| blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| - if (!GenerateKeyPairInternal( |
| - algorithm, extractable, usage_mask, &public_key, &private_key)) { |
| - result.completeWithError(); |
| + Status status = GenerateKeyPairInternal( |
| + algorithm, extractable, usage_mask, &public_key, &private_key); |
| + if (status.IsError()) { |
| + CompleteWithError(status, &result); |
| } else { |
| DCHECK(public_key.handle()); |
| DCHECK(private_key.handle()); |
| @@ -236,8 +248,10 @@ void WebCryptoImpl::generateKey( |
| } |
| } else { |
| blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| - if (!GenerateKeyInternal(algorithm, extractable, usage_mask, &key)) { |
| - result.completeWithError(); |
| + Status status = GenerateKeyInternal( |
| + algorithm, extractable, usage_mask, &key); |
| + if (status.IsError()) { |
| + CompleteWithError(status, &result); |
| } else { |
| DCHECK(key.handle()); |
| DCHECK_EQ(algorithm.id(), key.algorithm().id()); |
| @@ -257,32 +271,31 @@ void WebCryptoImpl::importKey( |
| blink::WebCryptoKeyUsageMask usage_mask, |
| blink::WebCryptoResult result) { |
| blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| + Status status = Status::Error(); |
| if (format == blink::WebCryptoKeyFormatJwk) { |
| - if (!ImportKeyJwk(key_data, |
| - key_data_size, |
| - algorithm_or_null, |
| - extractable, |
| - usage_mask, |
| - &key)) { |
| - result.completeWithError(); |
| - return; |
| - } |
| + status = ImportKeyJwk(key_data, |
| + key_data_size, |
| + algorithm_or_null, |
| + extractable, |
| + usage_mask, |
| + &key); |
| } else { |
| - if (!ImportKeyInternal(format, |
| - key_data, |
| - key_data_size, |
| - algorithm_or_null, |
| - extractable, |
| - usage_mask, |
| - &key)) { |
| - result.completeWithError(); |
| - return; |
| - } |
| + status = ImportKeyInternal(format, |
| + key_data, |
| + key_data_size, |
| + algorithm_or_null, |
| + extractable, |
| + usage_mask, |
| + &key); |
| + } |
| + if (status.IsError()) { |
| + CompleteWithError(status, &result); |
| + } else { |
| + DCHECK(key.handle()); |
| + DCHECK(!key.algorithm().isNull()); |
| + DCHECK_EQ(extractable, key.extractable()); |
| + result.completeWithKey(key); |
| } |
| - DCHECK(key.handle()); |
| - DCHECK(!key.algorithm().isNull()); |
| - DCHECK_EQ(extractable, key.extractable()); |
| - result.completeWithKey(key); |
| } |
| void WebCryptoImpl::exportKey( |
| @@ -290,11 +303,12 @@ void WebCryptoImpl::exportKey( |
| const blink::WebCryptoKey& key, |
| blink::WebCryptoResult result) { |
| blink::WebArrayBuffer buffer; |
| - if (!ExportKeyInternal(format, key, &buffer)) { |
| - result.completeWithError(); |
| - return; |
| + Status status = ExportKeyInternal(format, key, &buffer); |
| + if (status.IsError()) { |
| + CompleteWithError(status, &result); |
| + } else { |
| + result.completeWithBuffer(buffer); |
| } |
| - result.completeWithBuffer(buffer); |
| } |
| void WebCryptoImpl::sign( |
| @@ -305,8 +319,9 @@ void WebCryptoImpl::sign( |
| blink::WebCryptoResult result) { |
| DCHECK(!algorithm.isNull()); |
| blink::WebArrayBuffer buffer; |
| - if (!SignInternal(algorithm, key, data, data_size, &buffer)) { |
| - result.completeWithError(); |
| + Status status = SignInternal(algorithm, key, data, data_size, &buffer); |
| + if (status.IsError()) { |
| + CompleteWithError(status, &result); |
| } else { |
| result.completeWithBuffer(buffer); |
| } |
| @@ -322,20 +337,21 @@ void WebCryptoImpl::verifySignature( |
| blink::WebCryptoResult result) { |
| DCHECK(!algorithm.isNull()); |
| bool signature_match = false; |
| - if (!VerifySignatureInternal(algorithm, |
| - key, |
| - signature, |
| - signature_size, |
| - data, |
| - data_size, |
| - &signature_match)) { |
| - result.completeWithError(); |
| + Status status = VerifySignatureInternal(algorithm, |
| + key, |
| + signature, |
| + signature_size, |
| + data, |
| + data_size, |
| + &signature_match); |
| + if (status.IsError()) { |
| + CompleteWithError(status, &result); |
| } else { |
| result.completeWithBoolean(signature_match); |
| } |
| } |
| -bool WebCryptoImpl::ImportKeyJwk( |
| +Status WebCryptoImpl::ImportKeyJwk( |
| const unsigned char* key_data, |
| unsigned key_data_size, |
| const blink::WebCryptoAlgorithm& algorithm_or_null, |
| @@ -479,7 +495,7 @@ bool WebCryptoImpl::ImportKeyJwk( |
| // |
| if (!key_data_size) |
| - return false; |
| + return Status::ErrorImportEmptyKeyData(); |
| DCHECK(key); |
| // Parse the incoming JWK JSON. |
| @@ -489,19 +505,21 @@ bool WebCryptoImpl::ImportKeyJwk( |
| // Note, bare pointer dict_value is ok since it points into scoped value. |
| base::DictionaryValue* dict_value = NULL; |
| if (!value.get() || !value->GetAsDictionary(&dict_value) || !dict_value) |
| - return false; |
| + return Status::ErrorJwkNotDictionary(); |
| // JWK "kty". Exit early if this required JWK parameter is missing. |
| std::string jwk_kty_value; |
| if (!dict_value->GetString("kty", &jwk_kty_value)) |
| - return false; |
| + return Status::ErrorJwkMissingKty(); |
| // JWK "extractable" (optional) --> extractable parameter |
| + // TODO(eroman): Should error if "extractable" was specified but not a |
| + // boolean. |
| { |
| bool jwk_extractable_value; |
| if (dict_value->GetBoolean("extractable", &jwk_extractable_value)) { |
| if (!jwk_extractable_value && extractable) |
| - return false; |
| + return Status::ErrorJwkExtractableInconsistent(); |
| extractable = extractable && jwk_extractable_value; |
|
Ryan Sleevi
2014/01/30 18:43:52
FWIW (and in a cleanup), you don't need this line
|
| } |
| } |
| @@ -516,6 +534,7 @@ bool WebCryptoImpl::ImportKeyJwk( |
| // input value (because it has potentially more details) |
| // 5. JWK alg missing AND input algorithm isNull: error |
| // 6. JWK alg missing AND input algorithm specified: use input value |
| + // TODO(eroman): Should error if "alg" was specified but not a string. |
| blink::WebCryptoAlgorithm algorithm = blink::WebCryptoAlgorithm::createNull(); |
| std::string jwk_alg_value; |
| if (dict_value->GetString("alg", &jwk_alg_value)) { |
| @@ -528,7 +547,7 @@ bool WebCryptoImpl::ImportKeyJwk( |
| jwk_alg_factory.Get().CreateAlgorithmFromName(jwk_alg_value); |
| if (jwk_algorithm.isNull()) { |
| // JWK alg unrecognized |
| - return false; // case 1 |
| + return Status::ErrorJwkUnrecognizedAlgorithm(); // case 1 |
| } |
| // JWK alg valid |
| if (algorithm_or_null.isNull()) { |
| @@ -537,18 +556,19 @@ bool WebCryptoImpl::ImportKeyJwk( |
| } else { |
| // input algorithm specified |
| if (!WebCryptoAlgorithmsConsistent(jwk_algorithm, algorithm_or_null)) |
| - return false; // case 3 |
| + return Status::ErrorJwkAlgorithmInconsistent(); // case 3 |
| algorithm = algorithm_or_null; // case 4 |
| } |
| } else { |
| // JWK alg missing |
| if (algorithm_or_null.isNull()) |
| - return false; // case 5 |
| + return Status::ErrorJwkAlgorithmMissing(); // case 5 |
| algorithm = algorithm_or_null; // case 6 |
| } |
| DCHECK(!algorithm.isNull()); |
| // JWK "use" (optional) --> usage_mask parameter |
| + // TODO(eroman): Should error if "use" was specified but not a string. |
| std::string jwk_use_value; |
| if (dict_value->GetString("use", &jwk_use_value)) { |
| blink::WebCryptoKeyUsageMask jwk_usage_mask = 0; |
| @@ -562,11 +582,11 @@ bool WebCryptoImpl::ImportKeyJwk( |
| jwk_usage_mask = |
| blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey; |
| } else { |
| - return false; |
| + return Status::ErrorJwkUnrecognizedUsage(); |
| } |
| if ((jwk_usage_mask & usage_mask) != usage_mask) { |
| // A usage_mask must be a subset of jwk_usage_mask. |
| - return false; |
| + return Status::ErrorJwkUsageInconsistent(); |
| } |
| } |
| @@ -575,7 +595,7 @@ bool WebCryptoImpl::ImportKeyJwk( |
| std::string jwk_k_value; |
| if (!GetDecodedUrl64ValueByKey(*dict_value, "k", &jwk_k_value)) |
| - return false; |
| + return Status::ErrorJwkDecodeK(); |
| // TODO(padolph): Some JWK alg ID's embed information about the key length |
| // in the alg ID string. For example "A128" implies the JWK carries 128 bits |
| @@ -602,14 +622,14 @@ bool WebCryptoImpl::ImportKeyJwk( |
| // entry is found. |
| // TODO(padolph): Support RSA private key import. |
| if (dict_value->HasKey("d")) |
| - return false; |
| + return Status::ErrorJwkRsaPrivateKeyUnsupported(); |
| std::string jwk_n_value; |
| if (!GetDecodedUrl64ValueByKey(*dict_value, "n", &jwk_n_value)) |
| - return false; |
| + return Status::ErrorJwkDecodeN(); |
| std::string jwk_e_value; |
| if (!GetDecodedUrl64ValueByKey(*dict_value, "e", &jwk_e_value)) |
| - return false; |
| + return Status::ErrorJwkDecodeE(); |
| return ImportRsaPublicKeyInternal( |
| reinterpret_cast<const uint8*>(jwk_n_value.data()), |
| @@ -622,10 +642,10 @@ bool WebCryptoImpl::ImportKeyJwk( |
| key); |
| } else { |
| - return false; |
| + return Status::ErrorJwkUnrecognizedKty(); |
| } |
| - return true; |
| + return Status::Success(); |
| } |
| } // namespace content |