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

Side by Side Diff: components/webcrypto/algorithms/hmac.cc

Issue 2163053002: [webcrypto] Check for empty key usages *after* key creation rather than before, to match the spec's… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 4 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
« no previous file with comments | « components/webcrypto/algorithms/hkdf.cc ('k') | components/webcrypto/algorithms/pbkdf2.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <openssl/hmac.h> 5 #include <openssl/hmac.h>
6 #include <stddef.h> 6 #include <stddef.h>
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 } 111 }
112 112
113 class HmacImplementation : public AlgorithmImplementation { 113 class HmacImplementation : public AlgorithmImplementation {
114 public: 114 public:
115 HmacImplementation() {} 115 HmacImplementation() {}
116 116
117 Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm, 117 Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
118 bool extractable, 118 bool extractable,
119 blink::WebCryptoKeyUsageMask usages, 119 blink::WebCryptoKeyUsageMask usages,
120 GenerateKeyResult* result) const override { 120 GenerateKeyResult* result) const override {
121 Status status = CheckSecretKeyCreationUsages(kAllKeyUsages, usages); 121 Status status = CheckKeyCreationUsages(kAllKeyUsages, usages);
122 if (status.IsError()) 122 if (status.IsError())
123 return status; 123 return status;
124 124
125 const blink::WebCryptoHmacKeyGenParams* params = 125 const blink::WebCryptoHmacKeyGenParams* params =
126 algorithm.hmacKeyGenParams(); 126 algorithm.hmacKeyGenParams();
127 127
128 unsigned int keylen_bits = 0; 128 unsigned int keylen_bits = 0;
129 if (params->hasLengthBits()) { 129 if (params->hasLengthBits()) {
130 keylen_bits = params->optionalLengthBits(); 130 keylen_bits = params->optionalLengthBits();
131 // Zero-length HMAC keys are disallowed by the spec. 131 // Zero-length HMAC keys are disallowed by the spec.
132 if (keylen_bits == 0) 132 if (keylen_bits == 0)
133 return Status::ErrorGenerateHmacKeyLengthZero(); 133 return Status::ErrorGenerateHmacKeyLengthZero();
134 } else { 134 } else {
135 status = GetDigestBlockSizeBits(params->hash(), &keylen_bits); 135 status = GetDigestBlockSizeBits(params->hash(), &keylen_bits);
136 if (status.IsError()) 136 if (status.IsError())
137 return status; 137 return status;
138 } 138 }
139 139
140 return GenerateWebCryptoSecretKey(blink::WebCryptoKeyAlgorithm::createHmac( 140 return GenerateWebCryptoSecretKey(blink::WebCryptoKeyAlgorithm::createHmac(
141 params->hash().id(), keylen_bits), 141 params->hash().id(), keylen_bits),
142 extractable, usages, keylen_bits, result); 142 extractable, usages, keylen_bits, result);
143 } 143 }
144 144
145 Status VerifyKeyUsagesBeforeImportKey( 145 Status ImportKey(blink::WebCryptoKeyFormat format,
146 blink::WebCryptoKeyFormat format, 146 const CryptoData& key_data,
147 blink::WebCryptoKeyUsageMask usages) const override { 147 const blink::WebCryptoAlgorithm& algorithm,
148 bool extractable,
149 blink::WebCryptoKeyUsageMask usages,
150 blink::WebCryptoKey* key) const override {
148 switch (format) { 151 switch (format) {
149 case blink::WebCryptoKeyFormatRaw: 152 case blink::WebCryptoKeyFormatRaw:
153 return ImportKeyRaw(key_data, algorithm, extractable, usages, key);
150 case blink::WebCryptoKeyFormatJwk: 154 case blink::WebCryptoKeyFormatJwk:
151 return CheckSecretKeyCreationUsages(kAllKeyUsages, usages); 155 return ImportKeyJwk(key_data, algorithm, extractable, usages, key);
152 default: 156 default:
153 return Status::ErrorUnsupportedImportKeyFormat(); 157 return Status::ErrorUnsupportedImportKeyFormat();
154 } 158 }
155 } 159 }
156 160
161 Status ExportKey(blink::WebCryptoKeyFormat format,
162 const blink::WebCryptoKey& key,
163 std::vector<uint8_t>* buffer) const override {
164 switch (format) {
165 case blink::WebCryptoKeyFormatRaw:
166 return ExportKeyRaw(key, buffer);
167 case blink::WebCryptoKeyFormatJwk:
168 return ExportKeyJwk(key, buffer);
169 default:
170 return Status::ErrorUnsupportedExportKeyFormat();
171 }
172 }
173
157 Status ImportKeyRaw(const CryptoData& key_data, 174 Status ImportKeyRaw(const CryptoData& key_data,
158 const blink::WebCryptoAlgorithm& algorithm, 175 const blink::WebCryptoAlgorithm& algorithm,
159 bool extractable, 176 bool extractable,
160 blink::WebCryptoKeyUsageMask usages, 177 blink::WebCryptoKeyUsageMask usages,
161 blink::WebCryptoKey* key) const override { 178 blink::WebCryptoKey* key) const {
179 Status status = CheckKeyCreationUsages(kAllKeyUsages, usages);
180 if (status.IsError())
181 return status;
182
162 const blink::WebCryptoHmacImportParams* params = 183 const blink::WebCryptoHmacImportParams* params =
163 algorithm.hmacImportParams(); 184 algorithm.hmacImportParams();
164 185
165 unsigned int keylen_bits = 0; 186 unsigned int keylen_bits = 0;
166 Status status = GetHmacImportKeyLengthBits(params, key_data.byte_length(), 187 status = GetHmacImportKeyLengthBits(params, key_data.byte_length(),
167 &keylen_bits); 188 &keylen_bits);
168 if (status.IsError()) 189 if (status.IsError())
169 return status; 190 return status;
170 191
171 const blink::WebCryptoKeyAlgorithm key_algorithm = 192 const blink::WebCryptoKeyAlgorithm key_algorithm =
172 blink::WebCryptoKeyAlgorithm::createHmac(params->hash().id(), 193 blink::WebCryptoKeyAlgorithm::createHmac(params->hash().id(),
173 keylen_bits); 194 keylen_bits);
174 195
175 // If no bit truncation was requested, then done! 196 // If no bit truncation was requested, then done!
176 if ((keylen_bits % 8) == 0) { 197 if ((keylen_bits % 8) == 0) {
177 return CreateWebCryptoSecretKey(key_data, key_algorithm, extractable, 198 return CreateWebCryptoSecretKey(key_data, key_algorithm, extractable,
178 usages, key); 199 usages, key);
179 } 200 }
180 201
181 // Otherwise zero out the unused bits in the key data before importing. 202 // Otherwise zero out the unused bits in the key data before importing.
182 std::vector<uint8_t> modified_key_data( 203 std::vector<uint8_t> modified_key_data(
183 key_data.bytes(), key_data.bytes() + key_data.byte_length()); 204 key_data.bytes(), key_data.bytes() + key_data.byte_length());
184 TruncateToBitLength(keylen_bits, &modified_key_data); 205 TruncateToBitLength(keylen_bits, &modified_key_data);
185 return CreateWebCryptoSecretKey(CryptoData(modified_key_data), 206 return CreateWebCryptoSecretKey(CryptoData(modified_key_data),
186 key_algorithm, extractable, usages, key); 207 key_algorithm, extractable, usages, key);
187 } 208 }
188 209
189 Status ImportKeyJwk(const CryptoData& key_data, 210 Status ImportKeyJwk(const CryptoData& key_data,
190 const blink::WebCryptoAlgorithm& algorithm, 211 const blink::WebCryptoAlgorithm& algorithm,
191 bool extractable, 212 bool extractable,
192 blink::WebCryptoKeyUsageMask usages, 213 blink::WebCryptoKeyUsageMask usages,
193 blink::WebCryptoKey* key) const override { 214 blink::WebCryptoKey* key) const {
215 Status status = CheckKeyCreationUsages(kAllKeyUsages, usages);
216 if (status.IsError())
217 return status;
218
194 const char* algorithm_name = 219 const char* algorithm_name =
195 GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id()); 220 GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id());
196 if (!algorithm_name) 221 if (!algorithm_name)
197 return Status::ErrorUnexpected(); 222 return Status::ErrorUnexpected();
198 223
199 std::vector<uint8_t> raw_data; 224 std::vector<uint8_t> raw_data;
200 JwkReader jwk; 225 JwkReader jwk;
201 Status status = ReadSecretKeyNoExpectedAlgJwk(key_data, extractable, usages, 226 status = ReadSecretKeyNoExpectedAlgJwk(key_data, extractable, usages,
202 &raw_data, &jwk); 227 &raw_data, &jwk);
203 if (status.IsError()) 228 if (status.IsError())
204 return status; 229 return status;
205 status = jwk.VerifyAlg(algorithm_name); 230 status = jwk.VerifyAlg(algorithm_name);
206 if (status.IsError()) 231 if (status.IsError())
207 return status; 232 return status;
208 233
209 return ImportKeyRaw(CryptoData(raw_data), algorithm, extractable, usages, 234 return ImportKeyRaw(CryptoData(raw_data), algorithm, extractable, usages,
210 key); 235 key);
211 } 236 }
212 237
213 Status ExportKeyRaw(const blink::WebCryptoKey& key, 238 Status ExportKeyRaw(const blink::WebCryptoKey& key,
214 std::vector<uint8_t>* buffer) const override { 239 std::vector<uint8_t>* buffer) const {
215 *buffer = GetSymmetricKeyData(key); 240 *buffer = GetSymmetricKeyData(key);
216 return Status::Success(); 241 return Status::Success();
217 } 242 }
218 243
219 Status ExportKeyJwk(const blink::WebCryptoKey& key, 244 Status ExportKeyJwk(const blink::WebCryptoKey& key,
220 std::vector<uint8_t>* buffer) const override { 245 std::vector<uint8_t>* buffer) const {
221 const std::vector<uint8_t>& raw_data = GetSymmetricKeyData(key); 246 const std::vector<uint8_t>& raw_data = GetSymmetricKeyData(key);
222 247
223 const char* algorithm_name = 248 const char* algorithm_name =
224 GetJwkHmacAlgorithmName(key.algorithm().hmacParams()->hash().id()); 249 GetJwkHmacAlgorithmName(key.algorithm().hmacParams()->hash().id());
225 if (!algorithm_name) 250 if (!algorithm_name)
226 return Status::ErrorUnexpected(); 251 return Status::ErrorUnexpected();
227 252
228 WriteSecretKeyJwk(CryptoData(raw_data), algorithm_name, key.extractable(), 253 WriteSecretKeyJwk(CryptoData(raw_data), algorithm_name, key.extractable(),
229 key.usages(), buffer); 254 key.usages(), buffer);
230 255
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 } 313 }
289 }; 314 };
290 315
291 } // namespace 316 } // namespace
292 317
293 std::unique_ptr<AlgorithmImplementation> CreateHmacImplementation() { 318 std::unique_ptr<AlgorithmImplementation> CreateHmacImplementation() {
294 return base::WrapUnique(new HmacImplementation); 319 return base::WrapUnique(new HmacImplementation);
295 } 320 }
296 321
297 } // namespace webcrypto 322 } // namespace webcrypto
OLDNEW
« no previous file with comments | « components/webcrypto/algorithms/hkdf.cc ('k') | components/webcrypto/algorithms/pbkdf2.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698