Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1333)

Unified Diff: content/renderer/webcrypto/webcrypto_impl.cc

Issue 25906002: [webcrypto] Add JWK import for HMAC and AES-CBC key. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: re-upload Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/webcrypto/webcrypto_impl.h ('k') | content/renderer/webcrypto/webcrypto_impl_openssl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/webcrypto/webcrypto_impl.cc
diff --git a/content/renderer/webcrypto/webcrypto_impl.cc b/content/renderer/webcrypto/webcrypto_impl.cc
index f794c59ed8461beb0cbf1634d446e386980e15e5..2335401ec35823a845c9a78c6cfc343e8225151b 100644
--- a/content/renderer/webcrypto/webcrypto_impl.cc
+++ b/content/renderer/webcrypto/webcrypto_impl.cc
@@ -4,15 +4,274 @@
#include "content/renderer/webcrypto/webcrypto_impl.h"
+#include <algorithm>
+#include <map>
+#include "base/base64.h"
+#include "base/json/json_reader.h"
+#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_piece.h"
+#include "base/values.h"
#include "third_party/WebKit/public/platform/WebArrayBuffer.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKey.h"
namespace content {
+namespace {
+
+// FIXME! Need WebKit::WebCryptoAlgorithmIdNone
eroman 2013/10/22 21:49:38 There are other ways of accomplishing this that I
Ryan Sleevi 2013/10/24 01:45:58 There are other formats that may have embedded alg
eroman 2013/10/24 02:35:04 I will make the necessary changes to Blink side.
padolph 2013/10/28 20:35:07 This is addressed by your recent Blink checkin. Th
+const WebKit::WebCryptoAlgorithmId WebCryptoAlgorithmIdNone =
+ (WebKit::WebCryptoAlgorithmId)99;
+
+// TODO(padolph) Similar Create*Algorithm() methods are in
eroman 2013/10/22 21:49:38 What do you think about a renderer/webcrypto/webcr
padolph 2013/10/28 20:35:07 Done. Should the stuff in webcrypto_util.[h|cc] b
+// webcrypto_impl_unittest.cc. Find a common place to put these.
+
+WebKit::WebCryptoAlgorithm CreateAlgorithm(WebKit::WebCryptoAlgorithmId id) {
+ return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(id, NULL);
+}
+
+WebKit::WebCryptoAlgorithm CreateAlgorithmWithInnerHash(
+ WebKit::WebCryptoAlgorithmId algorithm_id,
+ unsigned short hash_key_length) {
+ WebKit::WebCryptoAlgorithmId hashId;
eroman 2013/10/22 21:49:38 use hacker_style_variable_naming for chromium code
padolph 2013/10/28 20:35:07 Done.
+ switch (hash_key_length) {
+ case 160:
+ hashId = WebKit::WebCryptoAlgorithmIdSha1;
+ break;
+ case 224:
+ hashId = WebKit::WebCryptoAlgorithmIdSha224;
+ break;
+ case 256:
+ hashId = WebKit::WebCryptoAlgorithmIdSha256;
+ break;
+ case 384:
+ hashId = WebKit::WebCryptoAlgorithmIdSha384;
+ break;
+ case 512:
+ hashId = WebKit::WebCryptoAlgorithmIdSha384;
+ break;
+ }
+ return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(
eroman 2013/10/22 21:49:38 Please add a default case to the switch above (per
padolph 2013/10/28 20:35:07 Done.
+ algorithm_id,
+ new WebKit::WebCryptoHmacParams(CreateAlgorithm(hashId)));
+}
+
+WebKit::WebCryptoAlgorithm CreateHmacAlgorithm(unsigned short hash_key_length) {
+ return CreateAlgorithmWithInnerHash(
+ WebKit::WebCryptoAlgorithmIdHmac,
+ hash_key_length);
+}
+
+WebKit::WebCryptoAlgorithm CreateRsaSsaAlgorithm(
+ unsigned short hash_key_length) {
+ return CreateAlgorithmWithInnerHash(
+ WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ hash_key_length);
+}
+
+WebKit::WebCryptoAlgorithm CreateRsaOaepAlgorithm(
+ unsigned short hash_key_length) {
+ return CreateAlgorithmWithInnerHash(
+ WebKit::WebCryptoAlgorithmIdRsaOaep,
+ hash_key_length);
+}
+
+WebKit::WebCryptoAlgorithm CreateAesAlgorithm(
+ WebKit::WebCryptoAlgorithmId aes_alg_id,
+ unsigned short length) {
+ return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(
+ aes_alg_id,
+ new WebKit::WebCryptoAesKeyGenParams(length));
+}
+
+WebKit::WebCryptoAlgorithm CreateAesCbcAlgorithm(unsigned short length) {
+ return CreateAesAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc, length);
+}
+
+WebKit::WebCryptoAlgorithm CreateAesGcmAlgorithm(unsigned short length) {
+ return CreateAesAlgorithm(WebKit::WebCryptoAlgorithmIdAesGcm, length);
+}
+
+bool Base64DecodeUrlSafe(const std::string& input, std::string* output) {
eroman 2013/10/22 21:49:38 Please provide a comment pointing to the definitio
padolph 2013/10/28 20:35:07 Will do. 'base64url' encoding is relatively common
+ std::string base64EncodedText(input);
+ std::replace(base64EncodedText.begin(), base64EncodedText.end(), '-', '+');
eroman 2013/10/22 21:49:38 Are these transformations enumerated int he JOSE s
padolph 2013/10/28 20:35:07 Yes, in RFC4648 Section 5.
+ std::replace(base64EncodedText.begin(), base64EncodedText.end(), '_', '/');
+ base64EncodedText.append((4 - base64EncodedText.size() % 4) % 4, '=');
+ return base::Base64Decode(base64EncodedText, output);
+}
+
+// Identifiers for all JWK "alg" (algorithm) values handled by this code. The
eroman 2013/10/22 21:49:38 There is enough JWK stuff, that I suggest moving t
padolph 2013/10/28 20:35:07 Most of this code went away with the function tabl
+// "enum trick" is used to force int type, so a user type is not required in
eroman 2013/10/22 21:49:38 Not sure I know what the "enum trick" refers to. Y
padolph 2013/10/28 20:35:07 This code went away with the function table refact
+// web_crypto_impl.h
+enum {
+ kJwkAlgorithmHs256,
+ kJwkAlgorithmHs384,
+ kJwkAlgorithmHs512,
+ kJwkAlgorithmRs256,
+ kJwkAlgorithmRs384,
+ kJwkAlgorithmRs512,
+ kJwkAlgorithmRsa1_5,
+ kJwkAlgorithmRsaOaep,
+ kJwkAlgorithmA128Kw,
+ kJwkAlgorithmA256Kw,
+ kJwkAlgorithmA128Gcm,
+ kJwkAlgorithmA256Gcm,
+ kJwkAlgorithmA128Cbc,
+ kJwkAlgorithmA256Cbc,
+ kJwkAlgorithmA384Cbc,
+ kJwkAlgorithmA512Cbc
+};
+
+WebKit::WebCryptoAlgorithmId JwkAlgIdToWebCryptoAlgId(int jwk_algorithm_id) {
eroman 2013/10/22 21:49:38 This function appears to be unused
padolph 2013/10/28 20:35:07 Done.
+ switch (jwk_algorithm_id) {
+ case kJwkAlgorithmHs256:
+ case kJwkAlgorithmHs384:
+ case kJwkAlgorithmHs512:
+ return WebKit::WebCryptoAlgorithmIdHmac;
+ case kJwkAlgorithmRs256:
+ case kJwkAlgorithmRs384:
+ case kJwkAlgorithmRs512:
+ return WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5;
+ case kJwkAlgorithmRsa1_5:
+ return WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5;
+ case kJwkAlgorithmRsaOaep:
+ return WebKit::WebCryptoAlgorithmIdRsaOaep;
+ case kJwkAlgorithmA128Kw:
+ case kJwkAlgorithmA256Kw:
+ // TODO(padolph) Support AES keywrap algorithm, required for JWK but not
+ // present in the Web Crypto spec.
+ return WebCryptoAlgorithmIdNone;
+ case kJwkAlgorithmA128Gcm:
+ case kJwkAlgorithmA256Gcm:
+ return WebKit::WebCryptoAlgorithmIdAesGcm;
+ case kJwkAlgorithmA128Cbc:
+ case kJwkAlgorithmA256Cbc:
+ case kJwkAlgorithmA384Cbc:
+ case kJwkAlgorithmA512Cbc:
+ return WebKit::WebCryptoAlgorithmIdAesCbc;
+ default:
+ DCHECK(false);
+ return WebCryptoAlgorithmIdNone;
+ }
+}
+
+unsigned short JwkAlgIdToKeyLengthBits(int jwk_algorithm_id) {
+ switch (jwk_algorithm_id) {
+ case kJwkAlgorithmA128Kw:
+ case kJwkAlgorithmA128Gcm:
+ case kJwkAlgorithmA128Cbc:
+ return 128;
+ case kJwkAlgorithmHs256:
+ case kJwkAlgorithmA256Kw:
+ case kJwkAlgorithmRs256:
+ case kJwkAlgorithmA256Gcm:
+ case kJwkAlgorithmA256Cbc:
+ return 256;
+ case kJwkAlgorithmHs384:
+ case kJwkAlgorithmRs384:
+ case kJwkAlgorithmA384Cbc:
+ return 384;
+ case kJwkAlgorithmHs512:
+ case kJwkAlgorithmRs512:
+ case kJwkAlgorithmA512Cbc:
+ return 512;
+ default:
+ return 0;
+ }
+}
+
+WebKit::WebCryptoAlgorithm CreateWebCryptoAlgorithmFromJwkAlgorithmId(
eroman 2013/10/22 21:49:38 I think things would be more readable to have a si
padolph 2013/10/28 20:35:07 Done. But since the creation functions have differ
+ int jwk_algorithm_id) {
+ const unsigned short key_length_bits =
+ JwkAlgIdToKeyLengthBits(jwk_algorithm_id);
+ DCHECK(key_length_bits);
+ switch(jwk_algorithm_id) {
+ case kJwkAlgorithmHs256:
+ case kJwkAlgorithmHs384:
+ case kJwkAlgorithmHs512:
+ return CreateHmacAlgorithm(key_length_bits);
+ case kJwkAlgorithmRs256:
+ case kJwkAlgorithmRs384:
+ case kJwkAlgorithmRs512:
+ return CreateRsaSsaAlgorithm(key_length_bits);
+ case kJwkAlgorithmRsa1_5:
+ return CreateAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5);
+ case kJwkAlgorithmRsaOaep:
+ return CreateRsaOaepAlgorithm(key_length_bits);
+ case kJwkAlgorithmA128Kw:
+ case kJwkAlgorithmA256Kw:
+ // TODO(padolph) Support AES keywrap algorithm, required for JWK but not
+ // present in the Web Crypto spec.
+ return CreateAlgorithm(WebCryptoAlgorithmIdNone);
+ case kJwkAlgorithmA128Gcm:
+ case kJwkAlgorithmA256Gcm:
+ return CreateAesGcmAlgorithm(key_length_bits);
+ case kJwkAlgorithmA128Cbc:
+ case kJwkAlgorithmA256Cbc:
+ case kJwkAlgorithmA384Cbc:
+ case kJwkAlgorithmA512Cbc:
+ return CreateAesCbcAlgorithm(key_length_bits);
+ default:
+ DCHECK(false);
eroman 2013/10/22 21:49:38 NOTREACHED()
padolph 2013/10/28 20:35:07 This code is now gone.
+ return CreateAlgorithm(WebCryptoAlgorithmIdNone);
+ }
+}
+
+typedef std::map<std::string, int> StringIntMap;
+
+void InitJwkAlgorithmMap(StringIntMap& jwk_algorithm_map)
eroman 2013/10/22 21:49:38 Chromium style (unlike Blink style) does not like
padolph 2013/10/28 20:35:07 This code is now gone.
+{
+ // Note: A*CBC are not yet present in the JOSE JWA spec
+ // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-16
+ jwk_algorithm_map["HS256" ] = kJwkAlgorithmHs256;
eroman 2013/10/22 21:49:38 style nit: remove the space padding (i personally
padolph 2013/10/28 20:35:07 Done.
+ jwk_algorithm_map["HS384" ] = kJwkAlgorithmHs384;
+ jwk_algorithm_map["HS512" ] = kJwkAlgorithmHs512;
+ jwk_algorithm_map["RS256" ] = kJwkAlgorithmRs256;
+ jwk_algorithm_map["RS384" ] = kJwkAlgorithmRs384;
+ jwk_algorithm_map["RS512" ] = kJwkAlgorithmRs512;
+ jwk_algorithm_map["RSA1_5" ] = kJwkAlgorithmRsa1_5;
+ jwk_algorithm_map["RSA-OAEP"] = kJwkAlgorithmRsaOaep;
+ jwk_algorithm_map["A128KW" ] = kJwkAlgorithmA128Kw;
+ jwk_algorithm_map["A256KW" ] = kJwkAlgorithmA256Kw;
+ jwk_algorithm_map["A128GCM" ] = kJwkAlgorithmA128Gcm;
+ jwk_algorithm_map["A256GCM" ] = kJwkAlgorithmA256Gcm;
+ jwk_algorithm_map["A128CBC" ] = kJwkAlgorithmA128Cbc;
+ jwk_algorithm_map["A256CBC" ] = kJwkAlgorithmA256Cbc;
+ jwk_algorithm_map["A384CBC" ] = kJwkAlgorithmA384Cbc;
+ jwk_algorithm_map["A512CBC" ] = kJwkAlgorithmA512Cbc;
+}
+
+// forward
+bool operator!=(const WebKit::WebCryptoAlgorithm& lhs,
+ const WebKit::WebCryptoAlgorithm& rhs);
+
+// TODO(padolph) Verify this logic is sufficient to judge algorithm
+// "consistency" for JWK import, and for all supported algorithms.
+bool operator==(const WebKit::WebCryptoAlgorithm& lhs,
eroman 2013/10/22 21:49:38 Chromium style guide doesn't like operator overloa
Ryan Sleevi 2013/10/24 01:45:58 Should WebKit::WebCryptoAlgorithm have an Equals()
eroman 2013/10/24 02:35:04 It isn't obvious what equality means, so I think t
padolph 2013/10/28 20:35:07 Function name changed. But I am also very confused
+ const WebKit::WebCryptoAlgorithm& rhs) {
+ if (lhs.id() != rhs.id())
+ return false;
+ if (lhs.id() == WebKit::WebCryptoAlgorithmIdHmac ||
+ lhs.id() == WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
+ lhs.id() == WebKit::WebCryptoAlgorithmIdRsaOaep) {
+ if (lhs.hmacParams()->hash() != rhs.hmacParams()->hash())
+ return false;
+ }
+ return true;
eroman 2013/10/22 21:49:38 For the sake of future proofing, I would rather ha
padolph 2013/10/28 20:35:07 Done.
+}
+
+bool operator!=(const WebKit::WebCryptoAlgorithm& lhs,
+ const WebKit::WebCryptoAlgorithm& rhs) {
+ return !(lhs == rhs);
+}
+
+} // namespace
+
WebCryptoImpl::WebCryptoImpl() {
Init();
+ InitJwkAlgorithmMap(jwk_algorithm_map_);
eroman 2013/10/22 21:49:38 I would prefer lazy initialization, since JWK may
Ryan Sleevi 2013/10/24 01:45:58 Don't use a function-level static. They're forbidd
eroman 2013/10/24 02:35:04 My mistake! I got muddled with Blink style vs Chro
padolph 2013/10/28 20:35:07 LazyInstance used.
}
void WebCryptoImpl::encrypt(
@@ -84,20 +343,30 @@ void WebCryptoImpl::importKey(
WebKit::WebCryptoKeyType type;
scoped_ptr<WebKit::WebCryptoKeyHandle> handle;
- if (!ImportKeyInternal(format,
- key_data,
- key_data_size,
- algorithm,
- usage_mask,
- &handle,
- &type)) {
- result.completeWithError();
- return;
+ if (format == WebKit::WebCryptoKeyFormatJwk) {
+ if (!ImportKeyJwk(key_data,
+ key_data_size,
+ extractable,
+ algorithm,
+ usage_mask,
+ &handle,
+ &type)) {
+ result.completeWithError();
+ }
+ } else {
+ if (!ImportKeyInternal(format,
+ key_data,
+ key_data_size,
+ algorithm,
+ usage_mask,
+ &handle,
+ &type)) {
+ result.completeWithError();
+ }
}
- WebKit::WebCryptoKey key(
- WebKit::WebCryptoKey::create(
- handle.release(), type, extractable, algorithm, usage_mask));
+ WebKit::WebCryptoKey key(WebKit::WebCryptoKey::create(
+ handle.release(), type, extractable, algorithm, usage_mask));
result.completeWithKey(key);
}
@@ -138,4 +407,204 @@ void WebCryptoImpl::verifySignature(
}
}
+bool WebCryptoImpl::ImportKeyJwk(
+ const unsigned char* key_data,
+ unsigned key_data_size,
+ bool extractable,
+ const WebKit::WebCryptoAlgorithm& algorithm,
+ WebKit::WebCryptoKeyUsageMask usage_mask,
+ scoped_ptr<WebKit::WebCryptoKeyHandle>* handle,
+ WebKit::WebCryptoKeyType* type) {
+
+ // JSON Web Key Format (JWK)
eroman 2013/10/22 21:49:38 This is a good comment block, thanks!
+ // http://tools.ietf.org/html/draft-ietf-jose-json-web-key-16
+ // TODO(padolph) Not all possible values are handled by this code right now
+ //
+ // A JWK is a simple JSON dictionary with the following entries
+ // - "kty" (Key Type) Parameter, REQUIRED
+ // - <kty-specific parameters, see below>, REQUIRED
+ // - "use" (Key Use) Parameter, OPTIONAL
+ // - "alg" (Algorithm) Parameter, OPTIONAL
+ // - "extractable" (Key Exportability), OPTIONAL [NOTE: not yet part of JOSE]
+ // (all other entries are ignored)
+ //
+ // Input key_data contains the JWK. To build a Web Crypto Key, the JWK values
+ // are parsed out and used as follows:
+ // Web Crypto Key type <-- (deduced)
+ // Web Crypto Key extractable <-- extractable
+ // Web Crypto Key algorithm <-- alg
+ // Web Crypto Key keyUsage <-- usage
+ // Web Crypto Key keying material <-- kty-specific parameters
+ //
+ // Values for each entry are case-sensitive and defined in
+ // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-16.
+ // Note that not all values specified by JOSE are handled by this code. Only
+ // handled values are listed.
+ // - kty (Key Type)
+ // +-------+--------------------------------------------------------------+
+ // | "RSA" | RSA [RFC3447] |
+ // | "oct" | Octet sequence (used to represent symmetric keys) |
+ // +-------+--------------------------------------------------------------+
+ // - use (Key Use)
+ // +-------+--------------------------------------------------------------+
+ // | "enc" | encrypt and decrypt operations |
+ // | "sig" | sign and verify (MAC) operations |
+ // | "wrap"| key wrap and unwrap [not yet part of JOSE] |
+ // +-------+--------------------------------------------------------------+
+ // - extractable (Key Exportability)
+ // +-------+--------------------------------------------------------------+
+ // | true | Key may be exported from the trusted environment |
+ // | false | Key cannot exit the trusted environment |
+ // +-------+--------------------------------------------------------------+
+ // - alg (Algorithm)
+ // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-16
+ // +--------------+-------------------------------------------------------+
+ // | Digital Signature or MAC Algorithm |
+ // +--------------+-------------------------------------------------------+
+ // | "HS256" | HMAC using SHA-256 hash algorithm |
+ // | "HS384" | HMAC using SHA-384 hash algorithm |
+ // | "HS512" | HMAC using SHA-512 hash algorithm |
+ // | "RS256" | RSASSA using SHA-256 hash algorithm |
+ // | "RS384" | RSASSA using SHA-384 hash algorithm |
+ // | "RS512" | RSASSA using SHA-512 hash algorithm |
+ // +--------------+-------------------------------------------------------|
+ // | Key Management Algorithm |
+ // +--------------+-------------------------------------------------------+
+ // | "RSA1_5" | RSAES-PKCS1-V1_5 [RFC3447] |
+ // | "RSA-OAEP" | RSAES using Optimal Asymmetric Encryption Padding |
+ // | | (OAEP) [RFC3447], with the default parameters |
+ // | | specified by RFC3447 in Section A.2.1 |
+ // | "A128KW" | Advanced Encryption Standard (AES) Key Wrap Algorithm |
+ // | | [RFC3394] using 128 bit keys |
+ // | "A256KW" | AES Key Wrap Algorithm using 256 bit keys |
+ // | "A128GCM" | AES in Galois/Counter Mode (GCM) [NIST.800-38D] using |
+ // | | 128 bit keys |
+ // | "A256GCM" | AES GCM using 256 bit keys |
+ // | "A128CBC" | AES in Cipher Block Chaining Mode (CBC) with PKCS #5 |
+ // | | padding [NIST.800-38A] [not yet part of JOSE] |
+ // | "A256CBC" | AES CBC using 256 bit keys [not yet part of JOSE] |
+ // | "A384CBC" | AES CBC using 384 bit keys [not yet part of JOSE] |
+ // | "A512CBC" | AES CBC using 512 bit keys [not yet part of JOSE] |
+ // +--------------+-------------------------------------------------------+
+ //
+ // kty-specific parameters
+ // The value of kty determines the type and content of the keying material
+ // carried in the JWK to be imported. Currently only two possibilities are
+ // supported: a raw key or an RSA public key. RSA private keys are not
+ // supported because typical applications seldom need to import a private key,
+ // and the large number of JWK parameters required to describe one.
+ // - kty == "oct" (symmetric or other raw key)
+ // +-------+--------------------------------------------------------------+
+ // | "k" | Contains the value of the symmetric (or other single-valued) |
+ // | | key. It is represented as the base64url encoding of the |
+ // | | octet sequence containing the key value. |
+ // +-------+--------------------------------------------------------------+
+ // - kty == "RSA" (RSA public key)
+ // +-------+--------------------------------------------------------------+
+ // | "n" | Contains the modulus value for the RSA public key. It is |
+ // | | represented as the base64url encoding of the value's |
+ // | | unsigned big endian representation as an octet sequence. |
+ // +-------+--------------------------------------------------------------+
+ // | "e" | Contains the exponent value for the RSA public key. It is |
+ // | | represented as the base64url encoding of the value's |
+ // | | unsigned big endian representation as an octet sequence. |
+ // +-------+--------------------------------------------------------------+
+ //
+ // Conflict resolution
+ // The type, algorithm, extractable, and usage_mask input parameters may be
+ // different from similar values inside the JWK. The Web Crypto spec says that
+ // if a JWK value is present, but is inconsistent with the input value, it is
+ // an error and the operation must fail.
+
+ const char* const foo = reinterpret_cast<const char *>(key_data);
eroman 2013/10/22 21:49:38 Please use a variable name other than "foo".
padolph 2013/10/28 20:35:07 Done.
+ base::StringPiece json_string(foo, key_data_size);
+ scoped_ptr<base::Value> value(base::JSONReader::Read(json_string));
+ // 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;
+
+ // 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;
+
+ // JWK "extractable" --> extractable parameter
+ bool jwk_extractable_value;
+ if (dict_value->GetBoolean("extractable", &jwk_extractable_value)) {
+ // collision check
+ if (jwk_extractable_value != extractable)
+ return false;
+ }
+
+ // JWK "alg" --> algorithm parameter
+ std::string jwk_alg_value;
+ if (dict_value->GetString("alg", &jwk_alg_value)) {
+ const StringIntMap::iterator pos = jwk_algorithm_map_.find(jwk_alg_value);
eroman 2013/10/22 21:49:38 const_iterator?
padolph 2013/10/28 20:35:07 Done.
+ if (pos == jwk_algorithm_map_.end())
+ return false;
+ const int jwk_algorithm_id = pos->second;
+ WebKit::WebCryptoAlgorithm webcrypto_algorithm_from_jwk =
+ CreateWebCryptoAlgorithmFromJwkAlgorithmId(jwk_algorithm_id);
+ // collision check
+ if (webcrypto_algorithm_from_jwk != algorithm)
+ return false;
+ }
+
+ // JWK "use" --> usage_mask parameter
+ std::string jwk_use_value;
+ if (dict_value->GetString("use", &jwk_use_value)) {
+ unsigned jwk_usage_mask;
+ if (jwk_use_value == "enc") {
+ jwk_usage_mask =
+ WebKit::WebCryptoKeyUsageEncrypt | WebKit::WebCryptoKeyUsageDecrypt;
+ } else if (jwk_use_value == "sig") {
+ jwk_usage_mask =
+ WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
+ } else if (jwk_use_value == "wrap") {
+ jwk_usage_mask =
+ WebKit::WebCryptoKeyUsageWrapKey | WebKit::WebCryptoKeyUsageUnwrapKey;
+ } else {
+ return false;
+ }
+ // collision check
+ if (!(jwk_usage_mask & usage_mask))
eroman 2013/10/22 21:49:38 Do they need to match exactly?
Ryan Sleevi 2013/10/24 01:45:58 No. The spec merely says that if they conflict in
eroman 2013/10/24 02:35:04 Thanks Ryan! My understanding then is that we wan
padolph 2013/10/28 20:35:07 Yea, after thinking about it more, subset makes mo
+ return false;
+ }
+
+ // JWK keying material --> ImportKeyInternal()
+ if (jwk_kty_value == "oct") {
+ // collision check
+ if (*type != WebKit::WebCryptoKeyTypeSecret)
+ return false;
+ std::string jwk_k_value_url64;
+ if (!dict_value->GetString("k", &jwk_k_value_url64))
+ return false;
+ std::string jwk_k_value;
+ if (!Base64DecodeUrlSafe(jwk_k_value_url64, &jwk_k_value))
+ return false;
+ const std::vector<uint8> data(jwk_k_value.begin(), jwk_k_value.end());
eroman 2013/10/22 21:49:38 Rather than copying into a std::vector<>, I believ
padolph 2013/10/28 20:35:07 Done.
+ if (!ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw,
+ &data[0],
eroman 2013/10/22 21:49:38 Is data guaranteed to have at least 1 element?
padolph 2013/10/28 20:35:07 No. I added a check for that plus a unit test. Tha
+ data.size(),
+ algorithm,
+ usage_mask,
+ handle,
+ type)) {
+ return false;
+ }
+ } else if (jwk_kty_value == "RSA") {
+ // Only an RSA public key is currently handled.
+ // collision check
+ if (*type != WebKit::WebCryptoKeyTypePublic)
+ return false;
+ // TODO(padolph): JWK import RSA public key
+ return false;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
} // namespace content
« no previous file with comments | « content/renderer/webcrypto/webcrypto_impl.h ('k') | content/renderer/webcrypto/webcrypto_impl_openssl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698