OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |