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

Unified Diff: content/child/webcrypto/jwk.cc

Issue 416993009: [webcrypto] JWK: Reject keys with non-minimal bigintegers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address sleevi comment Created 6 years, 5 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 | « no previous file | content/child/webcrypto/nss/rsa_key_nss.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/child/webcrypto/jwk.cc
diff --git a/content/child/webcrypto/jwk.cc b/content/child/webcrypto/jwk.cc
index 67eb5242fbf0e73e41a55928ddcf348bde264937..4bc15e2b788aa898ee618bbf31cb0bfba7cf3230 100644
--- a/content/child/webcrypto/jwk.cc
+++ b/content/child/webcrypto/jwk.cc
@@ -322,27 +322,23 @@ Status GetJwkBytes(base::DictionaryValue* dict,
return Status::Success();
}
-// Extracts the optional string property with key |path| from |dict| and saves
-// the base64url-decoded bytes to |*result|. If the property exist and is not a
-// string, or could not be base64url-decoded, returns an error. In the case
-// where the property does not exist, |result| is guaranteed to be empty.
-Status GetOptionalJwkBytes(base::DictionaryValue* dict,
- const std::string& path,
- std::string* result,
- bool* property_exists) {
- std::string base64_string;
- Status status =
- GetOptionalJwkString(dict, path, &base64_string, property_exists);
+// Extracts the required base64url property, which is interpreted as being a
+// big-endian unsigned integer.
+Status GetJwkBigInteger(base::DictionaryValue* dict,
+ const std::string& path,
+ std::string* result) {
+ Status status = GetJwkBytes(dict, path, result);
if (status.IsError())
return status;
- if (!*property_exists) {
- result->clear();
- return Status::Success();
- }
+ if (result->empty())
+ return Status::ErrorJwkEmptyBigInteger(path);
- if (!Base64DecodeUrlSafe(base64_string, result))
- return Status::ErrorJwkBase64Decode(path);
+ // The JWA spec says that "The octet sequence MUST utilize the minimum number
+ // of octets to represent the value." This means there shouldn't be any
+ // leading zeros.
+ if (result->size() > 1 && (*result)[0] == 0)
+ return Status::ErrorJwkBigIntegerHasLeadingZero(path);
return Status::Success();
}
@@ -650,10 +646,10 @@ Status ReadRsaKeyJwk(const CryptoData& key_data,
// (private exponent) entry.
// See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
// section 6.3.
- status = GetJwkBytes(dict.get(), "n", &result->n);
+ status = GetJwkBigInteger(dict.get(), "n", &result->n);
if (status.IsError())
return status;
- status = GetJwkBytes(dict.get(), "e", &result->e);
+ status = GetJwkBigInteger(dict.get(), "e", &result->e);
if (status.IsError())
return status;
@@ -661,43 +657,33 @@ Status ReadRsaKeyJwk(const CryptoData& key_data,
if (!result->is_private_key)
return Status::Success();
- status = GetJwkBytes(dict.get(), "d", &result->d);
+ status = GetJwkBigInteger(dict.get(), "d", &result->d);
if (status.IsError())
return status;
- // The "p", "q", "dp", "dq", and "qi" properties are optional. Treat these
- // properties the same if they are unspecified, as if they were specified-but
- // empty, since ImportRsaPrivateKey() doesn't do validation checks anyway.
+ // The "p", "q", "dp", "dq", and "qi" properties are optional in the JWA
+ // spec. However they are required by Chromium's WebCrypto implementation.
- bool has_p;
- status = GetOptionalJwkBytes(dict.get(), "p", &result->p, &has_p);
+ status = GetJwkBigInteger(dict.get(), "p", &result->p);
if (status.IsError())
return status;
- bool has_q;
- status = GetOptionalJwkBytes(dict.get(), "q", &result->q, &has_q);
+ status = GetJwkBigInteger(dict.get(), "q", &result->q);
if (status.IsError())
return status;
- bool has_dp;
- status = GetOptionalJwkBytes(dict.get(), "dp", &result->dp, &has_dp);
+ status = GetJwkBigInteger(dict.get(), "dp", &result->dp);
if (status.IsError())
return status;
- bool has_dq;
- status = GetOptionalJwkBytes(dict.get(), "dq", &result->dq, &has_dq);
+ status = GetJwkBigInteger(dict.get(), "dq", &result->dq);
if (status.IsError())
return status;
- bool has_qi;
- status = GetOptionalJwkBytes(dict.get(), "qi", &result->qi, &has_qi);
+ status = GetJwkBigInteger(dict.get(), "qi", &result->qi);
if (status.IsError())
return status;
- int num_optional_properties = has_p + has_q + has_dp + has_dq + has_qi;
- if (num_optional_properties != 0 && num_optional_properties != 5)
- return Status::ErrorJwkIncompleteOptionalRsaPrivateKey();
-
return Status::Success();
}
« no previous file with comments | « no previous file | content/child/webcrypto/nss/rsa_key_nss.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698