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

Side by Side Diff: content/child/webcrypto/openssl/rsa_key_openssl.cc

Issue 685213004: Refactor: Extract some general code for asymmetric algorithms from RSA files. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@jwk_refactor
Patch Set: tweak a comment Created 6 years, 1 month 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 | « no previous file | content/child/webcrypto/openssl/util_openssl.h » ('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 "content/child/webcrypto/openssl/rsa_key_openssl.h" 5 #include "content/child/webcrypto/openssl/rsa_key_openssl.h"
6 6
7 #include <openssl/evp.h> 7 #include <openssl/evp.h>
8 #include <openssl/pkcs12.h>
9 8
10 #include "base/logging.h" 9 #include "base/logging.h"
11 #include "base/stl_util.h" 10 #include "base/stl_util.h"
12 #include "content/child/webcrypto/crypto_data.h" 11 #include "content/child/webcrypto/crypto_data.h"
13 #include "content/child/webcrypto/generate_key_result.h" 12 #include "content/child/webcrypto/generate_key_result.h"
14 #include "content/child/webcrypto/jwk.h" 13 #include "content/child/webcrypto/jwk.h"
15 #include "content/child/webcrypto/openssl/key_openssl.h" 14 #include "content/child/webcrypto/openssl/key_openssl.h"
15 #include "content/child/webcrypto/openssl/util_openssl.h"
16 #include "content/child/webcrypto/status.h" 16 #include "content/child/webcrypto/status.h"
17 #include "content/child/webcrypto/webcrypto_util.h" 17 #include "content/child/webcrypto/webcrypto_util.h"
18 #include "crypto/openssl_util.h" 18 #include "crypto/openssl_util.h"
19 #include "crypto/scoped_openssl_types.h" 19 #include "crypto/scoped_openssl_types.h"
20 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" 20 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
21 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" 21 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
22 22
23 namespace content { 23 namespace content {
24 24
25 namespace webcrypto { 25 namespace webcrypto {
26 26
27 namespace { 27 namespace {
28 28
29 Status ExportPKeySpki(EVP_PKEY* key, std::vector<uint8_t>* buffer) {
30 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
31 crypto::ScopedBIO bio(BIO_new(BIO_s_mem()));
32
33 // TODO(eroman): Use the OID specified by webcrypto spec.
34 // http://crbug.com/373545
35 if (!i2d_PUBKEY_bio(bio.get(), key))
36 return Status::ErrorUnexpected();
37
38 char* data = NULL;
39 long len = BIO_get_mem_data(bio.get(), &data);
40 if (!data || len < 0)
41 return Status::ErrorUnexpected();
42
43 buffer->assign(data, data + len);
44 return Status::Success();
45 }
46
47 Status ExportPKeyPkcs8(EVP_PKEY* key, std::vector<uint8_t>* buffer) {
48 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
49 crypto::ScopedBIO bio(BIO_new(BIO_s_mem()));
50
51 // TODO(eroman): Use the OID specified by webcrypto spec.
52 // http://crbug.com/373545
53 if (!i2d_PKCS8PrivateKeyInfo_bio(bio.get(), key))
54 return Status::ErrorUnexpected();
55
56 char* data = NULL;
57 long len = BIO_get_mem_data(bio.get(), &data);
58 if (!data || len < 0)
59 return Status::ErrorUnexpected();
60
61 buffer->assign(data, data + len);
62 return Status::Success();
63 }
64
65 // Creates a blink::WebCryptoAlgorithm having the modulus length and public 29 // Creates a blink::WebCryptoAlgorithm having the modulus length and public
66 // exponent of |key|. 30 // exponent of |key|.
67 Status CreateRsaHashedKeyAlgorithm( 31 Status CreateRsaHashedKeyAlgorithm(
68 blink::WebCryptoAlgorithmId rsa_algorithm, 32 blink::WebCryptoAlgorithmId rsa_algorithm,
69 blink::WebCryptoAlgorithmId hash_algorithm, 33 blink::WebCryptoAlgorithmId hash_algorithm,
70 EVP_PKEY* key, 34 EVP_PKEY* key,
71 blink::WebCryptoKeyAlgorithm* key_algorithm) { 35 blink::WebCryptoKeyAlgorithm* key_algorithm) {
72 DCHECK_EQ(EVP_PKEY_RSA, EVP_PKEY_id(key)); 36 DCHECK_EQ(EVP_PKEY_RSA, EVP_PKEY_id(key));
73 37
74 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(key)); 38 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(key));
75 if (!rsa.get()) 39 if (!rsa.get())
76 return Status::ErrorUnexpected(); 40 return Status::ErrorUnexpected();
77 41
78 unsigned int modulus_length_bits = BN_num_bits(rsa.get()->n); 42 unsigned int modulus_length_bits = BN_num_bits(rsa.get()->n);
79 43
80 // Convert the public exponent to big-endian representation. 44 // Convert the public exponent to big-endian representation.
81 std::vector<uint8_t> e(BN_num_bytes(rsa.get()->e)); 45 std::vector<uint8_t> e(BN_num_bytes(rsa.get()->e));
82 if (e.size() == 0) 46 if (e.size() == 0)
83 return Status::ErrorUnexpected(); 47 return Status::ErrorUnexpected();
84 if (e.size() != BN_bn2bin(rsa.get()->e, &e[0])) 48 if (e.size() != BN_bn2bin(rsa.get()->e, &e[0]))
85 return Status::ErrorUnexpected(); 49 return Status::ErrorUnexpected();
86 50
87 *key_algorithm = blink::WebCryptoKeyAlgorithm::createRsaHashed( 51 *key_algorithm = blink::WebCryptoKeyAlgorithm::createRsaHashed(
88 rsa_algorithm, modulus_length_bits, &e[0], e.size(), hash_algorithm); 52 rsa_algorithm, modulus_length_bits, &e[0], e.size(), hash_algorithm);
89 53
90 return Status::Success(); 54 return Status::Success();
91 } 55 }
92 56
93 Status CreateWebCryptoPrivateKey( 57 // Creates a WebCryptoKey that wraps |private_key|.
58 Status CreateWebCryptoRsaPrivateKey(
94 crypto::ScopedEVP_PKEY private_key, 59 crypto::ScopedEVP_PKEY private_key,
95 const blink::WebCryptoAlgorithmId rsa_algorithm_id, 60 const blink::WebCryptoAlgorithmId rsa_algorithm_id,
96 const blink::WebCryptoAlgorithm& hash, 61 const blink::WebCryptoAlgorithm& hash,
97 bool extractable, 62 bool extractable,
98 blink::WebCryptoKeyUsageMask usages, 63 blink::WebCryptoKeyUsageMask usages,
99 blink::WebCryptoKey* key) { 64 blink::WebCryptoKey* key) {
100 blink::WebCryptoKeyAlgorithm key_algorithm; 65 blink::WebCryptoKeyAlgorithm key_algorithm;
101 Status status = CreateRsaHashedKeyAlgorithm( 66 Status status = CreateRsaHashedKeyAlgorithm(
102 rsa_algorithm_id, hash.id(), private_key.get(), &key_algorithm); 67 rsa_algorithm_id, hash.id(), private_key.get(), &key_algorithm);
103 if (status.IsError()) 68 if (status.IsError())
104 return status; 69 return status;
105 70
106 // Serialize the key at creation time so that if structured cloning is 71 return CreateWebCryptoPrivateKey(private_key.Pass(), key_algorithm,
107 // requested it can be done synchronously from the Blink thread. 72 extractable, usages, key);
108 std::vector<uint8_t> pkcs8_data;
109 status = ExportPKeyPkcs8(private_key.get(), &pkcs8_data);
110 if (status.IsError())
111 return status;
112
113 *key = blink::WebCryptoKey::create(
114 new AsymKeyOpenSsl(private_key.Pass(), CryptoData(pkcs8_data)),
115 blink::WebCryptoKeyTypePrivate,
116 extractable,
117 key_algorithm,
118 usages);
119 return Status::Success();
120 } 73 }
121 74
122 Status CreateWebCryptoPublicKey( 75 // Creates a WebCryptoKey that wraps |public_key|.
76 Status CreateWebCryptoRsaPublicKey(
123 crypto::ScopedEVP_PKEY public_key, 77 crypto::ScopedEVP_PKEY public_key,
124 const blink::WebCryptoAlgorithmId rsa_algorithm_id, 78 const blink::WebCryptoAlgorithmId rsa_algorithm_id,
125 const blink::WebCryptoAlgorithm& hash, 79 const blink::WebCryptoAlgorithm& hash,
126 bool extractable, 80 bool extractable,
127 blink::WebCryptoKeyUsageMask usages, 81 blink::WebCryptoKeyUsageMask usages,
128 blink::WebCryptoKey* key) { 82 blink::WebCryptoKey* key) {
129 blink::WebCryptoKeyAlgorithm key_algorithm; 83 blink::WebCryptoKeyAlgorithm key_algorithm;
130 Status status = CreateRsaHashedKeyAlgorithm( 84 Status status = CreateRsaHashedKeyAlgorithm(
131 rsa_algorithm_id, hash.id(), public_key.get(), &key_algorithm); 85 rsa_algorithm_id, hash.id(), public_key.get(), &key_algorithm);
132 if (status.IsError()) 86 if (status.IsError())
133 return status; 87 return status;
134 88
135 // Serialize the key at creation time so that if structured cloning is 89 return CreateWebCryptoPublicKey(public_key.Pass(), key_algorithm, extractable,
136 // requested it can be done synchronously from the Blink thread. 90 usages, key);
137 std::vector<uint8_t> spki_data;
138 status = ExportPKeySpki(public_key.get(), &spki_data);
139 if (status.IsError())
140 return status;
141
142 *key = blink::WebCryptoKey::create(
143 new AsymKeyOpenSsl(public_key.Pass(), CryptoData(spki_data)),
144 blink::WebCryptoKeyTypePublic,
145 extractable,
146 key_algorithm,
147 usages);
148 return Status::Success();
149 } 91 }
150 92
151 // Converts a BIGNUM to a big endian byte array. 93 // Converts a BIGNUM to a big endian byte array.
152 std::vector<uint8_t> BIGNUMToVector(BIGNUM* n) { 94 std::vector<uint8_t> BIGNUMToVector(BIGNUM* n) {
153 std::vector<uint8_t> v(BN_num_bytes(n)); 95 std::vector<uint8_t> v(BN_num_bytes(n));
154 BN_bn2bin(n, vector_as_array(&v)); 96 BN_bn2bin(n, vector_as_array(&v));
155 return v; 97 return v;
156 } 98 }
157 99
158 // Allocates a new BIGNUM given a std::string big-endian representation. 100 // Allocates a new BIGNUM given a std::string big-endian representation.
(...skipping 25 matching lines...) Expand all
184 // TODO(eroman): This should really be a DataError, however for compatibility 126 // TODO(eroman): This should really be a DataError, however for compatibility
185 // with NSS it is an OperationError. 127 // with NSS it is an OperationError.
186 if (!RSA_check_key(rsa.get())) 128 if (!RSA_check_key(rsa.get()))
187 return Status::OperationError(); 129 return Status::OperationError();
188 130
189 // Create a corresponding EVP_PKEY. 131 // Create a corresponding EVP_PKEY.
190 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); 132 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new());
191 if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) 133 if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get()))
192 return Status::OperationError(); 134 return Status::OperationError();
193 135
194 return CreateWebCryptoPrivateKey(pkey.Pass(), 136 return CreateWebCryptoRsaPrivateKey(pkey.Pass(), algorithm.id(),
195 algorithm.id(), 137 algorithm.rsaHashedImportParams()->hash(),
196 algorithm.rsaHashedImportParams()->hash(), 138 extractable, usages, key);
197 extractable,
198 usages,
199 key);
200 } 139 }
201 140
202 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, 141 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
203 bool extractable, 142 bool extractable,
204 blink::WebCryptoKeyUsageMask usages, 143 blink::WebCryptoKeyUsageMask usages,
205 const CryptoData& n, 144 const CryptoData& n,
206 const CryptoData& e, 145 const CryptoData& e,
207 blink::WebCryptoKey* key) { 146 blink::WebCryptoKey* key) {
208 crypto::ScopedRSA rsa(RSA_new()); 147 crypto::ScopedRSA rsa(RSA_new());
209 148
210 rsa->n = BN_bin2bn(n.bytes(), n.byte_length(), NULL); 149 rsa->n = BN_bin2bn(n.bytes(), n.byte_length(), NULL);
211 rsa->e = BN_bin2bn(e.bytes(), e.byte_length(), NULL); 150 rsa->e = BN_bin2bn(e.bytes(), e.byte_length(), NULL);
212 151
213 if (!rsa->n || !rsa->e) 152 if (!rsa->n || !rsa->e)
214 return Status::OperationError(); 153 return Status::OperationError();
215 154
216 // Create a corresponding EVP_PKEY. 155 // Create a corresponding EVP_PKEY.
217 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); 156 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new());
218 if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) 157 if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get()))
219 return Status::OperationError(); 158 return Status::OperationError();
220 159
221 return CreateWebCryptoPublicKey(pkey.Pass(), 160 return CreateWebCryptoRsaPublicKey(pkey.Pass(), algorithm.id(),
222 algorithm.id(), 161 algorithm.rsaHashedImportParams()->hash(),
223 algorithm.rsaHashedImportParams()->hash(), 162 extractable, usages, key);
224 extractable,
225 usages,
226 key);
227 } 163 }
228 164
229 } // namespace 165 } // namespace
230 166
231 Status RsaHashedAlgorithm::GenerateKey( 167 Status RsaHashedAlgorithm::GenerateKey(
232 const blink::WebCryptoAlgorithm& algorithm, 168 const blink::WebCryptoAlgorithm& algorithm,
233 bool extractable, 169 bool extractable,
234 blink::WebCryptoKeyUsageMask combined_usages, 170 blink::WebCryptoKeyUsageMask combined_usages,
235 GenerateKeyResult* result) const { 171 GenerateKeyResult* result) const {
236 Status status = CheckKeyCreationUsages( 172 Status status = CheckKeyCreationUsages(
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 if (!public_pkey || 217 if (!public_pkey ||
282 !EVP_PKEY_set1_RSA(public_pkey.get(), rsa_public_key.get())) { 218 !EVP_PKEY_set1_RSA(public_pkey.get(), rsa_public_key.get())) {
283 return Status::OperationError(); 219 return Status::OperationError();
284 } 220 }
285 221
286 blink::WebCryptoKey public_key; 222 blink::WebCryptoKey public_key;
287 blink::WebCryptoKey private_key; 223 blink::WebCryptoKey private_key;
288 224
289 // Note that extractable is unconditionally set to true. This is because per 225 // Note that extractable is unconditionally set to true. This is because per
290 // the WebCrypto spec generated public keys are always public. 226 // the WebCrypto spec generated public keys are always public.
291 status = CreateWebCryptoPublicKey(public_pkey.Pass(), 227 status = CreateWebCryptoRsaPublicKey(public_pkey.Pass(), algorithm.id(),
292 algorithm.id(), 228 params->hash(), true, public_usages,
293 params->hash(), 229 &public_key);
294 true,
295 public_usages,
296 &public_key);
297 if (status.IsError()) 230 if (status.IsError())
298 return status; 231 return status;
299 232
300 status = CreateWebCryptoPrivateKey(private_pkey.Pass(), 233 status = CreateWebCryptoRsaPrivateKey(private_pkey.Pass(), algorithm.id(),
301 algorithm.id(), 234 params->hash(), extractable,
302 params->hash(), 235 private_usages, &private_key);
303 extractable,
304 private_usages,
305 &private_key);
306 if (status.IsError()) 236 if (status.IsError())
307 return status; 237 return status;
308 238
309 result->AssignKeyPair(public_key, private_key); 239 result->AssignKeyPair(public_key, private_key);
310 return Status::Success(); 240 return Status::Success();
311 } 241 }
312 242
313 Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey( 243 Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey(
314 blink::WebCryptoKeyFormat format, 244 blink::WebCryptoKeyFormat format,
315 blink::WebCryptoKeyUsageMask usages) const { 245 blink::WebCryptoKeyUsageMask usages) const {
316 switch (format) { 246 switch (format) {
317 case blink::WebCryptoKeyFormatSpki: 247 case blink::WebCryptoKeyFormatSpki:
318 return CheckKeyCreationUsages(all_public_key_usages_, usages); 248 return CheckKeyCreationUsages(all_public_key_usages_, usages);
319 case blink::WebCryptoKeyFormatPkcs8: 249 case blink::WebCryptoKeyFormatPkcs8:
320 return CheckKeyCreationUsages(all_private_key_usages_, usages); 250 return CheckKeyCreationUsages(all_private_key_usages_, usages);
321 case blink::WebCryptoKeyFormatJwk: 251 case blink::WebCryptoKeyFormatJwk:
322 // The JWK could represent either a public key or private key. The usages 252 // The JWK could represent either a public key or private key. The usages
323 // must make sense for one of the two. The usages will be checked again by 253 // must make sense for one of the two. The usages will be checked again by
324 // ImportKeyJwk() once the key type has been determined. 254 // ImportKeyJwk() once the key type has been determined.
325 if (CheckKeyCreationUsages(all_private_key_usages_, usages) 255 if (CheckKeyCreationUsages(all_private_key_usages_, usages).IsSuccess() ||
326 .IsSuccess() || 256 CheckKeyCreationUsages(all_public_key_usages_, usages).IsSuccess()) {
327 CheckKeyCreationUsages(all_public_key_usages_, usages)
328 .IsSuccess()) {
329 return Status::Success(); 257 return Status::Success();
330 } 258 }
331 return Status::ErrorCreateKeyBadUsages(); 259 return Status::ErrorCreateKeyBadUsages();
332 default: 260 default:
333 return Status::ErrorUnsupportedImportKeyFormat(); 261 return Status::ErrorUnsupportedImportKeyFormat();
334 } 262 }
335 } 263 }
336 264
337 Status RsaHashedAlgorithm::ImportKeyPkcs8( 265 Status RsaHashedAlgorithm::ImportKeyPkcs8(
338 const CryptoData& key_data, 266 const CryptoData& key_data,
339 const blink::WebCryptoAlgorithm& algorithm, 267 const blink::WebCryptoAlgorithm& algorithm,
340 bool extractable, 268 bool extractable,
341 blink::WebCryptoKeyUsageMask usages, 269 blink::WebCryptoKeyUsageMask usages,
342 blink::WebCryptoKey* key) const { 270 blink::WebCryptoKey* key) const {
343 if (!key_data.byte_length()) 271 crypto::ScopedEVP_PKEY private_key;
344 return Status::ErrorImportEmptyKeyData(); 272 Status status =
273 ImportUnverifiedPkeyFromPkcs8(key_data, EVP_PKEY_RSA, &private_key);
274 if (status.IsError())
275 return status;
345 276
346 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 277 // Verify the parameters of the key.
347
348 crypto::ScopedBIO bio(BIO_new_mem_buf(const_cast<uint8_t*>(key_data.bytes()),
349 key_data.byte_length()));
350 if (!bio.get())
351 return Status::ErrorUnexpected();
352
353 crypto::ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>::Type
354 p8inf(d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL));
355 if (!p8inf.get())
356 return Status::DataError();
357
358 crypto::ScopedEVP_PKEY private_key(EVP_PKCS82PKEY(p8inf.get()));
359 if (!private_key.get())
360 return Status::DataError();
361
362 if (EVP_PKEY_id(private_key.get()) != EVP_PKEY_RSA)
363 return Status::DataError(); // Data did not define an RSA key.
364
365 // Verify the parameters of the key (because EVP_PKCS82PKEY() happily imports
366 // invalid keys).
367 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(private_key.get())); 278 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(private_key.get()));
368 if (!rsa.get()) 279 if (!rsa.get())
369 return Status::ErrorUnexpected(); 280 return Status::ErrorUnexpected();
370 if (!RSA_check_key(rsa.get())) 281 if (!RSA_check_key(rsa.get()))
371 return Status::DataError(); 282 return Status::DataError();
372 283
373 // TODO(eroman): Validate the algorithm OID against the webcrypto provided 284 // TODO(eroman): Validate the algorithm OID against the webcrypto provided
374 // hash. http://crbug.com/389400 285 // hash. http://crbug.com/389400
375 286
376 return CreateWebCryptoPrivateKey(private_key.Pass(), 287 return CreateWebCryptoRsaPrivateKey(private_key.Pass(), algorithm.id(),
377 algorithm.id(), 288 algorithm.rsaHashedImportParams()->hash(),
378 algorithm.rsaHashedImportParams()->hash(), 289 extractable, usages, key);
379 extractable,
380 usages,
381 key);
382 } 290 }
383 291
384 Status RsaHashedAlgorithm::ImportKeySpki( 292 Status RsaHashedAlgorithm::ImportKeySpki(
385 const CryptoData& key_data, 293 const CryptoData& key_data,
386 const blink::WebCryptoAlgorithm& algorithm, 294 const blink::WebCryptoAlgorithm& algorithm,
387 bool extractable, 295 bool extractable,
388 blink::WebCryptoKeyUsageMask usages, 296 blink::WebCryptoKeyUsageMask usages,
389 blink::WebCryptoKey* key) const { 297 blink::WebCryptoKey* key) const {
390 if (!key_data.byte_length()) 298 crypto::ScopedEVP_PKEY public_key;
391 return Status::ErrorImportEmptyKeyData(); 299 Status status =
392 300 ImportUnverifiedPkeyFromSpki(key_data, EVP_PKEY_RSA, &public_key);
393 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 301 if (status.IsError())
394 302 return status;
395 crypto::ScopedBIO bio(BIO_new_mem_buf(const_cast<uint8_t*>(key_data.bytes()),
396 key_data.byte_length()));
397 if (!bio.get())
398 return Status::ErrorUnexpected();
399
400 crypto::ScopedEVP_PKEY public_key(d2i_PUBKEY_bio(bio.get(), NULL));
401 if (!public_key.get())
402 return Status::DataError();
403
404 if (EVP_PKEY_id(public_key.get()) != EVP_PKEY_RSA)
405 return Status::DataError(); // Data did not define an RSA key.
406 303
407 // TODO(eroman): Validate the algorithm OID against the webcrypto provided 304 // TODO(eroman): Validate the algorithm OID against the webcrypto provided
408 // hash. http://crbug.com/389400 305 // hash. http://crbug.com/389400
409 306
410 return CreateWebCryptoPublicKey(public_key.Pass(), 307 return CreateWebCryptoRsaPublicKey(public_key.Pass(), algorithm.id(),
411 algorithm.id(), 308 algorithm.rsaHashedImportParams()->hash(),
412 algorithm.rsaHashedImportParams()->hash(), 309 extractable, usages, key);
413 extractable,
414 usages,
415 key);
416 } 310 }
417 311
418 Status RsaHashedAlgorithm::ImportKeyJwk( 312 Status RsaHashedAlgorithm::ImportKeyJwk(
419 const CryptoData& key_data, 313 const CryptoData& key_data,
420 const blink::WebCryptoAlgorithm& algorithm, 314 const blink::WebCryptoAlgorithm& algorithm,
421 bool extractable, 315 bool extractable,
422 blink::WebCryptoKeyUsageMask usages, 316 blink::WebCryptoKeyUsageMask usages,
423 blink::WebCryptoKey* key) const { 317 blink::WebCryptoKey* key) const {
424 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 318 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
425 319
(...skipping 11 matching lines...) Expand all
437 331
438 // Once the key type is known, verify the usages. 332 // Once the key type is known, verify the usages.
439 status = CheckKeyCreationUsages( 333 status = CheckKeyCreationUsages(
440 jwk.is_private_key ? all_private_key_usages_ : all_public_key_usages_, 334 jwk.is_private_key ? all_private_key_usages_ : all_public_key_usages_,
441 usages); 335 usages);
442 if (status.IsError()) 336 if (status.IsError())
443 return status; 337 return status;
444 338
445 return jwk.is_private_key 339 return jwk.is_private_key
446 ? ImportRsaPrivateKey(algorithm, extractable, usages, jwk, key) 340 ? ImportRsaPrivateKey(algorithm, extractable, usages, jwk, key)
447 : ImportRsaPublicKey(algorithm, 341 : ImportRsaPublicKey(algorithm, extractable, usages,
448 extractable, 342 CryptoData(jwk.n), CryptoData(jwk.e), key);
449 usages,
450 CryptoData(jwk.n),
451 CryptoData(jwk.e),
452 key);
453 } 343 }
454 344
455 Status RsaHashedAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key, 345 Status RsaHashedAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key,
456 std::vector<uint8_t>* buffer) const { 346 std::vector<uint8_t>* buffer) const {
457 if (key.type() != blink::WebCryptoKeyTypePrivate) 347 if (key.type() != blink::WebCryptoKeyTypePrivate)
458 return Status::ErrorUnexpectedKeyType(); 348 return Status::ErrorUnexpectedKeyType();
459 *buffer = AsymKeyOpenSsl::Cast(key)->serialized_key_data(); 349 *buffer = AsymKeyOpenSsl::Cast(key)->serialized_key_data();
460 return Status::Success(); 350 return Status::Success();
461 } 351 }
462 352
463 Status RsaHashedAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key, 353 Status RsaHashedAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key,
464 std::vector<uint8_t>* buffer) const { 354 std::vector<uint8_t>* buffer) const {
465 if (key.type() != blink::WebCryptoKeyTypePublic) 355 if (key.type() != blink::WebCryptoKeyTypePublic)
466 return Status::ErrorUnexpectedKeyType(); 356 return Status::ErrorUnexpectedKeyType();
467 *buffer = AsymKeyOpenSsl::Cast(key)->serialized_key_data(); 357 *buffer = AsymKeyOpenSsl::Cast(key)->serialized_key_data();
468 return Status::Success(); 358 return Status::Success();
469 } 359 }
470 360
471 Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, 361 Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key,
472 std::vector<uint8_t>* buffer) const { 362 std::vector<uint8_t>* buffer) const {
473 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 363 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
474 364
475 EVP_PKEY* public_key = AsymKeyOpenSsl::Cast(key)->key(); 365 EVP_PKEY* pkey = AsymKeyOpenSsl::Cast(key)->key();
476 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(public_key)); 366 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey));
477 if (!rsa.get()) 367 if (!rsa.get())
478 return Status::ErrorUnexpected(); 368 return Status::ErrorUnexpected();
479 369
480 const char* jwk_algorithm = 370 const char* jwk_algorithm =
481 GetJwkAlgorithm(key.algorithm().rsaHashedParams()->hash().id()); 371 GetJwkAlgorithm(key.algorithm().rsaHashedParams()->hash().id());
482 if (!jwk_algorithm) 372 if (!jwk_algorithm)
483 return Status::ErrorUnexpected(); 373 return Status::ErrorUnexpected();
484 374
485 switch (key.type()) { 375 switch (key.type()) {
486 case blink::WebCryptoKeyTypePublic: 376 case blink::WebCryptoKeyTypePublic:
487 WriteRsaPublicKeyJwk(CryptoData(BIGNUMToVector(rsa->n)), 377 WriteRsaPublicKeyJwk(CryptoData(BIGNUMToVector(rsa->n)),
488 CryptoData(BIGNUMToVector(rsa->e)), 378 CryptoData(BIGNUMToVector(rsa->e)), jwk_algorithm,
489 jwk_algorithm, 379 key.extractable(), key.usages(), buffer);
490 key.extractable(),
491 key.usages(),
492 buffer);
493 return Status::Success(); 380 return Status::Success();
494 case blink::WebCryptoKeyTypePrivate: 381 case blink::WebCryptoKeyTypePrivate:
495 WriteRsaPrivateKeyJwk(CryptoData(BIGNUMToVector(rsa->n)), 382 WriteRsaPrivateKeyJwk(CryptoData(BIGNUMToVector(rsa->n)),
496 CryptoData(BIGNUMToVector(rsa->e)), 383 CryptoData(BIGNUMToVector(rsa->e)),
497 CryptoData(BIGNUMToVector(rsa->d)), 384 CryptoData(BIGNUMToVector(rsa->d)),
498 CryptoData(BIGNUMToVector(rsa->p)), 385 CryptoData(BIGNUMToVector(rsa->p)),
499 CryptoData(BIGNUMToVector(rsa->q)), 386 CryptoData(BIGNUMToVector(rsa->q)),
500 CryptoData(BIGNUMToVector(rsa->dmp1)), 387 CryptoData(BIGNUMToVector(rsa->dmp1)),
501 CryptoData(BIGNUMToVector(rsa->dmq1)), 388 CryptoData(BIGNUMToVector(rsa->dmq1)),
502 CryptoData(BIGNUMToVector(rsa->iqmp)), 389 CryptoData(BIGNUMToVector(rsa->iqmp)),
503 jwk_algorithm, 390 jwk_algorithm, key.extractable(), key.usages(),
504 key.extractable(),
505 key.usages(),
506 buffer); 391 buffer);
507 return Status::Success(); 392 return Status::Success();
508 393
509 default: 394 default:
510 return Status::ErrorUnexpected(); 395 return Status::ErrorUnexpected();
511 } 396 }
512 } 397 }
513 398
514 } // namespace webcrypto 399 } // namespace webcrypto
515 400
516 } // namespace content 401 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/child/webcrypto/openssl/util_openssl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698