Corrected bugs in record parsing.
[gnutls.git] / lib / gnutls_pubkey.c
blob2c662c4d9544c2265519fba58f3b3ee63d4a0d6e
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_x509_crq:
183 * @key: The public key
184 * @crq: The certificate to be imported
185 * @flags: should be zero
187 * This function will import the given public key to the abstract
188 * #gnutls_pubkey_t structure.
190 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
191 * negative error value.
193 * Since: 3.1.5
196 gnutls_pubkey_import_x509_crq (gnutls_pubkey_t key, gnutls_x509_crq_t crq,
197 unsigned int flags)
199 int ret;
201 key->pk_algorithm = gnutls_x509_crq_get_pk_algorithm (crq, &key->bits);
203 ret = gnutls_x509_crq_get_key_usage (crq, &key->key_usage, NULL);
204 if (ret < 0)
205 key->key_usage = 0;
207 ret = _gnutls_x509_crq_get_mpis (crq, &key->params);
208 if (ret < 0)
210 gnutls_assert ();
211 return ret;
214 return 0;
218 * gnutls_pubkey_import_privkey:
219 * @key: The public key
220 * @pkey: The private key
221 * @usage: GNUTLS_KEY_* key usage flags.
222 * @flags: should be zero
224 * Imports the public key from a private. This function will import
225 * the given public key to the abstract #gnutls_pubkey_t structure.
227 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
228 * negative error value.
230 * Since: 2.12.0
233 gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey,
234 unsigned int usage, unsigned int flags)
236 key->pk_algorithm = gnutls_privkey_get_pk_algorithm (pkey, &key->bits);
238 key->key_usage = usage;
240 return _gnutls_privkey_get_public_mpis (pkey, &key->params);
244 * gnutls_pubkey_get_preferred_hash_algorithm:
245 * @key: Holds the certificate
246 * @hash: The result of the call with the hash algorithm used for signature
247 * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL.
249 * This function will read the certifcate and return the appropriate digest
250 * algorithm to use for signing with this certificate. Some certificates (i.e.
251 * DSA might not be able to sign without the preferred algorithm).
253 * Returns: the 0 if the hash algorithm is found. A negative error code is
254 * returned on error.
256 * Since: 2.12.0
259 gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key,
260 gnutls_digest_algorithm_t *
261 hash, unsigned int *mand)
263 int ret;
265 if (key == NULL)
267 gnutls_assert ();
268 return GNUTLS_E_INVALID_REQUEST;
271 ret = _gnutls_pk_get_hash_algorithm (key->pk_algorithm,
272 &key->params,
273 hash, mand);
275 return ret;
278 #ifdef ENABLE_PKCS11
281 * gnutls_pubkey_import_pkcs11:
282 * @key: The public key
283 * @obj: The parameters to be imported
284 * @flags: should be zero
286 * Imports a public key from a pkcs11 key. This function will import
287 * the given public key to the abstract #gnutls_pubkey_t structure.
289 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
290 * negative error value.
292 * Since: 2.12.0
295 gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key,
296 gnutls_pkcs11_obj_t obj, unsigned int flags)
298 int ret, type;
300 type = gnutls_pkcs11_obj_get_type (obj);
301 if (type != GNUTLS_PKCS11_OBJ_PUBKEY && type != GNUTLS_PKCS11_OBJ_X509_CRT)
303 gnutls_assert ();
304 return GNUTLS_E_INVALID_REQUEST;
307 if (type == GNUTLS_PKCS11_OBJ_X509_CRT)
309 gnutls_x509_crt_t xcrt;
311 ret = gnutls_x509_crt_init (&xcrt);
312 if (ret < 0)
314 gnutls_assert()
315 return ret;
318 ret = gnutls_x509_crt_import_pkcs11 (xcrt, obj);
319 if (ret < 0)
321 gnutls_assert();
322 goto cleanup_crt;
325 ret = gnutls_pubkey_import_x509 (key, xcrt, 0);
326 if (ret < 0)
328 gnutls_assert();
329 goto cleanup_crt;
332 gnutls_x509_crt_get_key_usage(xcrt, &key->key_usage, NULL);
334 ret = 0;
335 cleanup_crt:
336 gnutls_x509_crt_deinit(xcrt);
337 return ret;
340 key->key_usage = obj->key_usage;
342 switch (obj->pk_algorithm)
344 case GNUTLS_PK_RSA:
345 ret = gnutls_pubkey_import_rsa_raw (key, &obj->pubkey[0],
346 &obj->pubkey[1]);
347 break;
348 case GNUTLS_PK_DSA:
349 ret = gnutls_pubkey_import_dsa_raw (key, &obj->pubkey[0],
350 &obj->pubkey[1],
351 &obj->pubkey[2], &obj->pubkey[3]);
352 break;
353 case GNUTLS_PK_EC:
354 ret = gnutls_pubkey_import_ecc_x962 (key, &obj->pubkey[0],
355 &obj->pubkey[1]);
356 break;
357 default:
358 gnutls_assert ();
359 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
362 if (ret < 0)
364 gnutls_assert ();
365 return ret;
368 return 0;
371 #endif /* ENABLE_PKCS11 */
373 #ifdef ENABLE_OPENPGP
376 * gnutls_pubkey_import_openpgp:
377 * @key: The public key
378 * @crt: The certificate to be imported
379 * @flags: should be zero
381 * Imports a public key from an openpgp key. This function will import
382 * the given public key to the abstract #gnutls_pubkey_t
383 * structure. The subkey set as preferred will be imported or the
384 * master key otherwise.
386 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
387 * negative error value.
389 * Since: 2.12.0
392 gnutls_pubkey_import_openpgp (gnutls_pubkey_t key,
393 gnutls_openpgp_crt_t crt,
394 unsigned int flags)
396 int ret, idx;
397 uint32_t kid32[2];
398 uint32_t *k;
399 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
401 ret = gnutls_openpgp_crt_get_preferred_key_id (crt, keyid);
402 if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR)
404 key->pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (crt, &key->bits);
405 key->openpgp_key_id_set = OPENPGP_KEY_PRIMARY;
407 ret = gnutls_openpgp_crt_get_key_id(crt, key->openpgp_key_id);
408 if (ret < 0)
409 return gnutls_assert_val(ret);
411 ret = gnutls_openpgp_crt_get_key_usage (crt, &key->key_usage);
412 if (ret < 0)
413 key->key_usage = 0;
415 k = NULL;
417 else
419 if (ret < 0)
421 gnutls_assert ();
422 return ret;
424 key->openpgp_key_id_set = OPENPGP_KEY_SUBKEY;
426 KEYID_IMPORT (kid32, keyid);
427 k = kid32;
429 idx = gnutls_openpgp_crt_get_subkey_idx (crt, keyid);
431 ret = gnutls_openpgp_crt_get_subkey_id(crt, idx, key->openpgp_key_id);
432 if (ret < 0)
433 return gnutls_assert_val(ret);
435 ret = gnutls_openpgp_crt_get_subkey_usage (crt, idx, &key->key_usage);
436 if (ret < 0)
437 key->key_usage = 0;
439 key->pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm (crt, idx, NULL);
442 ret =
443 _gnutls_openpgp_crt_get_mpis (crt, k, &key->params);
444 if (ret < 0)
445 return gnutls_assert_val(ret);
447 return 0;
451 * gnutls_pubkey_get_openpgp_key_id:
452 * @key: Holds the public key
453 * @flags: should be 0 for now
454 * @output_data: will contain the key ID
455 * @output_data_size: holds the size of output_data (and will be
456 * replaced by the actual size of parameters)
457 * @subkey: Will be non zero if the key ID corresponds to a subkey
459 * This function returned the OpenPGP key ID of the corresponding key.
460 * The key is a unique ID that depends on the public
461 * key parameters.
463 * If the buffer provided is not long enough to hold the output, then
464 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
465 * be returned. The output is %GNUTLS_OPENPGP_KEYID_SIZE bytes long.
467 * Returns: In case of failure a negative error code will be
468 * returned, and 0 on success.
470 * Since: 3.0
473 gnutls_pubkey_get_openpgp_key_id (gnutls_pubkey_t key, unsigned int flags,
474 unsigned char *output_data,
475 size_t * output_data_size,
476 unsigned int *subkey)
478 if (key == NULL)
480 gnutls_assert ();
481 return GNUTLS_E_INVALID_REQUEST;
484 if (*output_data_size < sizeof(key->openpgp_key_id))
486 *output_data_size = sizeof(key->openpgp_key_id);
487 return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
490 if (key->openpgp_key_id_set == 0)
491 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
493 if (key->openpgp_key_id_set == OPENPGP_KEY_SUBKEY)
494 if (subkey) *subkey = 1;
496 if (output_data)
498 memcpy(output_data, key->openpgp_key_id, sizeof(key->openpgp_key_id));
500 *output_data_size = sizeof(key->openpgp_key_id);
502 return 0;
506 * gnutls_pubkey_import_openpgp_raw:
507 * @pkey: The public key
508 * @data: The public key data to be imported
509 * @format: The format of the public key
510 * @keyid: The key id to use (optional)
511 * @flags: Should be zero
513 * This function will import the given public key to the abstract
514 * #gnutls_pubkey_t structure.
516 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
517 * negative error value.
519 * Since: 3.1.3
521 int gnutls_pubkey_import_openpgp_raw (gnutls_pubkey_t pkey,
522 const gnutls_datum_t * data,
523 gnutls_openpgp_crt_fmt_t format,
524 const gnutls_openpgp_keyid_t keyid,
525 unsigned int flags)
527 gnutls_openpgp_crt_t xpriv;
528 int ret;
530 ret = gnutls_openpgp_crt_init(&xpriv);
531 if (ret < 0)
532 return gnutls_assert_val(ret);
534 ret = gnutls_openpgp_crt_import(xpriv, data, format);
535 if (ret < 0)
537 gnutls_assert();
538 goto cleanup;
541 if(keyid)
543 ret = gnutls_openpgp_crt_set_preferred_key_id(xpriv, keyid);
544 if (ret < 0)
546 gnutls_assert();
547 goto cleanup;
551 ret = gnutls_pubkey_import_openpgp(pkey, xpriv, flags);
552 if (ret < 0)
554 gnutls_assert();
555 goto cleanup;
558 ret = 0;
560 cleanup:
561 gnutls_openpgp_crt_deinit(xpriv);
563 return ret;
566 #endif
569 * gnutls_pubkey_export:
570 * @key: Holds the certificate
571 * @format: the format of output params. One of PEM or DER.
572 * @output_data: will contain a certificate PEM or DER encoded
573 * @output_data_size: holds the size of output_data (and will be
574 * replaced by the actual size of parameters)
576 * This function will export the public key to DER or PEM format.
577 * The contents of the exported data is the SubjectPublicKeyInfo
578 * X.509 structure.
580 * If the buffer provided is not long enough to hold the output, then
581 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
582 * be returned.
584 * If the structure is PEM encoded, it will have a header
585 * of "BEGIN CERTIFICATE".
587 * Returns: In case of failure a negative error code will be
588 * returned, and 0 on success.
590 * Since: 2.12.0
593 gnutls_pubkey_export (gnutls_pubkey_t key,
594 gnutls_x509_crt_fmt_t format, void *output_data,
595 size_t * output_data_size)
597 int result;
598 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
600 if (key == NULL)
602 gnutls_assert ();
603 return GNUTLS_E_INVALID_REQUEST;
606 if ((result = asn1_create_element
607 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
608 != ASN1_SUCCESS)
610 gnutls_assert ();
611 return _gnutls_asn2err (result);
614 result =
615 _gnutls_x509_encode_and_copy_PKI_params (spk, "",
616 key->pk_algorithm,
617 &key->params);
618 if (result < 0)
620 gnutls_assert ();
621 goto cleanup;
624 result = _gnutls_x509_export_int_named (spk, "",
625 format, PK_PEM_HEADER,
626 output_data, output_data_size);
627 if (result < 0)
629 gnutls_assert ();
630 goto cleanup;
633 result = 0;
635 cleanup:
636 asn1_delete_structure (&spk);
638 return result;
642 * gnutls_pubkey_export2:
643 * @key: Holds the certificate
644 * @format: the format of output params. One of PEM or DER.
645 * @out: will contain a certificate PEM or DER encoded
647 * This function will export the public key to DER or PEM format.
648 * The contents of the exported data is the SubjectPublicKeyInfo
649 * X.509 structure.
651 * The output buffer will be allocated using gnutls_malloc().
653 * If the structure is PEM encoded, it will have a header
654 * of "BEGIN CERTIFICATE".
656 * Returns: In case of failure a negative error code will be
657 * returned, and 0 on success.
659 * Since: 3.1.3
662 gnutls_pubkey_export2 (gnutls_pubkey_t key,
663 gnutls_x509_crt_fmt_t format,
664 gnutls_datum_t * out)
666 int result;
667 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
669 if (key == NULL)
671 gnutls_assert ();
672 return GNUTLS_E_INVALID_REQUEST;
675 if ((result = asn1_create_element
676 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
677 != ASN1_SUCCESS)
679 gnutls_assert ();
680 return _gnutls_asn2err (result);
683 result =
684 _gnutls_x509_encode_and_copy_PKI_params (spk, "",
685 key->pk_algorithm,
686 &key->params);
687 if (result < 0)
689 gnutls_assert ();
690 goto cleanup;
693 result = _gnutls_x509_export_int_named2 (spk, "",
694 format, PK_PEM_HEADER, out);
695 if (result < 0)
697 gnutls_assert ();
698 goto cleanup;
701 result = 0;
703 cleanup:
704 asn1_delete_structure (&spk);
706 return result;
710 * gnutls_pubkey_get_key_id:
711 * @key: Holds the public key
712 * @flags: should be 0 for now
713 * @output_data: will contain the key ID
714 * @output_data_size: holds the size of output_data (and will be
715 * replaced by the actual size of parameters)
717 * This function will return a unique ID that depends on the public
718 * key parameters. This ID can be used in checking whether a
719 * certificate corresponds to the given public key.
721 * If the buffer provided is not long enough to hold the output, then
722 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
723 * be returned. The output will normally be a SHA-1 hash output,
724 * which is 20 bytes.
726 * Returns: In case of failure a negative error code will be
727 * returned, and 0 on success.
729 * Since: 2.12.0
732 gnutls_pubkey_get_key_id (gnutls_pubkey_t key, unsigned int flags,
733 unsigned char *output_data,
734 size_t * output_data_size)
736 int ret = 0;
738 if (key == NULL)
740 gnutls_assert ();
741 return GNUTLS_E_INVALID_REQUEST;
744 ret =
745 _gnutls_get_key_id (key->pk_algorithm, &key->params,
746 output_data, output_data_size);
747 if (ret < 0)
749 gnutls_assert ();
750 return ret;
753 return 0;
757 * gnutls_pubkey_get_pk_rsa_raw:
758 * @key: Holds the certificate
759 * @m: will hold the modulus
760 * @e: will hold the public exponent
762 * This function will export the RSA public key's parameters found in
763 * the given structure. The new parameters will be allocated using
764 * gnutls_malloc() and will be stored in the appropriate datum.
766 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
768 * Since: 2.12.0
771 gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t key,
772 gnutls_datum_t * m, gnutls_datum_t * e)
774 int ret;
776 if (key == NULL)
778 gnutls_assert ();
779 return GNUTLS_E_INVALID_REQUEST;
782 if (key->pk_algorithm != GNUTLS_PK_RSA)
784 gnutls_assert ();
785 return GNUTLS_E_INVALID_REQUEST;
788 ret = _gnutls_mpi_dprint_lz (key->params.params[0], m);
789 if (ret < 0)
791 gnutls_assert ();
792 return ret;
795 ret = _gnutls_mpi_dprint_lz (key->params.params[1], e);
796 if (ret < 0)
798 gnutls_assert ();
799 _gnutls_free_datum (m);
800 return ret;
803 return 0;
807 * gnutls_pubkey_get_pk_dsa_raw:
808 * @key: Holds the public key
809 * @p: will hold the p
810 * @q: will hold the q
811 * @g: will hold the g
812 * @y: will hold the y
814 * This function will export the DSA public key's parameters found in
815 * the given certificate. The new parameters will be allocated using
816 * gnutls_malloc() and will be stored in the appropriate datum.
818 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
820 * Since: 2.12.0
823 gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
824 gnutls_datum_t * p, gnutls_datum_t * q,
825 gnutls_datum_t * g, gnutls_datum_t * y)
827 int ret;
829 if (key == NULL)
831 gnutls_assert ();
832 return GNUTLS_E_INVALID_REQUEST;
835 if (key->pk_algorithm != GNUTLS_PK_DSA)
837 gnutls_assert ();
838 return GNUTLS_E_INVALID_REQUEST;
841 /* P */
842 ret = _gnutls_mpi_dprint_lz (key->params.params[0], p);
843 if (ret < 0)
845 gnutls_assert ();
846 return ret;
849 /* Q */
850 ret = _gnutls_mpi_dprint_lz (key->params.params[1], q);
851 if (ret < 0)
853 gnutls_assert ();
854 _gnutls_free_datum (p);
855 return ret;
859 /* G */
860 ret = _gnutls_mpi_dprint_lz (key->params.params[2], g);
861 if (ret < 0)
863 gnutls_assert ();
864 _gnutls_free_datum (p);
865 _gnutls_free_datum (q);
866 return ret;
870 /* Y */
871 ret = _gnutls_mpi_dprint_lz (key->params.params[3], y);
872 if (ret < 0)
874 gnutls_assert ();
875 _gnutls_free_datum (p);
876 _gnutls_free_datum (g);
877 _gnutls_free_datum (q);
878 return ret;
881 return 0;
885 * gnutls_pubkey_get_pk_ecc_raw:
886 * @key: Holds the public key
887 * @curve: will hold the curve
888 * @x: will hold x
889 * @y: will hold y
891 * This function will export the ECC public key's parameters found in
892 * the given certificate. The new parameters will be allocated using
893 * gnutls_malloc() and will be stored in the appropriate datum.
895 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
897 * Since: 3.0
900 gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
901 gnutls_datum_t * x, gnutls_datum_t * y)
903 int ret;
905 if (key == NULL)
907 gnutls_assert ();
908 return GNUTLS_E_INVALID_REQUEST;
911 if (key->pk_algorithm != GNUTLS_PK_EC)
913 gnutls_assert ();
914 return GNUTLS_E_INVALID_REQUEST;
917 *curve = key->params.flags;
919 /* X */
920 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_X], x);
921 if (ret < 0)
923 gnutls_assert ();
924 return ret;
927 /* Y */
928 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_Y], y);
929 if (ret < 0)
931 gnutls_assert ();
932 _gnutls_free_datum (x);
933 return ret;
936 return 0;
940 * gnutls_pubkey_get_pk_ecc_x962:
941 * @key: Holds the public key
942 * @parameters: DER encoding of an ANSI X9.62 parameters
943 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
945 * This function will export the ECC public key's parameters found in
946 * the given certificate. The new parameters will be allocated using
947 * gnutls_malloc() and will be stored in the appropriate datum.
949 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
951 * Since: 3.0
953 int gnutls_pubkey_get_pk_ecc_x962 (gnutls_pubkey_t key, gnutls_datum_t* parameters,
954 gnutls_datum_t * ecpoint)
956 int ret;
958 if (key == NULL || key->pk_algorithm != GNUTLS_PK_EC)
959 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
961 ret = _gnutls_x509_write_ecc_pubkey(&key->params, ecpoint);
962 if (ret < 0)
963 return gnutls_assert_val(ret);
965 ret = _gnutls_x509_write_ecc_params(&key->params, parameters);
966 if (ret < 0)
968 _gnutls_free_datum(ecpoint);
969 return gnutls_assert_val(ret);
972 return 0;
976 * gnutls_pubkey_import:
977 * @key: The structure to store the parsed public key.
978 * @data: The DER or PEM encoded certificate.
979 * @format: One of DER or PEM
981 * This function will import the provided public key in
982 * a SubjectPublicKeyInfo X.509 structure to a native
983 * %gnutls_pubkey_t structure. The output will be stored
984 * in @key. If the public key is PEM encoded it should have a header
985 * of "PUBLIC KEY".
987 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
988 * negative error value.
990 * Since: 2.12.0
993 gnutls_pubkey_import (gnutls_pubkey_t key,
994 const gnutls_datum_t * data,
995 gnutls_x509_crt_fmt_t format)
997 int result = 0, need_free = 0;
998 gnutls_datum_t _data;
999 ASN1_TYPE spk;
1001 if (key == NULL)
1003 gnutls_assert ();
1004 return GNUTLS_E_INVALID_REQUEST;
1007 _data.data = data->data;
1008 _data.size = data->size;
1010 /* If the Certificate is in PEM format then decode it
1012 if (format == GNUTLS_X509_FMT_PEM)
1014 /* Try the first header */
1015 result =
1016 _gnutls_fbase64_decode (PK_PEM_HEADER, data->data, data->size, &_data);
1018 if (result < 0)
1020 gnutls_assert ();
1021 return result;
1024 need_free = 1;
1027 if ((result = asn1_create_element
1028 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
1029 != ASN1_SUCCESS)
1031 gnutls_assert ();
1032 result = _gnutls_asn2err (result);
1033 goto cleanup;
1036 result = asn1_der_decoding (&spk, _data.data, _data.size, NULL);
1037 if (result != ASN1_SUCCESS)
1039 gnutls_assert ();
1040 result = _gnutls_asn2err (result);
1041 goto cleanup;
1044 result = _gnutls_get_asn_mpis (spk, "", &key->params);
1045 if (result < 0)
1047 gnutls_assert ();
1048 goto cleanup;
1051 /* this has already been called by get_asn_mpis() thus it cannot
1052 * fail.
1054 key->pk_algorithm = _gnutls_x509_get_pk_algorithm (spk, "", NULL);
1055 key->bits = pubkey_to_bits(key->pk_algorithm, &key->params);
1057 result = 0;
1059 cleanup:
1060 asn1_delete_structure (&spk);
1062 if (need_free)
1063 _gnutls_free_datum (&_data);
1064 return result;
1068 * gnutls_x509_crt_set_pubkey:
1069 * @crt: should contain a #gnutls_x509_crt_t structure
1070 * @key: holds a public key
1072 * This function will set the public parameters from the given public
1073 * key to the request.
1075 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1076 * negative error value.
1078 * Since: 2.12.0
1081 gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, gnutls_pubkey_t key)
1083 int result;
1085 if (crt == NULL)
1087 gnutls_assert ();
1088 return GNUTLS_E_INVALID_REQUEST;
1091 result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
1092 "tbsCertificate.subjectPublicKeyInfo",
1093 key->pk_algorithm,
1094 &key->params);
1096 if (result < 0)
1098 gnutls_assert ();
1099 return result;
1102 if (key->key_usage)
1103 gnutls_x509_crt_set_key_usage (crt, key->key_usage);
1105 return 0;
1109 * gnutls_x509_crq_set_pubkey:
1110 * @crq: should contain a #gnutls_x509_crq_t structure
1111 * @key: holds a public key
1113 * This function will set the public parameters from the given public
1114 * key to the request.
1116 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1117 * negative error value.
1119 * Since: 2.12.0
1122 gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key)
1124 int result;
1126 if (crq == NULL)
1128 gnutls_assert ();
1129 return GNUTLS_E_INVALID_REQUEST;
1132 result = _gnutls_x509_encode_and_copy_PKI_params
1133 (crq->crq,
1134 "certificationRequestInfo.subjectPKInfo",
1135 key->pk_algorithm, &key->params);
1137 if (result < 0)
1139 gnutls_assert ();
1140 return result;
1143 if (key->key_usage)
1144 gnutls_x509_crq_set_key_usage (crq, key->key_usage);
1146 return 0;
1150 * gnutls_pubkey_set_key_usage:
1151 * @key: a certificate of type #gnutls_x509_crt_t
1152 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
1154 * This function will set the key usage flags of the public key. This
1155 * is only useful if the key is to be exported to a certificate or
1156 * certificate request.
1158 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1159 * negative error value.
1161 * Since: 2.12.0
1164 gnutls_pubkey_set_key_usage (gnutls_pubkey_t key, unsigned int usage)
1166 key->key_usage = usage;
1168 return 0;
1171 #ifdef ENABLE_PKCS11
1174 * gnutls_pubkey_import_pkcs11_url:
1175 * @key: A key of type #gnutls_pubkey_t
1176 * @url: A PKCS 11 url
1177 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1179 * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
1180 * structure.
1182 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1183 * negative error value.
1185 * Since: 2.12.0
1188 gnutls_pubkey_import_pkcs11_url (gnutls_pubkey_t key, const char *url,
1189 unsigned int flags)
1191 gnutls_pkcs11_obj_t pcrt;
1192 int ret;
1194 ret = gnutls_pkcs11_obj_init (&pcrt);
1195 if (ret < 0)
1197 gnutls_assert ();
1198 return ret;
1201 if (key->pin.cb)
1202 gnutls_pkcs11_obj_set_pin_function(pcrt, key->pin.cb, key->pin.data);
1204 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
1205 if (ret < 0)
1207 gnutls_assert ();
1208 goto cleanup;
1211 ret = gnutls_pubkey_import_pkcs11 (key, pcrt, 0);
1212 if (ret < 0)
1214 gnutls_assert ();
1215 goto cleanup;
1218 ret = 0;
1219 cleanup:
1221 gnutls_pkcs11_obj_deinit (pcrt);
1223 return ret;
1226 #endif /* ENABLE_PKCS11 */
1229 * gnutls_pubkey_import_url:
1230 * @key: A key of type #gnutls_pubkey_t
1231 * @url: A PKCS 11 url
1232 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1234 * This function will import a PKCS11 certificate or a TPM key
1235 * as a public key.
1237 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1238 * negative error value.
1240 * Since: 3.1.0
1243 gnutls_pubkey_import_url (gnutls_pubkey_t key, const char *url,
1244 unsigned int flags)
1246 #ifdef ENABLE_PKCS11
1247 if (strstr(url, "pkcs11:") != NULL)
1248 return gnutls_pubkey_import_pkcs11_url(key, url, flags);
1249 #endif
1250 #ifdef HAVE_TROUSERS
1251 if (strstr(url, "tpmkey:") != NULL)
1252 return gnutls_pubkey_import_tpm_url(key, url, NULL, 0);
1253 #endif
1254 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1258 * gnutls_pubkey_import_rsa_raw:
1259 * @key: Is a structure will hold the parameters
1260 * @m: holds the modulus
1261 * @e: holds the public exponent
1263 * This function will replace the parameters in the given structure.
1264 * The new parameters should be stored in the appropriate
1265 * gnutls_datum.
1267 * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
1269 * Since: 2.12.0
1272 gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key,
1273 const gnutls_datum_t * m,
1274 const gnutls_datum_t * e)
1276 size_t siz = 0;
1278 if (key == NULL)
1280 gnutls_assert ();
1281 return GNUTLS_E_INVALID_REQUEST;
1284 gnutls_pk_params_init(&key->params);
1286 siz = m->size;
1287 if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz))
1289 gnutls_assert ();
1290 return GNUTLS_E_MPI_SCAN_FAILED;
1293 siz = e->size;
1294 if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz))
1296 gnutls_assert ();
1297 _gnutls_mpi_release (&key->params.params[0]);
1298 return GNUTLS_E_MPI_SCAN_FAILED;
1301 key->params.params_nr = RSA_PUBLIC_PARAMS;
1302 key->pk_algorithm = GNUTLS_PK_RSA;
1303 key->bits = pubkey_to_bits(GNUTLS_PK_RSA, &key->params);
1305 return 0;
1309 * gnutls_pubkey_import_ecc_raw:
1310 * @key: The structure to store the parsed key
1311 * @curve: holds the curve
1312 * @x: holds the x
1313 * @y: holds the y
1315 * This function will convert the given elliptic curve parameters to a
1316 * #gnutls_pubkey_t. The output will be stored in @key.
1318 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1319 * negative error value.
1321 * Since: 3.0
1324 gnutls_pubkey_import_ecc_raw (gnutls_pubkey_t key,
1325 gnutls_ecc_curve_t curve,
1326 const gnutls_datum_t * x,
1327 const gnutls_datum_t * y)
1329 int ret;
1331 if (key == NULL)
1333 gnutls_assert ();
1334 return GNUTLS_E_INVALID_REQUEST;
1337 key->params.flags = curve;
1339 ret = _gnutls_ecc_curve_fill_params(curve, &key->params);
1340 if (ret < 0)
1341 return gnutls_assert_val(ret);
1343 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X], x->data, x->size))
1345 gnutls_assert ();
1346 ret = GNUTLS_E_MPI_SCAN_FAILED;
1347 goto cleanup;
1349 key->params.params_nr++;
1351 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_Y], y->data, y->size))
1353 gnutls_assert ();
1354 ret = GNUTLS_E_MPI_SCAN_FAILED;
1355 goto cleanup;
1357 key->params.params_nr++;
1358 key->pk_algorithm = GNUTLS_PK_EC;
1360 return 0;
1362 cleanup:
1363 gnutls_pk_params_release(&key->params);
1364 return ret;
1368 * gnutls_pubkey_import_ecc_x962:
1369 * @key: The structure to store the parsed key
1370 * @parameters: DER encoding of an ANSI X9.62 parameters
1371 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1373 * This function will convert the given elliptic curve parameters to a
1374 * #gnutls_pubkey_t. The output will be stored in @key.
1376 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1377 * negative error value.
1379 * Since: 3.0
1382 gnutls_pubkey_import_ecc_x962 (gnutls_pubkey_t key,
1383 const gnutls_datum_t * parameters,
1384 const gnutls_datum_t * ecpoint)
1386 int ret;
1388 if (key == NULL)
1390 gnutls_assert ();
1391 return GNUTLS_E_INVALID_REQUEST;
1394 key->params.params_nr = 0;
1396 ret = _gnutls_x509_read_ecc_params(parameters->data, parameters->size,
1397 &key->params);
1398 if (ret < 0)
1400 gnutls_assert ();
1401 goto cleanup;
1404 ret = _gnutls_ecc_ansi_x963_import(ecpoint->data, ecpoint->size,
1405 &key->params.params[ECC_X], &key->params.params[ECC_Y]);
1406 if (ret < 0)
1408 gnutls_assert ();
1409 goto cleanup;
1411 key->params.params_nr+=2;
1412 key->pk_algorithm = GNUTLS_PK_EC;
1414 return 0;
1416 cleanup:
1417 gnutls_pk_params_release(&key->params);
1418 return ret;
1422 * gnutls_pubkey_import_dsa_raw:
1423 * @key: The structure to store the parsed key
1424 * @p: holds the p
1425 * @q: holds the q
1426 * @g: holds the g
1427 * @y: holds the y
1429 * This function will convert the given DSA raw parameters to the
1430 * native #gnutls_pubkey_t format. The output will be stored
1431 * in @key.
1433 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1434 * negative error value.
1436 * Since: 2.12.0
1439 gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key,
1440 const gnutls_datum_t * p,
1441 const gnutls_datum_t * q,
1442 const gnutls_datum_t * g,
1443 const gnutls_datum_t * y)
1445 size_t siz = 0;
1447 if (key == NULL)
1449 gnutls_assert ();
1450 return GNUTLS_E_INVALID_REQUEST;
1453 gnutls_pk_params_init(&key->params);
1455 siz = p->size;
1456 if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz))
1458 gnutls_assert ();
1459 return GNUTLS_E_MPI_SCAN_FAILED;
1462 siz = q->size;
1463 if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz))
1465 gnutls_assert ();
1466 _gnutls_mpi_release (&key->params.params[0]);
1467 return GNUTLS_E_MPI_SCAN_FAILED;
1470 siz = g->size;
1471 if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz))
1473 gnutls_assert ();
1474 _gnutls_mpi_release (&key->params.params[1]);
1475 _gnutls_mpi_release (&key->params.params[0]);
1476 return GNUTLS_E_MPI_SCAN_FAILED;
1479 siz = y->size;
1480 if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz))
1482 gnutls_assert ();
1483 _gnutls_mpi_release (&key->params.params[2]);
1484 _gnutls_mpi_release (&key->params.params[1]);
1485 _gnutls_mpi_release (&key->params.params[0]);
1486 return GNUTLS_E_MPI_SCAN_FAILED;
1489 key->params.params_nr = DSA_PUBLIC_PARAMS;
1490 key->pk_algorithm = GNUTLS_PK_DSA;
1491 key->bits = pubkey_to_bits(GNUTLS_PK_DSA, &key->params);
1493 return 0;
1498 * gnutls_pubkey_verify_data:
1499 * @pubkey: Holds the public key
1500 * @flags: should be 0 for now
1501 * @data: holds the signed data
1502 * @signature: contains the signature
1504 * This function will verify the given signed data, using the
1505 * parameters from the certificate.
1507 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1508 * is returned, and zero or positive code on success.
1510 * Deprecated. Use gnutls_pubkey_verify_data2() instead of this function.
1512 * Since: 2.12.0
1515 gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, unsigned int flags,
1516 const gnutls_datum_t * data,
1517 const gnutls_datum_t * signature)
1519 int ret;
1521 if (pubkey == NULL)
1523 gnutls_assert ();
1524 return GNUTLS_E_INVALID_REQUEST;
1527 ret = pubkey_verify_data( pubkey->pk_algorithm, GNUTLS_DIG_UNKNOWN, data, signature,
1528 &pubkey->params);
1529 if (ret < 0)
1531 gnutls_assert();
1534 return ret;
1538 * gnutls_pubkey_verify_data2:
1539 * @pubkey: Holds the public key
1540 * @algo: The signature algorithm used
1541 * @flags: should be 0 for now
1542 * @data: holds the signed data
1543 * @signature: contains the signature
1545 * This function will verify the given signed data, using the
1546 * parameters from the certificate.
1548 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1549 * is returned, and zero or positive code on success.
1551 * Since: 3.0
1554 gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey,
1555 gnutls_sign_algorithm_t algo,
1556 unsigned int flags,
1557 const gnutls_datum_t * data,
1558 const gnutls_datum_t * signature)
1560 int ret;
1562 if (pubkey == NULL)
1564 gnutls_assert ();
1565 return GNUTLS_E_INVALID_REQUEST;
1568 ret = pubkey_verify_data( pubkey->pk_algorithm, gnutls_sign_get_hash_algorithm(algo),
1569 data, signature, &pubkey->params);
1570 if (ret < 0)
1572 gnutls_assert();
1575 return ret;
1580 * gnutls_pubkey_verify_hash:
1581 * @key: Holds the public key
1582 * @flags: should be 0 for now
1583 * @hash: holds the hash digest to be verified
1584 * @signature: contains the signature
1586 * This function will verify the given signed digest, using the
1587 * parameters from the public key.
1589 * Deprecated. Use gnutls_pubkey_verify_hash2() instead of this function.
1591 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1592 * is returned, and zero or positive code on success.
1594 * Since: 2.12.0
1597 gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
1598 const gnutls_datum_t * hash,
1599 const gnutls_datum_t * signature)
1601 gnutls_digest_algorithm_t algo;
1602 int ret;
1604 ret = gnutls_pubkey_get_verify_algorithm (key, signature, &algo);
1605 if (ret < 0)
1606 return gnutls_assert_val(ret);
1608 return gnutls_pubkey_verify_hash2(key, gnutls_pk_to_sign(key->pk_algorithm, algo),
1609 flags, hash, signature);
1613 * gnutls_pubkey_verify_hash2:
1614 * @key: Holds the public key
1615 * @algo: The signature algorithm used
1616 * @flags: should be 0 for now
1617 * @hash: holds the hash digest to be verified
1618 * @signature: contains the signature
1620 * This function will verify the given signed digest, using the
1621 * parameters from the public key.
1623 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1624 * is returned, and zero or positive code on success.
1626 * Since: 3.0
1629 gnutls_pubkey_verify_hash2 (gnutls_pubkey_t key,
1630 gnutls_sign_algorithm_t algo,
1631 unsigned int flags,
1632 const gnutls_datum_t * hash,
1633 const gnutls_datum_t * signature)
1635 if (key == NULL)
1637 gnutls_assert ();
1638 return GNUTLS_E_INVALID_REQUEST;
1641 if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA)
1642 return _gnutls_pk_verify (GNUTLS_PK_RSA, hash, signature, &key->params);
1643 else
1645 return pubkey_verify_hashed_data (key->pk_algorithm, gnutls_sign_get_hash_algorithm(algo),
1646 hash, signature, &key->params);
1651 * gnutls_pubkey_encrypt_data:
1652 * @key: Holds the public key
1653 * @flags: should be 0 for now
1654 * @plaintext: The data to be encrypted
1655 * @ciphertext: contains the encrypted data
1657 * This function will encrypt the given data, using the public
1658 * key.
1660 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1661 * negative error value.
1663 * Since: 3.0
1666 gnutls_pubkey_encrypt_data (gnutls_pubkey_t key, unsigned int flags,
1667 const gnutls_datum_t * plaintext,
1668 gnutls_datum_t * ciphertext)
1670 if (key == NULL)
1672 gnutls_assert ();
1673 return GNUTLS_E_INVALID_REQUEST;
1676 return _gnutls_pk_encrypt (key->pk_algorithm, ciphertext,
1677 plaintext, &key->params);
1681 * gnutls_pubkey_get_verify_algorithm:
1682 * @key: Holds the certificate
1683 * @signature: contains the signature
1684 * @hash: The result of the call with the hash algorithm used for signature
1686 * This function will read the certifcate and the signed data to
1687 * determine the hash algorithm used to generate the signature.
1689 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1690 * negative error value.
1692 * Since: 2.12.0
1695 gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
1696 const gnutls_datum_t * signature,
1697 gnutls_digest_algorithm_t * hash)
1699 if (key == NULL)
1701 gnutls_assert ();
1702 return GNUTLS_E_INVALID_REQUEST;
1705 return _gnutls_x509_verify_algorithm (hash, signature,
1706 key->pk_algorithm,
1707 &key->params);
1711 /* Checks whether the public key given is compatible with the
1712 * signature algorithm used. The session is only used for audit logging, and
1713 * it may be null.
1715 int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session,
1716 gnutls_pubkey_t pubkey,
1717 gnutls_protocol_t ver,
1718 gnutls_sign_algorithm_t sign)
1720 unsigned int hash_size;
1721 unsigned int hash_algo;
1722 unsigned int sig_hash_size;
1724 if (pubkey->pk_algorithm == GNUTLS_PK_DSA)
1726 hash_algo = _gnutls_dsa_q_to_hash (pubkey->pk_algorithm, &pubkey->params, &hash_size);
1728 /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
1729 if (!_gnutls_version_has_selectable_sighash (ver))
1731 if (hash_algo != GNUTLS_DIG_SHA1)
1732 return gnutls_assert_val(GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
1734 else if (sign != GNUTLS_SIGN_UNKNOWN)
1736 sig_hash_size = _gnutls_hash_get_algo_len(gnutls_sign_get_hash_algorithm(sign));
1737 if (sig_hash_size < hash_size)
1738 _gnutls_audit_log(session, "The hash size used in signature (%u) is less than the expected (%u)\n", sig_hash_size, hash_size);
1742 else if (pubkey->pk_algorithm == GNUTLS_PK_EC)
1744 if (_gnutls_version_has_selectable_sighash (ver) && sign != GNUTLS_SIGN_UNKNOWN)
1746 _gnutls_dsa_q_to_hash (pubkey->pk_algorithm, &pubkey->params, &hash_size);
1747 sig_hash_size = _gnutls_hash_get_algo_len(gnutls_sign_get_hash_algorithm(sign));
1749 if (sig_hash_size < hash_size)
1750 _gnutls_audit_log(session, "The hash size used in signature (%u) is less than the expected (%u)\n", sig_hash_size, hash_size);
1755 return 0;
1758 /* Returns zero if the public key has more than 512 bits */
1759 int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey)
1761 if (pubkey->pk_algorithm == GNUTLS_PK_RSA && _gnutls_mpi_get_nbits (pubkey->params.params[0]) > 512)
1762 return 0;
1763 else
1764 return GNUTLS_E_INVALID_REQUEST; /* doesn't matter */
1768 /* Returns the public key.
1771 _gnutls_pubkey_get_mpis (gnutls_pubkey_t key,
1772 gnutls_pk_params_st * params)
1774 return _gnutls_pk_params_copy(params, &key->params);
1777 /* if hash==MD5 then we do RSA-MD5
1778 * if hash==SHA then we do RSA-SHA
1779 * params[0] is modulus
1780 * params[1] is public key
1782 static int
1783 _pkcs1_rsa_verify_sig (gnutls_digest_algorithm_t hash,
1784 const gnutls_datum_t * text,
1785 const gnutls_datum_t * prehash,
1786 const gnutls_datum_t * signature,
1787 gnutls_pk_params_st * params)
1789 int ret;
1790 uint8_t md[MAX_HASH_SIZE], *cmp;
1791 unsigned int digest_size;
1792 gnutls_datum_t d, di;
1793 digest_hd_st hd;
1795 digest_size = _gnutls_hash_get_algo_len (hash);
1796 if (prehash)
1798 if (prehash->data == NULL || prehash->size != digest_size)
1799 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1801 cmp = prehash->data;
1803 else
1805 if (!text)
1807 gnutls_assert ();
1808 return GNUTLS_E_INVALID_REQUEST;
1811 ret = _gnutls_hash_init (&hd, hash);
1812 if (ret < 0)
1814 gnutls_assert ();
1815 return ret;
1818 _gnutls_hash (&hd, text->data, text->size);
1819 _gnutls_hash_deinit (&hd, md);
1821 cmp = md;
1824 d.data = cmp;
1825 d.size = digest_size;
1827 /* decrypted is a BER encoded data of type DigestInfo
1830 ret = encode_ber_digest_info (hash, &d, &di);
1831 if (ret < 0)
1832 return gnutls_assert_val(ret);
1834 ret = _gnutls_pk_verify (GNUTLS_PK_RSA, &di, signature, params);
1836 _gnutls_free_datum (&di);
1838 return ret;
1841 /* Hashes input data and verifies a signature.
1843 static int
1844 dsa_verify_hashed_data (gnutls_pk_algorithm_t pk,
1845 gnutls_digest_algorithm_t algo,
1846 const gnutls_datum_t * hash,
1847 const gnutls_datum_t * signature,
1848 gnutls_pk_params_st* params)
1850 gnutls_datum_t digest;
1851 unsigned int hash_len;
1853 if (algo == GNUTLS_DIG_UNKNOWN)
1854 algo = _gnutls_dsa_q_to_hash (pk, params, &hash_len);
1855 else hash_len = _gnutls_hash_get_algo_len(algo);
1857 /* SHA1 or better allowed */
1858 if (!hash->data || hash->size < hash_len)
1860 gnutls_assert();
1861 _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);
1863 if (hash->size != 20) /* SHA1 is allowed */
1864 return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
1867 digest.data = hash->data;
1868 digest.size = hash->size;
1870 return _gnutls_pk_verify (pk, &digest, signature, params);
1873 static int
1874 dsa_verify_data (gnutls_pk_algorithm_t pk,
1875 gnutls_digest_algorithm_t algo,
1876 const gnutls_datum_t * data,
1877 const gnutls_datum_t * signature,
1878 gnutls_pk_params_st* params)
1880 int ret;
1881 uint8_t _digest[MAX_HASH_SIZE];
1882 gnutls_datum_t digest;
1883 digest_hd_st hd;
1885 if (algo == GNUTLS_DIG_UNKNOWN)
1886 algo = _gnutls_dsa_q_to_hash (pk, params, NULL);
1888 ret = _gnutls_hash_init (&hd, algo);
1889 if (ret < 0)
1890 return gnutls_assert_val(ret);
1892 _gnutls_hash (&hd, data->data, data->size);
1893 _gnutls_hash_deinit (&hd, _digest);
1895 digest.data = _digest;
1896 digest.size = _gnutls_hash_get_algo_len(algo);
1898 return _gnutls_pk_verify (pk, &digest, signature, params);
1901 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
1902 * not verified, or 1 otherwise.
1905 pubkey_verify_hashed_data (gnutls_pk_algorithm_t pk,
1906 gnutls_digest_algorithm_t hash_algo,
1907 const gnutls_datum_t * hash,
1908 const gnutls_datum_t * signature,
1909 gnutls_pk_params_st * issuer_params)
1912 switch (pk)
1914 case GNUTLS_PK_RSA:
1916 if (_pkcs1_rsa_verify_sig
1917 (hash_algo, NULL, hash, signature, issuer_params) != 0)
1919 gnutls_assert ();
1920 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1923 return 1;
1924 break;
1926 case GNUTLS_PK_EC:
1927 case GNUTLS_PK_DSA:
1928 if (dsa_verify_hashed_data(pk, hash_algo, hash, signature, issuer_params) != 0)
1930 gnutls_assert ();
1931 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1934 return 1;
1935 break;
1936 default:
1937 gnutls_assert ();
1938 return GNUTLS_E_INTERNAL_ERROR;
1943 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
1944 * not verified, or 1 otherwise.
1947 pubkey_verify_data (gnutls_pk_algorithm_t pk,
1948 gnutls_digest_algorithm_t hash_algo,
1949 const gnutls_datum_t * data,
1950 const gnutls_datum_t * signature,
1951 gnutls_pk_params_st * issuer_params)
1954 switch (pk)
1956 case GNUTLS_PK_RSA:
1958 if (_pkcs1_rsa_verify_sig
1959 (hash_algo, data, NULL, signature, issuer_params) != 0)
1961 gnutls_assert ();
1962 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1965 return 1;
1966 break;
1968 case GNUTLS_PK_EC:
1969 case GNUTLS_PK_DSA:
1970 if (dsa_verify_data(pk, hash_algo, data, signature, issuer_params) != 0)
1972 gnutls_assert ();
1973 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
1976 return 1;
1977 break;
1978 default:
1979 gnutls_assert ();
1980 return GNUTLS_E_INTERNAL_ERROR;
1985 gnutls_digest_algorithm_t
1986 _gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* params,
1987 unsigned int* hash_len)
1989 int bits = 0;
1991 if (algo == GNUTLS_PK_DSA)
1992 bits = _gnutls_mpi_get_nbits (params->params[1]);
1993 else if (algo == GNUTLS_PK_EC)
1994 bits = gnutls_ecc_curve_get_size(params->flags)*8;
1996 if (bits <= 160)
1998 if (hash_len) *hash_len = 20;
1999 return GNUTLS_DIG_SHA1;
2001 else if (bits <= 192)
2003 if (hash_len) *hash_len = 24;
2004 return GNUTLS_DIG_SHA256;
2006 else if (bits <= 224)
2008 if (hash_len) *hash_len = 28;
2009 return GNUTLS_DIG_SHA256;
2011 else if (bits <= 256)
2013 if (hash_len) *hash_len = 32;
2014 return GNUTLS_DIG_SHA256;
2016 else if (bits <= 384)
2018 if (hash_len) *hash_len = 48;
2019 return GNUTLS_DIG_SHA384;
2021 else
2023 if (hash_len) *hash_len = 64;
2024 return GNUTLS_DIG_SHA512;
2029 * gnutls_pubkey_set_pin_function:
2030 * @key: A key of type #gnutls_pubkey_t
2031 * @fn: the callback
2032 * @userdata: data associated with the callback
2034 * This function will set a callback function to be used when
2035 * required to access the object. This function overrides any other
2036 * global PIN functions.
2038 * Note that this function must be called right after initialization
2039 * to have effect.
2041 * Since: 3.1.0
2044 void gnutls_pubkey_set_pin_function (gnutls_pubkey_t key,
2045 gnutls_pin_callback_t fn, void *userdata)
2047 key->pin.cb = fn;
2048 key->pin.data = userdata;
2052 * gnutls_pubkey_import_x509_raw:
2053 * @pkey: The public key
2054 * @data: The public key data to be imported
2055 * @format: The format of the public key
2056 * @flags: should be zero
2058 * This function will import the given public key to the abstract
2059 * #gnutls_pubkey_t structure.
2061 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2062 * negative error value.
2064 * Since: 3.1.3
2066 int gnutls_pubkey_import_x509_raw (gnutls_pubkey_t pkey,
2067 const gnutls_datum_t * data,
2068 gnutls_x509_crt_fmt_t format,
2069 unsigned int flags)
2071 gnutls_x509_crt_t xpriv;
2072 int ret;
2074 ret = gnutls_x509_crt_init(&xpriv);
2075 if (ret < 0)
2076 return gnutls_assert_val(ret);
2078 ret = gnutls_x509_crt_import(xpriv, data, format);
2079 if (ret < 0)
2081 gnutls_assert();
2082 goto cleanup;
2085 ret = gnutls_pubkey_import_x509(pkey, xpriv, flags);
2086 if (ret < 0)
2088 gnutls_assert();
2089 goto cleanup;
2092 return 0;
2094 cleanup:
2095 gnutls_x509_crt_deinit(xpriv);
2097 return ret;