Corrected initialization of key when generating request. Reported by Petr Pisar.
[gnutls.git] / lib / gnutls_pubkey.c
blob49688f7975a11011b95ef2fcc67dbe3c1ff2b6a9
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 <pakchois/pakchois.h>
25 #include <gnutls/pkcs11.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <gnutls_errors.h>
29 #include <gnutls_datum.h>
30 #include <pkcs11_int.h>
31 #include <gnutls/abstract.h>
32 #include <gnutls_pk.h>
33 #include <x509_int.h>
34 #include <openpgp/openpgp_int.h>
35 #include <pkcs11_int.h>
36 #include <gnutls_num.h>
37 #include <x509/common.h>
38 #include <x509_b64.h>
39 #include <abstract_int.h>
41 #define PK_PEM_HEADER "PUBLIC KEY"
44 struct gnutls_pubkey_st
46 gnutls_pk_algorithm_t pk_algorithm;
47 unsigned int bits; /* an indication of the security parameter */
49 /* the size of params depends on the public
50 * key algorithm
51 * RSA: [0] is modulus
52 * [1] is public exponent
53 * DSA: [0] is p
54 * [1] is q
55 * [2] is g
56 * [3] is public key
58 bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
59 int params_size; /* holds the size of MPI params */
61 unsigned int key_usage; /* bits from GNUTLS_KEY_* */
64 static int pubkey_to_bits(gnutls_pk_algorithm_t pk, bigint_t* params, int params_size)
66 switch(pk)
68 case GNUTLS_PK_RSA:
69 return _gnutls_mpi_get_nbits(params[0]);
70 case GNUTLS_PK_DSA:
71 if (params_size < 3) return 0;
72 return _gnutls_mpi_get_nbits(params[3]);
73 default:
74 return 0;
78 /**
79 * gnutls_pubkey_get_pk_algorithm:
80 * @key: should contain a #gnutls_pubkey_t structure
81 * @bits: If set will return the number of bits of the parameters (may be NULL)
83 * This function will return the public key algorithm of a public
84 * key and if possible will return a number of bits that indicates
85 * the security parameter of the key.
87 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
88 * success, or a negative value on error.
89 **/
90 int
91 gnutls_pubkey_get_pk_algorithm (gnutls_pubkey_t key, unsigned int *bits)
93 if (bits)
94 *bits = key->bits;
96 return key->pk_algorithm;
99 /**
100 * gnutls_pubkey_get_key_usage:
101 * @key: should contain a #gnutls_pubkey_t structure
102 * @usage: If set will return the number of bits of the parameters (may be NULL)
104 * This function will return the key usage of the public key.
106 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
107 * negative error value.
110 gnutls_pubkey_get_key_usage (gnutls_pubkey_t key, unsigned int *usage)
112 if (usage)
113 *usage = key->key_usage;
115 return 0;
119 * gnutls_pubkey_init:
120 * @key: The structure to be initialized
122 * This function will initialize an public key structure.
124 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
125 * negative error value.
128 gnutls_pubkey_init (gnutls_pubkey_t * key)
130 *key = gnutls_calloc (1, sizeof (struct gnutls_pubkey_st));
131 if (*key == NULL)
133 gnutls_assert ();
134 return GNUTLS_E_MEMORY_ERROR;
137 return 0;
141 * gnutls_pubkey_deinit:
142 * @key: The structure to be deinitialized
144 * This function will deinitialize a public key structure.
146 void
147 gnutls_pubkey_deinit (gnutls_pubkey_t key)
149 int i;
151 for (i = 0; i < key->params_size; i++)
153 _gnutls_mpi_release (&key->params[i]);
156 gnutls_free (key);
160 * gnutls_pubkey_import_x509:
161 * @key: The public key
162 * @crt: The certificate to be imported
163 * @flags: should be zero
165 * This function will import the given public key to the abstract
166 * #gnutls_pubkey_t structure.
168 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
169 * negative error value.
172 gnutls_pubkey_import_x509 (gnutls_pubkey_t key, gnutls_x509_crt_t crt,
173 unsigned int flags)
175 int ret;
177 key->pk_algorithm = gnutls_x509_crt_get_pk_algorithm (crt, &key->bits);
179 ret = gnutls_x509_crt_get_key_usage (crt, &key->key_usage, NULL);
180 if (ret < 0)
181 key->key_usage = 0;
183 key->params_size = sizeof (key->params) / sizeof (key->params[0]);
184 switch (key->pk_algorithm)
186 case GNUTLS_PK_RSA:
187 ret = _gnutls_x509_crt_get_mpis (crt, key->params, &key->params_size);
188 if (ret < 0)
190 gnutls_assert ();
191 return ret;
193 break;
194 case GNUTLS_PK_DSA:
195 ret = _gnutls_x509_crt_get_mpis (crt, key->params, &key->params_size);
196 if (ret < 0)
198 gnutls_assert ();
199 return ret;
202 break;
203 default:
204 gnutls_assert ();
205 return GNUTLS_E_INVALID_REQUEST;
208 return 0;
212 * gnutls_pubkey_import_privkey: Imports the public key from a private
213 * @key: The public key
214 * @pkey: The private key
215 * @usage: GNUTLS_KEY_* key usage flags.
216 * @flags: should be zero
218 * This function will import the given public key to the abstract
219 * #gnutls_pubkey_t structure.
221 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
222 * negative error value.
224 * Since: 2.12.0
227 gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey,
228 unsigned int usage, unsigned int flags)
230 key->pk_algorithm = gnutls_privkey_get_pk_algorithm (pkey, &key->bits);
232 key->key_usage = usage;
234 key->params_size = sizeof (key->params) / sizeof (key->params[0]);
236 return _gnutls_privkey_get_public_mpis (pkey, key->params,
237 &key->params_size);
241 * gnutls_pubkey_get_preferred_hash_algorithm:
242 * @key: Holds the certificate
243 * @hash: The result of the call with the hash algorithm used for signature
244 * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL.
246 * This function will read the certifcate and return the appropriate digest
247 * algorithm to use for signing with this certificate. Some certificates (i.e.
248 * DSA might not be able to sign without the preferred algorithm).
250 * Returns: the 0 if the hash algorithm is found. A negative value is
251 * returned on error.
253 * Since: 2.11.0
256 gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key,
257 gnutls_digest_algorithm_t *
258 hash, unsigned int *mand)
260 int ret;
262 if (key == NULL)
264 gnutls_assert ();
265 return GNUTLS_E_INVALID_REQUEST;
268 ret = _gnutls_pk_get_hash_algorithm (key->pk_algorithm,
269 key->params, key->params_size,
270 hash, mand);
272 return ret;
277 * gnutls_pubkey_import_pkcs11: Imports a public key from a pkcs11 key
278 * @key: The public key
279 * @obj: The parameters to be imported
280 * @flags: should be zero
282 * This function will import the given public key to the abstract
283 * #gnutls_pubkey_t structure.
285 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
286 * negative error value.
289 gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key,
290 gnutls_pkcs11_obj_t obj, unsigned int flags)
292 int ret;
294 ret = gnutls_pkcs11_obj_get_type (obj);
295 if (ret != GNUTLS_PKCS11_OBJ_PUBKEY)
297 gnutls_assert ();
298 return GNUTLS_E_INVALID_REQUEST;
301 key->key_usage = obj->key_usage;
303 switch (obj->pk_algorithm)
305 case GNUTLS_PK_RSA:
306 ret = gnutls_pubkey_import_rsa_raw (key, &obj->pubkey[0],
307 &obj->pubkey[1]);
308 break;
309 case GNUTLS_PK_DSA:
310 ret = gnutls_pubkey_import_dsa_raw (key, &obj->pubkey[0],
311 &obj->pubkey[1],
312 &obj->pubkey[2], &obj->pubkey[3]);
313 break;
314 default:
315 gnutls_assert ();
316 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
319 if (ret < 0)
321 gnutls_assert ();
322 return ret;
325 return 0;
328 #ifdef ENABLE_OPENPGP
330 * gnutls_pubkey_import_openpgp: Imports a public key from an openpgp key
331 * @key: The public key
332 * @crt: The certificate to be imported
333 * @flags: should be zero
335 * This function will import the given public key to the abstract
336 * #gnutls_pubkey_t structure. The subkey set as preferred will be
337 * imported or the master key otherwise.
339 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
340 * negative error value.
343 gnutls_pubkey_import_openpgp (gnutls_pubkey_t key,
344 gnutls_openpgp_crt_t crt,
345 unsigned int flags)
347 int ret, idx;
348 uint32_t kid32[2];
349 uint32_t *k;
350 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
352 ret = gnutls_openpgp_crt_get_preferred_key_id (crt, keyid);
353 if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR)
355 key->pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (crt, &key->bits);
357 ret = gnutls_openpgp_crt_get_key_usage (crt, &key->key_usage);
358 if (ret < 0)
359 key->key_usage = 0;
361 k = NULL;
363 else
365 if (ret < 0)
367 gnutls_assert ();
368 return ret;
371 KEYID_IMPORT (kid32, keyid);
372 k = kid32;
374 idx = gnutls_openpgp_crt_get_subkey_idx (crt, keyid);
376 ret = gnutls_openpgp_crt_get_subkey_usage (crt, idx, &key->key_usage);
377 if (ret < 0)
378 key->key_usage = 0;
380 key->pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm (crt, idx, NULL);
383 switch (key->pk_algorithm)
385 case GNUTLS_PK_RSA:
386 ret =
387 _gnutls_openpgp_crt_get_mpis (crt, k, key->params,
388 &key->params_size);
389 if (ret < 0)
391 gnutls_assert ();
392 return ret;
394 break;
395 case GNUTLS_PK_DSA:
396 ret =
397 _gnutls_openpgp_crt_get_mpis (crt, k, key->params,
398 &key->params_size);
399 if (ret < 0)
401 gnutls_assert ();
402 return ret;
404 break;
405 default:
406 gnutls_assert ();
407 return GNUTLS_E_INVALID_REQUEST;
410 return 0;
413 #endif
416 * gnutls_pubkey_export:
417 * @key: Holds the certificate
418 * @format: the format of output params. One of PEM or DER.
419 * @output_data: will contain a certificate PEM or DER encoded
420 * @output_data_size: holds the size of output_data (and will be
421 * replaced by the actual size of parameters)
423 * This function will export the certificate to DER or PEM format.
425 * If the buffer provided is not long enough to hold the output, then
426 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
427 * be returned.
429 * If the structure is PEM encoded, it will have a header
430 * of "BEGIN CERTIFICATE".
432 * Return value: In case of failure a negative value will be
433 * returned, and 0 on success.
436 gnutls_pubkey_export (gnutls_pubkey_t key,
437 gnutls_x509_crt_fmt_t format, void *output_data,
438 size_t * output_data_size)
440 int result;
441 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
443 if (key == NULL)
445 gnutls_assert ();
446 return GNUTLS_E_INVALID_REQUEST;
449 if ((result = asn1_create_element
450 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
451 != ASN1_SUCCESS)
453 gnutls_assert ();
454 return _gnutls_asn2err (result);
457 result =
458 _gnutls_x509_encode_and_copy_PKI_params (spk, "",
459 key->pk_algorithm,
460 key->params, key->params_size);
461 if (result < 0)
463 gnutls_assert ();
464 goto cleanup;
467 result = _gnutls_x509_export_int_named (spk, "",
468 format, PK_PEM_HEADER,
469 output_data, output_data_size);
470 if (result < 0)
472 gnutls_assert ();
473 goto cleanup;
476 result = 0;
478 cleanup:
479 asn1_delete_structure (&spk);
481 return result;
486 * gnutls_pubkey_get_key_id:
487 * @key: Holds the public key
488 * @flags: should be 0 for now
489 * @output_data: will contain the key ID
490 * @output_data_size: holds the size of output_data (and will be
491 * replaced by the actual size of parameters)
493 * This function will return a unique ID the depends on the public
494 * key parameters. This ID can be used in checking whether a
495 * certificate corresponds to the given public key.
497 * If the buffer provided is not long enough to hold the output, then
498 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
499 * be returned. The output will normally be a SHA-1 hash output,
500 * which is 20 bytes.
502 * Return value: In case of failure a negative value will be
503 * returned, and 0 on success.
506 gnutls_pubkey_get_key_id (gnutls_pubkey_t key, unsigned int flags,
507 unsigned char *output_data,
508 size_t * output_data_size)
510 int ret = 0;
512 if (key == NULL)
514 gnutls_assert ();
515 return GNUTLS_E_INVALID_REQUEST;
518 ret =
519 _gnutls_get_key_id (key->pk_algorithm, key->params,
520 key->params_size, output_data, output_data_size);
521 if (ret < 0)
523 gnutls_assert ();
524 return ret;
527 return 0;
531 * gnutls_pubkey_get_pk_rsa_raw:
532 * @key: Holds the certificate
533 * @m: will hold the modulus
534 * @e: will hold the public exponent
536 * This function will export the RSA public key's parameters found in
537 * the given structure. The new parameters will be allocated using
538 * gnutls_malloc() and will be stored in the appropriate datum.
540 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
543 gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t key,
544 gnutls_datum_t * m, gnutls_datum_t * e)
546 int ret;
548 if (key == NULL)
550 gnutls_assert ();
551 return GNUTLS_E_INVALID_REQUEST;
554 if (key->pk_algorithm != GNUTLS_PK_RSA)
556 gnutls_assert ();
557 return GNUTLS_E_INVALID_REQUEST;
560 ret = _gnutls_mpi_dprint_lz (key->params[0], m);
561 if (ret < 0)
563 gnutls_assert ();
564 return ret;
567 ret = _gnutls_mpi_dprint_lz (key->params[1], e);
568 if (ret < 0)
570 gnutls_assert ();
571 _gnutls_free_datum (m);
572 return ret;
575 return 0;
579 * gnutls_pubkey_get_pk_dsa_raw:
580 * @key: Holds the public key
581 * @p: will hold the p
582 * @q: will hold the q
583 * @g: will hold the g
584 * @y: will hold the y
586 * This function will export the DSA public key's parameters found in
587 * the given certificate. The new parameters will be allocated using
588 * gnutls_malloc() and will be stored in the appropriate datum.
590 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
593 gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
594 gnutls_datum_t * p, gnutls_datum_t * q,
595 gnutls_datum_t * g, gnutls_datum_t * y)
597 int ret;
599 if (key == NULL)
601 gnutls_assert ();
602 return GNUTLS_E_INVALID_REQUEST;
605 if (key->pk_algorithm != GNUTLS_PK_DSA)
607 gnutls_assert ();
608 return GNUTLS_E_INVALID_REQUEST;
611 /* P */
612 ret = _gnutls_mpi_dprint_lz (key->params[0], p);
613 if (ret < 0)
615 gnutls_assert ();
616 return ret;
619 /* Q */
620 ret = _gnutls_mpi_dprint_lz (key->params[1], q);
621 if (ret < 0)
623 gnutls_assert ();
624 _gnutls_free_datum (p);
625 return ret;
629 /* G */
630 ret = _gnutls_mpi_dprint_lz (key->params[2], g);
631 if (ret < 0)
633 gnutls_assert ();
634 _gnutls_free_datum (p);
635 _gnutls_free_datum (q);
636 return ret;
640 /* Y */
641 ret = _gnutls_mpi_dprint_lz (key->params[3], y);
642 if (ret < 0)
644 gnutls_assert ();
645 _gnutls_free_datum (p);
646 _gnutls_free_datum (g);
647 _gnutls_free_datum (q);
648 return ret;
651 return 0;
655 * gnutls_pubkey_import:
656 * @key: The structure to store the parsed public key.
657 * @data: The DER or PEM encoded certificate.
658 * @format: One of DER or PEM
660 * This function will convert the given DER or PEM encoded Public key
661 * to the native gnutls_pubkey_t format.The output will be stored * in @ key.
662 * If the Certificate is PEM encoded it should have a header of "PUBLIC KEY".
664 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
665 * negative error value.
668 gnutls_pubkey_import (gnutls_pubkey_t key,
669 const gnutls_datum_t * data,
670 gnutls_x509_crt_fmt_t format)
672 int result = 0, need_free = 0;
673 gnutls_datum_t _data;
674 ASN1_TYPE spk;
676 if (key == NULL)
678 gnutls_assert ();
679 return GNUTLS_E_INVALID_REQUEST;
682 _data.data = data->data;
683 _data.size = data->size;
685 /* If the Certificate is in PEM format then decode it
687 if (format == GNUTLS_X509_FMT_PEM)
689 opaque *out;
691 /* Try the first header */
692 result =
693 _gnutls_fbase64_decode (PK_PEM_HEADER, data->data, data->size, &out);
695 if (result <= 0)
697 if (result == 0)
698 result = GNUTLS_E_INTERNAL_ERROR;
699 gnutls_assert ();
700 return result;
703 _data.data = out;
704 _data.size = result;
706 need_free = 1;
709 if ((result = asn1_create_element
710 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
711 != ASN1_SUCCESS)
713 gnutls_assert ();
714 result = _gnutls_asn2err (result);
715 goto cleanup;
718 result = asn1_der_decoding (&spk, _data.data, _data.size, NULL);
719 if (result != ASN1_SUCCESS)
721 gnutls_assert ();
722 result = _gnutls_asn2err (result);
723 goto cleanup;
726 key->params_size = sizeof (key->params) / sizeof (key->params[0]);
727 result = _gnutls_get_asn_mpis (spk, "", key->params, &key->params_size);
728 if (result < 0)
730 gnutls_assert ();
731 goto cleanup;
734 /* this has already been called by get_asn_mpis() thus it cannot
735 * fail.
737 key->pk_algorithm = _gnutls_x509_get_pk_algorithm (spk, "", NULL);
738 key->bits = pubkey_to_bits(key->pk_algorithm, key->params, key->params_size);
740 result = 0;
742 cleanup:
743 asn1_delete_structure (&spk);
745 if (need_free)
746 _gnutls_free_datum (&_data);
747 return result;
751 * gnutls_x509_crt_set_pubkey:
752 * @crt: should contain a #gnutls_x509_crt_t structure
753 * @key: holds a public key
755 * This function will set the public parameters from the given public
756 * key to the request.
758 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
759 * negative error value.
762 gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, gnutls_pubkey_t key)
764 int result;
766 if (crt == NULL)
768 gnutls_assert ();
769 return GNUTLS_E_INVALID_REQUEST;
772 result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
773 "tbsCertificate.subjectPublicKeyInfo",
774 key->pk_algorithm,
775 key->params,
776 key->params_size);
778 if (result < 0)
780 gnutls_assert ();
781 return result;
784 if (key->key_usage)
785 gnutls_x509_crt_set_key_usage (crt, key->key_usage);
787 return 0;
791 * gnutls_x509_crq_set_pubkey:
792 * @crq: should contain a #gnutls_x509_crq_t structure
793 * @key: holds a public key
795 * This function will set the public parameters from the given public
796 * key to the request.
798 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
799 * negative error value.
802 gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key)
804 int result;
806 if (crq == NULL)
808 gnutls_assert ();
809 return GNUTLS_E_INVALID_REQUEST;
812 result = _gnutls_x509_encode_and_copy_PKI_params
813 (crq->crq,
814 "certificationRequestInfo.subjectPKInfo",
815 key->pk_algorithm, key->params, key->params_size);
817 if (result < 0)
819 gnutls_assert ();
820 return result;
823 if (key->key_usage)
824 gnutls_x509_crq_set_key_usage (crq, key->key_usage);
826 return 0;
830 * gnutls_pubkey_set_key_usage:
831 * @key: a certificate of type #gnutls_x509_crt_t
832 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
834 * This function will set the key usage flags of the public key. This
835 * is only useful if the key is to be exported to a certificate or
836 * certificate request.
838 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
839 * negative error value.
842 gnutls_pubkey_set_key_usage (gnutls_pubkey_t key, unsigned int usage)
844 key->key_usage = usage;
846 return 0;
850 * gnutls_pubkey_import_pkcs11_url:
851 * @key: A key of type #gnutls_pubkey_t
852 * @url: A PKCS 11 url
853 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
855 * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
856 * structure.
858 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
859 * negative error value.
863 gnutls_pubkey_import_pkcs11_url (gnutls_pubkey_t key, const char *url,
864 unsigned int flags)
866 gnutls_pkcs11_obj_t pcrt;
867 int ret;
869 ret = gnutls_pkcs11_obj_init (&pcrt);
870 if (ret < 0)
872 gnutls_assert ();
873 return ret;
876 ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
877 if (ret < 0)
879 gnutls_assert ();
880 goto cleanup;
883 ret = gnutls_pubkey_import_pkcs11 (key, pcrt, 0);
884 if (ret < 0)
886 gnutls_assert ();
887 goto cleanup;
890 ret = 0;
891 cleanup:
893 gnutls_pkcs11_obj_deinit (pcrt);
895 return ret;
899 * gnutls_pubkey_import_rsa_raw:
900 * @key: Is a structure will hold the parameters
901 * @m: holds the modulus
902 * @e: holds the public exponent
904 * This function will replace the parameters in the given structure.
905 * The new parameters should be stored in the appropriate
906 * gnutls_datum.
908 * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
911 gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key,
912 const gnutls_datum_t * m,
913 const gnutls_datum_t * e)
915 size_t siz = 0;
917 if (key == NULL)
919 gnutls_assert ();
920 return GNUTLS_E_INVALID_REQUEST;
923 siz = m->size;
924 if (_gnutls_mpi_scan_nz (&key->params[0], m->data, siz))
926 gnutls_assert ();
927 return GNUTLS_E_MPI_SCAN_FAILED;
930 siz = e->size;
931 if (_gnutls_mpi_scan_nz (&key->params[1], e->data, siz))
933 gnutls_assert ();
934 _gnutls_mpi_release (&key->params[0]);
935 return GNUTLS_E_MPI_SCAN_FAILED;
938 key->params_size = RSA_PUBLIC_PARAMS;
939 key->pk_algorithm = GNUTLS_PK_RSA;
940 key->bits = pubkey_to_bits(GNUTLS_PK_RSA, key->params, key->params_size);
942 return 0;
946 * gnutls_pubkey_import_dsa_raw:
947 * @key: The structure to store the parsed key
948 * @p: holds the p
949 * @q: holds the q
950 * @g: holds the g
951 * @y: holds the y
953 * This function will convert the given DSA raw parameters to the
954 * native #gnutls_pubkey_t format. The output will be stored
955 * in @key.
957 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
958 * negative error value.
961 gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key,
962 const gnutls_datum_t * p,
963 const gnutls_datum_t * q,
964 const gnutls_datum_t * g,
965 const gnutls_datum_t * y)
967 size_t siz = 0;
969 if (key == NULL)
971 gnutls_assert ();
972 return GNUTLS_E_INVALID_REQUEST;
975 siz = p->size;
976 if (_gnutls_mpi_scan_nz (&key->params[0], p->data, siz))
978 gnutls_assert ();
979 return GNUTLS_E_MPI_SCAN_FAILED;
982 siz = q->size;
983 if (_gnutls_mpi_scan_nz (&key->params[1], q->data, siz))
985 gnutls_assert ();
986 _gnutls_mpi_release (&key->params[0]);
987 return GNUTLS_E_MPI_SCAN_FAILED;
990 siz = g->size;
991 if (_gnutls_mpi_scan_nz (&key->params[2], g->data, siz))
993 gnutls_assert ();
994 _gnutls_mpi_release (&key->params[1]);
995 _gnutls_mpi_release (&key->params[0]);
996 return GNUTLS_E_MPI_SCAN_FAILED;
999 siz = y->size;
1000 if (_gnutls_mpi_scan_nz (&key->params[3], y->data, siz))
1002 gnutls_assert ();
1003 _gnutls_mpi_release (&key->params[2]);
1004 _gnutls_mpi_release (&key->params[1]);
1005 _gnutls_mpi_release (&key->params[0]);
1006 return GNUTLS_E_MPI_SCAN_FAILED;
1009 key->params_size = DSA_PUBLIC_PARAMS;
1010 key->pk_algorithm = GNUTLS_PK_DSA;
1011 key->bits = pubkey_to_bits(GNUTLS_PK_DSA, key->params, key->params_size);
1013 return 0;
1018 * gnutls_pubkey_verify_data:
1019 * @pubkey: Holds the public key
1020 * @flags: should be 0 for now
1021 * @data: holds the data to be signed
1022 * @signature: contains the signature
1024 * This function will verify the given signed data, using the
1025 * parameters from the certificate.
1027 * Returns: In case of a verification failure
1028 * %GNUTLS_E_PK_SIG_VERIFY_FAILED is returned, and a positive code
1029 * on success.
1031 * Since: 2.12.0
1034 gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, unsigned int flags,
1035 const gnutls_datum_t * data,
1036 const gnutls_datum_t * signature)
1038 int ret;
1040 if (pubkey == NULL)
1042 gnutls_assert ();
1043 return GNUTLS_E_INVALID_REQUEST;
1046 ret = pubkey_verify_sig( data, NULL, signature, pubkey->pk_algorithm,
1047 pubkey->params, pubkey->params_size);
1048 if (ret < 0)
1050 gnutls_assert();
1053 return ret;
1058 * gnutls_pubkey_verify_hash:
1059 * @key: Holds the certificate
1060 * @flags: should be 0 for now
1061 * @hash: holds the hash digest to be verified
1062 * @signature: contains the signature
1064 * This function will verify the given signed digest, using the
1065 * parameters from the certificate.
1067 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1068 * is returned, and a positive code on success.
1071 gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags,
1072 const gnutls_datum_t * hash,
1073 const gnutls_datum_t * signature)
1075 int ret;
1077 if (key == NULL)
1079 gnutls_assert ();
1080 return GNUTLS_E_INVALID_REQUEST;
1083 ret =
1084 pubkey_verify_sig (NULL, hash, signature, key->pk_algorithm,
1085 key->params, key->params_size);
1087 return ret;
1091 * gnutls_pubkey_get_verify_algorithm:
1092 * @key: Holds the certificate
1093 * @signature: contains the signature
1094 * @hash: The result of the call with the hash algorithm used for signature
1096 * This function will read the certifcate and the signed data to
1097 * determine the hash algorithm used to generate the signature.
1099 * Returns: the 0 if the hash algorithm is found. A negative value is
1100 * returned on error.
1103 gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
1104 const gnutls_datum_t * signature,
1105 gnutls_digest_algorithm_t * hash)
1107 if (key == NULL)
1109 gnutls_assert ();
1110 return GNUTLS_E_INVALID_REQUEST;
1113 return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *)
1114 hash, signature,
1115 key->pk_algorithm,
1116 key->params, key->params_size);