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, qi). |
| 2102 // |
| 2103 // The only optional parameter included is "p". |
| 2104 // |
| 2105 // This fails because JWA says that producers must include either ALL optional |
| 2106 // parameters or NONE. |
| 2107 TEST_F(SharedCryptoTest, MAYBE(ImportRsaPrivateKeyJwkMissingOptionalParams)) { |
| 2108 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 2109 |
| 2110 base::DictionaryValue dict; |
| 2111 dict.SetString("kty", "RSA"); |
| 2112 dict.SetString("alg", "RS1"); |
| 2113 |
| 2114 dict.SetString( |
| 2115 "n", |
| 2116 "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_" |
| 2117 "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_" |
| 2118 "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc"); |
| 2119 dict.SetString("e", "AQAB"); |
| 2120 dict.SetString( |
| 2121 "d", |
| 2122 "M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-" |
| 2123 "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ" |
| 2124 "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU"); |
| 2125 |
| 2126 dict.SetString("p", |
| 2127 "5-" |
| 2128 "iUJyCod1Fyc6NWBT6iobwMlKpy1VxuhilrLfyWeUjApyy8zKfqyzVwbgmh31W" |
| 2129 "hU1vZs8w0Fgs7bc0-2o5kQw"); |
| 2130 |
| 2131 ASSERT_EQ(Status::ErrorJwkIncompleteOptionalRsaPrivateKey(), |
| 2132 ImportKeyJwkFromDict(dict, |
| 2133 CreateRsaHashedImportAlgorithm( |
| 2134 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
| 2135 blink::WebCryptoAlgorithmIdSha1), |
| 2136 true, |
| 2137 blink::WebCryptoKeyUsageSign, |
| 2138 &key)); |
| 2139 } |
| 2140 |
| 2141 // Import a JWK RSA private key, without any of the optional parameters. |
| 2142 // |
| 2143 // This is expected to work, however based on the current NSS implementation it |
| 2144 // does not. |
| 2145 // |
| 2146 // TODO(eroman): http://crbug/com/374927 |
| 2147 TEST_F(SharedCryptoTest, MAYBE(ImportRsaPrivateKeyJwkIncorrectOptionalEmpty)) { |
| 2148 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 2149 |
| 2150 base::DictionaryValue dict; |
| 2151 dict.SetString("kty", "RSA"); |
| 2152 dict.SetString("alg", "RS1"); |
| 2153 |
| 2154 dict.SetString( |
| 2155 "n", |
| 2156 "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_" |
| 2157 "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_" |
| 2158 "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc"); |
| 2159 dict.SetString("e", "AQAB"); |
| 2160 dict.SetString( |
| 2161 "d", |
| 2162 "M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-" |
| 2163 "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ" |
| 2164 "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU"); |
| 2165 |
| 2166 // TODO(eroman): This should pass, see: http://crbug/com/374927 |
| 2167 // |
| 2168 // Technically it is OK to fail since JWA says that consumer are not required |
| 2169 // to support lack of the optional parameters. |
| 2170 ASSERT_EQ(Status::OperationError(), |
| 2171 ImportKeyJwkFromDict(dict, |
| 2172 CreateRsaHashedImportAlgorithm( |
| 2173 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
| 2174 blink::WebCryptoAlgorithmIdSha1), |
| 2175 true, |
| 2176 blink::WebCryptoKeyUsageSign, |
| 2177 &key)); |
| 2178 |
| 2179 } |
| 2180 |
2045 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyPairRsa)) { | 2181 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyPairRsa)) { |
2046 // Note: using unrealistic short key lengths here to avoid bogging down tests. | 2182 // Note: using unrealistic short key lengths here to avoid bogging down tests. |
2047 | 2183 |
2048 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation. | 2184 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation. |
2049 const unsigned int modulus_length = 256; | 2185 const unsigned int modulus_length = 256; |
2050 const std::vector<uint8> public_exponent = HexStringToBytes("010001"); | 2186 const std::vector<uint8> public_exponent = HexStringToBytes("010001"); |
2051 blink::WebCryptoAlgorithm algorithm = | 2187 blink::WebCryptoAlgorithm algorithm = |
2052 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, | 2188 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
2053 modulus_length, | 2189 modulus_length, |
2054 public_exponent); | 2190 public_exponent); |
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3475 algorithm, | 3611 algorithm, |
3476 CreateAesCbcAlgorithm(std::vector<uint8>(0, 16)), | 3612 CreateAesCbcAlgorithm(std::vector<uint8>(0, 16)), |
3477 true, | 3613 true, |
3478 blink::WebCryptoKeyUsageEncrypt, | 3614 blink::WebCryptoKeyUsageEncrypt, |
3479 &unwrapped_key)); | 3615 &unwrapped_key)); |
3480 } | 3616 } |
3481 | 3617 |
3482 } // namespace webcrypto | 3618 } // namespace webcrypto |
3483 | 3619 |
3484 } // namespace content | 3620 } // namespace content |
OLD | NEW |