Index: content/child/webcrypto/webcrypto_util.cc |
diff --git a/content/child/webcrypto/webcrypto_util.cc b/content/child/webcrypto/webcrypto_util.cc |
index 1fa46580519c067cf7eff959c28f341df1819970..537e551f0363bd39a316405e86ddf1c6822deed4 100644 |
--- a/content/child/webcrypto/webcrypto_util.cc |
+++ b/content/child/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 " |
@@ -219,6 +237,73 @@ bool Base64DecodeUrlSafe(const std::string& input, std::string* output) { |
return base::Base64Decode(base64EncodedText, output); |
} |
+// Returns an unpadded 'base64url' encoding of the input data, using the |
+// inverse of the process above. |
+std::string 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()); |
+ return output; |
+} |
+ |
+struct JwkToWebCryptoUsage { |
+ const char* const jwk_key_op; |
+ const blink::WebCryptoKeyUsage webcrypto_usage; |
+}; |
+ |
+const JwkToWebCryptoUsage kJwkWebCryptoUsageMap[] = { |
+ {"encrypt", blink::WebCryptoKeyUsageEncrypt}, |
+ {"decrypt", blink::WebCryptoKeyUsageDecrypt}, |
+ {"deriveKey", blink::WebCryptoKeyUsageDeriveKey}, |
+ // TODO(padolph): Add 'deriveBits' once supported by Blink. |
+ {"sign", blink::WebCryptoKeyUsageSign}, |
+ {"unwrapKey", blink::WebCryptoKeyUsageUnwrapKey}, |
+ {"verify", blink::WebCryptoKeyUsageVerify}, |
+ {"wrapKey", blink::WebCryptoKeyUsageWrapKey}}; |
+ |
+// Modifies the input usage_mask by according to the key_op value. |
+bool JwkKeyOpToWebCryptoUsage(const std::string& key_op, |
+ blink::WebCryptoKeyUsageMask* usage_mask) { |
+ for (size_t i = 0; i < arraysize(kJwkWebCryptoUsageMap); ++i) { |
+ if (kJwkWebCryptoUsageMap[i].jwk_key_op == key_op) { |
+ *usage_mask |= kJwkWebCryptoUsageMap[i].webcrypto_usage; |
+ return true; |
+ } |
+ } |
+ return false; |
+} |
+ |
+// Composes a Web Crypto usage mask from an array of JWK key_ops values. |
+Status GetWebCryptoUsagesFromJwkKeyOps( |
+ const base::ListValue* jwk_key_ops_value, |
+ blink::WebCryptoKeyUsageMask* usage_mask) { |
+ *usage_mask = 0; |
+ 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 (!JwkKeyOpToWebCryptoUsage(key_op, usage_mask)) |
+ return Status::ErrorJwkUnrecognizedKeyop(); |
+ } |
+ return Status::Success(); |
+} |
+ |
+// Composes a JWK key_ops List from a Web Crypto usage mask. |
+// Note: Caller must assume ownership of returned instance. |
+base::ListValue* CreateJwkKeyOpsFromWebCryptoUsages( |
+ blink::WebCryptoKeyUsageMask usage_mask) { |
+ base::ListValue* jwk_key_ops = new base::ListValue(); |
+ for (size_t i = 0; i < arraysize(kJwkWebCryptoUsageMap); ++i) { |
+ if (usage_mask & kJwkWebCryptoUsageMap[i].webcrypto_usage) |
+ jwk_key_ops->AppendString(kJwkWebCryptoUsageMap[i].jwk_key_op); |
+ } |
+ return jwk_key_ops; |
+} |
+ |
bool IsHashAlgorithm(blink::WebCryptoAlgorithmId alg_id) { |
return alg_id == blink::WebCryptoAlgorithmIdSha1 || |
alg_id == blink::WebCryptoAlgorithmIdSha256 || |