Index: content/renderer/webcrypto/webcrypto_util.cc |
diff --git a/content/renderer/webcrypto/webcrypto_util.cc b/content/renderer/webcrypto/webcrypto_util.cc |
index 3b565cfab478d97f32cbe1b9b6169187e3b21ce9..32703b2f5868877c0e942857750b38004b9a6267 100644 |
--- a/content/renderer/webcrypto/webcrypto_util.cc |
+++ b/content/renderer/webcrypto/webcrypto_util.cc |
@@ -6,6 +6,7 @@ |
#include "base/base64.h" |
#include "base/logging.h" |
+#include "base/strings/stringprintf.h" |
#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
@@ -47,10 +48,10 @@ Status Status::ErrorJwkBase64Decode(const std::string& property) { |
"\" could not be base64 decoded"); |
} |
-Status Status::ErrorJwkExtractableInconsistent() { |
+Status Status::ErrorJwkExtInconsistent() { |
return Status( |
- "The \"extractable\" property of the JWK dictionary is " |
- "inconsistent what that specified by the Web Crypto call"); |
+ "The \"ext\" property of the JWK dictionary is inconsistent what that " |
+ "specified by the Web Crypto call"); |
} |
Status Status::ErrorJwkUnrecognizedAlgorithm() { |
@@ -69,17 +70,34 @@ Status Status::ErrorJwkAlgorithmMissing() { |
"and one wasn't specified by the Web Crypto call"); |
} |
-Status Status::ErrorJwkUnrecognizedUsage() { |
+Status Status::ErrorJwkUnrecognizedUse() { |
return Status("The JWK \"use\" property could not be parsed"); |
} |
-Status Status::ErrorJwkUsageInconsistent() { |
+Status Status::ErrorJwkUnrecognizedKeyop() { |
+ return Status("The JWK \"key_ops\" property could not be parsed"); |
+} |
+ |
+Status Status::ErrorJwkUseInconsistent() { |
return Status( |
"The JWK \"use\" property was inconsistent with that specified " |
"by the Web Crypto call. The JWK usage must be a superset of " |
"those requested"); |
} |
+Status Status::ErrorJwkKeyopsInconsistent() { |
+ return Status( |
+ "The JWK \"key_ops\" property was inconsistent with that " |
+ "specified by the Web Crypto call. The JWK usage must be a " |
+ "superset of those requested"); |
+} |
+ |
+Status Status::ErrorJwkUseAndKeyopsInconsistent() { |
+ return Status( |
+ "The JWK \"use\" and \"key_ops\" properties were both found " |
+ "but are inconsistent with each other."); |
+} |
+ |
Status Status::ErrorJwkRsaPrivateKeyUnsupported() { |
return Status( |
"JWK RSA key contained \"d\" property: Private key import is " |
@@ -96,6 +114,10 @@ Status Status::ErrorJwkIncorrectKeyLength() { |
"of key data for the given algorithm."); |
} |
+Status Status::ErrorJwkUnsupportedHmacHash() { |
+ return Status("JWK does not support HMAC with this inner hash."); |
+} |
+ |
Status Status::ErrorImportEmptyKeyData() { |
return Status("No key data was provided"); |
} |
@@ -219,6 +241,45 @@ bool Base64DecodeUrlSafe(const std::string& input, std::string* output) { |
return base::Base64Decode(base64EncodedText, output); |
} |
+// Produces an unpadded 'base64url' encoding of the input data, using the |
+// inverse of the process above. |
+void Base64EncodeUrlSafe(const base::StringPiece& input, std::string* output) { |
+ base::Base64Encode(input, output); |
+ std::replace(output->begin(), output->end(), '+', '-'); |
+ std::replace(output->begin(), output->end(), '/', '_'); |
+ output->erase(std::remove(output->begin(), output->end(), '='), |
+ output->end()); |
+} |
+ |
+// Composes a Web Crypto usage mask from an array of JWK key_ops values. |
+Status GetUsagesFromJwkKeyOps(base::ListValue* jwk_key_ops_value, |
+ blink::WebCryptoKeyUsageMask* jwk_key_ops_mask) { |
+ for (size_t i = 0; i < jwk_key_ops_value->GetSize(); ++i) { |
+ std::string key_op; |
+ if (!jwk_key_ops_value->GetString(i, &key_op)) |
+ return Status::ErrorJwkPropertyWrongType( |
+ base::StringPrintf("key_ops[%d]", static_cast<int>(i)), "string"); |
+ if (key_op == "encrypt") |
+ *jwk_key_ops_mask |= blink::WebCryptoKeyUsageEncrypt; |
+ else if (key_op == "decrypt") |
+ *jwk_key_ops_mask |= blink::WebCryptoKeyUsageDecrypt; |
+ else if (key_op == "sign") |
+ *jwk_key_ops_mask |= blink::WebCryptoKeyUsageSign; |
+ else if (key_op == "verify") |
+ *jwk_key_ops_mask |= blink::WebCryptoKeyUsageVerify; |
+ else if (key_op == "wrapKey") |
+ *jwk_key_ops_mask |= blink::WebCryptoKeyUsageWrapKey; |
+ else if (key_op == "unwrapKey") |
+ *jwk_key_ops_mask |= blink::WebCryptoKeyUsageUnwrapKey; |
+ else if (key_op == "deriveKey") |
+ *jwk_key_ops_mask |= blink::WebCryptoKeyUsageDeriveKey; |
+ else |
+ return Status::ErrorJwkUnrecognizedKeyop(); |
+ // TODO(padolph): Add 'deriveBits' once supported by Blink. |
+ } |
+ return Status::Success(); |
+} |
+ |
bool IsHashAlgorithm(blink::WebCryptoAlgorithmId alg_id) { |
return alg_id == blink::WebCryptoAlgorithmIdSha1 || |
alg_id == blink::WebCryptoAlgorithmIdSha224 || |