Fixed leaks in key generation and other cleanups. Patch by Tomas Mraz.
[gnutls.git] / lib / gnutls_pubkey.c
blobdc4f545482aa1f7eb017841a5cd571649a992e62
1 /*
2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010 Free Software Foundation
4 *
5 * Author: Nikos Mavrogiannopoulos
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 * MA 02111-1307, USA
23 #include <gnutls_int.h>
24 #include <gnutls/pkcs11.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <gnutls_errors.h>
28 #include <gnutls_datum.h>
29 #include <pkcs11_int.h>
30 #include <gnutls/abstract.h>
31 #include <gnutls_pk.h>
32 #include <x509_int.h>
33 #include <openpgp/openpgp_int.h>
34 #include <gnutls_num.h>
35 #include <x509/common.h>
36 #include <x509_b64.h>
37 #include <abstract_int.h>
39 #define PK_PEM_HEADER "PUBLIC KEY"
42 struct gnutls_pubkey_st
44 gnutls_pk_algorithm_t pk_algorithm;
45 unsigned int bits; /* an indication of the security parameter */
47 /* the size of params depends on the public
48 * key algorithm
49 * RSA: [0] is modulus
50 * [1] is public exponent
51 * DSA: [0] is p
52 * [1] is q
53 * [2] is g
54 * [3] is public key
56 bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
57 int params_size; /* holds the size of MPI params */
59 unsigned int key_usage; /* bits from GNUTLS_KEY_* */
62 static int pubkey_to_bits(gnutls_pk_algorithm_t pk, bigint_t* params, int params_size)
64 switch(pk)
66 case GNUTLS_PK_RSA:
67 return _gnutls_mpi_get_nbits(params[0]);
68 case GNUTLS_PK_DSA:
69 if (params_size < 3) return 0;
70 return _gnutls_mpi_get_nbits(params[3]);
71 default:
72 return 0;
76 /**
77 * gnutls_pubkey_get_pk_algorithm:
78 * @key: should contain a #gnutls_pubkey_t structure
79 * @bits: If set will return the number of bits of the parameters (may be NULL)
81 * This function will return the public key algorithm of a public
82 * key and if possible will return a number of bits that indicates
83 * the security parameter of the key.
85 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
86 * success, or a negative value on error.
87 **/
88 int
89 gnutls_pubkey_get_pk_algorithm (gnutls_pubkey_t key, unsigned int *bits)
91 if (bits)
92 *bits = key->bits;
94 return key->pk_algorithm;
97 /**
98 * gnutls_pubkey_get_key_usage:
99 * @key: should contain a #gnutls_pubkey_t structure
100 * @usage: If set will return the number of bits of the parameters (may be NULL)
102 * This function will return the key usage of the public key.
104 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
105 * negative error value.
108 gnutls_pubkey_get_key_usage (gnutls_pubkey_t key, unsigned int *usage)
110 if (usage)
111 *usage = key->key_usage;
113 return 0;
117 * gnutls_pubkey_init:
118 * @key: The structure to be initialized
120 * This function will initialize an public key structure.
122 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
123 * negative error value.
126 gnutls_pubkey_init (gnutls_pubkey_t * key)
128 *key = gnutls_calloc (1, sizeof (struct gnutls_pubkey_st));
129 if (*key == NULL)
131 gnutls_assert ();
132 return GNUTLS_E_MEMORY_ERROR;
135 return 0;
139 * gnutls_pubkey_deinit:
140 * @key: The structure to be deinitialized
142 * This function will deinitialize a public key structure.
144 void
145 gnutls_pubkey_deinit (gnutls_pubkey_t key)
147 int i;
149 for (i = 0; i < key->params_size; i++)
151 _gnutls_mpi_release (&key->params[i]);
154 gnutls_free (key);
158 * gnutls_pubkey_import_x509:
159 * @key: The public key
160 * @crt: The certificate to be imported
161 * @flags: should be zero
163 * This function will import the given public key to the abstract
164 * #gnutls_pubkey_t structure.
166 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
167 * negative error value.
170 gnutls_pubkey_import_x509 (gnutls_pubkey_t key, gnutls_x509_crt_t crt,
171 unsigned int flags)
173 int ret;
175 key->pk_algorithm = gnutls_x509_crt_get_pk_algorithm (crt, &key->bits);
177 ret = gnutls_x509_crt_get_key_usage (crt, &key->key_usage, NULL);
178 if (ret < 0)
179 key->key_usage = 0;
181 key->params_size = sizeof (key->params) / sizeof (key->params[0]);
182 switch (key->pk_algorithm)
184 case GNUTLS_PK_RSA:
185 ret = _gnutls_x509_crt_get_mpis (crt, key->params, &key->params_size);
186 if (ret < 0)
188 gnutls_assert ();
189 return ret;
191 break;
192 case GNUTLS_PK_DSA:
193 ret = _gnutls_x509_crt_get_mpis (crt, key->params, &key->params_size);
194 if (ret < 0)
196 gnutls_assert ();
197 return ret;
200 break;
201 default:
202 gnutls_assert ();
203 return GNUTLS_E_INVALID_REQUEST;
206 return 0;
210 * gnutls_pubkey_import_privkey: Imports the public key from a private
211 * @key: The public key
212 * @pkey: The private key
213 * @usage: GNUTLS_KEY_* key usage flags.
214 * @flags: should be zero
216 * This function will import the given public key to the abstract
217 * #gnutls_pubkey_t structure.
219 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
220 * negative error value.
222 * Since: 2.12.0
225 gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey,
226 unsigned int usage, unsigned int flags)
228 key->pk_algorithm = gnutls_privkey_get_pk_algorithm (pkey, &key->bits);
230 key->key_usage = usage;
232 key->params_size = sizeof (key->params) / sizeof (key->params[0]);
234 return _gnutls_privkey_get_public_mpis (pkey, key->params,
235 &key->params_size);
239 * gnutls_pubkey_get_preferred_hash_algorithm:
240 * @key: Holds the certificate
241 * @hash: The result of the call with the hash algorithm used for signature
242 * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL.
244 * This function will read the certifcate and return the appropriate digest
245 * algorithm to use for signing with this certificate. Some certificates (i.e.
246 * DSA might not be able to sign without the preferred algorithm).
248 * Returns: the 0 if the hash algorithm is found. A negative value is
249 * returned on error.
251 * Since: 2.11.0
254 gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key,
255 gnutls_digest_algorithm_t *
256 hash, unsigned int *mand)
258 int ret;
260 if (key == NULL)
262 gnutls_assert ();
263 return GNUTLS_E_INVALID_REQUEST;
266 ret = _gnutls_pk_get_hash_algorithm (key->pk_algorithm,
267 key->params, key->params_size,
268 hash, mand);
270 return ret;
273 #ifdef ENABLE_PKCS11
276 * gnutls_pubkey_import_pkcs11: Imports a public key from a pkcs11 key
277 * @key: The public key
278 * @obj: The parameters to be imported
279 * @flags: should be zero
281 * This function will import the given public key to the abstract
282 * #gnutls_pubkey_t structure.
284 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
285 * negative error value.
288 gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key,
289 gnutls_pkcs11_obj_t obj, unsigned int flags)
291 int ret;
293 ret = gnutls_pkcs11_obj_get_type (obj);
294 if (ret != GNUTLS_PKCS11_OBJ_PUBKEY)
296 gnutls_assert ();
297 return GNUTLS_E_INVALID_REQUEST;
300 key->key_usage = obj->key_usage;
302 switch (obj->pk_algorithm)
304 case GNUTLS_PK_RSA:
305 ret = gnutls_pubkey_import_rsa_raw (key, &obj->pubkey[0],
306 &obj->pubkey[1]);
307 break;
308 case GNUTLS_PK_DSA:
309 ret = gnutls_pubkey_import_dsa_raw (key, &obj->pubkey[0],
310 &obj->pubkey[1],
311 &obj->pubkey[2], &obj->pubkey[3]);
312 break;
313 default:
314 gnutls_assert ();
315 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
318 if (ret < 0)
320 gnutls_assert ();
321 return ret;
324 return 0;
327 #endif /* ENABLE_PKCS11 */
329 #ifdef ENABLE_OPENPGP
331 * gnutls_pubkey_import_openpgp: Imports a public key from an openpgp key
332 * @key: The public key
333 * @crt: The certificate to be imported
334 * @flags: should be zero
336 * This function will import the given public key to the abstract
337 * #gnutls_pubkey_t structure. The subkey set as preferred will be
338 * imported or the master key otherwise.
340 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
341 * negative error value.
344 gnutls_pubkey_import_openpgp (gnutls_pubkey_t key,
345 gnutls_openpgp_crt_t crt,
346 unsigned int flags)
348 int ret, idx;
349 uint32_t kid32[2];
350 uint32_t *k;
351 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
353 ret = gnutls_openpgp_crt_get_preferred_key_id (crt, keyid);
354 if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR)
356 key->pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (crt, &key->bits);
358 ret = gnutls_openpgp_crt_get_key_usage (crt, &key->key_usage);
359 if (ret < 0)
360 key->key_usage = 0;
362 k = NULL;
364 else
366 if (ret < 0)
368 gnutls_assert ();
369 return ret;
372 KEYID_IMPORT (kid32, keyid);
373 k = kid32;
375 idx = gnutls_openpgp_crt_get_subkey_idx (crt, keyid);
377 ret = gnutls_openpgp_crt_get_subkey_usage (crt, idx, &key->key_usage);
378 if (ret < 0)
379 key->key_usage = 0;
381 key->pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm (crt, idx, NULL);
384 switch (key->pk_algorithm)
386 case GNUTLS_PK_RSA:
387 ret =
388 _gnutls_openpgp_crt_get_mpis (crt, k, key->params,
389 &key->params_size);
390 if (ret < 0)
392 gnutls_assert ();
393 return ret;
395 break;
396 case GNUTLS_PK_DSA:
397 ret =
398 _gnutls_openpgp_crt_get_mpis (crt, k, key->params,
399 &key->params_size);
400 if (ret < 0)
402 gnutls_assert ();
403 return ret;
405 break;
406 default:
407 gnutls_assert ();
408 return GNUTLS_E_INVALID_REQUEST;
411 return 0;
414 #endif
417 * gnutls_pubkey_export:
418 * @key: Holds the certificate
419 * @format: the format of output params. One of PEM or DER.
420 * @output_data: will contain a certificate PEM or DER encoded
421 * @output_data_size: holds the size of output_data (and will be
422 * replaced by the actual size of parameters)
424 * This function will export the certificate to DER or PEM format.
426 * If the buffer provided is not long enough to hold the output, then
427 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
428 * be returned.
430 * If the structure is PEM encoded, it will have a header
431 * of "BEGIN CERTIFICATE".
433 * Return value: In case of failure a negative value will be
434 * returned, and 0 on success.
437 gnutls_pubkey_export (gnutls_pubkey_t key,
438 gnutls_x509_crt_fmt_t format, void *output_data,
439 size_t * output_data_size)
441 int result;
442 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
444 if (key == NULL)
446 gnutls_assert ();
447 return GNUTLS_E_INVALID_REQUEST;
450 if ((result = asn1_create_element
451 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
452 != ASN1_SUCCESS)
454 gnutls_assert ();
455 return _gnutls_asn2err (result);
458 result =
459 _gnutls_x509_encode_and_copy_PKI_params (spk, "",
460 key->pk_algorithm,
461 key->params, key->params_size);
462 if (result < 0)
464 gnutls_assert ();
465 goto cleanup;
468 result = _gnutls_x509_export_int_named (spk, "",
469 format, PK_PEM_HEADER,
470 output_data, output_data_size);
471 if (result < 0)
473 gnutls_assert ();
474 goto cleanup;
477 result = 0;
479 cleanup:
480 asn1_delete_structure (&spk);
482 return result;
487 * gnutls_pubkey_get_key_id:
488 * @key: Holds the public key
489 * @flags: should be 0 for now
490 * @output_data: will contain the key ID
491 * @output_data_size: holds the size of output_data (and will be
492 * replaced by the actual size of parameters)
494 * This function will return a unique ID the depends on the public
495 * key parameters. This ID can be used in checking whether a
496 * certificate corresponds to the given public key.
498 * If the buffer provided is not long enough to hold the output, then
499 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
500 * be returned. The output will normally be a SHA-1 hash output,
501 * which is 20 bytes.
503 * Return value: In case of failure a negative value will be
504 * returned, and 0 on success.
507 gnutls_pubkey_get_key_id (gnutls_pubkey_t key, unsigned int flags,
508 unsigned char *output_data,
509 size_t * output_data_size)
511 int ret = 0;
513 if (key == NULL)
515 gnutls_assert ();
516 return GNUTLS_E_INVALID_REQUEST;
519 ret =
520 _gnutls_get_key_id (key->pk_algorithm, key->params,
521 key->params_size, output_data, output_data_size);
522 if (ret < 0)
524 gnutls_assert ();
525 return ret;
528 return 0;
532 * gnutls_pubkey_get_pk_rsa_raw:
533 * @key: Holds the certificate
534 * @m: will hold the modulus
535 * @e: will hold the public exponent
537 * This function will export the RSA public key's parameters found in
538 * the given structure. The new parameters will be allocated using
539 * gnutls_malloc() and will be stored in the appropriate datum.
541 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
544 gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t key,
545 gnutls_datum_t * m, gnutls_datum_t * e)
547 int ret;
549 if (key == NULL)
551 gnutls_assert ();
552 return GNUTLS_E_INVALID_REQUEST;
555 if (key->pk_algorithm != GNUTLS_PK_RSA)
557 gnutls_assert ();
558 return GNUTLS_E_INVALID_REQUEST;
561 ret = _gnutls_mpi_dprint_lz (key->params[0], m);
562 if (ret < 0)
564 gnutls_assert ();
565 return ret;
568 ret = _gnutls_mpi_dprint_lz (key->params[1], e);
569 if (ret < 0)
571 gnutls_assert ();
572 _gnutls_free_datum (m);
573 return ret;
576 return 0;
580 * gnutls_pubkey_get_pk_dsa_raw:
581 * @key: Holds the public key
582 * @p: will hold the p
583 * @q: will hold the q
584 * @g: will hold the g
585 * @y: will hold the y
587 * This function will export the DSA public key's parameters found in
588 * the given certificate. The new parameters will be allocated using
589 * gnutls_malloc() and will be stored in the appropriate datum.
591 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
594 gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
595 gnutls_datum_t * p, gnutls_datum_t * q,
596 gnutls_datum_t * g, gnutls_datum_t * y)
598 int ret;
600 if (key == NULL)
602 gnutls_assert ();
603 return GNUTLS_E_INVALID_REQUEST;
606 if (key->pk_algorithm != GNUTLS_PK_DSA)
608 gnutls_assert ();
609 return GNUTLS_E_INVALID_REQUEST;
612 /* P */
613 ret = _gnutls_mpi_dprint_lz (key->params[0], p);
614 if (ret < 0)
616 gnutls_assert ();
617 return ret;
620 /* Q */
621 ret = _gnutls_mpi_dprint_lz (key->params[1], q);
622 if (ret < 0)
624 gnutls_assert ();
625 _gnutls_free_datum (p);
626 return ret;
630 /* G */
631 ret = _gnutls_mpi_dprint_lz (key->params[2], g);
632 if (ret < 0)
634 gnutls_assert ();
635 _gnutls_free_datum (p);
636 _gnutls_free_datum (q);
637 return ret;
641 /* Y */
642 ret = _gnutls_mpi_dprint_lz (key->params[3], y);
643 if (ret < 0)
645 gnutls_assert ();
646 _gnutls_free_datum (p);
647 _gnutls_free_datum (g);
648 _gnutls_free_datum (q);
649 return ret;
652 return 0;
656 * gnutls_pubkey_import:
657 * @key: The structure to store the parsed public key.
658 * @data: The DER or PEM encoded certificate.
659 * @format: One of DER or PEM
661 * This function will convert the given DER or PEM encoded Public key
662 * to the native gnutls_pubkey_t format.The output will be stored * in @ key.
663 * If the Certificate is PEM encoded it should have a header of "PUBLIC KEY".
665 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
666 * negative error value.
669 gnutls_pubkey_import (gnutls_pubkey_t key,
670 const gnutls_datum_t * data,
671 gnutls_x509_crt_fmt_t format)
673 int result = 0, need_free = 0;
674 gnutls_datum_t _data;
675 ASN1_TYPE spk;
677 if (key == NULL)
679 gnutls_assert ();
680 return GNUTLS_E_INVALID_REQUEST;
683 _data.data = data->data;
684 _data.size = data->size;
686 /* If the Certificate is in PEM format then decode it
688 if (format == GNUTLS_X509_FMT_PEM)
690 opaque *out;
692 /* Try the first header */
693 result =
694 _gnutls_fbase64_decode (PK_PEM_HEADER, data->data, data->size, &out);
696 if (result <= 0)
698 if (result == 0)
699 result = GNUTLS_E_INTERNAL_ERROR;
700 gnutls_assert ();
701 return result;
704 _data.data = out;
705 _data.size = result;
707 need_free = 1;
710 if ((result = asn1_create_element
711 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
712 != ASN1_SUCCESS)
714 gnutls_assert ();
715 result = _gnutls_asn2err (result);
716 goto cleanup;
719 result = asn1_der_decoding (&spk, _data.data, _data.size, NULL);
720 if (result != ASN1_SUCCESS)
722 gnutls_assert ();
723 result = _gnutls_asn2err (result);
724 goto cleanup;
727 key->params_size = sizeof (key->params) / sizeof (key->params[0]);
728 result = _gnutls_get_asn_mpis (spk, "", key->params, &key->params_size);
729 if (result < 0)
731 gnutls_assert ();
732 goto cleanup;
735 /* this has already been called by get_asn_mpis() thus it cannot
736 * fail.
738 key->pk_algorithm = _gnutls_x509_get_pk_algorithm (spk, "", NULL);
739 key->bits = pubkey_to_bits(key->pk_algorithm, key->params, key->params_size);
741 result = 0;
743 cleanup:
744 asn1_delete_structure (&spk);
746 if (need_free)
747 _gnutls_free_datum (&_data);
748 return result;
752 * gnutls_x509_crt_set_pubkey:
753 * @crt: should contain a #gnutls_x509_crt_t structure
754 * @key: holds a public key
756 * This function will set the public parameters from the given public
757 * key to the request.
759 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
760 * negative error value.
763 gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, gnutls_pubkey_t key)
765 int result;
767 if (crt == NULL)
769 gnutls_assert ();
770 return GNUTLS_E_INVALID_REQUEST;
773 result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
774 "tbsCertificate.subjectPublicKeyInfo",
775 key->pk_algorithm,
776 key->params,
777 key->params_size);
779 if (result < 0)
781 gnutls_assert ();
782 return result;
785 if (key->key_usage)
786 gnutls_x509_crt_set_key_usage (crt, key->key_usage);
788 return 0;
792 * gnutls_x509_crq_set_pubkey:
793 * @crq: should contain a #gnutls_x509_crq_t structure
794 * @key: holds a public key
796 * This function will set the public parameters from the given public
797 * key to the request.
799 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
800 * negative error value.
803 gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key)
805 int result;
807 if (crq == NULL)
809 gnutls_assert ();
810 return GNUTLS_E_INVALID_REQUEST;
813 result = _gnutls_x509_encode_and_copy_PKI_params
814 (crq->crq,
815 "certificationRequestInfo.subjectPKInfo",
816 key->pk_algorithm, key->params, key->params_size);
818 if (result < 0)
820 gnutls_assert ();
821 return result;
824 if (key->key_usage)
825 gnutls_x509_crq_set_key_usage (crq, key->key_usage);
827 return 0;
831 * gnutls_pubkey_set_key_usage:
832 * @key: a certificate of type #gnutls_x509_crt_t
833 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
835 * This function will set the key usage flags of the public key. This
836 * is only useful if the key is to be exported to a certificate or
837 * certificate request.
839 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
840 * negative error value.
843 gnutls_pubkey_set_key_usage (gnutls_pubkey_t key, unsigned int usage)
845 key->key_usage = usage;
847 return 0;
850 #ifdef ENABLE_PKCS11
853 * gnutls_pubkey_import_pkcs11_url:
854 * @key: A key of type #gnutls_pubkey_t
855 * @url: A PKCS 11 url
856 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
858 * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
859 * structure.
861 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
862 * negative error value.
866 gnutls_pubkey_import_pkcs11_url (gnutls_pubkey_t key, const char *url,
867 unsigned int flags)
869 gnutls_pkcs11_obj_t pcrt;
870 int ret;
872 ret = gnutls_pkcs11_obj_init (&pcrt);
873 if (ret < 0)
875 gnutls_assert ();
876 return ret;
879 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
880 if (ret < 0)
882 gnutls_assert ();
883 goto cleanup;
886 ret = gnutls_pubkey_import_pkcs11 (key, pcrt, 0);
887 if (ret < 0)
889 gnutls_assert ();
890 goto cleanup;
893 ret = 0;
894 cleanup:
896 gnutls_pkcs11_obj_deinit (pcrt);
898 return ret;
901 #endif /* ENABLE_PKCS11 */
904 * gnutls_pubkey_import_rsa_raw:
905 * @key: Is a structure will hold the parameters
906 * @m: holds the modulus
907 * @e: holds the public exponent
909 * This function will replace the parameters in the given structure.
910 * The new parameters should be stored in the appropriate
911 * gnutls_datum.
913 * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
916 gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key,
917 const gnutls_datum_t * m,
918 const gnutls_datum_t * e)
920 size_t siz = 0;
922 if (key == NULL)
924 gnutls_assert ();
925 return GNUTLS_E_INVALID_REQUEST;
928 siz = m->size;
929 if (_gnutls_mpi_scan_nz (&key->params[0], m->data, siz))
931 gnutls_assert ();
932 return GNUTLS_E_MPI_SCAN_FAILED;
935 siz = e->size;
936 if (_gnutls_mpi_scan_nz (&key->params[1], e->data, siz))
938 gnutls_assert ();
939 _gnutls_mpi_release (&key->params[0]);
940 return GNUTLS_E_MPI_SCAN_FAILED;
943 key->params_size = RSA_PUBLIC_PARAMS;
944 key->pk_algorithm = GNUTLS_PK_RSA;
945 key->bits = pubkey_to_bits(GNUTLS_PK_RSA, key->params, key->params_size);
947 return 0;
951 * gnutls_pubkey_import_dsa_raw:
952 * @key: The structure to store the parsed key
953 * @p: holds the p
954 * @q: holds the q
955 * @g: holds the g
956 * @y: holds the y
958 * This function will convert the given DSA raw parameters to the
959 * native #gnutls_pubkey_t format. The output will be stored
960 * in @key.
962 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
963 * negative error value.
966 gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key,
967 const gnutls_datum_t * p,
968 const gnutls_datum_t * q,
969 const gnutls_datum_t * g,
970 const gnutls_datum_t * y)
972 size_t siz = 0;
974 if (key == NULL)
976 gnutls_assert ();
977 return GNUTLS_E_INVALID_REQUEST;
980 siz = p->size;
981 if (_gnutls_mpi_scan_nz (&key->params[0], p->data, siz))
983 gnutls_assert ();
984 return GNUTLS_E_MPI_SCAN_FAILED;
987 siz = q->size;
988 if (_gnutls_mpi_scan_nz (&key->params[1], q->data, siz))
990 gnutls_assert ();
991 _gnutls_mpi_release (&key->params[0]);
992 return GNUTLS_E_MPI_SCAN_FAILED;
995 siz = g->size;
996 if (_gnutls_mpi_scan_nz (&key->params[2], g->data, siz))
998 gnutls_assert ();
999 _gnutls_mpi_release (&key->params[1]);
1000 _gnutls_mpi_release (&key->params[0]);
1001 return GNUTLS_E_MPI_SCAN_FAILED;
1004 siz = y->size;
1005 if (_gnutls_mpi_scan_nz (&key->params[3], y->data, siz))
1007 gnutls_assert ();
1008 _gnutls_mpi_release (&key->params[2]);
1009 _gnutls_mpi_release (&key->params[1]);
1010 _gnutls_mpi_release (&key->params[0]);
1011 return GNUTLS_E_MPI_SCAN_FAILED;
1014 key->params_size = DSA_PUBLIC_PARAMS;
1015 key->pk_algorithm = GNUTLS_PK_DSA;
1016 key->bits = pubkey_to_bits(GNUTLS_PK_DSA, key->params, key->params_size);
1018 return 0;
1023 * gnutls_pubkey_verify_data:
1024 * @pubkey: Holds the public key
1025 * @flags: should be 0 for now
1026 * @data: holds the data to be signed
1027 * @signature: contains the signature
1029 * This function will verify the given signed data, using the
1030 * parameters from the certificate.
1032 * Returns: In case of a verification failure
1033 * %GNUTLS_E_PK_SIG_VERIFY_FAILED is returned, and a positive code
1034 * on success.
1036 * Since: 2.12.0
1039 gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, unsigned int flags,
1040 const gnutls_datum_t * data,
1041 const gnutls_datum_t * signature)
1043 int ret;
1045 if (pubkey == NULL)
1047 gnutls_assert ();
1048 return GNUTLS_E_INVALID_REQUEST;
1051 ret = pubkey_verify_sig( data, NULL, signature, pubkey->pk_algorithm,
1052 pubkey->params, pubkey->params_size);
1053 if (ret < 0)
1055 gnutls_assert();
1058 return ret;
1063 * gnutls_pubkey_verify_hash:
1064 * @key: Holds the certificate
1065 * @flags: should be 0 for now
1066 * @hash: holds the hash digest to be verified
1067 * @signature: contains the signature
1069 * This function will verify the given signed digest, using the
1070 * parameters from the certificate.
1072 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1073 * is returned, and a positive code on success.
1076 gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
1077 const gnutls_datum_t * hash,
1078 const gnutls_datum_t * signature)
1080 int ret;
1082 if (key == NULL)
1084 gnutls_assert ();
1085 return GNUTLS_E_INVALID_REQUEST;
1088 ret =
1089 pubkey_verify_sig (NULL, hash, signature, key->pk_algorithm,
1090 key->params, key->params_size);
1092 return ret;
1096 * gnutls_pubkey_get_verify_algorithm:
1097 * @key: Holds the certificate
1098 * @signature: contains the signature
1099 * @hash: The result of the call with the hash algorithm used for signature
1101 * This function will read the certifcate and the signed data to
1102 * determine the hash algorithm used to generate the signature.
1104 * Returns: the 0 if the hash algorithm is found. A negative value is
1105 * returned on error.
1108 gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
1109 const gnutls_datum_t * signature,
1110 gnutls_digest_algorithm_t * hash)
1112 if (key == NULL)
1114 gnutls_assert ();
1115 return GNUTLS_E_INVALID_REQUEST;
1118 return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *)
1119 hash, signature,
1120 key->pk_algorithm,
1121 key->params, key->params_size);