File: | lib/gnutls_pubkey.c |
Location: | line 1500, column 11 |
Description: | Value stored to 'hash_algo' is never read |
1 | /* |
2 | * GnuTLS PKCS#11 support |
3 | * Copyright (C) 2010,2011 Free Software Foundation |
4 | * |
5 | * Author: Nikos Mavrogiannopoulos |
6 | * |
7 | * The GnuTLS is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public License |
9 | * as published by the Free Software Foundation; either version 3 of |
10 | * the License, or (at your option) any later version. |
11 | * |
12 | * This library is distributed in the hope that it will be useful, but |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Lesser General Public License |
18 | * along with this program. If not, see <http://www.gnu.org/licenses/> |
19 | */ |
20 | |
21 | #include <gnutls_int.h> |
22 | #include <gnutls/pkcs11.h> |
23 | #include <stdio.h> |
24 | #include <string.h> |
25 | #include <gnutls_errors.h> |
26 | #include <gnutls_datumgnutls_datum_t.h> |
27 | #include <pkcs11_int.h> |
28 | #include <gnutls/abstract.h> |
29 | #include <gnutls_sig.h> |
30 | #include <gnutls_pk.h> |
31 | #include <x509_int.h> |
32 | #include <openpgp/openpgp_int.h> |
33 | #include <gnutls_num.h> |
34 | #include <x509/common.h> |
35 | #include <x509_b64.h> |
36 | #include <abstract_int.h> |
37 | #include <gnutls_ecc.h> |
38 | |
39 | #define PK_PEM_HEADER"PUBLIC KEY" "PUBLIC KEY" |
40 | |
41 | #define OPENPGP_KEY_PRIMARY2 2 |
42 | #define OPENPGP_KEY_SUBKEY1 1 |
43 | |
44 | struct gnutls_pubkey_st |
45 | { |
46 | gnutls_pk_algorithm_t pk_algorithm; |
47 | unsigned int bits; /* an indication of the security parameter */ |
48 | |
49 | /* the size of params depends on the public |
50 | * key algorithm |
51 | * RSA: [0] is modulus |
52 | * [1] is public exponent |
53 | * DSA: [0] is p |
54 | * [1] is q |
55 | * [2] is g |
56 | * [3] is public key |
57 | */ |
58 | gnutls_pk_params_st params; |
59 | |
60 | uint8_t openpgp_key_id[GNUTLS_OPENPGP_KEYID_SIZE8]; |
61 | int openpgp_key_id_set; |
62 | |
63 | unsigned int key_usage; /* bits from GNUTLS_KEY_* */ |
64 | }; |
65 | |
66 | int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st* params) |
67 | { |
68 | switch(pk) |
69 | { |
70 | case GNUTLS_PK_RSA: |
71 | return _gnutls_mpi_get_nbits(params->params[0])_gnutls_mpi_ops.bigint_get_nbits(params->params[0]); |
72 | case GNUTLS_PK_DSA: |
73 | return _gnutls_mpi_get_nbits(params->params[3])_gnutls_mpi_ops.bigint_get_nbits(params->params[3]); |
74 | case GNUTLS_PK_EC: |
75 | return gnutls_ecc_curve_get_size(params->flags)*8; |
76 | default: |
77 | return 0; |
78 | } |
79 | } |
80 | |
81 | /** |
82 | * gnutls_pubkey_get_pk_algorithm: |
83 | * @key: should contain a #gnutls_pubkey_t structure |
84 | * @bits: If set will return the number of bits of the parameters (may be NULL) |
85 | * |
86 | * This function will return the public key algorithm of a public |
87 | * key and if possible will return a number of bits that indicates |
88 | * the security parameter of the key. |
89 | * |
90 | * Returns: a member of the #gnutls_pk_algorithm_t enumeration on |
91 | * success, or a negative error code on error. |
92 | * |
93 | * Since: 2.12.0 |
94 | **/ |
95 | int |
96 | gnutls_pubkey_get_pk_algorithm (gnutls_pubkey_t key, unsigned int *bits) |
97 | { |
98 | if (bits) |
99 | *bits = key->bits; |
100 | |
101 | return key->pk_algorithm; |
102 | } |
103 | |
104 | /** |
105 | * gnutls_pubkey_get_key_usage: |
106 | * @key: should contain a #gnutls_pubkey_t structure |
107 | * @usage: If set will return the number of bits of the parameters (may be NULL) |
108 | * |
109 | * This function will return the key usage of the public key. |
110 | * |
111 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
112 | * negative error value. |
113 | * |
114 | * Since: 2.12.0 |
115 | **/ |
116 | int |
117 | gnutls_pubkey_get_key_usage (gnutls_pubkey_t key, unsigned int *usage) |
118 | { |
119 | if (usage) |
120 | *usage = key->key_usage; |
121 | |
122 | return 0; |
123 | } |
124 | |
125 | /** |
126 | * gnutls_pubkey_init: |
127 | * @key: The structure to be initialized |
128 | * |
129 | * This function will initialize an public key structure. |
130 | * |
131 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
132 | * negative error value. |
133 | * |
134 | * Since: 2.12.0 |
135 | **/ |
136 | int |
137 | gnutls_pubkey_init (gnutls_pubkey_t * key) |
138 | { |
139 | *key = gnutls_calloc (1, sizeof (struct gnutls_pubkey_st)); |
140 | if (*key == NULL((void*)0)) |
141 | { |
142 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",142); } while(0);; |
143 | return GNUTLS_E_MEMORY_ERROR-25; |
144 | } |
145 | |
146 | return 0; |
147 | } |
148 | |
149 | /** |
150 | * gnutls_pubkey_deinit: |
151 | * @key: The structure to be deinitialized |
152 | * |
153 | * This function will deinitialize a public key structure. |
154 | * |
155 | * Since: 2.12.0 |
156 | **/ |
157 | void |
158 | gnutls_pubkey_deinit (gnutls_pubkey_t key) |
159 | { |
160 | if (!key) |
161 | return; |
162 | gnutls_pk_params_release (&key->params); |
163 | gnutls_free (key); |
164 | } |
165 | |
166 | /** |
167 | * gnutls_pubkey_import_x509: |
168 | * @key: The public key |
169 | * @crt: The certificate to be imported |
170 | * @flags: should be zero |
171 | * |
172 | * This function will import the given public key to the abstract |
173 | * #gnutls_pubkey_t structure. |
174 | * |
175 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
176 | * negative error value. |
177 | * |
178 | * Since: 2.12.0 |
179 | **/ |
180 | int |
181 | gnutls_pubkey_import_x509 (gnutls_pubkey_t key, gnutls_x509_crt_t crt, |
182 | unsigned int flags) |
183 | { |
184 | int ret; |
185 | |
186 | key->pk_algorithm = gnutls_x509_crt_get_pk_algorithm (crt, &key->bits); |
187 | |
188 | ret = gnutls_x509_crt_get_key_usage (crt, &key->key_usage, NULL((void*)0)); |
189 | if (ret < 0) |
190 | key->key_usage = 0; |
191 | |
192 | ret = _gnutls_x509_crt_get_mpis (crt, &key->params); |
193 | if (ret < 0) |
194 | { |
195 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",195); } while(0);; |
196 | return ret; |
197 | } |
198 | |
199 | return 0; |
200 | } |
201 | |
202 | /** |
203 | * gnutls_pubkey_import_privkey: |
204 | * @key: The public key |
205 | * @pkey: The private key |
206 | * @usage: GNUTLS_KEY_* key usage flags. |
207 | * @flags: should be zero |
208 | * |
209 | * Imports the public key from a private. This function will import |
210 | * the given public key to the abstract #gnutls_pubkey_t structure. |
211 | * |
212 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
213 | * negative error value. |
214 | * |
215 | * Since: 2.12.0 |
216 | **/ |
217 | int |
218 | gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey, |
219 | unsigned int usage, unsigned int flags) |
220 | { |
221 | key->pk_algorithm = gnutls_privkey_get_pk_algorithm (pkey, &key->bits); |
222 | |
223 | key->key_usage = usage; |
224 | |
225 | return _gnutls_privkey_get_public_mpis (pkey, &key->params); |
226 | } |
227 | |
228 | /** |
229 | * gnutls_pubkey_get_preferred_hash_algorithm: |
230 | * @key: Holds the certificate |
231 | * @hash: The result of the call with the hash algorithm used for signature |
232 | * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL. |
233 | * |
234 | * This function will read the certifcate and return the appropriate digest |
235 | * algorithm to use for signing with this certificate. Some certificates (i.e. |
236 | * DSA might not be able to sign without the preferred algorithm). |
237 | * |
238 | * Returns: the 0 if the hash algorithm is found. A negative error code is |
239 | * returned on error. |
240 | * |
241 | * Since: 2.12.0 |
242 | **/ |
243 | int |
244 | gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key, |
245 | gnutls_digest_algorithm_t * |
246 | hash, unsigned int *mand) |
247 | { |
248 | int ret; |
249 | |
250 | if (key == NULL((void*)0)) |
251 | { |
252 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",252); } while(0);; |
253 | return GNUTLS_E_INVALID_REQUEST-50; |
254 | } |
255 | |
256 | ret = _gnutls_pk_get_hash_algorithm (key->pk_algorithm, |
257 | &key->params, |
258 | hash, mand); |
259 | |
260 | return ret; |
261 | } |
262 | |
263 | #ifdef ENABLE_PKCS111 |
264 | |
265 | /** |
266 | * gnutls_pubkey_import_pkcs11: |
267 | * @key: The public key |
268 | * @obj: The parameters to be imported |
269 | * @flags: should be zero |
270 | * |
271 | * Imports a public key from a pkcs11 key. This function will import |
272 | * the given public key to the abstract #gnutls_pubkey_t structure. |
273 | * |
274 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
275 | * negative error value. |
276 | * |
277 | * Since: 2.12.0 |
278 | **/ |
279 | int |
280 | gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key, |
281 | gnutls_pkcs11_obj_t obj, unsigned int flags) |
282 | { |
283 | int ret; |
284 | |
285 | ret = gnutls_pkcs11_obj_get_type (obj); |
286 | if (ret != GNUTLS_PKCS11_OBJ_PUBKEY) |
287 | { |
288 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",288); } while(0);; |
289 | return GNUTLS_E_INVALID_REQUEST-50; |
290 | } |
291 | |
292 | key->key_usage = obj->key_usage; |
293 | |
294 | switch (obj->pk_algorithm) |
295 | { |
296 | case GNUTLS_PK_RSA: |
297 | ret = gnutls_pubkey_import_rsa_raw (key, &obj->pubkey[0], |
298 | &obj->pubkey[1]); |
299 | break; |
300 | case GNUTLS_PK_DSA: |
301 | ret = gnutls_pubkey_import_dsa_raw (key, &obj->pubkey[0], |
302 | &obj->pubkey[1], |
303 | &obj->pubkey[2], &obj->pubkey[3]); |
304 | break; |
305 | case GNUTLS_PK_EC: |
306 | ret = gnutls_pubkey_import_ecc_x962 (key, &obj->pubkey[0], |
307 | &obj->pubkey[1]); |
308 | break; |
309 | default: |
310 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",310); } while(0);; |
311 | return GNUTLS_E_UNIMPLEMENTED_FEATURE-1250; |
312 | } |
313 | |
314 | if (ret < 0) |
315 | { |
316 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",316); } while(0);; |
317 | return ret; |
318 | } |
319 | |
320 | return 0; |
321 | } |
322 | |
323 | #endif /* ENABLE_PKCS11 */ |
324 | |
325 | #ifdef ENABLE_OPENPGP1 |
326 | |
327 | /** |
328 | * gnutls_pubkey_import_openpgp: |
329 | * @key: The public key |
330 | * @crt: The certificate to be imported |
331 | * @flags: should be zero |
332 | * |
333 | * Imports a public key from an openpgp key. This function will import |
334 | * the given public key to the abstract #gnutls_pubkey_t |
335 | * structure. The subkey set as preferred will be imported or the |
336 | * master key otherwise. |
337 | * |
338 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
339 | * negative error value. |
340 | * |
341 | * Since: 2.12.0 |
342 | **/ |
343 | int |
344 | gnutls_pubkey_import_openpgp (gnutls_pubkey_t key, |
345 | gnutls_openpgp_crt_t crt, |
346 | unsigned int flags) |
347 | { |
348 | int ret, idx; |
349 | uint32_t kid32[2]; |
350 | uint32_t *k; |
351 | uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE8]; |
352 | |
353 | ret = gnutls_openpgp_crt_get_preferred_key_id (crt, keyid); |
354 | if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR-215) |
355 | { |
356 | key->pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (crt, &key->bits); |
357 | key->openpgp_key_id_set = OPENPGP_KEY_PRIMARY2; |
358 | |
359 | ret = gnutls_openpgp_crt_get_key_id(crt, key->openpgp_key_id); |
360 | if (ret < 0) |
361 | return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_pubkey.c", 361); |
362 | |
363 | ret = gnutls_openpgp_crt_get_key_usage (crt, &key->key_usage); |
364 | if (ret < 0) |
365 | key->key_usage = 0; |
366 | |
367 | k = NULL((void*)0); |
368 | } |
369 | else |
370 | { |
371 | if (ret < 0) |
372 | { |
373 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",373); } while(0);; |
374 | return ret; |
375 | } |
376 | key->openpgp_key_id_set = OPENPGP_KEY_SUBKEY1; |
377 | |
378 | KEYID_IMPORT (kid32, keyid){ kid32[0] = _gnutls_read_uint32( keyid); kid32[1] = _gnutls_read_uint32 ( keyid+4); }; |
379 | k = kid32; |
380 | |
381 | idx = gnutls_openpgp_crt_get_subkey_idx (crt, keyid); |
382 | |
383 | ret = gnutls_openpgp_crt_get_subkey_id(crt, idx, key->openpgp_key_id); |
384 | if (ret < 0) |
385 | return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_pubkey.c", 385); |
386 | |
387 | ret = gnutls_openpgp_crt_get_subkey_usage (crt, idx, &key->key_usage); |
388 | if (ret < 0) |
389 | key->key_usage = 0; |
390 | |
391 | key->pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm (crt, idx, NULL((void*)0)); |
392 | } |
393 | |
394 | ret = |
395 | _gnutls_openpgp_crt_get_mpis (crt, k, &key->params); |
396 | if (ret < 0) |
397 | return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_pubkey.c", 397); |
398 | |
399 | return 0; |
400 | } |
401 | |
402 | /** |
403 | * gnutls_pubkey_get_openpgp_key_id: |
404 | * @key: Holds the public key |
405 | * @flags: should be 0 for now |
406 | * @output_data: will contain the key ID |
407 | * @output_data_size: holds the size of output_data (and will be |
408 | * replaced by the actual size of parameters) |
409 | * @subkey: Will be non zero if the key ID corresponds to a subkey |
410 | * |
411 | * This function will return a unique ID the depends on the public |
412 | * key parameters. This ID can be used in checking whether a |
413 | * certificate corresponds to the given public key. |
414 | * |
415 | * If the buffer provided is not long enough to hold the output, then |
416 | * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will |
417 | * be returned. The output will normally be a SHA-1 hash output, |
418 | * which is 20 bytes. |
419 | * |
420 | * Returns: In case of failure a negative error code will be |
421 | * returned, and 0 on success. |
422 | * |
423 | * Since: 3.0.0 |
424 | **/ |
425 | int |
426 | gnutls_pubkey_get_openpgp_key_id (gnutls_pubkey_t key, unsigned int flags, |
427 | unsigned char *output_data, |
428 | size_t * output_data_size, |
429 | unsigned int *subkey) |
430 | { |
431 | if (key == NULL((void*)0)) |
432 | { |
433 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",433); } while(0);; |
434 | return GNUTLS_E_INVALID_REQUEST-50; |
435 | } |
436 | |
437 | if (*output_data_size < sizeof(key->openpgp_key_id)) |
438 | { |
439 | *output_data_size = sizeof(key->openpgp_key_id); |
440 | return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER)gnutls_assert_val_int(-51, "gnutls_pubkey.c", 440); |
441 | } |
442 | |
443 | if (key->openpgp_key_id_set == 0) |
444 | return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST)gnutls_assert_val_int(-50, "gnutls_pubkey.c", 444); |
445 | |
446 | if (key->openpgp_key_id_set == OPENPGP_KEY_SUBKEY1) |
447 | if (subkey) *subkey = 1; |
448 | |
449 | if (output_data) |
450 | { |
451 | memcpy(output_data, key->openpgp_key_id, sizeof(key->openpgp_key_id)); |
452 | } |
453 | *output_data_size = sizeof(key->openpgp_key_id); |
454 | |
455 | return 0; |
456 | } |
457 | |
458 | #endif |
459 | |
460 | /** |
461 | * gnutls_pubkey_export: |
462 | * @key: Holds the certificate |
463 | * @format: the format of output params. One of PEM or DER. |
464 | * @output_data: will contain a certificate PEM or DER encoded |
465 | * @output_data_size: holds the size of output_data (and will be |
466 | * replaced by the actual size of parameters) |
467 | * |
468 | * This function will export the certificate to DER or PEM format. |
469 | * |
470 | * If the buffer provided is not long enough to hold the output, then |
471 | * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will |
472 | * be returned. |
473 | * |
474 | * If the structure is PEM encoded, it will have a header |
475 | * of "BEGIN CERTIFICATE". |
476 | * |
477 | * Returns: In case of failure a negative error code will be |
478 | * returned, and 0 on success. |
479 | * |
480 | * Since: 2.12.0 |
481 | **/ |
482 | int |
483 | gnutls_pubkey_export (gnutls_pubkey_t key, |
484 | gnutls_x509_crt_fmt_t format, void *output_data, |
485 | size_t * output_data_size) |
486 | { |
487 | int result; |
488 | ASN1_TYPE spk = ASN1_TYPE_EMPTY((void*)0); |
489 | |
490 | if (key == NULL((void*)0)) |
491 | { |
492 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",492); } while(0);; |
493 | return GNUTLS_E_INVALID_REQUEST-50; |
494 | } |
495 | |
496 | if ((result = asn1_create_element |
497 | (_gnutls_get_pkix ()((ASN1_TYPE) _gnutls_pkix1_asn), "PKIX1.SubjectPublicKeyInfo", &spk)) |
498 | != ASN1_SUCCESS0) |
499 | { |
500 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",500); } while(0);; |
501 | return _gnutls_asn2err (result); |
502 | } |
503 | |
504 | result = |
505 | _gnutls_x509_encode_and_copy_PKI_params (spk, "", |
506 | key->pk_algorithm, |
507 | &key->params); |
508 | if (result < 0) |
509 | { |
510 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",510); } while(0);; |
511 | goto cleanup; |
512 | } |
513 | |
514 | result = _gnutls_x509_export_int_named (spk, "", |
515 | format, PK_PEM_HEADER"PUBLIC KEY", |
516 | output_data, output_data_size); |
517 | if (result < 0) |
518 | { |
519 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",519); } while(0);; |
520 | goto cleanup; |
521 | } |
522 | |
523 | result = 0; |
524 | |
525 | cleanup: |
526 | asn1_delete_structure (&spk); |
527 | |
528 | return result; |
529 | |
530 | } |
531 | |
532 | /** |
533 | * gnutls_pubkey_get_key_id: |
534 | * @key: Holds the public key |
535 | * @flags: should be 0 for now |
536 | * @output_data: will contain the key ID |
537 | * @output_data_size: holds the size of output_data (and will be |
538 | * replaced by the actual size of parameters) |
539 | * |
540 | * This function will return a unique ID the depends on the public |
541 | * key parameters. This ID can be used in checking whether a |
542 | * certificate corresponds to the given public key. |
543 | * |
544 | * If the buffer provided is not long enough to hold the output, then |
545 | * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will |
546 | * be returned. The output will normally be a SHA-1 hash output, |
547 | * which is 20 bytes. |
548 | * |
549 | * Returns: In case of failure a negative error code will be |
550 | * returned, and 0 on success. |
551 | * |
552 | * Since: 2.12.0 |
553 | **/ |
554 | int |
555 | gnutls_pubkey_get_key_id (gnutls_pubkey_t key, unsigned int flags, |
556 | unsigned char *output_data, |
557 | size_t * output_data_size) |
558 | { |
559 | int ret = 0; |
560 | |
561 | if (key == NULL((void*)0)) |
562 | { |
563 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",563); } while(0);; |
564 | return GNUTLS_E_INVALID_REQUEST-50; |
565 | } |
566 | |
567 | ret = |
568 | _gnutls_get_key_id (key->pk_algorithm, &key->params, |
569 | output_data, output_data_size); |
570 | if (ret < 0) |
571 | { |
572 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",572); } while(0);; |
573 | return ret; |
574 | } |
575 | |
576 | return 0; |
577 | } |
578 | |
579 | /** |
580 | * gnutls_pubkey_get_pk_rsa_raw: |
581 | * @key: Holds the certificate |
582 | * @m: will hold the modulus |
583 | * @e: will hold the public exponent |
584 | * |
585 | * This function will export the RSA public key's parameters found in |
586 | * the given structure. The new parameters will be allocated using |
587 | * gnutls_malloc() and will be stored in the appropriate datum. |
588 | * |
589 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. |
590 | * |
591 | * Since: 2.12.0 |
592 | **/ |
593 | int |
594 | gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t key, |
595 | gnutls_datum_t * m, gnutls_datum_t * e) |
596 | { |
597 | int ret; |
598 | |
599 | if (key == NULL((void*)0)) |
600 | { |
601 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",601); } while(0);; |
602 | return GNUTLS_E_INVALID_REQUEST-50; |
603 | } |
604 | |
605 | if (key->pk_algorithm != GNUTLS_PK_RSA) |
606 | { |
607 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",607); } while(0);; |
608 | return GNUTLS_E_INVALID_REQUEST-50; |
609 | } |
610 | |
611 | ret = _gnutls_mpi_dprint_lz (key->params.params[0], m); |
612 | if (ret < 0) |
613 | { |
614 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",614); } while(0);; |
615 | return ret; |
616 | } |
617 | |
618 | ret = _gnutls_mpi_dprint_lz (key->params.params[1], e); |
619 | if (ret < 0) |
620 | { |
621 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",621); } while(0);; |
622 | _gnutls_free_datum (m)_gnutls_free_datum_m(m, gnutls_free); |
623 | return ret; |
624 | } |
625 | |
626 | return 0; |
627 | } |
628 | |
629 | /** |
630 | * gnutls_pubkey_get_pk_dsa_raw: |
631 | * @key: Holds the public key |
632 | * @p: will hold the p |
633 | * @q: will hold the q |
634 | * @g: will hold the g |
635 | * @y: will hold the y |
636 | * |
637 | * This function will export the DSA public key's parameters found in |
638 | * the given certificate. The new parameters will be allocated using |
639 | * gnutls_malloc() and will be stored in the appropriate datum. |
640 | * |
641 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. |
642 | * |
643 | * Since: 2.12.0 |
644 | **/ |
645 | int |
646 | gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key, |
647 | gnutls_datum_t * p, gnutls_datum_t * q, |
648 | gnutls_datum_t * g, gnutls_datum_t * y) |
649 | { |
650 | int ret; |
651 | |
652 | if (key == NULL((void*)0)) |
653 | { |
654 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",654); } while(0);; |
655 | return GNUTLS_E_INVALID_REQUEST-50; |
656 | } |
657 | |
658 | if (key->pk_algorithm != GNUTLS_PK_DSA) |
659 | { |
660 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",660); } while(0);; |
661 | return GNUTLS_E_INVALID_REQUEST-50; |
662 | } |
663 | |
664 | /* P */ |
665 | ret = _gnutls_mpi_dprint_lz (key->params.params[0], p); |
666 | if (ret < 0) |
667 | { |
668 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",668); } while(0);; |
669 | return ret; |
670 | } |
671 | |
672 | /* Q */ |
673 | ret = _gnutls_mpi_dprint_lz (key->params.params[1], q); |
674 | if (ret < 0) |
675 | { |
676 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",676); } while(0);; |
677 | _gnutls_free_datum (p)_gnutls_free_datum_m(p, gnutls_free); |
678 | return ret; |
679 | } |
680 | |
681 | |
682 | /* G */ |
683 | ret = _gnutls_mpi_dprint_lz (key->params.params[2], g); |
684 | if (ret < 0) |
685 | { |
686 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",686); } while(0);; |
687 | _gnutls_free_datum (p)_gnutls_free_datum_m(p, gnutls_free); |
688 | _gnutls_free_datum (q)_gnutls_free_datum_m(q, gnutls_free); |
689 | return ret; |
690 | } |
691 | |
692 | |
693 | /* Y */ |
694 | ret = _gnutls_mpi_dprint_lz (key->params.params[3], y); |
695 | if (ret < 0) |
696 | { |
697 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",697); } while(0);; |
698 | _gnutls_free_datum (p)_gnutls_free_datum_m(p, gnutls_free); |
699 | _gnutls_free_datum (g)_gnutls_free_datum_m(g, gnutls_free); |
700 | _gnutls_free_datum (q)_gnutls_free_datum_m(q, gnutls_free); |
701 | return ret; |
702 | } |
703 | |
704 | return 0; |
705 | } |
706 | |
707 | /** |
708 | * gnutls_pubkey_get_pk_ecc_raw: |
709 | * @key: Holds the public key |
710 | * @curve: will hold the curve |
711 | * @x: will hold x |
712 | * @y: will hold y |
713 | * |
714 | * This function will export the ECC public key's parameters found in |
715 | * the given certificate. The new parameters will be allocated using |
716 | * gnutls_malloc() and will be stored in the appropriate datum. |
717 | * |
718 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. |
719 | * |
720 | * Since: 3.0.0 |
721 | **/ |
722 | int |
723 | gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve, |
724 | gnutls_datum_t * x, gnutls_datum_t * y) |
725 | { |
726 | int ret; |
727 | |
728 | if (key == NULL((void*)0)) |
729 | { |
730 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",730); } while(0);; |
731 | return GNUTLS_E_INVALID_REQUEST-50; |
732 | } |
733 | |
734 | if (key->pk_algorithm != GNUTLS_PK_EC) |
735 | { |
736 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",736); } while(0);; |
737 | return GNUTLS_E_INVALID_REQUEST-50; |
738 | } |
739 | |
740 | *curve = key->params.flags; |
741 | |
742 | /* X */ |
743 | ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_X6], x); |
744 | if (ret < 0) |
745 | { |
746 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",746); } while(0);; |
747 | return ret; |
748 | } |
749 | |
750 | /* Y */ |
751 | ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_Y7], y); |
752 | if (ret < 0) |
753 | { |
754 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",754); } while(0);; |
755 | _gnutls_free_datum (x)_gnutls_free_datum_m(x, gnutls_free); |
756 | return ret; |
757 | } |
758 | |
759 | return 0; |
760 | } |
761 | |
762 | /** |
763 | * gnutls_pubkey_get_pk_ecc_x962: |
764 | * @key: Holds the public key |
765 | * @parameters: DER encoding of an ANSI X9.62 parameters |
766 | * @ecpoint: DER encoding of ANSI X9.62 ECPoint |
767 | * |
768 | * This function will export the ECC public key's parameters found in |
769 | * the given certificate. The new parameters will be allocated using |
770 | * gnutls_malloc() and will be stored in the appropriate datum. |
771 | * |
772 | * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. |
773 | * |
774 | * Since: 3.0.0 |
775 | **/ |
776 | int gnutls_pubkey_get_pk_ecc_x962 (gnutls_pubkey_t key, gnutls_datum_t* parameters, |
777 | gnutls_datum_t * ecpoint) |
778 | { |
779 | int ret; |
780 | |
781 | if (key == NULL((void*)0) || key->pk_algorithm != GNUTLS_PK_EC) |
782 | return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST)gnutls_assert_val_int(-50, "gnutls_pubkey.c", 782); |
783 | |
784 | ret = _gnutls_x509_write_ecc_pubkey(&key->params, ecpoint); |
785 | if (ret < 0) |
786 | return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_pubkey.c", 786); |
787 | |
788 | ret = _gnutls_x509_write_ecc_params(&key->params, parameters); |
789 | if (ret < 0) |
790 | { |
791 | _gnutls_free_datum(ecpoint)_gnutls_free_datum_m(ecpoint, gnutls_free); |
792 | return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_pubkey.c", 792); |
793 | } |
794 | |
795 | return 0; |
796 | } |
797 | |
798 | /** |
799 | * gnutls_pubkey_import: |
800 | * @key: The structure to store the parsed public key. |
801 | * @data: The DER or PEM encoded certificate. |
802 | * @format: One of DER or PEM |
803 | * |
804 | * This function will convert the given DER or PEM encoded Public key |
805 | * to the native gnutls_pubkey_t format.The output will be stored |
806 | * in @key. |
807 | * If the Certificate is PEM encoded it should have a header of "PUBLIC KEY". |
808 | * |
809 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
810 | * negative error value. |
811 | * |
812 | * Since: 2.12.0 |
813 | **/ |
814 | int |
815 | gnutls_pubkey_import (gnutls_pubkey_t key, |
816 | const gnutls_datum_t * data, |
817 | gnutls_x509_crt_fmt_t format) |
818 | { |
819 | int result = 0, need_free = 0; |
820 | gnutls_datum_t _data; |
821 | ASN1_TYPE spk; |
822 | |
823 | if (key == NULL((void*)0)) |
824 | { |
825 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",825); } while(0);; |
826 | return GNUTLS_E_INVALID_REQUEST-50; |
827 | } |
828 | |
829 | _data.data = data->data; |
830 | _data.size = data->size; |
831 | |
832 | /* If the Certificate is in PEM format then decode it |
833 | */ |
834 | if (format == GNUTLS_X509_FMT_PEM) |
835 | { |
836 | opaque *out; |
837 | |
838 | /* Try the first header */ |
839 | result = |
840 | _gnutls_fbase64_decode (PK_PEM_HEADER"PUBLIC KEY", data->data, data->size, &out); |
841 | |
842 | if (result <= 0) |
843 | { |
844 | if (result == 0) |
845 | result = GNUTLS_E_INTERNAL_ERROR-59; |
846 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",846); } while(0);; |
847 | return result; |
848 | } |
849 | |
850 | _data.data = out; |
851 | _data.size = result; |
852 | |
853 | need_free = 1; |
854 | } |
855 | |
856 | if ((result = asn1_create_element |
857 | (_gnutls_get_pkix ()((ASN1_TYPE) _gnutls_pkix1_asn), "PKIX1.SubjectPublicKeyInfo", &spk)) |
858 | != ASN1_SUCCESS0) |
859 | { |
860 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",860); } while(0);; |
861 | result = _gnutls_asn2err (result); |
862 | goto cleanup; |
863 | } |
864 | |
865 | result = asn1_der_decoding (&spk, _data.data, _data.size, NULL((void*)0)); |
866 | if (result != ASN1_SUCCESS0) |
867 | { |
868 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",868); } while(0);; |
869 | result = _gnutls_asn2err (result); |
870 | goto cleanup; |
871 | } |
872 | |
873 | result = _gnutls_get_asn_mpis (spk, "", &key->params); |
874 | if (result < 0) |
875 | { |
876 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",876); } while(0);; |
877 | goto cleanup; |
878 | } |
879 | |
880 | /* this has already been called by get_asn_mpis() thus it cannot |
881 | * fail. |
882 | */ |
883 | key->pk_algorithm = _gnutls_x509_get_pk_algorithm (spk, "", NULL((void*)0)); |
884 | key->bits = pubkey_to_bits(key->pk_algorithm, &key->params); |
885 | |
886 | result = 0; |
887 | |
888 | cleanup: |
889 | asn1_delete_structure (&spk); |
890 | |
891 | if (need_free) |
892 | _gnutls_free_datum (&_data)_gnutls_free_datum_m(&_data, gnutls_free); |
893 | return result; |
894 | } |
895 | |
896 | /** |
897 | * gnutls_x509_crt_set_pubkey: |
898 | * @crt: should contain a #gnutls_x509_crt_t structure |
899 | * @key: holds a public key |
900 | * |
901 | * This function will set the public parameters from the given public |
902 | * key to the request. |
903 | * |
904 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
905 | * negative error value. |
906 | * |
907 | * Since: 2.12.0 |
908 | **/ |
909 | int |
910 | gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, gnutls_pubkey_t key) |
911 | { |
912 | int result; |
913 | |
914 | if (crt == NULL((void*)0)) |
915 | { |
916 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",916); } while(0);; |
917 | return GNUTLS_E_INVALID_REQUEST-50; |
918 | } |
919 | |
920 | result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert, |
921 | "tbsCertificate.subjectPublicKeyInfo", |
922 | key->pk_algorithm, |
923 | &key->params); |
924 | |
925 | if (result < 0) |
926 | { |
927 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",927); } while(0);; |
928 | return result; |
929 | } |
930 | |
931 | if (key->key_usage) |
932 | gnutls_x509_crt_set_key_usage (crt, key->key_usage); |
933 | |
934 | return 0; |
935 | } |
936 | |
937 | /** |
938 | * gnutls_x509_crq_set_pubkey: |
939 | * @crq: should contain a #gnutls_x509_crq_t structure |
940 | * @key: holds a public key |
941 | * |
942 | * This function will set the public parameters from the given public |
943 | * key to the request. |
944 | * |
945 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
946 | * negative error value. |
947 | * |
948 | * Since: 2.12.0 |
949 | **/ |
950 | int |
951 | gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key) |
952 | { |
953 | int result; |
954 | |
955 | if (crq == NULL((void*)0)) |
956 | { |
957 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",957); } while(0);; |
958 | return GNUTLS_E_INVALID_REQUEST-50; |
959 | } |
960 | |
961 | result = _gnutls_x509_encode_and_copy_PKI_params |
962 | (crq->crq, |
963 | "certificationRequestInfo.subjectPKInfo", |
964 | key->pk_algorithm, &key->params); |
965 | |
966 | if (result < 0) |
967 | { |
968 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",968); } while(0);; |
969 | return result; |
970 | } |
971 | |
972 | if (key->key_usage) |
973 | gnutls_x509_crq_set_key_usage (crq, key->key_usage); |
974 | |
975 | return 0; |
976 | } |
977 | |
978 | /** |
979 | * gnutls_pubkey_set_key_usage: |
980 | * @key: a certificate of type #gnutls_x509_crt_t |
981 | * @usage: an ORed sequence of the GNUTLS_KEY_* elements. |
982 | * |
983 | * This function will set the key usage flags of the public key. This |
984 | * is only useful if the key is to be exported to a certificate or |
985 | * certificate request. |
986 | * |
987 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
988 | * negative error value. |
989 | * |
990 | * Since: 2.12.0 |
991 | **/ |
992 | int |
993 | gnutls_pubkey_set_key_usage (gnutls_pubkey_t key, unsigned int usage) |
994 | { |
995 | key->key_usage = usage; |
996 | |
997 | return 0; |
998 | } |
999 | |
1000 | #ifdef ENABLE_PKCS111 |
1001 | |
1002 | /** |
1003 | * gnutls_pubkey_import_pkcs11_url: |
1004 | * @key: A key of type #gnutls_pubkey_t |
1005 | * @url: A PKCS 11 url |
1006 | * @flags: One of GNUTLS_PKCS11_OBJ_* flags |
1007 | * |
1008 | * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t |
1009 | * structure. |
1010 | * |
1011 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
1012 | * negative error value. |
1013 | * |
1014 | * Since: 2.12.0 |
1015 | **/ |
1016 | int |
1017 | gnutls_pubkey_import_pkcs11_url (gnutls_pubkey_t key, const char *url, |
1018 | unsigned int flags) |
1019 | { |
1020 | gnutls_pkcs11_obj_t pcrt; |
1021 | int ret; |
1022 | |
1023 | ret = gnutls_pkcs11_obj_init (&pcrt); |
1024 | if (ret < 0) |
1025 | { |
1026 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1026); } while(0);; |
1027 | return ret; |
1028 | } |
1029 | |
1030 | ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags); |
1031 | if (ret < 0) |
1032 | { |
1033 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1033); } while(0);; |
1034 | goto cleanup; |
1035 | } |
1036 | |
1037 | ret = gnutls_pubkey_import_pkcs11 (key, pcrt, 0); |
1038 | if (ret < 0) |
1039 | { |
1040 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1040); } while(0);; |
1041 | goto cleanup; |
1042 | } |
1043 | |
1044 | ret = 0; |
1045 | cleanup: |
1046 | |
1047 | gnutls_pkcs11_obj_deinit (pcrt); |
1048 | |
1049 | return ret; |
1050 | } |
1051 | |
1052 | #endif /* ENABLE_PKCS11 */ |
1053 | |
1054 | /** |
1055 | * gnutls_pubkey_import_rsa_raw: |
1056 | * @key: Is a structure will hold the parameters |
1057 | * @m: holds the modulus |
1058 | * @e: holds the public exponent |
1059 | * |
1060 | * This function will replace the parameters in the given structure. |
1061 | * The new parameters should be stored in the appropriate |
1062 | * gnutls_datum. |
1063 | * |
1064 | * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code. |
1065 | * |
1066 | * Since: 2.12.0 |
1067 | **/ |
1068 | int |
1069 | gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key, |
1070 | const gnutls_datum_t * m, |
1071 | const gnutls_datum_t * e) |
1072 | { |
1073 | size_t siz = 0; |
1074 | |
1075 | if (key == NULL((void*)0)) |
1076 | { |
1077 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1077); } while(0);; |
1078 | return GNUTLS_E_INVALID_REQUEST-50; |
1079 | } |
1080 | |
1081 | gnutls_pk_params_init(&key->params); |
1082 | |
1083 | siz = m->size; |
1084 | if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz)) |
1085 | { |
1086 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1086); } while(0);; |
1087 | return GNUTLS_E_MPI_SCAN_FAILED-23; |
1088 | } |
1089 | |
1090 | siz = e->size; |
1091 | if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz)) |
1092 | { |
1093 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1093); } while(0);; |
1094 | _gnutls_mpi_release (&key->params.params[0]); |
1095 | return GNUTLS_E_MPI_SCAN_FAILED-23; |
1096 | } |
1097 | |
1098 | key->params.params_nr = RSA_PUBLIC_PARAMS2; |
1099 | key->pk_algorithm = GNUTLS_PK_RSA; |
1100 | key->bits = pubkey_to_bits(GNUTLS_PK_RSA, &key->params); |
1101 | |
1102 | return 0; |
1103 | } |
1104 | |
1105 | /** |
1106 | * gnutls_pubkey_import_ecc_raw: |
1107 | * @key: The structure to store the parsed key |
1108 | * @curve: holds the curve |
1109 | * @x: holds the x |
1110 | * @y: holds the y |
1111 | * |
1112 | * This function will convert the given elliptic curve parameters to a |
1113 | * #gnutls_pubkey_t. The output will be stored in @key. |
1114 | * |
1115 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
1116 | * negative error value. |
1117 | * |
1118 | * Since: 3.0.0 |
1119 | **/ |
1120 | int |
1121 | gnutls_pubkey_import_ecc_raw (gnutls_pubkey_t key, |
1122 | gnutls_ecc_curve_t curve, |
1123 | const gnutls_datum_t * x, |
1124 | const gnutls_datum_t * y) |
1125 | { |
1126 | int ret; |
1127 | |
1128 | if (key == NULL((void*)0)) |
1129 | { |
1130 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1130); } while(0);; |
1131 | return GNUTLS_E_INVALID_REQUEST-50; |
1132 | } |
1133 | |
1134 | key->params.flags = curve; |
1135 | |
1136 | ret = _gnutls_ecc_curve_fill_params(curve, &key->params); |
1137 | if (ret < 0) |
1138 | return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_pubkey.c", 1138); |
1139 | |
1140 | if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X6], x->data, x->size)) |
1141 | { |
1142 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1142); } while(0);; |
1143 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; |
1144 | goto cleanup; |
1145 | } |
1146 | key->params.params_nr++; |
1147 | |
1148 | if (_gnutls_mpi_scan_nz (&key->params.params[ECC_Y7], y->data, y->size)) |
1149 | { |
1150 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1150); } while(0);; |
1151 | ret = GNUTLS_E_MPI_SCAN_FAILED-23; |
1152 | goto cleanup; |
1153 | } |
1154 | key->params.params_nr++; |
1155 | key->pk_algorithm = GNUTLS_PK_EC; |
1156 | |
1157 | return 0; |
1158 | |
1159 | cleanup: |
1160 | gnutls_pk_params_release(&key->params); |
1161 | return ret; |
1162 | } |
1163 | |
1164 | /** |
1165 | * gnutls_pubkey_import_ecc_x962: |
1166 | * @key: The structure to store the parsed key |
1167 | * @parameters: DER encoding of an ANSI X9.62 parameters |
1168 | * @ecpoint: DER encoding of ANSI X9.62 ECPoint |
1169 | * |
1170 | * This function will convert the given elliptic curve parameters to a |
1171 | * #gnutls_pubkey_t. The output will be stored in @key. |
1172 | * |
1173 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
1174 | * negative error value. |
1175 | * |
1176 | * Since: 3.0.0 |
1177 | **/ |
1178 | int |
1179 | gnutls_pubkey_import_ecc_x962 (gnutls_pubkey_t key, |
1180 | const gnutls_datum_t * parameters, |
1181 | const gnutls_datum_t * ecpoint) |
1182 | { |
1183 | int ret; |
1184 | |
1185 | if (key == NULL((void*)0)) |
1186 | { |
1187 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1187); } while(0);; |
1188 | return GNUTLS_E_INVALID_REQUEST-50; |
1189 | } |
1190 | |
1191 | key->params.params_nr = 0; |
1192 | |
1193 | ret = _gnutls_x509_read_ecc_params(parameters->data, parameters->size, |
1194 | &key->params); |
1195 | if (ret < 0) |
1196 | { |
1197 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1197); } while(0);; |
1198 | goto cleanup; |
1199 | } |
1200 | |
1201 | ret = _gnutls_ecc_ansi_x963_import(ecpoint->data, ecpoint->size, |
1202 | &key->params.params[ECC_X6], &key->params.params[ECC_Y7]); |
1203 | if (ret < 0) |
1204 | { |
1205 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1205); } while(0);; |
1206 | goto cleanup; |
1207 | } |
1208 | key->params.params_nr+=2; |
1209 | key->pk_algorithm = GNUTLS_PK_EC; |
1210 | |
1211 | return 0; |
1212 | |
1213 | cleanup: |
1214 | gnutls_pk_params_release(&key->params); |
1215 | return ret; |
1216 | } |
1217 | |
1218 | /** |
1219 | * gnutls_pubkey_import_dsa_raw: |
1220 | * @key: The structure to store the parsed key |
1221 | * @p: holds the p |
1222 | * @q: holds the q |
1223 | * @g: holds the g |
1224 | * @y: holds the y |
1225 | * |
1226 | * This function will convert the given DSA raw parameters to the |
1227 | * native #gnutls_pubkey_t format. The output will be stored |
1228 | * in @key. |
1229 | * |
1230 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
1231 | * negative error value. |
1232 | * |
1233 | * Since: 2.12.0 |
1234 | **/ |
1235 | int |
1236 | gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key, |
1237 | const gnutls_datum_t * p, |
1238 | const gnutls_datum_t * q, |
1239 | const gnutls_datum_t * g, |
1240 | const gnutls_datum_t * y) |
1241 | { |
1242 | size_t siz = 0; |
1243 | |
1244 | if (key == NULL((void*)0)) |
1245 | { |
1246 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1246); } while(0);; |
1247 | return GNUTLS_E_INVALID_REQUEST-50; |
1248 | } |
1249 | |
1250 | gnutls_pk_params_init(&key->params); |
1251 | |
1252 | siz = p->size; |
1253 | if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz)) |
1254 | { |
1255 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1255); } while(0);; |
1256 | return GNUTLS_E_MPI_SCAN_FAILED-23; |
1257 | } |
1258 | |
1259 | siz = q->size; |
1260 | if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz)) |
1261 | { |
1262 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1262); } while(0);; |
1263 | _gnutls_mpi_release (&key->params.params[0]); |
1264 | return GNUTLS_E_MPI_SCAN_FAILED-23; |
1265 | } |
1266 | |
1267 | siz = g->size; |
1268 | if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz)) |
1269 | { |
1270 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1270); } while(0);; |
1271 | _gnutls_mpi_release (&key->params.params[1]); |
1272 | _gnutls_mpi_release (&key->params.params[0]); |
1273 | return GNUTLS_E_MPI_SCAN_FAILED-23; |
1274 | } |
1275 | |
1276 | siz = y->size; |
1277 | if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz)) |
1278 | { |
1279 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1279); } while(0);; |
1280 | _gnutls_mpi_release (&key->params.params[2]); |
1281 | _gnutls_mpi_release (&key->params.params[1]); |
1282 | _gnutls_mpi_release (&key->params.params[0]); |
1283 | return GNUTLS_E_MPI_SCAN_FAILED-23; |
1284 | } |
1285 | |
1286 | key->params.params_nr = DSA_PUBLIC_PARAMS4; |
1287 | key->pk_algorithm = GNUTLS_PK_DSA; |
1288 | key->bits = pubkey_to_bits(GNUTLS_PK_DSA, &key->params); |
1289 | |
1290 | return 0; |
1291 | |
1292 | } |
1293 | |
1294 | /** |
1295 | * gnutls_pubkey_verify_data: |
1296 | * @pubkey: Holds the public key |
1297 | * @flags: should be 0 for now |
1298 | * @data: holds the signed data |
1299 | * @signature: contains the signature |
1300 | * |
1301 | * This function will verify the given signed data, using the |
1302 | * parameters from the certificate. |
1303 | * |
1304 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
1305 | * negative error value (%GNUTLS_E_PK_SIG_VERIFY_FAILED in verification failure). |
1306 | * |
1307 | * Since: 2.12.0 |
1308 | **/ |
1309 | int |
1310 | gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, unsigned int flags, |
1311 | const gnutls_datum_t * data, |
1312 | const gnutls_datum_t * signature) |
1313 | { |
1314 | int ret; |
1315 | |
1316 | if (pubkey == NULL((void*)0)) |
1317 | { |
1318 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1318); } while(0);; |
1319 | return GNUTLS_E_INVALID_REQUEST-50; |
1320 | } |
1321 | |
1322 | ret = pubkey_verify_data( pubkey->pk_algorithm, GNUTLS_DIG_UNKNOWN, data, signature, |
1323 | &pubkey->params); |
1324 | if (ret < 0) |
1325 | { |
1326 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1326); } while(0);; |
1327 | } |
1328 | |
1329 | return ret; |
1330 | } |
1331 | |
1332 | /** |
1333 | * gnutls_pubkey_verify_data2: |
1334 | * @pubkey: Holds the public key |
1335 | * @algo: The signature algorithm used |
1336 | * @flags: should be 0 for now |
1337 | * @data: holds the signed data |
1338 | * @signature: contains the signature |
1339 | * |
1340 | * This function will verify the given signed data, using the |
1341 | * parameters from the certificate. |
1342 | * |
1343 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
1344 | * negative error value (%GNUTLS_E_PK_SIG_VERIFY_FAILED in verification failure). |
1345 | * |
1346 | * Since: 3.0.0 |
1347 | **/ |
1348 | int |
1349 | gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey, |
1350 | gnutls_sign_algorithm_t algo, |
1351 | unsigned int flags, |
1352 | const gnutls_datum_t * data, |
1353 | const gnutls_datum_t * signature) |
1354 | { |
1355 | int ret; |
1356 | |
1357 | if (pubkey == NULL((void*)0)) |
1358 | { |
1359 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1359); } while(0);; |
1360 | return GNUTLS_E_INVALID_REQUEST-50; |
1361 | } |
1362 | |
1363 | ret = pubkey_verify_data( pubkey->pk_algorithm, _gnutls_sign_get_hash_algorithm(algo), data, signature, |
1364 | &pubkey->params); |
1365 | if (ret < 0) |
1366 | { |
1367 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1367); } while(0);; |
1368 | } |
1369 | |
1370 | return ret; |
1371 | } |
1372 | |
1373 | |
1374 | /** |
1375 | * gnutls_pubkey_verify_hash: |
1376 | * @key: Holds the public key |
1377 | * @flags: should be 0 for now |
1378 | * @hash: holds the hash digest to be verified |
1379 | * @signature: contains the signature |
1380 | * |
1381 | * This function will verify the given signed digest, using the |
1382 | * parameters from the public key. |
1383 | * |
1384 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
1385 | * negative error value (%GNUTLS_E_PK_SIG_VERIFY_FAILED in verification failure). |
1386 | * |
1387 | * Since: 2.12.0 |
1388 | **/ |
1389 | int |
1390 | gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags, |
1391 | const gnutls_datum_t * hash, |
1392 | const gnutls_datum_t * signature) |
1393 | { |
1394 | if (key == NULL((void*)0)) |
1395 | { |
1396 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1396); } while(0);; |
1397 | return GNUTLS_E_INVALID_REQUEST-50; |
1398 | } |
1399 | |
1400 | if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA1) |
1401 | return _gnutls_rsa_verify (hash, signature, &key->params, 1); |
1402 | else |
1403 | { |
1404 | return pubkey_verify_hashed_data (key->pk_algorithm, hash, signature, |
1405 | &key->params); |
1406 | } |
1407 | } |
1408 | |
1409 | /** |
1410 | * gnutls_pubkey_encrypt_data: |
1411 | * @key: Holds the public key |
1412 | * @flags: should be 0 for now |
1413 | * @plaintext: The data to be encrypted |
1414 | * @ciphertext: contains the encrypted data |
1415 | * |
1416 | * This function will encrypt the given data, using the public |
1417 | * key. |
1418 | * |
1419 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
1420 | * negative error value. |
1421 | * |
1422 | * Since: 3.0.0 |
1423 | **/ |
1424 | int |
1425 | gnutls_pubkey_encrypt_data (gnutls_pubkey_t key, unsigned int flags, |
1426 | const gnutls_datum_t * plaintext, |
1427 | gnutls_datum_t * ciphertext) |
1428 | { |
1429 | if (key == NULL((void*)0) || key->pk_algorithm != GNUTLS_PK_RSA) |
1430 | { |
1431 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1431); } while(0);; |
1432 | return GNUTLS_E_INVALID_REQUEST-50; |
1433 | } |
1434 | |
1435 | return _gnutls_pkcs1_rsa_encrypt (ciphertext, plaintext, |
1436 | &key->params, |
1437 | 2); |
1438 | } |
1439 | |
1440 | /** |
1441 | * gnutls_pubkey_get_verify_algorithm: |
1442 | * @key: Holds the certificate |
1443 | * @signature: contains the signature |
1444 | * @hash: The result of the call with the hash algorithm used for signature |
1445 | * |
1446 | * This function will read the certifcate and the signed data to |
1447 | * determine the hash algorithm used to generate the signature. |
1448 | * |
1449 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a |
1450 | * negative error value. |
1451 | * |
1452 | * Since: 2.12.0 |
1453 | **/ |
1454 | int |
1455 | gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key, |
1456 | const gnutls_datum_t * signature, |
1457 | gnutls_digest_algorithm_t * hash) |
1458 | { |
1459 | if (key == NULL((void*)0)) |
1460 | { |
1461 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1461); } while(0);; |
1462 | return GNUTLS_E_INVALID_REQUEST-50; |
1463 | } |
1464 | |
1465 | return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) |
1466 | hash, signature, |
1467 | key->pk_algorithm, |
1468 | &key->params); |
1469 | |
1470 | } |
1471 | |
1472 | |
1473 | int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, gnutls_protocol_t ver, |
1474 | gnutls_sign_algorithm_t sign) |
1475 | { |
1476 | int hash_size; |
1477 | int hash_algo; |
1478 | |
1479 | if (pubkey->pk_algorithm == GNUTLS_PK_DSA) |
1480 | { |
1481 | hash_algo = _gnutls_dsa_q_to_hash (pubkey->pk_algorithm, &pubkey->params, &hash_size); |
1482 | |
1483 | /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */ |
1484 | if (!_gnutls_version_has_selectable_sighash (ver)) |
1485 | { |
1486 | if (hash_algo != GNUTLS_DIG_SHA1) |
1487 | return gnutls_assert_val(GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL)gnutls_assert_val_int(-216, "gnutls_pubkey.c", 1487); |
1488 | } |
1489 | else if (sign != GNUTLS_SIGN_UNKNOWN) |
1490 | { |
1491 | if (_gnutls_hash_get_algo_len(_gnutls_sign_get_hash_algorithm(sign)) != hash_size) |
1492 | return GNUTLS_E_UNWANTED_ALGORITHM-22; |
1493 | } |
1494 | |
1495 | } |
1496 | else if (pubkey->pk_algorithm == GNUTLS_PK_EC) |
1497 | { |
1498 | if (_gnutls_version_has_selectable_sighash (ver) && sign != GNUTLS_SIGN_UNKNOWN) |
1499 | { |
1500 | hash_algo = _gnutls_dsa_q_to_hash (pubkey->pk_algorithm, &pubkey->params, &hash_size); |
Value stored to 'hash_algo' is never read | |
1501 | |
1502 | if (_gnutls_hash_get_algo_len(_gnutls_sign_get_hash_algorithm(sign)) != hash_size) |
1503 | return GNUTLS_E_UNWANTED_ALGORITHM-22; |
1504 | } |
1505 | |
1506 | } |
1507 | |
1508 | return 0; |
1509 | } |
1510 | |
1511 | /* Returns zero if the public key has more than 512 bits */ |
1512 | int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey) |
1513 | { |
1514 | if (pubkey->pk_algorithm == GNUTLS_PK_RSA && _gnutls_mpi_get_nbits (pubkey->params.params[0])_gnutls_mpi_ops.bigint_get_nbits(pubkey->params.params[0]) > 512) |
1515 | return 0; |
1516 | else |
1517 | return GNUTLS_E_INVALID_REQUEST-50; /* doesn't matter */ |
1518 | |
1519 | } |
1520 | |
1521 | /* Returns the public key. |
1522 | */ |
1523 | int |
1524 | _gnutls_pubkey_get_mpis (gnutls_pubkey_t key, |
1525 | gnutls_pk_params_st * params) |
1526 | { |
1527 | return _gnutls_pk_params_copy(params, &key->params); |
1528 | } |
1529 | |
1530 | /* if hash==MD5 then we do RSA-MD5 |
1531 | * if hash==SHA then we do RSA-SHA |
1532 | * params[0] is modulus |
1533 | * params[1] is public key |
1534 | */ |
1535 | static int |
1536 | _pkcs1_rsa_verify_sig (const gnutls_datum_t * text, |
1537 | const gnutls_datum_t * prehash, |
1538 | const gnutls_datum_t * signature, |
1539 | gnutls_pk_params_st * params) |
1540 | { |
1541 | gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN; |
1542 | int ret; |
1543 | opaque digest[MAX_HASH_SIZE64], md[MAX_HASH_SIZE64], *cmp; |
1544 | int digest_size; |
1545 | digest_hd_st hd; |
1546 | gnutls_datum_t decrypted; |
1547 | |
1548 | ret = |
1549 | _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, 1); |
1550 | if (ret < 0) |
1551 | { |
1552 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1552); } while(0);; |
1553 | return ret; |
1554 | } |
1555 | |
1556 | /* decrypted is a BER encoded data of type DigestInfo |
1557 | */ |
1558 | |
1559 | digest_size = sizeof (digest); |
1560 | if ((ret = |
1561 | decode_ber_digest_info (&decrypted, &hash, digest, &digest_size)) != 0) |
1562 | { |
1563 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1563); } while(0);; |
1564 | _gnutls_free_datum (&decrypted)_gnutls_free_datum_m(&decrypted, gnutls_free); |
1565 | return ret; |
1566 | } |
1567 | |
1568 | _gnutls_free_datum (&decrypted)_gnutls_free_datum_m(&decrypted, gnutls_free); |
1569 | |
1570 | if (digest_size != _gnutls_hash_get_algo_len (hash)) |
1571 | { |
1572 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1572); } while(0);; |
1573 | return GNUTLS_E_ASN1_GENERIC_ERROR-71; |
1574 | } |
1575 | |
1576 | if (prehash && prehash->data && prehash->size == digest_size) |
1577 | { |
1578 | cmp = prehash->data; |
1579 | } |
1580 | else |
1581 | { |
1582 | if (!text) |
1583 | { |
1584 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1584); } while(0);; |
1585 | return GNUTLS_E_INVALID_REQUEST-50; |
1586 | } |
1587 | |
1588 | ret = _gnutls_hash_init (&hd, hash); |
1589 | if (ret < 0) |
1590 | { |
1591 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1591); } while(0);; |
1592 | return ret; |
1593 | } |
1594 | |
1595 | _gnutls_hash (&hd, text->data, text->size); |
1596 | _gnutls_hash_deinit (&hd, md); |
1597 | |
1598 | cmp = md; |
1599 | } |
1600 | |
1601 | if (memcmp (cmp, digest, digest_size) != 0) |
1602 | { |
1603 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1603); } while(0);; |
1604 | return GNUTLS_E_PK_SIG_VERIFY_FAILED-89; |
1605 | } |
1606 | |
1607 | return 0; |
1608 | } |
1609 | |
1610 | /* Hashes input data and verifies a signature. |
1611 | */ |
1612 | static int |
1613 | dsa_verify_hashed_data (const gnutls_datum_t * hash, |
1614 | const gnutls_datum_t * signature, |
1615 | gnutls_pk_algorithm_t pk, |
1616 | gnutls_pk_params_st* params) |
1617 | { |
1618 | gnutls_datum_t digest; |
1619 | gnutls_digest_algorithm_t algo; |
1620 | int hash_len; |
1621 | |
1622 | algo = _gnutls_dsa_q_to_hash (pk, params, &hash_len); |
1623 | |
1624 | /* SHA1 or better allowed */ |
1625 | if (!hash->data || hash->size < hash_len) |
1626 | { |
1627 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1627); } while(0);; |
1628 | _gnutls_debug_log("Hash size (%d) does not correspond to hash %s(%d) or better.\n", (int)hash->size, gnutls_mac_get_name(algo), hash_len)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "Hash size (%d) does not correspond to hash %s(%d) or better.\n" , (int)hash->size, gnutls_mac_get_name(algo), hash_len); } while(0); |
1629 | |
1630 | if (hash->size != 20) /* SHA1 is allowed */ |
1631 | return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED)gnutls_assert_val_int(-89, "gnutls_pubkey.c", 1631); |
1632 | } |
1633 | |
1634 | digest.data = hash->data; |
1635 | digest.size = hash->size; |
1636 | |
1637 | return _gnutls_pk_verify (pk, &digest, signature, params)_gnutls_pk_ops.verify( pk, &digest, signature, params); |
1638 | } |
1639 | |
1640 | static int |
1641 | dsa_verify_data (gnutls_pk_algorithm_t pk, |
1642 | gnutls_digest_algorithm_t algo, |
1643 | const gnutls_datum_t * data, |
1644 | const gnutls_datum_t * signature, |
1645 | gnutls_pk_params_st* params) |
1646 | { |
1647 | int ret; |
1648 | opaque _digest[MAX_HASH_SIZE64]; |
1649 | gnutls_datum_t digest; |
1650 | digest_hd_st hd; |
1651 | |
1652 | if (algo == GNUTLS_DIG_UNKNOWN) |
1653 | algo = _gnutls_dsa_q_to_hash (pk, params, NULL((void*)0)); |
1654 | |
1655 | ret = _gnutls_hash_init (&hd, algo); |
1656 | if (ret < 0) |
1657 | return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_pubkey.c", 1657); |
1658 | |
1659 | _gnutls_hash (&hd, data->data, data->size); |
1660 | _gnutls_hash_deinit (&hd, _digest); |
1661 | |
1662 | digest.data = _digest; |
1663 | digest.size = _gnutls_hash_get_algo_len(algo); |
1664 | |
1665 | return _gnutls_pk_verify (pk, &digest, signature, params)_gnutls_pk_ops.verify( pk, &digest, signature, params); |
1666 | } |
1667 | |
1668 | /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if |
1669 | * not verified, or 1 otherwise. |
1670 | */ |
1671 | int |
1672 | pubkey_verify_hashed_data (gnutls_pk_algorithm_t pk, |
1673 | const gnutls_datum_t * hash, |
1674 | const gnutls_datum_t * signature, |
1675 | gnutls_pk_params_st * issuer_params) |
1676 | { |
1677 | |
1678 | switch (pk) |
1679 | { |
1680 | case GNUTLS_PK_RSA: |
1681 | |
1682 | if (_pkcs1_rsa_verify_sig |
1683 | (NULL((void*)0), hash, signature, issuer_params) != 0) |
1684 | { |
1685 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1685); } while(0);; |
1686 | return GNUTLS_E_PK_SIG_VERIFY_FAILED-89; |
1687 | } |
1688 | |
1689 | return 1; |
1690 | break; |
1691 | |
1692 | case GNUTLS_PK_EC: |
1693 | case GNUTLS_PK_DSA: |
1694 | if (dsa_verify_hashed_data(hash, signature, pk, issuer_params) != 0) |
1695 | { |
1696 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1696); } while(0);; |
1697 | return GNUTLS_E_PK_SIG_VERIFY_FAILED-89; |
1698 | } |
1699 | |
1700 | return 1; |
1701 | break; |
1702 | default: |
1703 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1703); } while(0);; |
1704 | return GNUTLS_E_INTERNAL_ERROR-59; |
1705 | |
1706 | } |
1707 | } |
1708 | |
1709 | /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if |
1710 | * not verified, or 1 otherwise. |
1711 | */ |
1712 | int |
1713 | pubkey_verify_data (gnutls_pk_algorithm_t pk, |
1714 | gnutls_digest_algorithm_t algo, |
1715 | const gnutls_datum_t * data, |
1716 | const gnutls_datum_t * signature, |
1717 | gnutls_pk_params_st * issuer_params) |
1718 | { |
1719 | |
1720 | switch (pk) |
1721 | { |
1722 | case GNUTLS_PK_RSA: |
1723 | |
1724 | if (_pkcs1_rsa_verify_sig |
1725 | (data, NULL((void*)0), signature, issuer_params) != 0) |
1726 | { |
1727 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1727); } while(0);; |
1728 | return GNUTLS_E_PK_SIG_VERIFY_FAILED-89; |
1729 | } |
1730 | |
1731 | return 1; |
1732 | break; |
1733 | |
1734 | case GNUTLS_PK_EC: |
1735 | case GNUTLS_PK_DSA: |
1736 | if (dsa_verify_data(pk, algo, data, signature, issuer_params) != 0) |
1737 | { |
1738 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1738); } while(0);; |
1739 | return GNUTLS_E_PK_SIG_VERIFY_FAILED-89; |
1740 | } |
1741 | |
1742 | return 1; |
1743 | break; |
1744 | default: |
1745 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "gnutls_pubkey.c",1745); } while(0);; |
1746 | return GNUTLS_E_INTERNAL_ERROR-59; |
1747 | |
1748 | } |
1749 | } |
1750 | |
1751 | gnutls_digest_algorithm_t |
1752 | _gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* params, int* hash_len) |
1753 | { |
1754 | int bits = 0; |
1755 | |
1756 | if (algo == GNUTLS_PK_DSA) |
1757 | bits = _gnutls_mpi_get_nbits (params->params[1])_gnutls_mpi_ops.bigint_get_nbits(params->params[1]); |
1758 | else if (algo == GNUTLS_PK_EC) |
1759 | bits = gnutls_ecc_curve_get_size(params->flags)*8; |
1760 | |
1761 | if (bits <= 160) |
1762 | { |
1763 | if (hash_len) *hash_len = 20; |
1764 | return GNUTLS_DIG_SHA1; |
1765 | } |
1766 | else if (bits <= 192) |
1767 | { |
1768 | if (hash_len) *hash_len = 24; |
1769 | return GNUTLS_DIG_SHA256; |
1770 | } |
1771 | else if (bits <= 224) |
1772 | { |
1773 | if (hash_len) *hash_len = 28; |
1774 | return GNUTLS_DIG_SHA256; |
1775 | } |
1776 | else if (bits <= 256) |
1777 | { |
1778 | if (hash_len) *hash_len = 32; |
1779 | return GNUTLS_DIG_SHA256; |
1780 | } |
1781 | else if (bits <= 384) |
1782 | { |
1783 | if (hash_len) *hash_len = 48; |
1784 | return GNUTLS_DIG_SHA384; |
1785 | } |
1786 | else |
1787 | { |
1788 | if (hash_len) *hash_len = 64; |
1789 | return GNUTLS_DIG_SHA512; |
1790 | } |
1791 | } |