Added test on DTLS SRTP functions.
[gnutls.git] / lib / gnutls_pubkey.c
blobe9dbcbe9f1fdf856210cdfb6d34a3ab22de616a9
1 /*
2 * GnuTLS public key 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
45 int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st* params)
47 switch(pk)
49 case GNUTLS_PK_RSA:
50 return _gnutls_mpi_get_nbits(params->params[0]);
51 case GNUTLS_PK_DSA:
52 return _gnutls_mpi_get_nbits(params->params[3]);
53 case GNUTLS_PK_EC:
54 return gnutls_ecc_curve_get_size(params->flags)*8;
55 default:
56 return 0;
60 /**
61 * gnutls_pubkey_get_pk_algorithm:
62 * @key: should contain a #gnutls_pubkey_t structure
63 * @bits: If set will return the number of bits of the parameters (may be NULL)
65 * This function will return the public key algorithm of a public
66 * key and if possible will return a number of bits that indicates
67 * the security parameter of the key.
69 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
70 * success, or a negative error code on error.
72 * Since: 2.12.0
73 **/
74 int
75 gnutls_pubkey_get_pk_algorithm (gnutls_pubkey_t key, unsigned int *bits)
77 if (bits)
78 *bits = key->bits;
80 return key->pk_algorithm;
83 /**
84 * gnutls_pubkey_get_key_usage:
85 * @key: should contain a #gnutls_pubkey_t structure
86 * @usage: If set will return the number of bits of the parameters (may be NULL)
88 * This function will return the key usage of the public key.
90 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
91 * negative error value.
93 * Since: 2.12.0
94 **/
95 int
96 gnutls_pubkey_get_key_usage (gnutls_pubkey_t key, unsigned int *usage)
98 if (usage)
99 *usage = key->key_usage;
101 return 0;
105 * gnutls_pubkey_init:
106 * @key: The structure to be initialized
108 * This function will initialize an public key structure.
110 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
111 * negative error value.
113 * Since: 2.12.0
116 gnutls_pubkey_init (gnutls_pubkey_t * key)
118 *key = gnutls_calloc (1, sizeof (struct gnutls_pubkey_st));
119 if (*key == NULL)
121 gnutls_assert ();
122 return GNUTLS_E_MEMORY_ERROR;
125 return 0;
129 * gnutls_pubkey_deinit:
130 * @key: The structure to be deinitialized
132 * This function will deinitialize a public key structure.
134 * Since: 2.12.0
136 void
137 gnutls_pubkey_deinit (gnutls_pubkey_t key)
139 if (!key)
140 return;
141 gnutls_pk_params_release (&key->params);
142 gnutls_free (key);
146 * gnutls_pubkey_import_x509:
147 * @key: The public key
148 * @crt: The certificate to be imported
149 * @flags: should be zero
151 * This function will import the given public key to the abstract
152 * #gnutls_pubkey_t structure.
154 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
155 * negative error value.
157 * Since: 2.12.0
160 gnutls_pubkey_import_x509 (gnutls_pubkey_t key, gnutls_x509_crt_t crt,
161 unsigned int flags)
163 int ret;
165 key->pk_algorithm = gnutls_x509_crt_get_pk_algorithm (crt, &key->bits);
167 ret = gnutls_x509_crt_get_key_usage (crt, &key->key_usage, NULL);
168 if (ret < 0)
169 key->key_usage = 0;
171 ret = _gnutls_x509_crt_get_mpis (crt, &key->params);
172 if (ret < 0)
174 gnutls_assert ();
175 return ret;
178 return 0;
182 * gnutls_pubkey_import_privkey:
183 * @key: The public key
184 * @pkey: The private key
185 * @usage: GNUTLS_KEY_* key usage flags.
186 * @flags: should be zero
188 * Imports the public key from a private. This function will import
189 * the given public key to the abstract #gnutls_pubkey_t structure.
191 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
192 * negative error value.
194 * Since: 2.12.0
197 gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey,
198 unsigned int usage, unsigned int flags)
200 key->pk_algorithm = gnutls_privkey_get_pk_algorithm (pkey, &key->bits);
202 key->key_usage = usage;
204 return _gnutls_privkey_get_public_mpis (pkey, &key->params);
208 * gnutls_pubkey_get_preferred_hash_algorithm:
209 * @key: Holds the certificate
210 * @hash: The result of the call with the hash algorithm used for signature
211 * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL.
213 * This function will read the certifcate and return the appropriate digest
214 * algorithm to use for signing with this certificate. Some certificates (i.e.
215 * DSA might not be able to sign without the preferred algorithm).
217 * Returns: the 0 if the hash algorithm is found. A negative error code is
218 * returned on error.
220 * Since: 2.12.0
223 gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key,
224 gnutls_digest_algorithm_t *
225 hash, unsigned int *mand)
227 int ret;
229 if (key == NULL)
231 gnutls_assert ();
232 return GNUTLS_E_INVALID_REQUEST;
235 ret = _gnutls_pk_get_hash_algorithm (key->pk_algorithm,
236 &key->params,
237 hash, mand);
239 return ret;
242 #ifdef ENABLE_PKCS11
245 * gnutls_pubkey_import_pkcs11:
246 * @key: The public key
247 * @obj: The parameters to be imported
248 * @flags: should be zero
250 * Imports a public key from a pkcs11 key. This function will import
251 * the given public key to the abstract #gnutls_pubkey_t structure.
253 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
254 * negative error value.
256 * Since: 2.12.0
259 gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key,
260 gnutls_pkcs11_obj_t obj, unsigned int flags)
262 int ret, type;
264 type = gnutls_pkcs11_obj_get_type (obj);
265 if (type != GNUTLS_PKCS11_OBJ_PUBKEY && type != GNUTLS_PKCS11_OBJ_X509_CRT)
267 gnutls_assert ();
268 return GNUTLS_E_INVALID_REQUEST;
271 if (type == GNUTLS_PKCS11_OBJ_X509_CRT)
273 gnutls_x509_crt_t xcrt;
275 ret = gnutls_x509_crt_init (&xcrt);
276 if (ret < 0)
278 gnutls_assert()
279 return ret;
282 ret = gnutls_x509_crt_import_pkcs11 (xcrt, obj);
283 if (ret < 0)
285 gnutls_assert();
286 goto cleanup_crt;
289 ret = gnutls_pubkey_import_x509 (key, xcrt, 0);
290 if (ret < 0)
292 gnutls_assert();
293 goto cleanup_crt;
296 gnutls_x509_crt_get_key_usage(xcrt, &key->key_usage, NULL);
298 ret = 0;
299 cleanup_crt:
300 gnutls_x509_crt_deinit(xcrt);
301 return ret;
304 key->key_usage = obj->key_usage;
306 switch (obj->pk_algorithm)
308 case GNUTLS_PK_RSA:
309 ret = gnutls_pubkey_import_rsa_raw (key, &obj->pubkey[0],
310 &obj->pubkey[1]);
311 break;
312 case GNUTLS_PK_DSA:
313 ret = gnutls_pubkey_import_dsa_raw (key, &obj->pubkey[0],
314 &obj->pubkey[1],
315 &obj->pubkey[2], &obj->pubkey[3]);
316 break;
317 case GNUTLS_PK_EC:
318 ret = gnutls_pubkey_import_ecc_x962 (key, &obj->pubkey[0],
319 &obj->pubkey[1]);
320 break;
321 default:
322 gnutls_assert ();
323 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
326 if (ret < 0)
328 gnutls_assert ();
329 return ret;
332 return 0;
335 #endif /* ENABLE_PKCS11 */
337 #ifdef ENABLE_OPENPGP
340 * gnutls_pubkey_import_openpgp:
341 * @key: The public key
342 * @crt: The certificate to be imported
343 * @flags: should be zero
345 * Imports a public key from an openpgp key. This function will import
346 * the given public key to the abstract #gnutls_pubkey_t
347 * structure. The subkey set as preferred will be imported or the
348 * master key otherwise.
350 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
351 * negative error value.
353 * Since: 2.12.0
356 gnutls_pubkey_import_openpgp (gnutls_pubkey_t key,
357 gnutls_openpgp_crt_t crt,
358 unsigned int flags)
360 int ret, idx;
361 uint32_t kid32[2];
362 uint32_t *k;
363 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
365 ret = gnutls_openpgp_crt_get_preferred_key_id (crt, keyid);
366 if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR)
368 key->pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (crt, &key->bits);
369 key->openpgp_key_id_set = OPENPGP_KEY_PRIMARY;
371 ret = gnutls_openpgp_crt_get_key_id(crt, key->openpgp_key_id);
372 if (ret < 0)
373 return gnutls_assert_val(ret);
375 ret = gnutls_openpgp_crt_get_key_usage (crt, &key->key_usage);
376 if (ret < 0)
377 key->key_usage = 0;
379 k = NULL;
381 else
383 if (ret < 0)
385 gnutls_assert ();
386 return ret;
388 key->openpgp_key_id_set = OPENPGP_KEY_SUBKEY;
390 KEYID_IMPORT (kid32, keyid);
391 k = kid32;
393 idx = gnutls_openpgp_crt_get_subkey_idx (crt, keyid);
395 ret = gnutls_openpgp_crt_get_subkey_id(crt, idx, key->openpgp_key_id);
396 if (ret < 0)
397 return gnutls_assert_val(ret);
399 ret = gnutls_openpgp_crt_get_subkey_usage (crt, idx, &key->key_usage);
400 if (ret < 0)
401 key->key_usage = 0;
403 key->pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm (crt, idx, NULL);
406 ret =
407 _gnutls_openpgp_crt_get_mpis (crt, k, &key->params);
408 if (ret < 0)
409 return gnutls_assert_val(ret);
411 return 0;
415 * gnutls_pubkey_get_openpgp_key_id:
416 * @key: Holds the public key
417 * @flags: should be 0 for now
418 * @output_data: will contain the key ID
419 * @output_data_size: holds the size of output_data (and will be
420 * replaced by the actual size of parameters)
421 * @subkey: Will be non zero if the key ID corresponds to a subkey
423 * This function returned the OpenPGP key ID of the corresponding key.
424 * The key is a unique ID that depends on the public
425 * key parameters.
427 * If the buffer provided is not long enough to hold the output, then
428 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
429 * be returned. The output is %GNUTLS_OPENPGP_KEYID_SIZE bytes long.
431 * Returns: In case of failure a negative error code will be
432 * returned, and 0 on success.
434 * Since: 3.0
437 gnutls_pubkey_get_openpgp_key_id (gnutls_pubkey_t key, unsigned int flags,
438 unsigned char *output_data,
439 size_t * output_data_size,
440 unsigned int *subkey)
442 if (key == NULL)
444 gnutls_assert ();
445 return GNUTLS_E_INVALID_REQUEST;
448 if (*output_data_size < sizeof(key->openpgp_key_id))
450 *output_data_size = sizeof(key->openpgp_key_id);
451 return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
454 if (key->openpgp_key_id_set == 0)
455 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
457 if (key->openpgp_key_id_set == OPENPGP_KEY_SUBKEY)
458 if (subkey) *subkey = 1;
460 if (output_data)
462 memcpy(output_data, key->openpgp_key_id, sizeof(key->openpgp_key_id));
464 *output_data_size = sizeof(key->openpgp_key_id);
466 return 0;
470 * gnutls_pubkey_import_openpgp_raw:
471 * @pkey: The public key
472 * @data: The public key data to be imported
473 * @format: The format of the public key
474 * @keyid: The key id to use (optional)
475 * @flags: Should be zero
477 * This function will import the given public key to the abstract
478 * #gnutls_pubkey_t structure.
480 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
481 * negative error value.
483 * Since: 3.1.3
485 int gnutls_pubkey_import_openpgp_raw (gnutls_pubkey_t pkey,
486 const gnutls_datum_t * data,
487 gnutls_openpgp_crt_fmt_t format,
488 const gnutls_openpgp_keyid_t keyid,
489 unsigned int flags)
491 gnutls_openpgp_crt_t xpriv;
492 int ret;
494 ret = gnutls_openpgp_crt_init(&xpriv);
495 if (ret < 0)
496 return gnutls_assert_val(ret);
498 ret = gnutls_openpgp_crt_import(xpriv, data, format);
499 if (ret < 0)
501 gnutls_assert();
502 goto cleanup;
505 if(keyid)
507 ret = gnutls_openpgp_crt_set_preferred_key_id(xpriv, keyid);
508 if (ret < 0)
510 gnutls_assert();
511 goto cleanup;
515 ret = gnutls_pubkey_import_openpgp(pkey, xpriv, flags);
516 if (ret < 0)
518 gnutls_assert();
519 goto cleanup;
522 ret = 0;
524 cleanup:
525 gnutls_openpgp_crt_deinit(xpriv);
527 return ret;
530 #endif
533 * gnutls_pubkey_export:
534 * @key: Holds the certificate
535 * @format: the format of output params. One of PEM or DER.
536 * @output_data: will contain a certificate PEM or DER encoded
537 * @output_data_size: holds the size of output_data (and will be
538 * replaced by the actual size of parameters)
540 * This function will export the public key to DER or PEM format.
541 * The contents of the exported data is the SubjectPublicKeyInfo
542 * X.509 structure.
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.
548 * If the structure is PEM encoded, it will have a header
549 * of "BEGIN CERTIFICATE".
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_export (gnutls_pubkey_t key,
558 gnutls_x509_crt_fmt_t format, void *output_data,
559 size_t * output_data_size)
561 int result;
562 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
564 if (key == NULL)
566 gnutls_assert ();
567 return GNUTLS_E_INVALID_REQUEST;
570 if ((result = asn1_create_element
571 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
572 != ASN1_SUCCESS)
574 gnutls_assert ();
575 return _gnutls_asn2err (result);
578 result =
579 _gnutls_x509_encode_and_copy_PKI_params (spk, "",
580 key->pk_algorithm,
581 &key->params);
582 if (result < 0)
584 gnutls_assert ();
585 goto cleanup;
588 result = _gnutls_x509_export_int_named (spk, "",
589 format, PK_PEM_HEADER,
590 output_data, output_data_size);
591 if (result < 0)
593 gnutls_assert ();
594 goto cleanup;
597 result = 0;
599 cleanup:
600 asn1_delete_structure (&spk);
602 return result;
606 * gnutls_pubkey_export2:
607 * @key: Holds the certificate
608 * @format: the format of output params. One of PEM or DER.
609 * @out: will contain a certificate PEM or DER encoded
611 * This function will export the public key to DER or PEM format.
612 * The contents of the exported data is the SubjectPublicKeyInfo
613 * X.509 structure.
615 * The output buffer will be allocated using gnutls_malloc().
617 * If the structure is PEM encoded, it will have a header
618 * of "BEGIN CERTIFICATE".
620 * Returns: In case of failure a negative error code will be
621 * returned, and 0 on success.
623 * Since: 3.1.3
626 gnutls_pubkey_export2 (gnutls_pubkey_t key,
627 gnutls_x509_crt_fmt_t format,
628 gnutls_datum_t * out)
630 int result;
631 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
633 if (key == NULL)
635 gnutls_assert ();
636 return GNUTLS_E_INVALID_REQUEST;
639 if ((result = asn1_create_element
640 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
641 != ASN1_SUCCESS)
643 gnutls_assert ();
644 return _gnutls_asn2err (result);
647 result =
648 _gnutls_x509_encode_and_copy_PKI_params (spk, "",
649 key->pk_algorithm,
650 &key->params);
651 if (result < 0)
653 gnutls_assert ();
654 goto cleanup;
657 result = _gnutls_x509_export_int_named2 (spk, "",
658 format, PK_PEM_HEADER, out);
659 if (result < 0)
661 gnutls_assert ();
662 goto cleanup;
665 result = 0;
667 cleanup:
668 asn1_delete_structure (&spk);
670 return result;
674 * gnutls_pubkey_get_key_id:
675 * @key: Holds the public key
676 * @flags: should be 0 for now
677 * @output_data: will contain the key ID
678 * @output_data_size: holds the size of output_data (and will be
679 * replaced by the actual size of parameters)
681 * This function will return a unique ID that depends on the public
682 * key parameters. This ID can be used in checking whether a
683 * certificate corresponds to the given public key.
685 * If the buffer provided is not long enough to hold the output, then
686 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
687 * be returned. The output will normally be a SHA-1 hash output,
688 * which is 20 bytes.
690 * Returns: In case of failure a negative error code will be
691 * returned, and 0 on success.
693 * Since: 2.12.0
696 gnutls_pubkey_get_key_id (gnutls_pubkey_t key, unsigned int flags,
697 unsigned char *output_data,
698 size_t * output_data_size)
700 int ret = 0;
702 if (key == NULL)
704 gnutls_assert ();
705 return GNUTLS_E_INVALID_REQUEST;
708 ret =
709 _gnutls_get_key_id (key->pk_algorithm, &key->params,
710 output_data, output_data_size);
711 if (ret < 0)
713 gnutls_assert ();
714 return ret;
717 return 0;
721 * gnutls_pubkey_get_pk_rsa_raw:
722 * @key: Holds the certificate
723 * @m: will hold the modulus
724 * @e: will hold the public exponent
726 * This function will export the RSA public key's parameters found in
727 * the given structure. The new parameters will be allocated using
728 * gnutls_malloc() and will be stored in the appropriate datum.
730 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
732 * Since: 2.12.0
735 gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t key,
736 gnutls_datum_t * m, gnutls_datum_t * e)
738 int ret;
740 if (key == NULL)
742 gnutls_assert ();
743 return GNUTLS_E_INVALID_REQUEST;
746 if (key->pk_algorithm != GNUTLS_PK_RSA)
748 gnutls_assert ();
749 return GNUTLS_E_INVALID_REQUEST;
752 ret = _gnutls_mpi_dprint_lz (key->params.params[0], m);
753 if (ret < 0)
755 gnutls_assert ();
756 return ret;
759 ret = _gnutls_mpi_dprint_lz (key->params.params[1], e);
760 if (ret < 0)
762 gnutls_assert ();
763 _gnutls_free_datum (m);
764 return ret;
767 return 0;
771 * gnutls_pubkey_get_pk_dsa_raw:
772 * @key: Holds the public key
773 * @p: will hold the p
774 * @q: will hold the q
775 * @g: will hold the g
776 * @y: will hold the y
778 * This function will export the DSA public key's parameters found in
779 * the given certificate. The new parameters will be allocated using
780 * gnutls_malloc() and will be stored in the appropriate datum.
782 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
784 * Since: 2.12.0
787 gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
788 gnutls_datum_t * p, gnutls_datum_t * q,
789 gnutls_datum_t * g, gnutls_datum_t * y)
791 int ret;
793 if (key == NULL)
795 gnutls_assert ();
796 return GNUTLS_E_INVALID_REQUEST;
799 if (key->pk_algorithm != GNUTLS_PK_DSA)
801 gnutls_assert ();
802 return GNUTLS_E_INVALID_REQUEST;
805 /* P */
806 ret = _gnutls_mpi_dprint_lz (key->params.params[0], p);
807 if (ret < 0)
809 gnutls_assert ();
810 return ret;
813 /* Q */
814 ret = _gnutls_mpi_dprint_lz (key->params.params[1], q);
815 if (ret < 0)
817 gnutls_assert ();
818 _gnutls_free_datum (p);
819 return ret;
823 /* G */
824 ret = _gnutls_mpi_dprint_lz (key->params.params[2], g);
825 if (ret < 0)
827 gnutls_assert ();
828 _gnutls_free_datum (p);
829 _gnutls_free_datum (q);
830 return ret;
834 /* Y */
835 ret = _gnutls_mpi_dprint_lz (key->params.params[3], y);
836 if (ret < 0)
838 gnutls_assert ();
839 _gnutls_free_datum (p);
840 _gnutls_free_datum (g);
841 _gnutls_free_datum (q);
842 return ret;
845 return 0;
849 * gnutls_pubkey_get_pk_ecc_raw:
850 * @key: Holds the public key
851 * @curve: will hold the curve
852 * @x: will hold x
853 * @y: will hold y
855 * This function will export the ECC public key's parameters found in
856 * the given certificate. The new parameters will be allocated using
857 * gnutls_malloc() and will be stored in the appropriate datum.
859 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
861 * Since: 3.0
864 gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
865 gnutls_datum_t * x, gnutls_datum_t * y)
867 int ret;
869 if (key == NULL)
871 gnutls_assert ();
872 return GNUTLS_E_INVALID_REQUEST;
875 if (key->pk_algorithm != GNUTLS_PK_EC)
877 gnutls_assert ();
878 return GNUTLS_E_INVALID_REQUEST;
881 *curve = key->params.flags;
883 /* X */
884 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_X], x);
885 if (ret < 0)
887 gnutls_assert ();
888 return ret;
891 /* Y */
892 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_Y], y);
893 if (ret < 0)
895 gnutls_assert ();
896 _gnutls_free_datum (x);
897 return ret;
900 return 0;
904 * gnutls_pubkey_get_pk_ecc_x962:
905 * @key: Holds the public key
906 * @parameters: DER encoding of an ANSI X9.62 parameters
907 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
909 * This function will export the ECC public key's parameters found in
910 * the given certificate. The new parameters will be allocated using
911 * gnutls_malloc() and will be stored in the appropriate datum.
913 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
915 * Since: 3.0
917 int gnutls_pubkey_get_pk_ecc_x962 (gnutls_pubkey_t key, gnutls_datum_t* parameters,
918 gnutls_datum_t * ecpoint)
920 int ret;
922 if (key == NULL || key->pk_algorithm != GNUTLS_PK_EC)
923 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
925 ret = _gnutls_x509_write_ecc_pubkey(&key->params, ecpoint);
926 if (ret < 0)
927 return gnutls_assert_val(ret);
929 ret = _gnutls_x509_write_ecc_params(&key->params, parameters);
930 if (ret < 0)
932 _gnutls_free_datum(ecpoint);
933 return gnutls_assert_val(ret);
936 return 0;
940 * gnutls_pubkey_import:
941 * @key: The structure to store the parsed public key.
942 * @data: The DER or PEM encoded certificate.
943 * @format: One of DER or PEM
945 * This function will import the provided public key in
946 * a SubjectPublicKeyInfo X.509 structure to a native
947 * %gnutls_pubkey_t structure. The output will be stored
948 * in @key. If the public key is PEM encoded it should have a header
949 * of "PUBLIC KEY".
951 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
952 * negative error value.
954 * Since: 2.12.0
957 gnutls_pubkey_import (gnutls_pubkey_t key,
958 const gnutls_datum_t * data,
959 gnutls_x509_crt_fmt_t format)
961 int result = 0, need_free = 0;
962 gnutls_datum_t _data;
963 ASN1_TYPE spk;
965 if (key == NULL)
967 gnutls_assert ();
968 return GNUTLS_E_INVALID_REQUEST;
971 _data.data = data->data;
972 _data.size = data->size;
974 /* If the Certificate is in PEM format then decode it
976 if (format == GNUTLS_X509_FMT_PEM)
978 /* Try the first header */
979 result =
980 _gnutls_fbase64_decode (PK_PEM_HEADER, data->data, data->size, &_data);
982 if (result < 0)
984 gnutls_assert ();
985 return result;
988 need_free = 1;
991 if ((result = asn1_create_element
992 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
993 != ASN1_SUCCESS)
995 gnutls_assert ();
996 result = _gnutls_asn2err (result);
997 goto cleanup;
1000 result = asn1_der_decoding (&spk, _data.data, _data.size, NULL);
1001 if (result != ASN1_SUCCESS)
1003 gnutls_assert ();
1004 result = _gnutls_asn2err (result);
1005 goto cleanup;
1008 result = _gnutls_get_asn_mpis (spk, "", &key->params);
1009 if (result < 0)
1011 gnutls_assert ();
1012 goto cleanup;
1015 /* this has already been called by get_asn_mpis() thus it cannot
1016 * fail.
1018 key->pk_algorithm = _gnutls_x509_get_pk_algorithm (spk, "", NULL);
1019 key->bits = pubkey_to_bits(key->pk_algorithm, &key->params);
1021 result = 0;
1023 cleanup:
1024 asn1_delete_structure (&spk);
1026 if (need_free)
1027 _gnutls_free_datum (&_data);
1028 return result;
1032 * gnutls_x509_crt_set_pubkey:
1033 * @crt: should contain a #gnutls_x509_crt_t structure
1034 * @key: holds a public key
1036 * This function will set the public parameters from the given public
1037 * key to the request.
1039 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1040 * negative error value.
1042 * Since: 2.12.0
1045 gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, gnutls_pubkey_t key)
1047 int result;
1049 if (crt == NULL)
1051 gnutls_assert ();
1052 return GNUTLS_E_INVALID_REQUEST;
1055 result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
1056 "tbsCertificate.subjectPublicKeyInfo",
1057 key->pk_algorithm,
1058 &key->params);
1060 if (result < 0)
1062 gnutls_assert ();
1063 return result;
1066 if (key->key_usage)
1067 gnutls_x509_crt_set_key_usage (crt, key->key_usage);
1069 return 0;
1073 * gnutls_x509_crq_set_pubkey:
1074 * @crq: should contain a #gnutls_x509_crq_t structure
1075 * @key: holds a public key
1077 * This function will set the public parameters from the given public
1078 * key to the request.
1080 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1081 * negative error value.
1083 * Since: 2.12.0
1086 gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key)
1088 int result;
1090 if (crq == NULL)
1092 gnutls_assert ();
1093 return GNUTLS_E_INVALID_REQUEST;
1096 result = _gnutls_x509_encode_and_copy_PKI_params
1097 (crq->crq,
1098 "certificationRequestInfo.subjectPKInfo",
1099 key->pk_algorithm, &key->params);
1101 if (result < 0)
1103 gnutls_assert ();
1104 return result;
1107 if (key->key_usage)
1108 gnutls_x509_crq_set_key_usage (crq, key->key_usage);
1110 return 0;
1114 * gnutls_pubkey_set_key_usage:
1115 * @key: a certificate of type #gnutls_x509_crt_t
1116 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
1118 * This function will set the key usage flags of the public key. This
1119 * is only useful if the key is to be exported to a certificate or
1120 * certificate request.
1122 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1123 * negative error value.
1125 * Since: 2.12.0
1128 gnutls_pubkey_set_key_usage (gnutls_pubkey_t key, unsigned int usage)
1130 key->key_usage = usage;
1132 return 0;
1135 #ifdef ENABLE_PKCS11
1138 * gnutls_pubkey_import_pkcs11_url:
1139 * @key: A key of type #gnutls_pubkey_t
1140 * @url: A PKCS 11 url
1141 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1143 * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
1144 * structure.
1146 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1147 * negative error value.
1149 * Since: 2.12.0
1152 gnutls_pubkey_import_pkcs11_url (gnutls_pubkey_t key, const char *url,
1153 unsigned int flags)
1155 gnutls_pkcs11_obj_t pcrt;
1156 int ret;
1158 ret = gnutls_pkcs11_obj_init (&pcrt);
1159 if (ret < 0)
1161 gnutls_assert ();
1162 return ret;
1165 if (key->pin.cb)
1166 gnutls_pkcs11_obj_set_pin_function(pcrt, key->pin.cb, key->pin.data);
1168 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
1169 if (ret < 0)
1171 gnutls_assert ();
1172 goto cleanup;
1175 ret = gnutls_pubkey_import_pkcs11 (key, pcrt, 0);
1176 if (ret < 0)
1178 gnutls_assert ();
1179 goto cleanup;
1182 ret = 0;
1183 cleanup:
1185 gnutls_pkcs11_obj_deinit (pcrt);
1187 return ret;
1190 #endif /* ENABLE_PKCS11 */
1193 * gnutls_pubkey_import_url:
1194 * @key: A key of type #gnutls_pubkey_t
1195 * @url: A PKCS 11 url
1196 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1198 * This function will import a PKCS11 certificate or a TPM key
1199 * as a public key.
1201 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1202 * negative error value.
1204 * Since: 3.1.0
1207 gnutls_pubkey_import_url (gnutls_pubkey_t key, const char *url,
1208 unsigned int flags)
1210 #ifdef ENABLE_PKCS11
1211 if (strstr(url, "pkcs11:") != NULL)
1212 return gnutls_pubkey_import_pkcs11_url(key, url, flags);
1213 #endif
1214 #ifdef HAVE_TROUSERS
1215 if (strstr(url, "tpmkey:") != NULL)
1216 return gnutls_pubkey_import_tpm_url(key, url, NULL, 0);
1217 #endif
1218 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1222 * gnutls_pubkey_import_rsa_raw:
1223 * @key: Is a structure will hold the parameters
1224 * @m: holds the modulus
1225 * @e: holds the public exponent
1227 * This function will replace the parameters in the given structure.
1228 * The new parameters should be stored in the appropriate
1229 * gnutls_datum.
1231 * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
1233 * Since: 2.12.0
1236 gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key,
1237 const gnutls_datum_t * m,
1238 const gnutls_datum_t * e)
1240 size_t siz = 0;
1242 if (key == NULL)
1244 gnutls_assert ();
1245 return GNUTLS_E_INVALID_REQUEST;
1248 gnutls_pk_params_init(&key->params);
1250 siz = m->size;
1251 if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz))
1253 gnutls_assert ();
1254 return GNUTLS_E_MPI_SCAN_FAILED;
1257 siz = e->size;
1258 if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz))
1260 gnutls_assert ();
1261 _gnutls_mpi_release (&key->params.params[0]);
1262 return GNUTLS_E_MPI_SCAN_FAILED;
1265 key->params.params_nr = RSA_PUBLIC_PARAMS;
1266 key->pk_algorithm = GNUTLS_PK_RSA;
1267 key->bits = pubkey_to_bits(GNUTLS_PK_RSA, &key->params);
1269 return 0;
1273 * gnutls_pubkey_import_ecc_raw:
1274 * @key: The structure to store the parsed key
1275 * @curve: holds the curve
1276 * @x: holds the x
1277 * @y: holds the y
1279 * This function will convert the given elliptic curve parameters to a
1280 * #gnutls_pubkey_t. The output will be stored in @key.
1282 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1283 * negative error value.
1285 * Since: 3.0
1288 gnutls_pubkey_import_ecc_raw (gnutls_pubkey_t key,
1289 gnutls_ecc_curve_t curve,
1290 const gnutls_datum_t * x,
1291 const gnutls_datum_t * y)
1293 int ret;
1295 if (key == NULL)
1297 gnutls_assert ();
1298 return GNUTLS_E_INVALID_REQUEST;
1301 key->params.flags = curve;
1303 ret = _gnutls_ecc_curve_fill_params(curve, &key->params);
1304 if (ret < 0)
1305 return gnutls_assert_val(ret);
1307 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X], x->data, x->size))
1309 gnutls_assert ();
1310 ret = GNUTLS_E_MPI_SCAN_FAILED;
1311 goto cleanup;
1313 key->params.params_nr++;
1315 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_Y], y->data, y->size))
1317 gnutls_assert ();
1318 ret = GNUTLS_E_MPI_SCAN_FAILED;
1319 goto cleanup;
1321 key->params.params_nr++;
1322 key->pk_algorithm = GNUTLS_PK_EC;
1324 return 0;
1326 cleanup:
1327 gnutls_pk_params_release(&key->params);
1328 return ret;
1332 * gnutls_pubkey_import_ecc_x962:
1333 * @key: The structure to store the parsed key
1334 * @parameters: DER encoding of an ANSI X9.62 parameters
1335 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1337 * This function will convert the given elliptic curve parameters to a
1338 * #gnutls_pubkey_t. The output will be stored in @key.
1340 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1341 * negative error value.
1343 * Since: 3.0
1346 gnutls_pubkey_import_ecc_x962 (gnutls_pubkey_t key,
1347 const gnutls_datum_t * parameters,
1348 const gnutls_datum_t * ecpoint)
1350 int ret;
1352 if (key == NULL)
1354 gnutls_assert ();
1355 return GNUTLS_E_INVALID_REQUEST;
1358 key->params.params_nr = 0;
1360 ret = _gnutls_x509_read_ecc_params(parameters->data, parameters->size,
1361 &key->params);
1362 if (ret < 0)
1364 gnutls_assert ();
1365 goto cleanup;
1368 ret = _gnutls_ecc_ansi_x963_import(ecpoint->data, ecpoint->size,
1369 &key->params.params[ECC_X], &key->params.params[ECC_Y]);
1370 if (ret < 0)
1372 gnutls_assert ();
1373 goto cleanup;
1375 key->params.params_nr+=2;
1376 key->pk_algorithm = GNUTLS_PK_EC;
1378 return 0;
1380 cleanup:
1381 gnutls_pk_params_release(&key->params);
1382 return ret;
1386 * gnutls_pubkey_import_dsa_raw:
1387 * @key: The structure to store the parsed key
1388 * @p: holds the p
1389 * @q: holds the q
1390 * @g: holds the g
1391 * @y: holds the y
1393 * This function will convert the given DSA raw parameters to the
1394 * native #gnutls_pubkey_t format. The output will be stored
1395 * in @key.
1397 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1398 * negative error value.
1400 * Since: 2.12.0
1403 gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key,
1404 const gnutls_datum_t * p,
1405 const gnutls_datum_t * q,
1406 const gnutls_datum_t * g,
1407 const gnutls_datum_t * y)
1409 size_t siz = 0;
1411 if (key == NULL)
1413 gnutls_assert ();
1414 return GNUTLS_E_INVALID_REQUEST;
1417 gnutls_pk_params_init(&key->params);
1419 siz = p->size;
1420 if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz))
1422 gnutls_assert ();
1423 return GNUTLS_E_MPI_SCAN_FAILED;
1426 siz = q->size;
1427 if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz))
1429 gnutls_assert ();
1430 _gnutls_mpi_release (&key->params.params[0]);
1431 return GNUTLS_E_MPI_SCAN_FAILED;
1434 siz = g->size;
1435 if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz))
1437 gnutls_assert ();
1438 _gnutls_mpi_release (&key->params.params[1]);
1439 _gnutls_mpi_release (&key->params.params[0]);
1440 return GNUTLS_E_MPI_SCAN_FAILED;
1443 siz = y->size;
1444 if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz))
1446 gnutls_assert ();
1447 _gnutls_mpi_release (&key->params.params[2]);
1448 _gnutls_mpi_release (&key->params.params[1]);
1449 _gnutls_mpi_release (&key->params.params[0]);
1450 return GNUTLS_E_MPI_SCAN_FAILED;
1453 key->params.params_nr = DSA_PUBLIC_PARAMS;
1454 key->pk_algorithm = GNUTLS_PK_DSA;
1455 key->bits = pubkey_to_bits(GNUTLS_PK_DSA, &key->params);
1457 return 0;
1462 * gnutls_pubkey_verify_data:
1463 * @pubkey: Holds the public key
1464 * @flags: should be 0 for now
1465 * @data: holds the signed data
1466 * @signature: contains the signature
1468 * This function will verify the given signed data, using the
1469 * parameters from the certificate.
1471 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1472 * is returned, and zero or positive code on success.
1474 * Deprecated. Use gnutls_pubkey_verify_data2() instead of this function.
1476 * Since: 2.12.0
1479 gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, unsigned int flags,
1480 const gnutls_datum_t * data,
1481 const gnutls_datum_t * signature)
1483 int ret;
1485 if (pubkey == NULL)
1487 gnutls_assert ();
1488 return GNUTLS_E_INVALID_REQUEST;
1491 ret = pubkey_verify_data( pubkey->pk_algorithm, GNUTLS_DIG_UNKNOWN, data, signature,
1492 &pubkey->params);
1493 if (ret < 0)
1495 gnutls_assert();
1498 return ret;
1502 * gnutls_pubkey_verify_data2:
1503 * @pubkey: Holds the public key
1504 * @algo: The signature algorithm used
1505 * @flags: should be 0 for now
1506 * @data: holds the signed data
1507 * @signature: contains the signature
1509 * This function will verify the given signed data, using the
1510 * parameters from the certificate.
1512 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1513 * is returned, and zero or positive code on success.
1515 * Since: 3.0
1518 gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey,
1519 gnutls_sign_algorithm_t algo,
1520 unsigned int flags,
1521 const gnutls_datum_t * data,
1522 const gnutls_datum_t * signature)
1524 int ret;
1526 if (pubkey == NULL)
1528 gnutls_assert ();
1529 return GNUTLS_E_INVALID_REQUEST;
1532 ret = pubkey_verify_data( pubkey->pk_algorithm, gnutls_sign_get_hash_algorithm(algo),
1533 data, signature, &pubkey->params);
1534 if (ret < 0)
1536 gnutls_assert();
1539 return ret;
1544 * gnutls_pubkey_verify_hash:
1545 * @key: Holds the public key
1546 * @flags: should be 0 for now
1547 * @hash: holds the hash digest to be verified
1548 * @signature: contains the signature
1550 * This function will verify the given signed digest, using the
1551 * parameters from the public key.
1553 * Deprecated. Use gnutls_pubkey_verify_hash2() instead of this function.
1555 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1556 * is returned, and zero or positive code on success.
1558 * Since: 2.12.0
1561 gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
1562 const gnutls_datum_t * hash,
1563 const gnutls_datum_t * signature)
1565 gnutls_digest_algorithm_t algo;
1566 int ret;
1568 ret = gnutls_pubkey_get_verify_algorithm (key, signature, &algo);
1569 if (ret < 0)
1570 return gnutls_assert_val(ret);
1572 return gnutls_pubkey_verify_hash2(key, gnutls_pk_to_sign(key->pk_algorithm, algo),
1573 flags, hash, signature);
1577 * gnutls_pubkey_verify_hash2:
1578 * @key: Holds the public key
1579 * @algo: The signature algorithm used
1580 * @flags: should be 0 for now
1581 * @hash: holds the hash digest to be verified
1582 * @signature: contains the signature
1584 * This function will verify the given signed digest, using the
1585 * parameters from the public key.
1587 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1588 * is returned, and zero or positive code on success.
1590 * Since: 3.0
1593 gnutls_pubkey_verify_hash2 (gnutls_pubkey_t key,
1594 gnutls_sign_algorithm_t algo,
1595 unsigned int flags,
1596 const gnutls_datum_t * hash,
1597 const gnutls_datum_t * signature)
1599 if (key == NULL)
1601 gnutls_assert ();
1602 return GNUTLS_E_INVALID_REQUEST;
1605 if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA)
1606 return _gnutls_pk_verify (GNUTLS_PK_RSA, hash, signature, &key->params);
1607 else
1609 return pubkey_verify_hashed_data (key->pk_algorithm, gnutls_sign_get_hash_algorithm(algo),
1610 hash, signature, &key->params);
1615 * gnutls_pubkey_encrypt_data:
1616 * @key: Holds the public key
1617 * @flags: should be 0 for now
1618 * @plaintext: The data to be encrypted
1619 * @ciphertext: contains the encrypted data
1621 * This function will encrypt the given data, using the public
1622 * key.
1624 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1625 * negative error value.
1627 * Since: 3.0
1630 gnutls_pubkey_encrypt_data (gnutls_pubkey_t key, unsigned int flags,
1631 const gnutls_datum_t * plaintext,
1632 gnutls_datum_t * ciphertext)
1634 if (key == NULL)
1636 gnutls_assert ();
1637 return GNUTLS_E_INVALID_REQUEST;
1640 return _gnutls_pk_encrypt (key->pk_algorithm, ciphertext,
1641 plaintext, &key->params);
1645 * gnutls_pubkey_get_verify_algorithm:
1646 * @key: Holds the certificate
1647 * @signature: contains the signature
1648 * @hash: The result of the call with the hash algorithm used for signature
1650 * This function will read the certifcate and the signed data to
1651 * determine the hash algorithm used to generate the signature.
1653 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1654 * negative error value.
1656 * Since: 2.12.0
1659 gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
1660 const gnutls_datum_t * signature,
1661 gnutls_digest_algorithm_t * hash)
1663 if (key == NULL)
1665 gnutls_assert ();
1666 return GNUTLS_E_INVALID_REQUEST;
1669 return _gnutls_x509_verify_algorithm (hash, signature,
1670 key->pk_algorithm,
1671 &key->params);
1675 /* Checks whether the public key given is compatible with the
1676 * signature algorithm used. The session is only used for audit logging, and
1677 * it may be null.
1679 int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session,
1680 gnutls_pubkey_t pubkey,
1681 gnutls_protocol_t ver,
1682 gnutls_sign_algorithm_t sign)
1684 unsigned int hash_size;
1685 unsigned int hash_algo;
1686 unsigned int sig_hash_size;
1688 if (pubkey->pk_algorithm == GNUTLS_PK_DSA)
1690 hash_algo = _gnutls_dsa_q_to_hash (pubkey->pk_algorithm, &pubkey->params, &hash_size);
1692 /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
1693 if (!_gnutls_version_has_selectable_sighash (ver))
1695 if (hash_algo != GNUTLS_DIG_SHA1)
1696 return gnutls_assert_val(GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
1698 else if (sign != GNUTLS_SIGN_UNKNOWN)
1700 sig_hash_size = _gnutls_hash_get_algo_len(gnutls_sign_get_hash_algorithm(sign));
1701 if (sig_hash_size < hash_size)
1702 _gnutls_audit_log(session, "The hash size used in signature (%u) is less than the expected (%u)\n", sig_hash_size, hash_size);
1706 else if (pubkey->pk_algorithm == GNUTLS_PK_EC)
1708 if (_gnutls_version_has_selectable_sighash (ver) && sign != GNUTLS_SIGN_UNKNOWN)
1710 _gnutls_dsa_q_to_hash (pubkey->pk_algorithm, &pubkey->params, &hash_size);
1711 sig_hash_size = _gnutls_hash_get_algo_len(gnutls_sign_get_hash_algorithm(sign));
1713 if (sig_hash_size < hash_size)
1714 _gnutls_audit_log(session, "The hash size used in signature (%u) is less than the expected (%u)\n", sig_hash_size, hash_size);
1719 return 0;
1722 /* Returns zero if the public key has more than 512 bits */
1723 int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey)
1725 if (pubkey->pk_algorithm == GNUTLS_PK_RSA && _gnutls_mpi_get_nbits (pubkey->params.params[0]) > 512)
1726 return 0;
1727 else
1728 return GNUTLS_E_INVALID_REQUEST; /* doesn't matter */
1732 /* Returns the public key.
1735 _gnutls_pubkey_get_mpis (gnutls_pubkey_t key,
1736 gnutls_pk_params_st * params)
1738 return _gnutls_pk_params_copy(params, &key->params);
1741 /* if hash==MD5 then we do RSA-MD5
1742 * if hash==SHA then we do RSA-SHA
1743 * params[0] is modulus
1744 * params[1] is public key
1746 static int
1747 _pkcs1_rsa_verify_sig (gnutls_digest_algorithm_t hash,
1748 const gnutls_datum_t * text,
1749 const gnutls_datum_t * prehash,
1750 const gnutls_datum_t * signature,
1751 gnutls_pk_params_st * params)
1753 int ret;
1754 uint8_t md[MAX_HASH_SIZE], *cmp;
1755 unsigned int digest_size;
1756 gnutls_datum_t d, di;
1757 digest_hd_st hd;
1759 digest_size = _gnutls_hash_get_algo_len (hash);
1760 if (prehash)
1762 if (prehash->data == NULL || prehash->size != digest_size)
1763 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1765 cmp = prehash->data;
1767 else
1769 if (!text)
1771 gnutls_assert ();
1772 return GNUTLS_E_INVALID_REQUEST;
1775 ret = _gnutls_hash_init (&hd, hash);
1776 if (ret < 0)
1778 gnutls_assert ();
1779 return ret;
1782 _gnutls_hash (&hd, text->data, text->size);
1783 _gnutls_hash_deinit (&hd, md);
1785 cmp = md;
1788 d.data = cmp;
1789 d.size = digest_size;
1791 /* decrypted is a BER encoded data of type DigestInfo
1794 ret = encode_ber_digest_info (hash, &d, &di);
1795 if (ret < 0)
1796 return gnutls_assert_val(ret);
1798 ret = _gnutls_pk_verify (GNUTLS_PK_RSA, &di, signature, params);
1800 _gnutls_free_datum (&di);
1802 return ret;
1805 /* Hashes input data and verifies a signature.
1807 static int
1808 dsa_verify_hashed_data (gnutls_pk_algorithm_t pk,
1809 gnutls_digest_algorithm_t algo,
1810 const gnutls_datum_t * hash,
1811 const gnutls_datum_t * signature,
1812 gnutls_pk_params_st* params)
1814 gnutls_datum_t digest;
1815 unsigned int hash_len;
1817 if (algo == GNUTLS_DIG_UNKNOWN)
1818 algo = _gnutls_dsa_q_to_hash (pk, params, &hash_len);
1819 else hash_len = _gnutls_hash_get_algo_len(algo);
1821 /* SHA1 or better allowed */
1822 if (!hash->data || hash->size < hash_len)
1824 gnutls_assert();
1825 _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);
1827 if (hash->size != 20) /* SHA1 is allowed */
1828 return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
1831 digest.data = hash->data;
1832 digest.size = hash->size;
1834 return _gnutls_pk_verify (pk, &digest, signature, params);
1837 static int
1838 dsa_verify_data (gnutls_pk_algorithm_t pk,
1839 gnutls_digest_algorithm_t algo,
1840 const gnutls_datum_t * data,
1841 const gnutls_datum_t * signature,
1842 gnutls_pk_params_st* params)
1844 int ret;
1845 uint8_t _digest[MAX_HASH_SIZE];
1846 gnutls_datum_t digest;
1847 digest_hd_st hd;
1849 if (algo == GNUTLS_DIG_UNKNOWN)
1850 algo = _gnutls_dsa_q_to_hash (pk, params, NULL);
1852 ret = _gnutls_hash_init (&hd, algo);
1853 if (ret < 0)
1854 return gnutls_assert_val(ret);
1856 _gnutls_hash (&hd, data->data, data->size);
1857 _gnutls_hash_deinit (&hd, _digest);
1859 digest.data = _digest;
1860 digest.size = _gnutls_hash_get_algo_len(algo);
1862 return _gnutls_pk_verify (pk, &digest, signature, params);
1865 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
1866 * not verified, or 1 otherwise.
1869 pubkey_verify_hashed_data (gnutls_pk_algorithm_t pk,
1870 gnutls_digest_algorithm_t hash_algo,
1871 const gnutls_datum_t * hash,
1872 const gnutls_datum_t * signature,
1873 gnutls_pk_params_st * issuer_params)
1876 switch (pk)
1878 case GNUTLS_PK_RSA:
1880 if (_pkcs1_rsa_verify_sig
1881 (hash_algo, NULL, hash, signature, issuer_params) != 0)
1883 gnutls_assert ();
1884 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1887 return 1;
1888 break;
1890 case GNUTLS_PK_EC:
1891 case GNUTLS_PK_DSA:
1892 if (dsa_verify_hashed_data(pk, hash_algo, hash, signature, issuer_params) != 0)
1894 gnutls_assert ();
1895 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1898 return 1;
1899 break;
1900 default:
1901 gnutls_assert ();
1902 return GNUTLS_E_INTERNAL_ERROR;
1907 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
1908 * not verified, or 1 otherwise.
1911 pubkey_verify_data (gnutls_pk_algorithm_t pk,
1912 gnutls_digest_algorithm_t hash_algo,
1913 const gnutls_datum_t * data,
1914 const gnutls_datum_t * signature,
1915 gnutls_pk_params_st * issuer_params)
1918 switch (pk)
1920 case GNUTLS_PK_RSA:
1922 if (_pkcs1_rsa_verify_sig
1923 (hash_algo, data, NULL, signature, issuer_params) != 0)
1925 gnutls_assert ();
1926 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1929 return 1;
1930 break;
1932 case GNUTLS_PK_EC:
1933 case GNUTLS_PK_DSA:
1934 if (dsa_verify_data(pk, hash_algo, data, signature, issuer_params) != 0)
1936 gnutls_assert ();
1937 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1940 return 1;
1941 break;
1942 default:
1943 gnutls_assert ();
1944 return GNUTLS_E_INTERNAL_ERROR;
1949 gnutls_digest_algorithm_t
1950 _gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* params,
1951 unsigned int* hash_len)
1953 int bits = 0;
1955 if (algo == GNUTLS_PK_DSA)
1956 bits = _gnutls_mpi_get_nbits (params->params[1]);
1957 else if (algo == GNUTLS_PK_EC)
1958 bits = gnutls_ecc_curve_get_size(params->flags)*8;
1960 if (bits <= 160)
1962 if (hash_len) *hash_len = 20;
1963 return GNUTLS_DIG_SHA1;
1965 else if (bits <= 192)
1967 if (hash_len) *hash_len = 24;
1968 return GNUTLS_DIG_SHA256;
1970 else if (bits <= 224)
1972 if (hash_len) *hash_len = 28;
1973 return GNUTLS_DIG_SHA256;
1975 else if (bits <= 256)
1977 if (hash_len) *hash_len = 32;
1978 return GNUTLS_DIG_SHA256;
1980 else if (bits <= 384)
1982 if (hash_len) *hash_len = 48;
1983 return GNUTLS_DIG_SHA384;
1985 else
1987 if (hash_len) *hash_len = 64;
1988 return GNUTLS_DIG_SHA512;
1993 * gnutls_pubkey_set_pin_function:
1994 * @key: A key of type #gnutls_pubkey_t
1995 * @fn: the callback
1996 * @userdata: data associated with the callback
1998 * This function will set a callback function to be used when
1999 * required to access the object. This function overrides any other
2000 * global PIN functions.
2002 * Note that this function must be called right after initialization
2003 * to have effect.
2005 * Since: 3.1.0
2008 void gnutls_pubkey_set_pin_function (gnutls_pubkey_t key,
2009 gnutls_pin_callback_t fn, void *userdata)
2011 key->pin.cb = fn;
2012 key->pin.data = userdata;
2016 * gnutls_pubkey_import_x509_raw:
2017 * @pkey: The public key
2018 * @data: The public key data to be imported
2019 * @format: The format of the public key
2020 * @flags: should be zero
2022 * This function will import the given public key to the abstract
2023 * #gnutls_pubkey_t structure.
2025 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2026 * negative error value.
2028 * Since: 3.1.3
2030 int gnutls_pubkey_import_x509_raw (gnutls_pubkey_t pkey,
2031 const gnutls_datum_t * data,
2032 gnutls_x509_crt_fmt_t format,
2033 unsigned int flags)
2035 gnutls_x509_crt_t xpriv;
2036 int ret;
2038 ret = gnutls_x509_crt_init(&xpriv);
2039 if (ret < 0)
2040 return gnutls_assert_val(ret);
2042 ret = gnutls_x509_crt_import(xpriv, data, format);
2043 if (ret < 0)
2045 gnutls_assert();
2046 goto cleanup;
2049 ret = gnutls_pubkey_import_x509(pkey, xpriv, flags);
2050 if (ret < 0)
2052 gnutls_assert();
2053 goto cleanup;
2056 return 0;
2058 cleanup:
2059 gnutls_x509_crt_deinit(xpriv);
2061 return ret;