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

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

Issue 76363006: [webcrypto] Add JWK import of RSA public key for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: adjusted #ifdef to make android (openssl) build pass Created 7 years 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_openssl.cc ('k') | content/renderer/webcrypto/webcrypto_util.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/webcrypto/webcrypto_impl_unittest.cc
diff --git a/content/renderer/webcrypto/webcrypto_impl_unittest.cc b/content/renderer/webcrypto/webcrypto_impl_unittest.cc
index c59de0e3d856f5c1fe171d3a73e775dad341134f..48552b76e62bb32a1fe5d0f2b6609a5f9fc13d5f 100644
--- a/content/renderer/webcrypto/webcrypto_impl_unittest.cc
+++ b/content/renderer/webcrypto/webcrypto_impl_unittest.cc
@@ -49,8 +49,9 @@ std::vector<uint8> MakeJsonVector(const base::DictionaryValue& dict) {
return MakeJsonVector(json);
}
-// Helper for ImportJwkBadJwk; restores JWK JSON dictionary to a good state
-void RestoreDictionaryForImportBadJwkTest(base::DictionaryValue* dict) {
+// Helper for ImportJwkFailures and ImportJwkOctFailures. Restores the JWK JSON
+// dictionary to a good state
+void RestoreJwkOctDictionary(base::DictionaryValue* dict) {
dict->Clear();
dict->SetString("kty", "oct");
dict->SetString("alg", "A128CBC");
@@ -58,8 +59,24 @@ void RestoreDictionaryForImportBadJwkTest(base::DictionaryValue* dict) {
dict->SetBoolean("extractable", false);
dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
}
+
#if !defined(USE_OPENSSL)
+// Helper for ImportJwkRsaFailures. Restores the JWK JSON
+// dictionary to a good state
+void RestoreJwkRsaDictionary(base::DictionaryValue* dict) {
+ dict->Clear();
+ dict->SetString("kty", "RSA");
+ dict->SetString("alg", "RSA1_5");
+ dict->SetString("use", "enc");
+ dict->SetBoolean("extractable", false);
+ dict->SetString("n",
+ "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk"
+ "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm"
+ "e7PUJHYW1PW6ENTP0ibeiNOfFvs");
+ dict->SetString("e", "AQAB");
+}
+
blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm(
blink::WebCryptoAlgorithmId algorithm_id,
unsigned modulus_length,
@@ -707,7 +724,7 @@ TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) {
#endif //#if !defined(USE_OPENSSL)
-TEST_F(WebCryptoImplTest, ImportJwkBadJwk) {
+TEST_F(WebCryptoImplTest, ImportJwkFailures) {
blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
blink::WebCryptoAlgorithm algorithm =
@@ -719,13 +736,13 @@ TEST_F(WebCryptoImplTest, ImportJwkBadJwk) {
// Each breaking subtest below resets the dictionary to this passing case when
// complete.
base::DictionaryValue dict;
- RestoreDictionaryForImportBadJwkTest(&dict);
- std::vector<uint8> json_vec = MakeJsonVector(dict);
- EXPECT_TRUE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
+ RestoreJwkOctDictionary(&dict);
+ EXPECT_TRUE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
// Fail on empty JSON.
- EXPECT_FALSE(
- ImportKeyJwk(MakeJsonVector(""), algorithm, false, usage_mask, &key));
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(""), algorithm, false, usage_mask, &key));
// Fail on invalid JSON.
const std::vector<uint8> bad_json_vec = MakeJsonVector(
@@ -738,70 +755,143 @@ TEST_F(WebCryptoImplTest, ImportJwkBadJwk) {
// Fail on JWK alg present but unrecognized.
dict.SetString("alg", "A127CBC");
- json_vec = MakeJsonVector(dict);
- EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
- RestoreDictionaryForImportBadJwkTest(&dict);
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkOctDictionary(&dict);
// Fail on both JWK and input algorithm missing.
dict.Remove("alg", NULL);
- json_vec = MakeJsonVector(dict);
- EXPECT_FALSE(ImportKeyJwk(json_vec,
+ EXPECT_FALSE(ImportKeyJwk(MakeJsonVector(dict),
blink::WebCryptoAlgorithm::createNull(),
false,
usage_mask,
&key));
- RestoreDictionaryForImportBadJwkTest(&dict);
+ RestoreJwkOctDictionary(&dict);
// Fail on invalid kty.
dict.SetString("kty", "foo");
- json_vec = MakeJsonVector(dict);
- EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
- RestoreDictionaryForImportBadJwkTest(&dict);
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkOctDictionary(&dict);
// Fail on missing kty.
dict.Remove("kty", NULL);
- json_vec = MakeJsonVector(dict);
- EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
- RestoreDictionaryForImportBadJwkTest(&dict);
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkOctDictionary(&dict);
// Fail on invalid use.
dict.SetString("use", "foo");
- json_vec = MakeJsonVector(dict);
- EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
- RestoreDictionaryForImportBadJwkTest(&dict);
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkOctDictionary(&dict);
+}
+
+TEST_F(WebCryptoImplTest, ImportJwkOctFailures) {
+
+ base::DictionaryValue dict;
+ RestoreJwkOctDictionary(&dict);
+ blink::WebCryptoAlgorithm algorithm =
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
+ blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt;
+ blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+
+ // Baseline pass.
+ EXPECT_TRUE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ EXPECT_EQ(algorithm.id(), key.algorithm().id());
+ EXPECT_FALSE(key.extractable());
+ EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
- // Fail on missing k when kty = "oct".
+ // The following are specific failure cases for when kty = "oct".
+
+ // Fail on missing k.
dict.Remove("k", NULL);
- json_vec = MakeJsonVector(dict);
- EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
- RestoreDictionaryForImportBadJwkTest(&dict);
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkOctDictionary(&dict);
// Fail on bad b64 encoding for k.
dict.SetString("k", "Qk3f0DsytU8lfza2au #$% Htaw2xpop9GYyTuH0p5GghxTI=");
- json_vec = MakeJsonVector(dict);
- EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
- RestoreDictionaryForImportBadJwkTest(&dict);
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkOctDictionary(&dict);
// Fail on empty k.
dict.SetString("k", "");
- json_vec = MakeJsonVector(dict);
- EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
- RestoreDictionaryForImportBadJwkTest(&dict);
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkOctDictionary(&dict);
// Fail on k actual length (120 bits) inconsistent with the embedded JWK alg
// value (128) for an AES key.
dict.SetString("k", "AVj42h0Y5aqGtE3yluKL");
- json_vec = MakeJsonVector(dict);
- EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
- RestoreDictionaryForImportBadJwkTest(&dict);
-
- // TODO(padolph) RSA public key bad data:
- // Missing n or e when kty = "RSA"
- // Bad encoding for n or e
- // Size check on n??
- // Value check on e??
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkOctDictionary(&dict);
+}
+
+#if !defined(USE_OPENSSL)
+
+TEST_F(WebCryptoImplTest, ImportJwkRsaFailures) {
+
+ base::DictionaryValue dict;
+ RestoreJwkRsaDictionary(&dict);
+ blink::WebCryptoAlgorithm algorithm =
+ webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5);
+ blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt;
+ blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+
+ // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent)
+ // entry, while an RSA private key must have those plus at least a "d"
+ // (private exponent) entry.
+ // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
+ // section 6.3.
+
+ // Baseline pass.
+ EXPECT_TRUE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ EXPECT_EQ(algorithm.id(), key.algorithm().id());
+ EXPECT_FALSE(key.extractable());
+ EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages());
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type());
+
+ // The following are specific failure cases for when kty = "RSA".
+
+ // Fail if either "n" or "e" is not present or malformed.
+ const std::string kKtyParmName[] = {"n", "e"};
+ for (size_t idx = 0; idx < ARRAYSIZE_UNSAFE(kKtyParmName); ++idx) {
+
+ // Fail on missing parameter.
+ dict.Remove(kKtyParmName[idx], NULL);
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkRsaDictionary(&dict);
+
+ // Fail on bad b64 parameter encoding.
+ dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0");
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkRsaDictionary(&dict);
+
+ // Fail on empty parameter.
+ dict.SetString(kKtyParmName[idx], "");
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkRsaDictionary(&dict);
+ }
+
+ // Fail if "d" parameter is present, implying the JWK is a private key, which
+ // is not supported.
+ dict.SetString("d", "Qk3f0Dsyt");
+ EXPECT_FALSE(ImportKeyJwk(
+ MakeJsonVector(dict), algorithm, false, usage_mask, &key));
+ RestoreJwkRsaDictionary(&dict);
}
+#endif // #if !defined(USE_OPENSSL)
+
TEST_F(WebCryptoImplTest, ImportJwkInputConsistency) {
// The Web Crypto spec says that if a JWK value is present, but is
// inconsistent with the input value, the operation must fail.
@@ -904,6 +994,11 @@ TEST_F(WebCryptoImplTest, ImportJwkInputConsistency) {
EXPECT_FALSE(
ImportKeyJwk(json_vec, algorithm, extractable, usage_mask, &key));
usage_mask = blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify;
+
+ // TODO(padolph): kty vs alg consistency tests: Depending on the kty value,
+ // only certain alg values are permitted. For example, when kty = "RSA" alg
+ // must be of the RSA family, or when kty = "oct" alg must be symmetric
+ // algorithm.
}
TEST_F(WebCryptoImplTest, ImportJwkHappy) {
@@ -945,8 +1040,7 @@ TEST_F(WebCryptoImplTest, ImportJwkHappy) {
ExpectArrayBufferMatchesHex(mac_raw, output);
- // TODO(padolph)
- // Import an RSA public key JWK and use it
+ // TODO(padolph): Import an RSA public key JWK and use it
}
#if !defined(USE_OPENSSL)
« no previous file with comments | « content/renderer/webcrypto/webcrypto_impl_openssl.cc ('k') | content/renderer/webcrypto/webcrypto_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698