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

Side by Side Diff: content/child/webcrypto/shared_crypto_unittest.cc

Issue 287133004: [webcrypto] Add JWK import/export of RSA private keys (NSS). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Don't distinguish between unspecified optional params and empty params Created 6 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/child/webcrypto/shared_crypto.h" 5 #include "content/child/webcrypto/shared_crypto.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 public_exponent.size())); 136 public_exponent.size()));
137 } 137 }
138 138
139 // Creates an AES-CBC algorithm. 139 // Creates an AES-CBC algorithm.
140 blink::WebCryptoAlgorithm CreateAesCbcAlgorithm(const std::vector<uint8>& iv) { 140 blink::WebCryptoAlgorithm CreateAesCbcAlgorithm(const std::vector<uint8>& iv) {
141 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( 141 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
142 blink::WebCryptoAlgorithmIdAesCbc, 142 blink::WebCryptoAlgorithmIdAesCbc,
143 new blink::WebCryptoAesCbcParams(Uint8VectorStart(iv), iv.size())); 143 new blink::WebCryptoAesCbcParams(Uint8VectorStart(iv), iv.size()));
144 } 144 }
145 145
146 // Creates and AES-GCM algorithm. 146 // Creates an AES-GCM algorithm.
147 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm( 147 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm(
148 const std::vector<uint8>& iv, 148 const std::vector<uint8>& iv,
149 const std::vector<uint8>& additional_data, 149 const std::vector<uint8>& additional_data,
150 unsigned int tag_length_bits) { 150 unsigned int tag_length_bits) {
151 EXPECT_TRUE(SupportsAesGcm()); 151 EXPECT_TRUE(SupportsAesGcm());
152 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( 152 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
153 blink::WebCryptoAlgorithmIdAesGcm, 153 blink::WebCryptoAlgorithmIdAesGcm,
154 new blink::WebCryptoAesGcmParams(Uint8VectorStart(iv), 154 new blink::WebCryptoAesGcmParams(Uint8VectorStart(iv),
155 iv.size(), 155 iv.size(),
156 true, 156 true,
(...skipping 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 EXPECT_NE(Status::Success(), 1557 EXPECT_NE(Status::Success(),
1558 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); 1558 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
1559 RestoreJwkRsaDictionary(&dict); 1559 RestoreJwkRsaDictionary(&dict);
1560 1560
1561 // Fail on empty parameter. 1561 // Fail on empty parameter.
1562 dict.SetString(kKtyParmName[idx], ""); 1562 dict.SetString(kKtyParmName[idx], "");
1563 EXPECT_NE(Status::Success(), 1563 EXPECT_NE(Status::Success(),
1564 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); 1564 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
1565 RestoreJwkRsaDictionary(&dict); 1565 RestoreJwkRsaDictionary(&dict);
1566 } 1566 }
1567
1568 // Fail if "d" parameter is present, implying the JWK is a private key, which
1569 // is not supported.
1570 dict.SetString("d", "Qk3f0Dsyt");
1571 EXPECT_EQ(Status::ErrorJwkRsaPrivateKeyUnsupported(),
1572 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
1573 RestoreJwkRsaDictionary(&dict);
1574 } 1567 }
1575 1568
1576 TEST_F(SharedCryptoTest, MAYBE(ImportJwkInputConsistency)) { 1569 TEST_F(SharedCryptoTest, MAYBE(ImportJwkInputConsistency)) {
1577 // The Web Crypto spec says that if a JWK value is present, but is 1570 // The Web Crypto spec says that if a JWK value is present, but is
1578 // inconsistent with the input value, the operation must fail. 1571 // inconsistent with the input value, the operation must fail.
1579 1572
1580 // Consistency rules when JWK value is not present: Inputs should be used. 1573 // Consistency rules when JWK value is not present: Inputs should be used.
1581 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); 1574 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1582 bool extractable = false; 1575 bool extractable = false;
1583 blink::WebCryptoAlgorithm algorithm = 1576 blink::WebCryptoAlgorithm algorithm =
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
2035 // Failing case: Import RSA key but provide an inconsistent input algorithm. 2028 // Failing case: Import RSA key but provide an inconsistent input algorithm.
2036 EXPECT_EQ(Status::DataError(), 2029 EXPECT_EQ(Status::DataError(),
2037 ImportKey(blink::WebCryptoKeyFormatPkcs8, 2030 ImportKey(blink::WebCryptoKeyFormatPkcs8,
2038 CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)), 2031 CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
2039 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), 2032 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
2040 true, 2033 true,
2041 blink::WebCryptoKeyUsageSign, 2034 blink::WebCryptoKeyUsageSign,
2042 &key)); 2035 &key));
2043 } 2036 }
2044 2037
2038 // Tests JWK import and export by doing a roundtrip key conversion and ensuring
2039 // it was lossless:
2040 //
2041 // PKCS8 --> JWK --> PKCS8
2042 TEST_F(SharedCryptoTest, MAYBE(ImportRsaPrivateKeyJwkToPkcs8RoundTrip)) {
2043 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
2044 ASSERT_EQ(Status::Success(),
2045 ImportKey(blink::WebCryptoKeyFormatPkcs8,
2046 CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
2047 CreateRsaHashedImportAlgorithm(
2048 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
2049 blink::WebCryptoAlgorithmIdSha1),
2050 true,
2051 blink::WebCryptoKeyUsageSign,
2052 &key));
2053
2054 std::vector<uint8> exported_key_jwk;
2055 ASSERT_EQ(Status::Success(),
2056 ExportKey(blink::WebCryptoKeyFormatJwk, key, &exported_key_jwk));
2057
2058 // All of the optional parameters (p, q, dp, dq, qi) should be present in the
2059 // output.
2060 const char* expected_jwk =
2061 "{\"alg\":\"RS1\",\"d\":\"M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-"
2062 "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ"
2063 "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU\",\"dp\":"
2064 "\"KPoTk4ZVvh-"
2065 "KFZy6ylpy6hkMMAieGc0nSlVvNsT24Z9VSzTAd3kEJ7vdjdPt4kSDKPOF2Bsw6OQ7L_-"
2066 "gJ4YZeQ\",\"dq\":\"Gos485j6cSBJiY1_t57gp3ZoeRKZzfoJ78DlB6yyHtdDAe9b_Ui-"
2067 "RV6utuFnglWCdYCo5OjhQVHRUQqCo_LnKQ\",\"e\":\"AQAB\",\"ext\":true,\"key_"
2068 "ops\":[\"sign\"],\"kty\":\"RSA\",\"n\":"
2069 "\"pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_"
2070 "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_"
2071 "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc\",\"p\":\"5-"
2072 "iUJyCod1Fyc6NWBT6iobwMlKpy1VxuhilrLfyWeUjApyy8zKfqyzVwbgmh31WhU1vZs8w0Fg"
2073 "s7bc0-2o5kQw\",\"q\":\"tp3KHPfU1-yB51uQ_MqHSrzeEj_"
2074 "ScAGAqpBHm25I3o1n7ST58Z2FuidYdPVCzSDccj5pYzZKH5QlRSsmmmeZ_Q\",\"qi\":"
2075 "\"JxVqukEm0kqB86Uoy_sn9WiG-"
2076 "ECp9uhuF6RLlP6TGVhLjiL93h5aLjvYqluo2FhBlOshkKz4MrhH8To9JKefTQ\"}";
2077
2078 ASSERT_EQ(CryptoData(std::string(expected_jwk)),
2079 CryptoData(exported_key_jwk));
2080
2081 ASSERT_EQ(Status::Success(),
2082 ImportKey(blink::WebCryptoKeyFormatJwk,
2083 CryptoData(exported_key_jwk),
2084 CreateRsaHashedImportAlgorithm(
2085 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
2086 blink::WebCryptoAlgorithmIdSha1),
2087 true,
2088 blink::WebCryptoKeyUsageSign,
2089 &key));
2090
2091 std::vector<uint8> exported_key_pkcs8;
2092 ASSERT_EQ(
2093 Status::Success(),
2094 ExportKey(blink::WebCryptoKeyFormatPkcs8, key, &exported_key_pkcs8));
2095
2096 ASSERT_EQ(CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
2097 CryptoData(exported_key_pkcs8));
2098 }
2099
2100 // Import a JWK RSA private key with some optional parameters missing (q, dp,
2101 // dq,
2102 // qi). The only optional parameter included is "p" (without this import fails).
Ryan Sleevi 2014/05/19 20:48:45 1: Re-align this comment 2: Indicate via a clear T
eroman 2014/05/19 21:04:54 Done.
2103 TEST_F(SharedCryptoTest, MAYBE(ImportRsaPrivateKeyJwkMissingOptionalParams)) {
2104 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
2105
2106 base::DictionaryValue dict;
2107 dict.SetString("kty", "RSA");
2108 dict.SetString("alg", "RS1");
2109
2110 dict.SetString(
2111 "n",
2112 "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_"
2113 "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_"
2114 "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc");
2115 dict.SetString("e", "AQAB");
2116 dict.SetString(
2117 "d",
2118 "M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-"
2119 "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ"
2120 "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU");
2121
2122 dict.SetString("p",
2123 "5-"
2124 "iUJyCod1Fyc6NWBT6iobwMlKpy1VxuhilrLfyWeUjApyy8zKfqyzVwbgmh31W"
2125 "hU1vZs8w0Fgs7bc0-2o5kQw");
2126
2127 ASSERT_EQ(Status::Success(),
2128 ImportKeyJwkFromDict(dict,
2129 CreateRsaHashedImportAlgorithm(
2130 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
2131 blink::WebCryptoAlgorithmIdSha1),
2132 true,
2133 blink::WebCryptoKeyUsageSign,
2134 &key));
2135
2136 std::vector<uint8> exported_key_pkcs8;
2137 ASSERT_EQ(
2138 Status::Success(),
2139 ExportKey(blink::WebCryptoKeyFormatPkcs8, key, &exported_key_pkcs8));
2140
2141 ASSERT_EQ(CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
2142 CryptoData(exported_key_pkcs8));
2143 }
2144
2145 // Import a JWK RSA private key, with incorrect values for "p and
2146 // "q".
2147 //
2148 // The semantics for incorrect parameters are undefined by the spec (for
2149 // instance what if p was correct, but q was wrong?)
Ryan Sleevi 2014/05/19 20:48:45 Update to point to https://www.w3.org/Bugs/Public/
eroman 2014/05/19 21:04:54 Done.
2150 TEST_F(SharedCryptoTest, MAYBE(ImportRsaPrivateKeyJwkIncorrectOptional)) {
2151 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
2152
2153 base::DictionaryValue dict;
2154 dict.SetString("kty", "RSA");
2155 dict.SetString("alg", "RS1");
2156
2157 dict.SetString(
2158 "n",
2159 "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_"
2160 "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_"
2161 "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc");
2162 dict.SetString("e", "AQAB");
2163 dict.SetString(
2164 "d",
2165 "M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-"
2166 "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ"
2167 "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU");
2168 // These values are incorrect.
2169 dict.SetString("p", "AQAB");
2170 dict.SetString("q", "AQAB");
2171
2172 ASSERT_EQ(Status::OperationError(),
2173 ImportKeyJwkFromDict(dict,
2174 CreateRsaHashedImportAlgorithm(
2175 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
2176 blink::WebCryptoAlgorithmIdSha1),
2177 true,
2178 blink::WebCryptoKeyUsageSign,
2179 &key));
2180 }
2181
2182 // Import a JWK RSA private key, with empty values for the optional "p" and
2183 // "q". Similar to test above, but exercises the empty data case in case it
2184 // is handled differently.
Ryan Sleevi 2014/05/19 20:48:45 Update to point to https://www.w3.org/Bugs/Public/
eroman 2014/05/19 21:04:54 Done.
2185 TEST_F(SharedCryptoTest, MAYBE(ImportRsaPrivateKeyJwkIncorrectOptionalEmpty)) {
2186 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
2187
2188 base::DictionaryValue dict;
2189 dict.SetString("kty", "RSA");
2190 dict.SetString("alg", "RS1");
2191
2192 dict.SetString(
2193 "n",
2194 "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_"
2195 "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_"
2196 "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc");
2197 dict.SetString("e", "AQAB");
2198 dict.SetString(
2199 "d",
2200 "M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-"
2201 "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ"
2202 "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU");
2203 dict.SetString("p", "");
2204 dict.SetString("q", "");
2205
2206 ASSERT_EQ(Status::OperationError(),
2207 ImportKeyJwkFromDict(dict,
2208 CreateRsaHashedImportAlgorithm(
2209 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
2210 blink::WebCryptoAlgorithmIdSha1),
2211 true,
2212 blink::WebCryptoKeyUsageSign,
2213 &key));
2214 }
2215
2045 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyPairRsa)) { 2216 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyPairRsa)) {
2046 // Note: using unrealistic short key lengths here to avoid bogging down tests. 2217 // Note: using unrealistic short key lengths here to avoid bogging down tests.
2047 2218
2048 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation. 2219 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation.
2049 const unsigned int modulus_length = 256; 2220 const unsigned int modulus_length = 256;
2050 const std::vector<uint8> public_exponent = HexStringToBytes("010001"); 2221 const std::vector<uint8> public_exponent = HexStringToBytes("010001");
2051 blink::WebCryptoAlgorithm algorithm = 2222 blink::WebCryptoAlgorithm algorithm =
2052 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, 2223 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
2053 modulus_length, 2224 modulus_length,
2054 public_exponent); 2225 public_exponent);
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after
3475 algorithm, 3646 algorithm,
3476 CreateAesCbcAlgorithm(std::vector<uint8>(0, 16)), 3647 CreateAesCbcAlgorithm(std::vector<uint8>(0, 16)),
3477 true, 3648 true,
3478 blink::WebCryptoKeyUsageEncrypt, 3649 blink::WebCryptoKeyUsageEncrypt,
3479 &unwrapped_key)); 3650 &unwrapped_key));
3480 } 3651 }
3481 3652
3482 } // namespace webcrypto 3653 } // namespace webcrypto
3483 3654
3484 } // namespace content 3655 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698