| 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;
|
| }
|
| }
|
| @@ -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
|
|
|