Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / child / webcrypto / test / rsa_ssa_unittest.cc
index f3246c0..b4ba716 100644 (file)
@@ -38,7 +38,7 @@ void RestoreJwkRsaDictionary(base::DictionaryValue* dict) {
 
 TEST(WebCryptoRsaSsaTest, ImportExportSpki) {
   // Passing case: Import a valid RSA key in SPKI format.
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatSpki,
                       CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
@@ -58,26 +58,6 @@ TEST(WebCryptoRsaSsaTest, ImportExportSpki) {
       "010001",
       CryptoData(key.algorithm().rsaHashedParams()->publicExponent()));
 
-  // Failing case: Empty SPKI data
-  EXPECT_EQ(
-      Status::ErrorImportEmptyKeyData(),
-      ImportKey(blink::WebCryptoKeyFormatSpki,
-                CryptoData(std::vector<uint8_t>()),
-                CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5),
-                true,
-                blink::WebCryptoKeyUsageVerify,
-                &key));
-
-  // Failing case: Bad DER encoding.
-  EXPECT_EQ(
-      Status::DataError(),
-      ImportKey(blink::WebCryptoKeyFormatSpki,
-                CryptoData(HexStringToBytes("618333c4cb")),
-                CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5),
-                true,
-                blink::WebCryptoKeyUsageVerify,
-                &key));
-
   // Failing case: Import RSA key but provide an inconsistent input algorithm.
   EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(),
             ImportKey(blink::WebCryptoKeyFormatSpki,
@@ -127,7 +107,7 @@ TEST(WebCryptoRsaSsaTest, ImportExportPkcs8) {
     return;
 
   // Passing case: Import a valid RSA key in PKCS#8 format.
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatPkcs8,
                       CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
@@ -154,27 +134,6 @@ TEST(WebCryptoRsaSsaTest, ImportExportPkcs8) {
             ExportKey(blink::WebCryptoKeyFormatPkcs8, key, &exported_key));
   EXPECT_BYTES_EQ_HEX(kPrivateKeyPkcs8DerHex, exported_key);
 
-  // Failing case: Empty PKCS#8 data
-  EXPECT_EQ(Status::ErrorImportEmptyKeyData(),
-            ImportKey(blink::WebCryptoKeyFormatPkcs8,
-                      CryptoData(std::vector<uint8_t>()),
-                      CreateRsaHashedImportAlgorithm(
-                          blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
-                          blink::WebCryptoAlgorithmIdSha1),
-                      true,
-                      blink::WebCryptoKeyUsageSign,
-                      &key));
-
-  // Failing case: Bad DER encoding.
-  EXPECT_EQ(
-      Status::DataError(),
-      ImportKey(blink::WebCryptoKeyFormatPkcs8,
-                CryptoData(HexStringToBytes("618333c4cb")),
-                CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5),
-                true,
-                blink::WebCryptoKeyUsageSign,
-                &key));
-
   // Failing case: Import RSA key but provide an inconsistent input algorithm
   // and usage. Several issues here:
   //   * AES-CBC doesn't support PKCS8 key format
@@ -188,57 +147,6 @@ TEST(WebCryptoRsaSsaTest, ImportExportPkcs8) {
                       &key));
 }
 
-// Tests importing of PKCS8 data that does not define a valid RSA key.
-TEST(WebCryptoRsaSsaTest, ImportInvalidPkcs8) {
-  if (!SupportsRsaPrivateKeyImport())
-    return;
-
-  // kPrivateKeyPkcs8DerHex defines an RSA private key in PKCS8 format, whose
-  // parameters appear at the following offsets:
-  //
-  //   n: (offset=36, len=129)
-  //   e: (offset=167, len=3)
-  //   d: (offset=173, len=128)
-  //   p: (offset=303, len=65)
-  //   q: (offset=370, len=65)
-  //   dp: (offset=437, len=64)
-  //   dq; (offset=503, len=64)
-  //   qi: (offset=569, len=64)
-
-  // Do several tests, each of which invert a single byte within the input.
-  const unsigned int kOffsetsToCorrupt[] = {
-      50,   // inside n
-      168,  // inside e
-      175,  // inside d
-      333,  // inside p
-      373,  // inside q
-      450,  // inside dp
-      550,  // inside dq
-      600,  // inside qi
-  };
-
-  for (size_t test_index = 0; test_index < arraysize(kOffsetsToCorrupt);
-       ++test_index) {
-    SCOPED_TRACE(test_index);
-
-    unsigned int i = kOffsetsToCorrupt[test_index];
-    std::vector<uint8_t> corrupted_data =
-        HexStringToBytes(kPrivateKeyPkcs8DerHex);
-    corrupted_data[i] = ~corrupted_data[i];
-
-    blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
-    EXPECT_EQ(Status::DataError(),
-              ImportKey(blink::WebCryptoKeyFormatPkcs8,
-                        CryptoData(corrupted_data),
-                        CreateRsaHashedImportAlgorithm(
-                            blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
-                            blink::WebCryptoAlgorithmIdSha1),
-                        true,
-                        blink::WebCryptoKeyUsageSign,
-                        &key));
-  }
-}
-
 // Tests JWK import and export by doing a roundtrip key conversion and ensuring
 // it was lossless:
 //
@@ -247,7 +155,7 @@ TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkToPkcs8RoundTrip) {
   if (!SupportsRsaPrivateKeyImport())
     return;
 
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatPkcs8,
                       CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
@@ -341,7 +249,7 @@ TEST(WebCryptoRsaSsaTest, ImportMultipleRSAPrivateKeysJwk) {
     int modulus_length_bits = 0;
     ASSERT_TRUE(key_values->GetInteger("modulusLength", &modulus_length_bits));
 
-    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey private_key;
 
     // Import the key from JWK.
     ASSERT_EQ(
@@ -389,7 +297,7 @@ TEST(WebCryptoRsaSsaTest, ImportJwkExistingModulusAndInvalid) {
   base::DictionaryValue* key1_jwk;
   ASSERT_TRUE(key1_props->GetDictionary("jwk", &key1_jwk));
 
-  blink::WebCryptoKey key1 = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key1;
   ASSERT_EQ(Status::Success(),
             ImportKeyJwkFromDict(*key1_jwk,
                                  CreateRsaHashedImportAlgorithm(
@@ -413,7 +321,7 @@ TEST(WebCryptoRsaSsaTest, ImportJwkExistingModulusAndInvalid) {
 
   // This should fail, as the n,e,d parameters are not consistent. It MUST NOT
   // somehow return the key created earlier.
-  blink::WebCryptoKey key2 = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key2;
   ASSERT_EQ(Status::OperationError(),
             ImportKeyJwkFromDict(*key2_jwk,
                                  CreateRsaHashedImportAlgorithm(
@@ -424,109 +332,6 @@ TEST(WebCryptoRsaSsaTest, ImportJwkExistingModulusAndInvalid) {
                                  &key2));
 }
 
-// Import a JWK RSA private key with some optional parameters missing (q, dp,
-// dq, qi).
-//
-// The only optional parameter included is "p".
-//
-// This fails because JWA says that producers must include either ALL optional
-// parameters or NONE.
-TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkMissingOptionalParams) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
-
-  base::DictionaryValue dict;
-  dict.SetString("kty", "RSA");
-  dict.SetString("alg", "RS1");
-
-  dict.SetString(
-      "n",
-      "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_"
-      "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_"
-      "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc");
-  dict.SetString("e", "AQAB");
-  dict.SetString(
-      "d",
-      "M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-"
-      "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ"
-      "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU");
-
-  dict.SetString("p",
-                 "5-"
-                 "iUJyCod1Fyc6NWBT6iobwMlKpy1VxuhilrLfyWeUjApyy8zKfqyzVwbgmh31W"
-                 "hU1vZs8w0Fgs7bc0-2o5kQw");
-
-  ASSERT_EQ(Status::ErrorJwkPropertyMissing("q"),
-            ImportKeyJwkFromDict(dict,
-                                 CreateRsaHashedImportAlgorithm(
-                                     blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
-                                     blink::WebCryptoAlgorithmIdSha1),
-                                 true,
-                                 blink::WebCryptoKeyUsageSign,
-                                 &key));
-}
-
-// Import a JWK RSA private key, without any of the optional parameters.
-//
-// According to JWA, such keys are valid, but applications SHOULD
-// include all the parameters when sending, and recipients MAY
-// accept them, but are not required to. Chromium's WebCrypto does
-// not allow such degenerate keys.
-TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkIncorrectOptionalEmpty) {
-  if (!SupportsRsaPrivateKeyImport())
-    return;
-
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
-
-  base::DictionaryValue dict;
-  dict.SetString("kty", "RSA");
-  dict.SetString("alg", "RS1");
-
-  dict.SetString(
-      "n",
-      "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_"
-      "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_"
-      "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc");
-  dict.SetString("e", "AQAB");
-  dict.SetString(
-      "d",
-      "M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-"
-      "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ"
-      "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU");
-
-  ASSERT_EQ(Status::ErrorJwkPropertyMissing("p"),
-            ImportKeyJwkFromDict(dict,
-                                 CreateRsaHashedImportAlgorithm(
-                                     blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
-                                     blink::WebCryptoAlgorithmIdSha1),
-                                 true,
-                                 blink::WebCryptoKeyUsageSign,
-                                 &key));
-}
-
-// Tries importing a public RSA key whose exponent contains leading zeros.
-TEST(WebCryptoRsaSsaTest, ImportJwkRsaNonMinimalExponent) {
-  base::DictionaryValue dict;
-
-  dict.SetString("kty", "RSA");
-  dict.SetString("e", "AAEAAQ");  // 00 01 00 01
-  dict.SetString(
-      "n",
-      "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk"
-      "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm"
-      "e7PUJHYW1PW6ENTP0ibeiNOfFvs");
-
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
-
-  EXPECT_EQ(Status::ErrorJwkBigIntegerHasLeadingZero("e"),
-            ImportKeyJwkFromDict(dict,
-                                 CreateRsaHashedImportAlgorithm(
-                                     blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
-                                     blink::WebCryptoAlgorithmIdSha256),
-                                 false,
-                                 blink::WebCryptoKeyUsageVerify,
-                                 &key));
-}
-
 TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
   // Note: using unrealistic short key lengths here to avoid bogging down tests.
 
@@ -539,13 +344,13 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
                                      modulus_length,
                                      public_exponent);
   bool extractable = true;
-  const blink::WebCryptoKeyUsageMask usage_mask = 0;
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  const blink::WebCryptoKeyUsageMask usages = 0;
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
 
   EXPECT_EQ(Status::Success(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
   EXPECT_FALSE(public_key.isNull());
   EXPECT_FALSE(private_key.isNull());
   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
@@ -560,8 +365,8 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
             private_key.algorithm().rsaHashedParams()->hash().id());
   EXPECT_TRUE(public_key.extractable());
   EXPECT_EQ(extractable, private_key.extractable());
-  EXPECT_EQ(usage_mask, public_key.usages());
-  EXPECT_EQ(usage_mask, private_key.usages());
+  EXPECT_EQ(usages, public_key.usages());
+  EXPECT_EQ(usages, private_key.usages());
 
   // Try exporting the generated key pair, and then re-importing to verify that
   // the exported data was valid.
@@ -579,7 +384,7 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
                             blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                             blink::WebCryptoAlgorithmIdSha256),
                         true,
-                        usage_mask,
+                        usages,
                         &public_key));
     EXPECT_EQ(modulus_length,
               public_key.algorithm().rsaHashedParams()->modulusLengthBits());
@@ -597,7 +402,7 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
                             blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                             blink::WebCryptoAlgorithmIdSha256),
                         true,
-                        usage_mask,
+                        usages,
                         &private_key));
     EXPECT_EQ(modulus_length,
               private_key.algorithm().rsaHashedParams()->modulusLengthBits());
@@ -611,7 +416,7 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
                                      public_exponent);
   EXPECT_EQ(Status::ErrorGenerateRsaUnsupportedModulus(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
 
   // Fail with bad exponent: larger than unsigned long.
   unsigned int exponent_length = sizeof(unsigned long) + 1;  // NOLINT
@@ -623,7 +428,7 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
                                      long_exponent);
   EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
 
   // Fail with bad exponent: empty.
   const std::vector<uint8_t> empty_exponent;
@@ -634,7 +439,7 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
                                      empty_exponent);
   EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
 
   // Fail with bad exponent: all zeros.
   std::vector<uint8_t> exponent_with_leading_zeros(15, 0x00);
@@ -645,7 +450,7 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
                                      exponent_with_leading_zeros);
   EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
 
   // Key generation success using exponent with leading zeros.
   exponent_with_leading_zeros.insert(exponent_with_leading_zeros.end(),
@@ -658,15 +463,15 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
                                      exponent_with_leading_zeros);
   EXPECT_EQ(Status::Success(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
   EXPECT_FALSE(public_key.isNull());
   EXPECT_FALSE(private_key.isNull());
   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
   EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type());
   EXPECT_TRUE(public_key.extractable());
   EXPECT_EQ(extractable, private_key.extractable());
-  EXPECT_EQ(usage_mask, public_key.usages());
-  EXPECT_EQ(usage_mask, private_key.usages());
+  EXPECT_EQ(usages, public_key.usages());
+  EXPECT_EQ(usages, private_key.usages());
 
   // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation (sha1)
   algorithm =
@@ -676,7 +481,7 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
                                      public_exponent);
   EXPECT_EQ(
       Status::Success(),
-      GenerateKeyPair(algorithm, false, usage_mask, &public_key, &private_key));
+      GenerateKeyPair(algorithm, false, usages, &public_key, &private_key));
   EXPECT_FALSE(public_key.isNull());
   EXPECT_FALSE(private_key.isNull());
   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
@@ -693,8 +498,8 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
   // extractable.
   EXPECT_TRUE(public_key.extractable());
   EXPECT_FALSE(private_key.extractable());
-  EXPECT_EQ(usage_mask, public_key.usages());
-  EXPECT_EQ(usage_mask, private_key.usages());
+  EXPECT_EQ(usages, public_key.usages());
+  EXPECT_EQ(usages, private_key.usages());
 
   // Exporting a private key as SPKI format doesn't make sense. However this
   // will first fail because the key is not extractable.
@@ -706,7 +511,7 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
   // This should fail since spki is for public keys.
   EXPECT_EQ(
       Status::Success(),
-      GenerateKeyPair(algorithm, true, usage_mask, &public_key, &private_key));
+      GenerateKeyPair(algorithm, true, usages, &public_key, &private_key));
   EXPECT_EQ(Status::ErrorUnexpectedKeyType(),
             ExportKey(blink::WebCryptoKeyFormatSpki, private_key, &output));
 }
@@ -731,14 +536,13 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsaBadModulusLength) {
         modulus_length_bits,
         public_exponent);
     bool extractable = true;
-    const blink::WebCryptoKeyUsageMask usage_mask = 0;
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+    const blink::WebCryptoKeyUsageMask usages = 0;
+    blink::WebCryptoKey public_key;
+    blink::WebCryptoKey private_key;
 
-    EXPECT_EQ(
-        Status::ErrorGenerateRsaUnsupportedModulus(),
-        GenerateKeyPair(
-            algorithm, extractable, usage_mask, &public_key, &private_key));
+    EXPECT_EQ(Status::ErrorGenerateRsaUnsupportedModulus(),
+              GenerateKeyPair(
+                  algorithm, extractable, usages, &public_key, &private_key));
   }
 }
 
@@ -763,8 +567,8 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsaBadExponent) {
         modulus_length,
         HexStringToBytes(kPublicExponents[i]));
 
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
+    blink::WebCryptoKey private_key;
 
     EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
               GenerateKeyPair(algorithm, true, 0, &public_key, &private_key));
@@ -779,8 +583,8 @@ TEST(WebCryptoRsaSsaTest, SignVerifyFailures) {
   blink::WebCryptoAlgorithm import_algorithm =
       CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                      blink::WebCryptoAlgorithmIdSha1);
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
   ASSERT_NO_FATAL_FAILURE(
       ImportRsaKeyPair(HexStringToBytes(kPublicKeySpkiDerHex),
                        HexStringToBytes(kPrivateKeyPkcs8DerHex),
@@ -872,7 +676,7 @@ TEST(WebCryptoRsaSsaTest, SignVerifyFailures) {
                  CryptoData(data),
                  &signature));
 
-  blink::WebCryptoKey public_key_256 = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key_256;
   EXPECT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatSpki,
                       CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
@@ -914,8 +718,8 @@ TEST(WebCryptoRsaSsaTest, SignVerifyKnownAnswer) {
   blink::WebCryptoAlgorithm import_algorithm =
       CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                      blink::WebCryptoAlgorithmIdSha1);
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
   ASSERT_NO_FATAL_FAILURE(
       ImportRsaKeyPair(HexStringToBytes(kPublicKeySpkiDerHex),
                        HexStringToBytes(kPrivateKeyPkcs8DerHex),
@@ -976,7 +780,7 @@ TEST(WebCryptoRsaSsaTest, ImportRsaSsaPublicKeyBadUsage_SPKI) {
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
     ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
               ImportKey(blink::WebCryptoKeyFormatSpki,
                         CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
@@ -1009,7 +813,7 @@ TEST(WebCryptoRsaSsaTest, ImportRsaSsaPublicKeyBadUsage_JWK) {
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
     ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
               ImportKeyJwkFromDict(
                   dict, algorithm, false, bad_usages[i], &public_key));
@@ -1031,8 +835,8 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyBadUsages) {
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
+    blink::WebCryptoKey private_key;
 
     ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
               GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
@@ -1054,8 +858,8 @@ TEST(WebCryptoRsaSsaTest, GenerateKeyPairIntersectUsages) {
   const unsigned int modulus_length = 256;
   const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
 
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
 
   ASSERT_EQ(Status::Success(),
             GenerateKeyPair(
@@ -1103,8 +907,7 @@ TEST(WebCryptoRsaSsaTest, ImportExportJwkRsaPublicKey) {
       {blink::WebCryptoAlgorithmIdSha512, blink::WebCryptoKeyUsageVerify,
        "RS512"}};
 
-  for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests);
-       ++test_index) {
+  for (size_t test_index = 0; test_index < arraysize(kTests); ++test_index) {
     SCOPED_TRACE(test_index);
     const TestCase& test = kTests[test_index];
 
@@ -1113,7 +916,7 @@ TEST(WebCryptoRsaSsaTest, ImportExportJwkRsaPublicKey) {
             blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, test.hash);
 
     // Import the spki to create a public key
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
     ASSERT_EQ(Status::Success(),
               ImportKey(blink::WebCryptoKeyFormatSpki,
                         CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
@@ -1133,7 +936,7 @@ TEST(WebCryptoRsaSsaTest, ImportExportJwkRsaPublicKey) {
                                 test.usage));
 
     // Import the JWK back in to create a new key
-    blink::WebCryptoKey public_key2 = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key2;
     ASSERT_EQ(Status::Success(),
               ImportKey(blink::WebCryptoKeyFormatJwk,
                         CryptoData(jwk),
@@ -1160,8 +963,8 @@ TEST(WebCryptoRsaSsaTest, ImportJwkRsaFailures) {
   blink::WebCryptoAlgorithm algorithm =
       CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                      blink::WebCryptoAlgorithmIdSha256);
-  blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageVerify;
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageVerify;
+  blink::WebCryptoKey key;
 
   // 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"
@@ -1171,7 +974,7 @@ TEST(WebCryptoRsaSsaTest, ImportJwkRsaFailures) {
 
   // Baseline pass.
   EXPECT_EQ(Status::Success(),
-            ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+            ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
   EXPECT_EQ(algorithm.id(), key.algorithm().id());
   EXPECT_FALSE(key.extractable());
   EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages());
@@ -1181,27 +984,83 @@ TEST(WebCryptoRsaSsaTest, ImportJwkRsaFailures) {
 
   // 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) {
+  for (size_t idx = 0; idx < arraysize(kKtyParmName); ++idx) {
     // Fail on missing parameter.
     dict.Remove(kKtyParmName[idx], NULL);
     EXPECT_NE(Status::Success(),
-              ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+              ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
     RestoreJwkRsaDictionary(&dict);
 
     // Fail on bad b64 parameter encoding.
     dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0");
     EXPECT_NE(Status::Success(),
-              ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+              ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
     RestoreJwkRsaDictionary(&dict);
 
     // Fail on empty parameter.
     dict.SetString(kKtyParmName[idx], "");
     EXPECT_EQ(Status::ErrorJwkEmptyBigInteger(kKtyParmName[idx]),
-              ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+              ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
     RestoreJwkRsaDictionary(&dict);
   }
 }
 
+// Try importing an RSA-SSA key from JWK format, having specified both Sign and
+// Verify usage, and an invalid JWK.
+//
+// The test must fail with a usage error BEFORE attempting to read the JWK data.
+// Although both Sign and Verify are valid usages for RSA-SSA keys, it is
+// invalid to have them both at the same time for one key (since Sign applies to
+// private keys, whereas Verify applies to public keys).
+//
+// If the implementation does not fail fast, this test will crash dereferencing
+// invalid memory.
+TEST(WebCryptoRsaSsaTest, ImportRsaSsaJwkBadUsageFailFast) {
+  CryptoData bad_data(NULL, 128);  // Invalid buffer of length 128.
+
+  blink::WebCryptoKey key;
+  ASSERT_EQ(
+      Status::ErrorCreateKeyBadUsages(),
+      ImportKey(blink::WebCryptoKeyFormatJwk,
+                bad_data,
+                CreateRsaHashedImportAlgorithm(
+                    blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+                    blink::WebCryptoAlgorithmIdSha256),
+                true,
+                blink::WebCryptoKeyUsageVerify | blink::WebCryptoKeyUsageSign,
+                &key));
+}
+
+// Imports invalid JWK/SPKI/PKCS8 data and verifies that it fails as expected.
+TEST(WebCryptoRsaSsaTest, ImportInvalidKeyData) {
+  if (!SupportsRsaPrivateKeyImport())
+    return;
+
+  scoped_ptr<base::ListValue> tests;
+  ASSERT_TRUE(ReadJsonTestFileToList("bad_rsa_keys.json", &tests));
+
+  for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+    SCOPED_TRACE(test_index);
+
+    const base::DictionaryValue* test;
+    ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+
+    blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
+    std::vector<uint8_t> key_data =
+        GetKeyDataFromJsonTestCase(test, key_format);
+    std::string test_error;
+    ASSERT_TRUE(test->GetString("error", &test_error));
+
+    blink::WebCryptoKey key;
+    Status status = ImportKey(key_format, CryptoData(key_data),
+                              CreateRsaHashedImportAlgorithm(
+                                  blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+                                  blink::WebCryptoAlgorithmIdSha256),
+                              true, 0, &key);
+    EXPECT_EQ(test_error, StatusToString(status));
+  }
+}
+
 }  // namespace
 
 }  // namespace webcrypto