Be tolerant in ECDSA-violating signatures.
[gnutls.git] / lib / gnutls_pubkey.c
blobf2be13031db0c8f6a6f1290830a1595ca8d5eb5f
1 /*
2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4 *
5 * Author: Nikos Mavrogiannopoulos
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.
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.
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/>
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_datum.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>
39 #define PK_PEM_HEADER "PUBLIC KEY"
41 #define OPENPGP_KEY_PRIMARY 2
42 #define OPENPGP_KEY_SUBKEY 1
44 struct gnutls_pubkey_st
46 gnutls_pk_algorithm_t pk_algorithm;
47 unsigned int bits; /* an indication of the security parameter */
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
58 gnutls_pk_params_st params;
60 uint8_t openpgp_key_id[GNUTLS_OPENPGP_KEYID_SIZE];
61 int openpgp_key_id_set;
63 unsigned int key_usage; /* bits from GNUTLS_KEY_* */
66 int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st* params)
68 switch(pk)
70 case GNUTLS_PK_RSA:
71 return _gnutls_mpi_get_nbits(params->params[0]);
72 case GNUTLS_PK_DSA:
73 return _gnutls_mpi_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;
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)
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.
90 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
91 * success, or a negative error code on error.
93 * Since: 2.12.0
94 **/
95 int
96 gnutls_pubkey_get_pk_algorithm (gnutls_pubkey_t key, unsigned int *bits)
98 if (bits)
99 *bits = key->bits;
101 return key->pk_algorithm;
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)
109 * This function will return the key usage of the public key.
111 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
112 * negative error value.
114 * Since: 2.12.0
117 gnutls_pubkey_get_key_usage (gnutls_pubkey_t key, unsigned int *usage)
119 if (usage)
120 *usage = key->key_usage;
122 return 0;
126 * gnutls_pubkey_init:
127 * @key: The structure to be initialized
129 * This function will initialize an public key structure.
131 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
132 * negative error value.
134 * Since: 2.12.0
137 gnutls_pubkey_init (gnutls_pubkey_t * key)
139 *key = gnutls_calloc (1, sizeof (struct gnutls_pubkey_st));
140 if (*key == NULL)
142 gnutls_assert ();
143 return GNUTLS_E_MEMORY_ERROR;
146 return 0;
150 * gnutls_pubkey_deinit:
151 * @key: The structure to be deinitialized
153 * This function will deinitialize a public key structure.
155 * Since: 2.12.0
157 void
158 gnutls_pubkey_deinit (gnutls_pubkey_t key)
160 if (!key)
161 return;
162 gnutls_pk_params_release (&key->params);
163 gnutls_free (key);
167 * gnutls_pubkey_import_x509:
168 * @key: The public key
169 * @crt: The certificate to be imported
170 * @flags: should be zero
172 * This function will import the given public key to the abstract
173 * #gnutls_pubkey_t structure.
175 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
176 * negative error value.
178 * Since: 2.12.0
181 gnutls_pubkey_import_x509 (gnutls_pubkey_t key, gnutls_x509_crt_t crt,
182 unsigned int flags)
184 int ret;
186 key->pk_algorithm = gnutls_x509_crt_get_pk_algorithm (crt, &key->bits);
188 ret = gnutls_x509_crt_get_key_usage (crt, &key->key_usage, NULL);
189 if (ret < 0)
190 key->key_usage = 0;
192 ret = _gnutls_x509_crt_get_mpis (crt, &key->params);
193 if (ret < 0)
195 gnutls_assert ();
196 return ret;
199 return 0;
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
209 * Imports the public key from a private. This function will import
210 * the given public key to the abstract #gnutls_pubkey_t structure.
212 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
213 * negative error value.
215 * Since: 2.12.0
218 gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey,
219 unsigned int usage, unsigned int flags)
221 key->pk_algorithm = gnutls_privkey_get_pk_algorithm (pkey, &key->bits);
223 key->key_usage = usage;
225 return _gnutls_privkey_get_public_mpis (pkey, &key->params);
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.
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).
238 * Returns: the 0 if the hash algorithm is found. A negative error code is
239 * returned on error.
241 * Since: 2.12.0
244 gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key,
245 gnutls_digest_algorithm_t *
246 hash, unsigned int *mand)
248 int ret;
250 if (key == NULL)
252 gnutls_assert ();
253 return GNUTLS_E_INVALID_REQUEST;
256 ret = _gnutls_pk_get_hash_algorithm (key->pk_algorithm,
257 &key->params,
258 hash, mand);
260 return ret;
263 #ifdef ENABLE_PKCS11
266 * gnutls_pubkey_import_pkcs11:
267 * @key: The public key
268 * @obj: The parameters to be imported
269 * @flags: should be zero
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.
274 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
275 * negative error value.
277 * Since: 2.12.0
280 gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key,
281 gnutls_pkcs11_obj_t obj, unsigned int flags)
283 int ret;
285 ret = gnutls_pkcs11_obj_get_type (obj);
286 if (ret != GNUTLS_PKCS11_OBJ_PUBKEY)
288 gnutls_assert ();
289 return GNUTLS_E_INVALID_REQUEST;
292 key->key_usage = obj->key_usage;
294 switch (obj->pk_algorithm)
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 ();
311 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
314 if (ret < 0)
316 gnutls_assert ();
317 return ret;
320 return 0;
323 #endif /* ENABLE_PKCS11 */
325 #ifdef ENABLE_OPENPGP
328 * gnutls_pubkey_import_openpgp:
329 * @key: The public key
330 * @crt: The certificate to be imported
331 * @flags: should be zero
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.
338 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
339 * negative error value.
341 * Since: 2.12.0
344 gnutls_pubkey_import_openpgp (gnutls_pubkey_t key,
345 gnutls_openpgp_crt_t crt,
346 unsigned int flags)
348 int ret, idx;
349 uint32_t kid32[2];
350 uint32_t *k;
351 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
353 ret = gnutls_openpgp_crt_get_preferred_key_id (crt, keyid);
354 if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR)
356 key->pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (crt, &key->bits);
357 key->openpgp_key_id_set = OPENPGP_KEY_PRIMARY;
359 ret = gnutls_openpgp_crt_get_key_id(crt, key->openpgp_key_id);
360 if (ret < 0)
361 return gnutls_assert_val(ret);
363 ret = gnutls_openpgp_crt_get_key_usage (crt, &key->key_usage);
364 if (ret < 0)
365 key->key_usage = 0;
367 k = NULL;
369 else
371 if (ret < 0)
373 gnutls_assert ();
374 return ret;
376 key->openpgp_key_id_set = OPENPGP_KEY_SUBKEY;
378 KEYID_IMPORT (kid32, keyid);
379 k = kid32;
381 idx = gnutls_openpgp_crt_get_subkey_idx (crt, keyid);
383 ret = gnutls_openpgp_crt_get_subkey_id(crt, idx, key->openpgp_key_id);
384 if (ret < 0)
385 return gnutls_assert_val(ret);
387 ret = gnutls_openpgp_crt_get_subkey_usage (crt, idx, &key->key_usage);
388 if (ret < 0)
389 key->key_usage = 0;
391 key->pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm (crt, idx, NULL);
394 ret =
395 _gnutls_openpgp_crt_get_mpis (crt, k, &key->params);
396 if (ret < 0)
397 return gnutls_assert_val(ret);
399 return 0;
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
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.
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.
420 * Returns: In case of failure a negative error code will be
421 * returned, and 0 on success.
423 * Since: 3.0
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)
431 if (key == NULL)
433 gnutls_assert ();
434 return GNUTLS_E_INVALID_REQUEST;
437 if (*output_data_size < sizeof(key->openpgp_key_id))
439 *output_data_size = sizeof(key->openpgp_key_id);
440 return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
443 if (key->openpgp_key_id_set == 0)
444 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
446 if (key->openpgp_key_id_set == OPENPGP_KEY_SUBKEY)
447 if (subkey) *subkey = 1;
449 if (output_data)
451 memcpy(output_data, key->openpgp_key_id, sizeof(key->openpgp_key_id));
453 *output_data_size = sizeof(key->openpgp_key_id);
455 return 0;
458 #endif
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)
468 * This function will export the public key to DER or PEM format.
469 * The contents of the exported data is the SubjectPublicKeyInfo
470 * X.509 structure.
472 * If the buffer provided is not long enough to hold the output, then
473 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
474 * be returned.
476 * If the structure is PEM encoded, it will have a header
477 * of "BEGIN CERTIFICATE".
479 * Returns: In case of failure a negative error code will be
480 * returned, and 0 on success.
482 * Since: 2.12.0
485 gnutls_pubkey_export (gnutls_pubkey_t key,
486 gnutls_x509_crt_fmt_t format, void *output_data,
487 size_t * output_data_size)
489 int result;
490 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
492 if (key == NULL)
494 gnutls_assert ();
495 return GNUTLS_E_INVALID_REQUEST;
498 if ((result = asn1_create_element
499 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
500 != ASN1_SUCCESS)
502 gnutls_assert ();
503 return _gnutls_asn2err (result);
506 result =
507 _gnutls_x509_encode_and_copy_PKI_params (spk, "",
508 key->pk_algorithm,
509 &key->params);
510 if (result < 0)
512 gnutls_assert ();
513 goto cleanup;
516 result = _gnutls_x509_export_int_named (spk, "",
517 format, PK_PEM_HEADER,
518 output_data, output_data_size);
519 if (result < 0)
521 gnutls_assert ();
522 goto cleanup;
525 result = 0;
527 cleanup:
528 asn1_delete_structure (&spk);
530 return result;
535 * gnutls_pubkey_get_key_id:
536 * @key: Holds the public key
537 * @flags: should be 0 for now
538 * @output_data: will contain the key ID
539 * @output_data_size: holds the size of output_data (and will be
540 * replaced by the actual size of parameters)
542 * This function will return a unique ID the depends on the public
543 * key parameters. This ID can be used in checking whether a
544 * certificate corresponds to the given public key.
546 * If the buffer provided is not long enough to hold the output, then
547 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
548 * be returned. The output will normally be a SHA-1 hash output,
549 * which is 20 bytes.
551 * Returns: In case of failure a negative error code will be
552 * returned, and 0 on success.
554 * Since: 2.12.0
557 gnutls_pubkey_get_key_id (gnutls_pubkey_t key, unsigned int flags,
558 unsigned char *output_data,
559 size_t * output_data_size)
561 int ret = 0;
563 if (key == NULL)
565 gnutls_assert ();
566 return GNUTLS_E_INVALID_REQUEST;
569 ret =
570 _gnutls_get_key_id (key->pk_algorithm, &key->params,
571 output_data, output_data_size);
572 if (ret < 0)
574 gnutls_assert ();
575 return ret;
578 return 0;
582 * gnutls_pubkey_get_pk_rsa_raw:
583 * @key: Holds the certificate
584 * @m: will hold the modulus
585 * @e: will hold the public exponent
587 * This function will export the RSA public key's parameters found in
588 * the given structure. The new parameters will be allocated using
589 * gnutls_malloc() and will be stored in the appropriate datum.
591 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
593 * Since: 2.12.0
596 gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t key,
597 gnutls_datum_t * m, gnutls_datum_t * e)
599 int ret;
601 if (key == NULL)
603 gnutls_assert ();
604 return GNUTLS_E_INVALID_REQUEST;
607 if (key->pk_algorithm != GNUTLS_PK_RSA)
609 gnutls_assert ();
610 return GNUTLS_E_INVALID_REQUEST;
613 ret = _gnutls_mpi_dprint_lz (key->params.params[0], m);
614 if (ret < 0)
616 gnutls_assert ();
617 return ret;
620 ret = _gnutls_mpi_dprint_lz (key->params.params[1], e);
621 if (ret < 0)
623 gnutls_assert ();
624 _gnutls_free_datum (m);
625 return ret;
628 return 0;
632 * gnutls_pubkey_get_pk_dsa_raw:
633 * @key: Holds the public key
634 * @p: will hold the p
635 * @q: will hold the q
636 * @g: will hold the g
637 * @y: will hold the y
639 * This function will export the DSA public key's parameters found in
640 * the given certificate. The new parameters will be allocated using
641 * gnutls_malloc() and will be stored in the appropriate datum.
643 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
645 * Since: 2.12.0
648 gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
649 gnutls_datum_t * p, gnutls_datum_t * q,
650 gnutls_datum_t * g, gnutls_datum_t * y)
652 int ret;
654 if (key == NULL)
656 gnutls_assert ();
657 return GNUTLS_E_INVALID_REQUEST;
660 if (key->pk_algorithm != GNUTLS_PK_DSA)
662 gnutls_assert ();
663 return GNUTLS_E_INVALID_REQUEST;
666 /* P */
667 ret = _gnutls_mpi_dprint_lz (key->params.params[0], p);
668 if (ret < 0)
670 gnutls_assert ();
671 return ret;
674 /* Q */
675 ret = _gnutls_mpi_dprint_lz (key->params.params[1], q);
676 if (ret < 0)
678 gnutls_assert ();
679 _gnutls_free_datum (p);
680 return ret;
684 /* G */
685 ret = _gnutls_mpi_dprint_lz (key->params.params[2], g);
686 if (ret < 0)
688 gnutls_assert ();
689 _gnutls_free_datum (p);
690 _gnutls_free_datum (q);
691 return ret;
695 /* Y */
696 ret = _gnutls_mpi_dprint_lz (key->params.params[3], y);
697 if (ret < 0)
699 gnutls_assert ();
700 _gnutls_free_datum (p);
701 _gnutls_free_datum (g);
702 _gnutls_free_datum (q);
703 return ret;
706 return 0;
710 * gnutls_pubkey_get_pk_ecc_raw:
711 * @key: Holds the public key
712 * @curve: will hold the curve
713 * @x: will hold x
714 * @y: will hold y
716 * This function will export the ECC public key's parameters found in
717 * the given certificate. The new parameters will be allocated using
718 * gnutls_malloc() and will be stored in the appropriate datum.
720 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
722 * Since: 3.0
725 gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
726 gnutls_datum_t * x, gnutls_datum_t * y)
728 int ret;
730 if (key == NULL)
732 gnutls_assert ();
733 return GNUTLS_E_INVALID_REQUEST;
736 if (key->pk_algorithm != GNUTLS_PK_EC)
738 gnutls_assert ();
739 return GNUTLS_E_INVALID_REQUEST;
742 *curve = key->params.flags;
744 /* X */
745 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_X], x);
746 if (ret < 0)
748 gnutls_assert ();
749 return ret;
752 /* Y */
753 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_Y], y);
754 if (ret < 0)
756 gnutls_assert ();
757 _gnutls_free_datum (x);
758 return ret;
761 return 0;
765 * gnutls_pubkey_get_pk_ecc_x962:
766 * @key: Holds the public key
767 * @parameters: DER encoding of an ANSI X9.62 parameters
768 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
770 * This function will export the ECC public key's parameters found in
771 * the given certificate. The new parameters will be allocated using
772 * gnutls_malloc() and will be stored in the appropriate datum.
774 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
776 * Since: 3.0
778 int gnutls_pubkey_get_pk_ecc_x962 (gnutls_pubkey_t key, gnutls_datum_t* parameters,
779 gnutls_datum_t * ecpoint)
781 int ret;
783 if (key == NULL || key->pk_algorithm != GNUTLS_PK_EC)
784 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
786 ret = _gnutls_x509_write_ecc_pubkey(&key->params, ecpoint);
787 if (ret < 0)
788 return gnutls_assert_val(ret);
790 ret = _gnutls_x509_write_ecc_params(&key->params, parameters);
791 if (ret < 0)
793 _gnutls_free_datum(ecpoint);
794 return gnutls_assert_val(ret);
797 return 0;
801 * gnutls_pubkey_import:
802 * @key: The structure to store the parsed public key.
803 * @data: The DER or PEM encoded certificate.
804 * @format: One of DER or PEM
806 * This function will import the provided public key in
807 * a SubjectPublicKeyInfo X.509 structure to a native
808 * %gnutls_pubkey_t structure. The output will be stored
809 * in @key. If the public key is PEM encoded it should have a header
810 * of "PUBLIC KEY".
812 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
813 * negative error value.
815 * Since: 2.12.0
818 gnutls_pubkey_import (gnutls_pubkey_t key,
819 const gnutls_datum_t * data,
820 gnutls_x509_crt_fmt_t format)
822 int result = 0, need_free = 0;
823 gnutls_datum_t _data;
824 ASN1_TYPE spk;
826 if (key == NULL)
828 gnutls_assert ();
829 return GNUTLS_E_INVALID_REQUEST;
832 _data.data = data->data;
833 _data.size = data->size;
835 /* If the Certificate is in PEM format then decode it
837 if (format == GNUTLS_X509_FMT_PEM)
839 uint8_t *out;
841 /* Try the first header */
842 result =
843 _gnutls_fbase64_decode (PK_PEM_HEADER, data->data, data->size, &out);
845 if (result <= 0)
847 if (result == 0)
848 result = GNUTLS_E_INTERNAL_ERROR;
849 gnutls_assert ();
850 return result;
853 _data.data = out;
854 _data.size = result;
856 need_free = 1;
859 if ((result = asn1_create_element
860 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
861 != ASN1_SUCCESS)
863 gnutls_assert ();
864 result = _gnutls_asn2err (result);
865 goto cleanup;
868 result = asn1_der_decoding (&spk, _data.data, _data.size, NULL);
869 if (result != ASN1_SUCCESS)
871 gnutls_assert ();
872 result = _gnutls_asn2err (result);
873 goto cleanup;
876 result = _gnutls_get_asn_mpis (spk, "", &key->params);
877 if (result < 0)
879 gnutls_assert ();
880 goto cleanup;
883 /* this has already been called by get_asn_mpis() thus it cannot
884 * fail.
886 key->pk_algorithm = _gnutls_x509_get_pk_algorithm (spk, "", NULL);
887 key->bits = pubkey_to_bits(key->pk_algorithm, &key->params);
889 result = 0;
891 cleanup:
892 asn1_delete_structure (&spk);
894 if (need_free)
895 _gnutls_free_datum (&_data);
896 return result;
900 * gnutls_x509_crt_set_pubkey:
901 * @crt: should contain a #gnutls_x509_crt_t structure
902 * @key: holds a public key
904 * This function will set the public parameters from the given public
905 * key to the request.
907 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
908 * negative error value.
910 * Since: 2.12.0
913 gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, gnutls_pubkey_t key)
915 int result;
917 if (crt == NULL)
919 gnutls_assert ();
920 return GNUTLS_E_INVALID_REQUEST;
923 result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
924 "tbsCertificate.subjectPublicKeyInfo",
925 key->pk_algorithm,
926 &key->params);
928 if (result < 0)
930 gnutls_assert ();
931 return result;
934 if (key->key_usage)
935 gnutls_x509_crt_set_key_usage (crt, key->key_usage);
937 return 0;
941 * gnutls_x509_crq_set_pubkey:
942 * @crq: should contain a #gnutls_x509_crq_t structure
943 * @key: holds a public key
945 * This function will set the public parameters from the given public
946 * key to the request.
948 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
949 * negative error value.
951 * Since: 2.12.0
954 gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key)
956 int result;
958 if (crq == NULL)
960 gnutls_assert ();
961 return GNUTLS_E_INVALID_REQUEST;
964 result = _gnutls_x509_encode_and_copy_PKI_params
965 (crq->crq,
966 "certificationRequestInfo.subjectPKInfo",
967 key->pk_algorithm, &key->params);
969 if (result < 0)
971 gnutls_assert ();
972 return result;
975 if (key->key_usage)
976 gnutls_x509_crq_set_key_usage (crq, key->key_usage);
978 return 0;
982 * gnutls_pubkey_set_key_usage:
983 * @key: a certificate of type #gnutls_x509_crt_t
984 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
986 * This function will set the key usage flags of the public key. This
987 * is only useful if the key is to be exported to a certificate or
988 * certificate request.
990 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
991 * negative error value.
993 * Since: 2.12.0
996 gnutls_pubkey_set_key_usage (gnutls_pubkey_t key, unsigned int usage)
998 key->key_usage = usage;
1000 return 0;
1003 #ifdef ENABLE_PKCS11
1006 * gnutls_pubkey_import_pkcs11_url:
1007 * @key: A key of type #gnutls_pubkey_t
1008 * @url: A PKCS 11 url
1009 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1011 * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
1012 * structure.
1014 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1015 * negative error value.
1017 * Since: 2.12.0
1020 gnutls_pubkey_import_pkcs11_url (gnutls_pubkey_t key, const char *url,
1021 unsigned int flags)
1023 gnutls_pkcs11_obj_t pcrt;
1024 int ret;
1026 ret = gnutls_pkcs11_obj_init (&pcrt);
1027 if (ret < 0)
1029 gnutls_assert ();
1030 return ret;
1033 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
1034 if (ret < 0)
1036 gnutls_assert ();
1037 goto cleanup;
1040 ret = gnutls_pubkey_import_pkcs11 (key, pcrt, 0);
1041 if (ret < 0)
1043 gnutls_assert ();
1044 goto cleanup;
1047 ret = 0;
1048 cleanup:
1050 gnutls_pkcs11_obj_deinit (pcrt);
1052 return ret;
1055 #endif /* ENABLE_PKCS11 */
1058 * gnutls_pubkey_import_rsa_raw:
1059 * @key: Is a structure will hold the parameters
1060 * @m: holds the modulus
1061 * @e: holds the public exponent
1063 * This function will replace the parameters in the given structure.
1064 * The new parameters should be stored in the appropriate
1065 * gnutls_datum.
1067 * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
1069 * Since: 2.12.0
1072 gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key,
1073 const gnutls_datum_t * m,
1074 const gnutls_datum_t * e)
1076 size_t siz = 0;
1078 if (key == NULL)
1080 gnutls_assert ();
1081 return GNUTLS_E_INVALID_REQUEST;
1084 gnutls_pk_params_init(&key->params);
1086 siz = m->size;
1087 if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz))
1089 gnutls_assert ();
1090 return GNUTLS_E_MPI_SCAN_FAILED;
1093 siz = e->size;
1094 if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz))
1096 gnutls_assert ();
1097 _gnutls_mpi_release (&key->params.params[0]);
1098 return GNUTLS_E_MPI_SCAN_FAILED;
1101 key->params.params_nr = RSA_PUBLIC_PARAMS;
1102 key->pk_algorithm = GNUTLS_PK_RSA;
1103 key->bits = pubkey_to_bits(GNUTLS_PK_RSA, &key->params);
1105 return 0;
1109 * gnutls_pubkey_import_ecc_raw:
1110 * @key: The structure to store the parsed key
1111 * @curve: holds the curve
1112 * @x: holds the x
1113 * @y: holds the y
1115 * This function will convert the given elliptic curve parameters to a
1116 * #gnutls_pubkey_t. The output will be stored in @key.
1118 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1119 * negative error value.
1121 * Since: 3.0
1124 gnutls_pubkey_import_ecc_raw (gnutls_pubkey_t key,
1125 gnutls_ecc_curve_t curve,
1126 const gnutls_datum_t * x,
1127 const gnutls_datum_t * y)
1129 int ret;
1131 if (key == NULL)
1133 gnutls_assert ();
1134 return GNUTLS_E_INVALID_REQUEST;
1137 key->params.flags = curve;
1139 ret = _gnutls_ecc_curve_fill_params(curve, &key->params);
1140 if (ret < 0)
1141 return gnutls_assert_val(ret);
1143 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X], x->data, x->size))
1145 gnutls_assert ();
1146 ret = GNUTLS_E_MPI_SCAN_FAILED;
1147 goto cleanup;
1149 key->params.params_nr++;
1151 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_Y], y->data, y->size))
1153 gnutls_assert ();
1154 ret = GNUTLS_E_MPI_SCAN_FAILED;
1155 goto cleanup;
1157 key->params.params_nr++;
1158 key->pk_algorithm = GNUTLS_PK_EC;
1160 return 0;
1162 cleanup:
1163 gnutls_pk_params_release(&key->params);
1164 return ret;
1168 * gnutls_pubkey_import_ecc_x962:
1169 * @key: The structure to store the parsed key
1170 * @parameters: DER encoding of an ANSI X9.62 parameters
1171 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1173 * This function will convert the given elliptic curve parameters to a
1174 * #gnutls_pubkey_t. The output will be stored in @key.
1176 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1177 * negative error value.
1179 * Since: 3.0
1182 gnutls_pubkey_import_ecc_x962 (gnutls_pubkey_t key,
1183 const gnutls_datum_t * parameters,
1184 const gnutls_datum_t * ecpoint)
1186 int ret;
1188 if (key == NULL)
1190 gnutls_assert ();
1191 return GNUTLS_E_INVALID_REQUEST;
1194 key->params.params_nr = 0;
1196 ret = _gnutls_x509_read_ecc_params(parameters->data, parameters->size,
1197 &key->params);
1198 if (ret < 0)
1200 gnutls_assert ();
1201 goto cleanup;
1204 ret = _gnutls_ecc_ansi_x963_import(ecpoint->data, ecpoint->size,
1205 &key->params.params[ECC_X], &key->params.params[ECC_Y]);
1206 if (ret < 0)
1208 gnutls_assert ();
1209 goto cleanup;
1211 key->params.params_nr+=2;
1212 key->pk_algorithm = GNUTLS_PK_EC;
1214 return 0;
1216 cleanup:
1217 gnutls_pk_params_release(&key->params);
1218 return ret;
1222 * gnutls_pubkey_import_dsa_raw:
1223 * @key: The structure to store the parsed key
1224 * @p: holds the p
1225 * @q: holds the q
1226 * @g: holds the g
1227 * @y: holds the y
1229 * This function will convert the given DSA raw parameters to the
1230 * native #gnutls_pubkey_t format. The output will be stored
1231 * in @key.
1233 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1234 * negative error value.
1236 * Since: 2.12.0
1239 gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key,
1240 const gnutls_datum_t * p,
1241 const gnutls_datum_t * q,
1242 const gnutls_datum_t * g,
1243 const gnutls_datum_t * y)
1245 size_t siz = 0;
1247 if (key == NULL)
1249 gnutls_assert ();
1250 return GNUTLS_E_INVALID_REQUEST;
1253 gnutls_pk_params_init(&key->params);
1255 siz = p->size;
1256 if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz))
1258 gnutls_assert ();
1259 return GNUTLS_E_MPI_SCAN_FAILED;
1262 siz = q->size;
1263 if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz))
1265 gnutls_assert ();
1266 _gnutls_mpi_release (&key->params.params[0]);
1267 return GNUTLS_E_MPI_SCAN_FAILED;
1270 siz = g->size;
1271 if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz))
1273 gnutls_assert ();
1274 _gnutls_mpi_release (&key->params.params[1]);
1275 _gnutls_mpi_release (&key->params.params[0]);
1276 return GNUTLS_E_MPI_SCAN_FAILED;
1279 siz = y->size;
1280 if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz))
1282 gnutls_assert ();
1283 _gnutls_mpi_release (&key->params.params[2]);
1284 _gnutls_mpi_release (&key->params.params[1]);
1285 _gnutls_mpi_release (&key->params.params[0]);
1286 return GNUTLS_E_MPI_SCAN_FAILED;
1289 key->params.params_nr = DSA_PUBLIC_PARAMS;
1290 key->pk_algorithm = GNUTLS_PK_DSA;
1291 key->bits = pubkey_to_bits(GNUTLS_PK_DSA, &key->params);
1293 return 0;
1298 * gnutls_pubkey_verify_data:
1299 * @pubkey: Holds the public key
1300 * @flags: should be 0 for now
1301 * @data: holds the signed data
1302 * @signature: contains the signature
1304 * This function will verify the given signed data, using the
1305 * parameters from the certificate.
1307 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1308 * is returned, and zero or positive code on success.
1310 * Since: 2.12.0
1313 gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, unsigned int flags,
1314 const gnutls_datum_t * data,
1315 const gnutls_datum_t * signature)
1317 int ret;
1319 if (pubkey == NULL)
1321 gnutls_assert ();
1322 return GNUTLS_E_INVALID_REQUEST;
1325 ret = pubkey_verify_data( pubkey->pk_algorithm, GNUTLS_DIG_UNKNOWN, data, signature,
1326 &pubkey->params);
1327 if (ret < 0)
1329 gnutls_assert();
1332 return ret;
1336 * gnutls_pubkey_verify_data2:
1337 * @pubkey: Holds the public key
1338 * @algo: The signature algorithm used
1339 * @flags: should be 0 for now
1340 * @data: holds the signed data
1341 * @signature: contains the signature
1343 * This function will verify the given signed data, using the
1344 * parameters from the certificate.
1346 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1347 * is returned, and zero or positive code on success.
1349 * Since: 3.0
1352 gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey,
1353 gnutls_sign_algorithm_t algo,
1354 unsigned int flags,
1355 const gnutls_datum_t * data,
1356 const gnutls_datum_t * signature)
1358 int ret;
1360 if (pubkey == NULL)
1362 gnutls_assert ();
1363 return GNUTLS_E_INVALID_REQUEST;
1366 ret = pubkey_verify_data( pubkey->pk_algorithm, _gnutls_sign_get_hash_algorithm(algo), data, signature,
1367 &pubkey->params);
1368 if (ret < 0)
1370 gnutls_assert();
1373 return ret;
1377 * gnutls_pubkey_verify_hash:
1378 * @key: Holds the public key
1379 * @flags: should be 0 for now
1380 * @hash: holds the hash digest to be verified
1381 * @signature: contains the signature
1383 * This function will verify the given signed digest, using the
1384 * parameters from the public key. Use gnutls_pubkey_verify_hash2()
1385 * instead of this function.
1387 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1388 * is returned, and zero or positive code on success.
1390 * Since: 2.12.0
1393 gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
1394 const gnutls_datum_t * hash,
1395 const gnutls_datum_t * signature)
1397 gnutls_digest_algorithm_t algo;
1398 int ret;
1400 ret = gnutls_pubkey_get_verify_algorithm (key, signature, &algo);
1401 if (ret < 0)
1402 return gnutls_assert_val(ret);
1404 return gnutls_pubkey_verify_hash2(key, gnutls_pk_to_sign(key->pk_algorithm, algo),
1405 flags, hash, signature);
1410 * gnutls_pubkey_verify_hash:
1411 * @key: Holds the public key
1412 * @algo: The signature algorithm used
1413 * @flags: should be 0 for now
1414 * @hash: holds the hash digest to be verified
1415 * @signature: contains the signature
1417 * This function will verify the given signed digest, using the
1418 * parameters from the public key.
1420 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1421 * is returned, and zero or positive code on success.
1423 * Since: 3.0
1426 gnutls_pubkey_verify_hash2 (gnutls_pubkey_t key,
1427 gnutls_sign_algorithm_t algo,
1428 unsigned int flags,
1429 const gnutls_datum_t * hash,
1430 const gnutls_datum_t * signature)
1432 if (key == NULL)
1434 gnutls_assert ();
1435 return GNUTLS_E_INVALID_REQUEST;
1438 if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA)
1439 return _gnutls_rsa_verify (hash, signature, &key->params, 1);
1440 else
1442 return pubkey_verify_hashed_data (key->pk_algorithm, _gnutls_sign_get_hash_algorithm(algo),
1443 hash, signature, &key->params);
1448 * gnutls_pubkey_encrypt_data:
1449 * @key: Holds the public key
1450 * @flags: should be 0 for now
1451 * @plaintext: The data to be encrypted
1452 * @ciphertext: contains the encrypted data
1454 * This function will encrypt the given data, using the public
1455 * key.
1457 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1458 * negative error value.
1460 * Since: 3.0
1463 gnutls_pubkey_encrypt_data (gnutls_pubkey_t key, unsigned int flags,
1464 const gnutls_datum_t * plaintext,
1465 gnutls_datum_t * ciphertext)
1467 if (key == NULL || key->pk_algorithm != GNUTLS_PK_RSA)
1469 gnutls_assert ();
1470 return GNUTLS_E_INVALID_REQUEST;
1473 return _gnutls_pkcs1_rsa_encrypt (ciphertext, plaintext,
1474 &key->params,
1479 * gnutls_pubkey_get_verify_algorithm:
1480 * @key: Holds the certificate
1481 * @signature: contains the signature
1482 * @hash: The result of the call with the hash algorithm used for signature
1484 * This function will read the certifcate and the signed data to
1485 * determine the hash algorithm used to generate the signature.
1487 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1488 * negative error value.
1490 * Since: 2.12.0
1493 gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
1494 const gnutls_datum_t * signature,
1495 gnutls_digest_algorithm_t * hash)
1497 if (key == NULL)
1499 gnutls_assert ();
1500 return GNUTLS_E_INVALID_REQUEST;
1503 return _gnutls_x509_verify_algorithm (hash, signature,
1504 key->pk_algorithm,
1505 &key->params);
1509 /* Checks whether the public key given is compatible with the
1510 * signature algorithm used. The session is only used for audit logging, and
1511 * it may be null.
1513 int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session,
1514 gnutls_pubkey_t pubkey,
1515 gnutls_protocol_t ver,
1516 gnutls_sign_algorithm_t sign)
1518 unsigned int hash_size;
1519 unsigned int hash_algo;
1520 unsigned int sig_hash_size;
1522 if (pubkey->pk_algorithm == GNUTLS_PK_DSA)
1524 hash_algo = _gnutls_dsa_q_to_hash (pubkey->pk_algorithm, &pubkey->params, &hash_size);
1526 /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
1527 if (!_gnutls_version_has_selectable_sighash (ver))
1529 if (hash_algo != GNUTLS_DIG_SHA1)
1530 return gnutls_assert_val(GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
1532 else if (sign != GNUTLS_SIGN_UNKNOWN)
1534 sig_hash_size = _gnutls_hash_get_algo_len(_gnutls_sign_get_hash_algorithm(sign));
1535 if (sig_hash_size < hash_size)
1536 _gnutls_audit_log(session, "The hash size used in signature (%u) is less than the expected (%u)\n", sig_hash_size, hash_size);
1540 else if (pubkey->pk_algorithm == GNUTLS_PK_EC)
1542 if (_gnutls_version_has_selectable_sighash (ver) && sign != GNUTLS_SIGN_UNKNOWN)
1544 hash_algo = _gnutls_dsa_q_to_hash (pubkey->pk_algorithm, &pubkey->params, &hash_size);
1545 sig_hash_size = _gnutls_hash_get_algo_len(_gnutls_sign_get_hash_algorithm(sign));
1547 if (sig_hash_size < hash_size)
1548 _gnutls_audit_log(session, "The hash size used in signature (%u) is less than the expected (%u)\n", sig_hash_size, hash_size);
1553 return 0;
1556 /* Returns zero if the public key has more than 512 bits */
1557 int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey)
1559 if (pubkey->pk_algorithm == GNUTLS_PK_RSA && _gnutls_mpi_get_nbits (pubkey->params.params[0]) > 512)
1560 return 0;
1561 else
1562 return GNUTLS_E_INVALID_REQUEST; /* doesn't matter */
1566 /* Returns the public key.
1569 _gnutls_pubkey_get_mpis (gnutls_pubkey_t key,
1570 gnutls_pk_params_st * params)
1572 return _gnutls_pk_params_copy(params, &key->params);
1575 /* if hash==MD5 then we do RSA-MD5
1576 * if hash==SHA then we do RSA-SHA
1577 * params[0] is modulus
1578 * params[1] is public key
1580 static int
1581 _pkcs1_rsa_verify_sig (gnutls_digest_algorithm_t hash_algo,
1582 const gnutls_datum_t * text,
1583 const gnutls_datum_t * prehash,
1584 const gnutls_datum_t * signature,
1585 gnutls_pk_params_st * params)
1587 gnutls_digest_algorithm_t hash = GNUTLS_DIG_UNKNOWN;
1588 int ret;
1589 uint8_t digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE], *cmp;
1590 unsigned int digest_size;
1591 digest_hd_st hd;
1592 gnutls_datum_t decrypted;
1594 ret =
1595 _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, 1);
1596 if (ret < 0)
1598 gnutls_assert ();
1599 return ret;
1602 /* decrypted is a BER encoded data of type DigestInfo
1605 digest_size = sizeof (digest);
1606 if ((ret =
1607 decode_ber_digest_info (&decrypted, &hash, digest, &digest_size)) != 0)
1609 gnutls_assert ();
1610 _gnutls_free_datum (&decrypted);
1611 return ret;
1614 _gnutls_free_datum (&decrypted);
1616 if (hash_algo != GNUTLS_DIG_UNKNOWN && hash_algo != hash)
1617 return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
1619 if (digest_size != _gnutls_hash_get_algo_len (hash))
1621 gnutls_assert ();
1622 return GNUTLS_E_ASN1_GENERIC_ERROR;
1625 if (prehash && prehash->data && prehash->size == digest_size)
1627 cmp = prehash->data;
1629 else
1631 if (!text)
1633 gnutls_assert ();
1634 return GNUTLS_E_INVALID_REQUEST;
1637 ret = _gnutls_hash_init (&hd, hash);
1638 if (ret < 0)
1640 gnutls_assert ();
1641 return ret;
1644 _gnutls_hash (&hd, text->data, text->size);
1645 _gnutls_hash_deinit (&hd, md);
1647 cmp = md;
1650 if (memcmp (cmp, digest, digest_size) != 0)
1652 gnutls_assert ();
1653 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1656 return 0;
1659 /* Hashes input data and verifies a signature.
1661 static int
1662 dsa_verify_hashed_data (const gnutls_datum_t * hash,
1663 const gnutls_datum_t * signature,
1664 gnutls_pk_algorithm_t pk,
1665 gnutls_pk_params_st* params)
1667 gnutls_datum_t digest;
1668 unsigned int algo;
1669 unsigned int hash_len;
1671 algo = _gnutls_dsa_q_to_hash (pk, params, &hash_len);
1673 /* SHA1 or better allowed */
1674 if (!hash->data || hash->size < hash_len)
1676 gnutls_assert();
1677 _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);
1679 if (hash->size != 20) /* SHA1 is allowed */
1680 return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
1683 digest.data = hash->data;
1684 digest.size = hash->size;
1686 return _gnutls_pk_verify (pk, &digest, signature, params);
1689 static int
1690 dsa_verify_data (gnutls_pk_algorithm_t pk,
1691 gnutls_digest_algorithm_t algo,
1692 const gnutls_datum_t * data,
1693 const gnutls_datum_t * signature,
1694 gnutls_pk_params_st* params)
1696 int ret;
1697 uint8_t _digest[MAX_HASH_SIZE];
1698 gnutls_datum_t digest;
1699 digest_hd_st hd;
1701 if (algo == GNUTLS_DIG_UNKNOWN)
1702 algo = _gnutls_dsa_q_to_hash (pk, params, NULL);
1704 ret = _gnutls_hash_init (&hd, algo);
1705 if (ret < 0)
1706 return gnutls_assert_val(ret);
1708 _gnutls_hash (&hd, data->data, data->size);
1709 _gnutls_hash_deinit (&hd, _digest);
1711 digest.data = _digest;
1712 digest.size = _gnutls_hash_get_algo_len(algo);
1714 return _gnutls_pk_verify (pk, &digest, signature, params);
1717 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
1718 * not verified, or 1 otherwise.
1721 pubkey_verify_hashed_data (gnutls_pk_algorithm_t pk,
1722 gnutls_digest_algorithm_t hash_algo,
1723 const gnutls_datum_t * hash,
1724 const gnutls_datum_t * signature,
1725 gnutls_pk_params_st * issuer_params)
1728 switch (pk)
1730 case GNUTLS_PK_RSA:
1732 if (_pkcs1_rsa_verify_sig
1733 (hash_algo, NULL, hash, signature, issuer_params) != 0)
1735 gnutls_assert ();
1736 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1739 return 1;
1740 break;
1742 case GNUTLS_PK_EC:
1743 case GNUTLS_PK_DSA:
1744 if (dsa_verify_hashed_data(hash, signature, pk, issuer_params) != 0)
1746 gnutls_assert ();
1747 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1750 return 1;
1751 break;
1752 default:
1753 gnutls_assert ();
1754 return GNUTLS_E_INTERNAL_ERROR;
1759 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
1760 * not verified, or 1 otherwise.
1763 pubkey_verify_data (gnutls_pk_algorithm_t pk,
1764 gnutls_digest_algorithm_t algo,
1765 const gnutls_datum_t * data,
1766 const gnutls_datum_t * signature,
1767 gnutls_pk_params_st * issuer_params)
1770 switch (pk)
1772 case GNUTLS_PK_RSA:
1774 if (_pkcs1_rsa_verify_sig
1775 (algo, data, NULL, signature, issuer_params) != 0)
1777 gnutls_assert ();
1778 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1781 return 1;
1782 break;
1784 case GNUTLS_PK_EC:
1785 case GNUTLS_PK_DSA:
1786 if (dsa_verify_data(pk, algo, data, signature, issuer_params) != 0)
1788 gnutls_assert ();
1789 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1792 return 1;
1793 break;
1794 default:
1795 gnutls_assert ();
1796 return GNUTLS_E_INTERNAL_ERROR;
1801 gnutls_digest_algorithm_t
1802 _gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* params,
1803 unsigned int* hash_len)
1805 int bits = 0;
1807 if (algo == GNUTLS_PK_DSA)
1808 bits = _gnutls_mpi_get_nbits (params->params[1]);
1809 else if (algo == GNUTLS_PK_EC)
1810 bits = gnutls_ecc_curve_get_size(params->flags)*8;
1812 if (bits <= 160)
1814 if (hash_len) *hash_len = 20;
1815 return GNUTLS_DIG_SHA1;
1817 else if (bits <= 192)
1819 if (hash_len) *hash_len = 24;
1820 return GNUTLS_DIG_SHA256;
1822 else if (bits <= 224)
1824 if (hash_len) *hash_len = 28;
1825 return GNUTLS_DIG_SHA256;
1827 else if (bits <= 256)
1829 if (hash_len) *hash_len = 32;
1830 return GNUTLS_DIG_SHA256;
1832 else if (bits <= 384)
1834 if (hash_len) *hash_len = 48;
1835 return GNUTLS_DIG_SHA384;
1837 else
1839 if (hash_len) *hash_len = 64;
1840 return GNUTLS_DIG_SHA512;