Bug Summary

File:lib/gnutls_pubkey.c
Location:line 1500, column 11
Description:Value stored to 'hash_algo' is never read

Annotated Source Code

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
44struct 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
66int 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 **/
95int
96gnutls_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 **/
116int
117gnutls_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 **/
136int
137gnutls_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 **/
157void
158gnutls_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 **/
180int
181gnutls_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 **/
217int
218gnutls_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 **/
243int
244gnutls_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 **/
279int
280gnutls_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 **/
343int
344gnutls_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 **/
425int
426gnutls_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 **/
482int
483gnutls_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
525cleanup:
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 **/
554int
555gnutls_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 **/
593int
594gnutls_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 **/
645int
646gnutls_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 **/
722int
723gnutls_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 **/
776int 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 **/
814int
815gnutls_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
888cleanup:
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 **/
909int
910gnutls_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 **/
950int
951gnutls_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 **/
992int
993gnutls_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 **/
1016int
1017gnutls_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;
1045cleanup:
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 **/
1068int
1069gnutls_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 **/
1120int
1121gnutls_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
1159cleanup:
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 **/
1178int
1179gnutls_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
1213cleanup:
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 **/
1235int
1236gnutls_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 **/
1309int
1310gnutls_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 **/
1348int
1349gnutls_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 **/
1389int
1390gnutls_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 **/
1424int
1425gnutls_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 **/
1454int
1455gnutls_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
1473int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, gnutls_protocol_t ver,
1474 gnutls_sign_algorithm_t sign)
1475{
1476int hash_size;
1477int 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 */
1512int _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 */
1523int
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 */
1535static 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 */
1612static int
1613dsa_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
1640static int
1641dsa_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 */
1671int
1672pubkey_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 */
1712int
1713pubkey_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
1751gnutls_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}