Index: content/child/webcrypto/jwk.h |
diff --git a/content/child/webcrypto/jwk.h b/content/child/webcrypto/jwk.h |
index a5872090cb7410409038a3b8b1b1fd6d315c5a8d..0f538ffd109d0e7fa05b7259868322ec8dbfe9de 100644 |
--- a/content/child/webcrypto/jwk.h |
+++ b/content/child/webcrypto/jwk.h |
@@ -11,9 +11,7 @@ |
#include "base/strings/string_piece.h" |
#include "base/values.h" |
#include "content/common/content_export.h" |
-#include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
#include "third_party/WebKit/public/platform/WebCrypto.h" |
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
namespace content { |
@@ -22,6 +20,113 @@ namespace webcrypto { |
class CryptoData; |
class Status; |
+// Helper class for parsing a JWK from JSON. |
+// |
+// This primarily exists to ensure strict enforcement of the JWK schema, as the |
+// type and presence of particular fields is security relevant. For example, |
Ryan Sleevi
2014/11/04 20:59:50
s/fields/members/
eroman
2014/11/04 21:50:45
Done.
|
+// GetString() will ensure a given JSON field is present and is a string type, |
Ryan Sleevi
2014/11/04 20:59:50
s/field/member/
eroman
2014/11/04 21:50:45
Done.
|
+// and will fail if these conditions aren't met. |
+// |
+// Users of JwkReader must call Init() successfully before any other method can |
+// be called. |
+class JwkReader { |
+ public: |
+ JwkReader(); |
+ ~JwkReader(); |
+ |
+ // Initializes a JWK reader by parsing the JSON |bytes|. To succeed, the JWK |
+ // must: |
+ // * Have "kty" matching |expected_kty| |
+ // * Have "ext" compatible with |expected_extractable| |
+ // * Have usages ("use", "key_ops") compatible with |expected_usages| |
+ // * Have an "alg" matching |expected_alg| |
+ // |
+ // NOTE: If |expected_alg| is empty, then the test on "alg" is skipped. |
+ Status Init(const CryptoData& bytes, |
+ bool expected_extractable, |
+ blink::WebCryptoKeyUsageMask expected_usages, |
+ const std::string& expected_kty, |
+ const std::string& expected_alg); |
+ |
+ // Returns true if the member |member_name| is present. |
+ bool HasMember(const std::string& member_name) const; |
+ |
+ // Extracts the required string member |member_name| and saves the result to |
+ // |*result|. If the member does not exist or is not a string, returns an |
+ // error. |
+ Status GetString(const std::string& member_name, std::string* result) const; |
+ |
+ // Extracts the optional string member |member_name| and saves the result to |
+ // |*result| if it was found. If the member exists and is not a string, |
+ // returns an error. Otherwise returns success, and sets |*member_exists| if |
+ // it was found. |
+ Status GetOptionalString(const std::string& member_name, |
+ std::string* result, |
+ bool* member_exists) const; |
+ |
+ // Extracts the optional array member |member_name| and saves the result to |
+ // |*result| if it was found. If the member exists and is not an array, |
+ // returns an error. Otherwise returns success, and sets |*member_exists| if |
+ // it was found. |
+ // |
+ // NOTE: |*result| is owned by the JwkReader. |
+ Status GetOptionalList(const std::string& member_name, |
+ base::ListValue** result, |
+ bool* member_exists) const; |
+ |
+ // Extracts the required string member |member_name| and saves the |
+ // base64url-decoded bytes to |*result|. If the member does not exist or is |
+ // not a string, or could not be base64url-decoded, returns an error. |
+ Status GetBytes(const std::string& member_name, std::string* result) const; |
+ |
+ // Extracts the required base64url member, which is interpreted as being a |
+ // big-endian unsigned integer. |
+ // |
+ // Sequences that contain leading zeros will be rejected. |
+ Status GetBigInteger(const std::string& member_name, |
+ std::string* result) const; |
+ |
+ // Extracts the optional boolean member |member_name| and saves the result to |
+ // |*result| if it was found. If the member exists and is not a boolean, |
+ // returns an error. Otherwise returns success, and sets |*member_exists| if |
+ // it was found. |
+ Status GetOptionalBool(const std::string& member_name, |
+ bool* result, |
+ bool* member_exists) const; |
+ |
+ // Gets the optional algorithm ("alg") string. |
+ Status GetAlg(std::string* alg, bool* has_alg) const; |
+ |
+ // Checks if the "alg" member matches |expected_alg|. |
+ Status VerifyAlg(const std::string& expected_alg) const; |
+ |
+ private: |
+ scoped_ptr<base::DictionaryValue> dict_; |
+}; |
+ |
+// Helper class for building the JSON for a JWK. |
+class JwkWriter { |
+ public: |
+ // Initializes a writer, and sets the standard JWK members as indicated. |
+ JwkWriter(const std::string& algorithm, |
+ bool extractable, |
+ blink::WebCryptoKeyUsageMask usages, |
+ const std::string& kty); |
+ |
+ // Sets a string member |member_name| to |value|. |
+ void SetString(const std::string& member_name, const std::string& value); |
+ |
+ // Sets a bytes member |value| to |value| by base64 url-safe encoding it. |
+ void SetBytes(const std::string& member_name, const CryptoData& value); |
+ |
+ // Flattens the JWK to JSON (UTF-8 encoded if necessary, however in practice |
+ // it will be ASCII). |
+ void ToJson(std::vector<uint8_t>* utf8_bytes) const; |
+ |
+ private: |
+ base::DictionaryValue dict_; |
+}; |
+ |
// Writes a JWK-formatted symmetric key to |jwk_key_data|. |
// * raw_key_data: The actual key data |
// * algorithm: The JWK algorithm name (i.e. "alg") |
@@ -36,12 +141,12 @@ void WriteSecretKeyJwk(const CryptoData& raw_key_data, |
// Parses a UTF-8 encoded JWK (key_data), and extracts the key material to |
// |*raw_key_data|. Returns Status::Success() on success, otherwise an error. |
// In order for this to succeed: |
-// * expected_algorithm must match the JWK's "alg", if present. |
+// * expected_alg must match the JWK's "alg", if present. |
// * expected_extractable must be consistent with the JWK's "ext", if |
// present. |
// * expected_usages must be a subset of the JWK's "key_ops" if present. |
Status ReadSecretKeyJwk(const CryptoData& key_data, |
- const std::string& expected_algorithm, |
+ const std::string& expected_alg, |
bool expected_extractable, |
blink::WebCryptoKeyUsageMask expected_usages, |
std::vector<uint8_t>* raw_key_data); |
@@ -52,7 +157,7 @@ std::string MakeJwkAesAlgorithmName(const std::string& suffix, |
unsigned int keylen_bytes); |
// This is very similar to ReadSecretKeyJwk(), except instead of specifying an |
-// absolut "expected_algorithm", the suffix for an AES algorithm name is given |
+// absolute "expected_alg", the suffix for an AES algorithm name is given |
// (See MakeJwkAesAlgorithmName() for an explanation of what the suffix is). |
// |
// This is because the algorithm name for AES keys is dependent on the length |
@@ -110,12 +215,12 @@ struct JwkRsaInfo { |
// Parses a UTF-8 encoded JWK (key_data), and extracts the RSA components to |
// |*result|. Returns Status::Success() on success, otherwise an error. |
// In order for this to succeed: |
-// * expected_algorithm must match the JWK's "alg", if present. |
+// * expected_alg must match the JWK's "alg", if present. |
// * expected_extractable must be consistent with the JWK's "ext", if |
// present. |
// * expected_usages must be a subset of the JWK's "key_ops" if present. |
Status ReadRsaKeyJwk(const CryptoData& key_data, |
- const std::string& expected_algorithm, |
+ const std::string& expected_alg, |
bool expected_extractable, |
blink::WebCryptoKeyUsageMask expected_usages, |
JwkRsaInfo* result); |