2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
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>
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>
32 #include <openpgp/openpgp_int.h>
33 #include <gnutls_num.h>
34 #include <x509/common.h>
36 #include <abstract_int.h>
37 #include <gnutls_ecc.h>
39 #define PK_PEM_HEADER "PUBLIC KEY"
41 #define OPENPGP_KEY_PRIMARY 2
42 #define OPENPGP_KEY_SUBKEY 1
44 struct gnutls_pubkey_st
46 gnutls_pk_algorithm_t pk_algorithm
;
47 unsigned int bits
; /* an indication of the security parameter */
49 /* the size of params depends on the public
52 * [1] is public exponent
58 gnutls_pk_params_st params
;
60 uint8_t openpgp_key_id
[GNUTLS_OPENPGP_KEYID_SIZE
];
61 int openpgp_key_id_set
;
63 unsigned int key_usage
; /* bits from GNUTLS_KEY_* */
66 int pubkey_to_bits(gnutls_pk_algorithm_t pk
, gnutls_pk_params_st
* params
)
71 return _gnutls_mpi_get_nbits(params
->params
[0]);
73 return _gnutls_mpi_get_nbits(params
->params
[3]);
75 return gnutls_ecc_curve_get_size(params
->flags
)*8;
82 * gnutls_pubkey_get_pk_algorithm:
83 * @key: should contain a #gnutls_pubkey_t structure
84 * @bits: If set will return the number of bits of the parameters (may be NULL)
86 * This function will return the public key algorithm of a public
87 * key and if possible will return a number of bits that indicates
88 * the security parameter of the key.
90 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
91 * success, or a negative error code on error.
96 gnutls_pubkey_get_pk_algorithm (gnutls_pubkey_t key
, unsigned int *bits
)
101 return key
->pk_algorithm
;
105 * gnutls_pubkey_get_key_usage:
106 * @key: should contain a #gnutls_pubkey_t structure
107 * @usage: If set will return the number of bits of the parameters (may be NULL)
109 * This function will return the key usage of the public key.
111 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
112 * negative error value.
117 gnutls_pubkey_get_key_usage (gnutls_pubkey_t key
, unsigned int *usage
)
120 *usage
= key
->key_usage
;
126 * gnutls_pubkey_init:
127 * @key: The structure to be initialized
129 * This function will initialize an public key structure.
131 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
132 * negative error value.
137 gnutls_pubkey_init (gnutls_pubkey_t
* key
)
139 *key
= gnutls_calloc (1, sizeof (struct gnutls_pubkey_st
));
143 return GNUTLS_E_MEMORY_ERROR
;
150 * gnutls_pubkey_deinit:
151 * @key: The structure to be deinitialized
153 * This function will deinitialize a public key structure.
158 gnutls_pubkey_deinit (gnutls_pubkey_t key
)
162 gnutls_pk_params_release (&key
->params
);
167 * gnutls_pubkey_import_x509:
168 * @key: The public key
169 * @crt: The certificate to be imported
170 * @flags: should be zero
172 * This function will import the given public key to the abstract
173 * #gnutls_pubkey_t structure.
175 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
176 * negative error value.
181 gnutls_pubkey_import_x509 (gnutls_pubkey_t key
, gnutls_x509_crt_t crt
,
186 key
->pk_algorithm
= gnutls_x509_crt_get_pk_algorithm (crt
, &key
->bits
);
188 ret
= gnutls_x509_crt_get_key_usage (crt
, &key
->key_usage
, NULL
);
192 ret
= _gnutls_x509_crt_get_mpis (crt
, &key
->params
);
203 * gnutls_pubkey_import_privkey:
204 * @key: The public key
205 * @pkey: The private key
206 * @usage: GNUTLS_KEY_* key usage flags.
207 * @flags: should be zero
209 * Imports the public key from a private. This function will import
210 * the given public key to the abstract #gnutls_pubkey_t structure.
212 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
213 * negative error value.
218 gnutls_pubkey_import_privkey (gnutls_pubkey_t key
, gnutls_privkey_t pkey
,
219 unsigned int usage
, unsigned int flags
)
221 key
->pk_algorithm
= gnutls_privkey_get_pk_algorithm (pkey
, &key
->bits
);
223 key
->key_usage
= usage
;
225 return _gnutls_privkey_get_public_mpis (pkey
, &key
->params
);
229 * gnutls_pubkey_get_preferred_hash_algorithm:
230 * @key: Holds the certificate
231 * @hash: The result of the call with the hash algorithm used for signature
232 * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL.
234 * This function will read the certifcate and return the appropriate digest
235 * algorithm to use for signing with this certificate. Some certificates (i.e.
236 * DSA might not be able to sign without the preferred algorithm).
238 * Returns: the 0 if the hash algorithm is found. A negative error code is
244 gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key
,
245 gnutls_digest_algorithm_t
*
246 hash
, unsigned int *mand
)
253 return GNUTLS_E_INVALID_REQUEST
;
256 ret
= _gnutls_pk_get_hash_algorithm (key
->pk_algorithm
,
266 * gnutls_pubkey_import_pkcs11:
267 * @key: The public key
268 * @obj: The parameters to be imported
269 * @flags: should be zero
271 * Imports a public key from a pkcs11 key. This function will import
272 * the given public key to the abstract #gnutls_pubkey_t structure.
274 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
275 * negative error value.
280 gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key
,
281 gnutls_pkcs11_obj_t obj
, unsigned int flags
)
285 ret
= gnutls_pkcs11_obj_get_type (obj
);
286 if (ret
!= GNUTLS_PKCS11_OBJ_PUBKEY
)
289 return GNUTLS_E_INVALID_REQUEST
;
292 key
->key_usage
= obj
->key_usage
;
294 switch (obj
->pk_algorithm
)
297 ret
= gnutls_pubkey_import_rsa_raw (key
, &obj
->pubkey
[0],
301 ret
= gnutls_pubkey_import_dsa_raw (key
, &obj
->pubkey
[0],
303 &obj
->pubkey
[2], &obj
->pubkey
[3]);
306 ret
= gnutls_pubkey_import_ecc_x962 (key
, &obj
->pubkey
[0],
311 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
323 #endif /* ENABLE_PKCS11 */
325 #ifdef ENABLE_OPENPGP
328 * gnutls_pubkey_import_openpgp:
329 * @key: The public key
330 * @crt: The certificate to be imported
331 * @flags: should be zero
333 * Imports a public key from an openpgp key. This function will import
334 * the given public key to the abstract #gnutls_pubkey_t
335 * structure. The subkey set as preferred will be imported or the
336 * master key otherwise.
338 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
339 * negative error value.
344 gnutls_pubkey_import_openpgp (gnutls_pubkey_t key
,
345 gnutls_openpgp_crt_t crt
,
351 uint8_t keyid
[GNUTLS_OPENPGP_KEYID_SIZE
];
353 ret
= gnutls_openpgp_crt_get_preferred_key_id (crt
, keyid
);
354 if (ret
== GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR
)
356 key
->pk_algorithm
= gnutls_openpgp_crt_get_pk_algorithm (crt
, &key
->bits
);
357 key
->openpgp_key_id_set
= OPENPGP_KEY_PRIMARY
;
359 ret
= gnutls_openpgp_crt_get_key_id(crt
, key
->openpgp_key_id
);
361 return gnutls_assert_val(ret
);
363 ret
= gnutls_openpgp_crt_get_key_usage (crt
, &key
->key_usage
);
376 key
->openpgp_key_id_set
= OPENPGP_KEY_SUBKEY
;
378 KEYID_IMPORT (kid32
, keyid
);
381 idx
= gnutls_openpgp_crt_get_subkey_idx (crt
, keyid
);
383 ret
= gnutls_openpgp_crt_get_subkey_id(crt
, idx
, key
->openpgp_key_id
);
385 return gnutls_assert_val(ret
);
387 ret
= gnutls_openpgp_crt_get_subkey_usage (crt
, idx
, &key
->key_usage
);
391 key
->pk_algorithm
= gnutls_openpgp_crt_get_subkey_pk_algorithm (crt
, idx
, NULL
);
395 _gnutls_openpgp_crt_get_mpis (crt
, k
, &key
->params
);
397 return gnutls_assert_val(ret
);
403 * gnutls_pubkey_get_openpgp_key_id:
404 * @key: Holds the public key
405 * @flags: should be 0 for now
406 * @output_data: will contain the key ID
407 * @output_data_size: holds the size of output_data (and will be
408 * replaced by the actual size of parameters)
409 * @subkey: Will be non zero if the key ID corresponds to a subkey
411 * This function will return a unique ID the depends on the public
412 * key parameters. This ID can be used in checking whether a
413 * certificate corresponds to the given public key.
415 * If the buffer provided is not long enough to hold the output, then
416 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
417 * be returned. The output will normally be a SHA-1 hash output,
420 * Returns: In case of failure a negative error code will be
421 * returned, and 0 on success.
426 gnutls_pubkey_get_openpgp_key_id (gnutls_pubkey_t key
, unsigned int flags
,
427 unsigned char *output_data
,
428 size_t * output_data_size
,
429 unsigned int *subkey
)
434 return GNUTLS_E_INVALID_REQUEST
;
437 if (*output_data_size
< sizeof(key
->openpgp_key_id
))
439 *output_data_size
= sizeof(key
->openpgp_key_id
);
440 return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER
);
443 if (key
->openpgp_key_id_set
== 0)
444 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST
);
446 if (key
->openpgp_key_id_set
== OPENPGP_KEY_SUBKEY
)
447 if (subkey
) *subkey
= 1;
451 memcpy(output_data
, key
->openpgp_key_id
, sizeof(key
->openpgp_key_id
));
453 *output_data_size
= sizeof(key
->openpgp_key_id
);
461 * gnutls_pubkey_export:
462 * @key: Holds the certificate
463 * @format: the format of output params. One of PEM or DER.
464 * @output_data: will contain a certificate PEM or DER encoded
465 * @output_data_size: holds the size of output_data (and will be
466 * replaced by the actual size of parameters)
468 * This function will export the public key to DER or PEM format.
469 * The contents of the exported data is the SubjectPublicKeyInfo
472 * If the buffer provided is not long enough to hold the output, then
473 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
476 * If the structure is PEM encoded, it will have a header
477 * of "BEGIN CERTIFICATE".
479 * Returns: In case of failure a negative error code will be
480 * returned, and 0 on success.
485 gnutls_pubkey_export (gnutls_pubkey_t key
,
486 gnutls_x509_crt_fmt_t format
, void *output_data
,
487 size_t * output_data_size
)
490 ASN1_TYPE spk
= ASN1_TYPE_EMPTY
;
495 return GNUTLS_E_INVALID_REQUEST
;
498 if ((result
= asn1_create_element
499 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk
))
503 return _gnutls_asn2err (result
);
507 _gnutls_x509_encode_and_copy_PKI_params (spk
, "",
516 result
= _gnutls_x509_export_int_named (spk
, "",
517 format
, PK_PEM_HEADER
,
518 output_data
, output_data_size
);
528 asn1_delete_structure (&spk
);
535 * gnutls_pubkey_get_key_id:
536 * @key: Holds the public key
537 * @flags: should be 0 for now
538 * @output_data: will contain the key ID
539 * @output_data_size: holds the size of output_data (and will be
540 * replaced by the actual size of parameters)
542 * This function will return a unique ID the depends on the public
543 * key parameters. This ID can be used in checking whether a
544 * certificate corresponds to the given public key.
546 * If the buffer provided is not long enough to hold the output, then
547 * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
548 * be returned. The output will normally be a SHA-1 hash output,
551 * Returns: In case of failure a negative error code will be
552 * returned, and 0 on success.
557 gnutls_pubkey_get_key_id (gnutls_pubkey_t key
, unsigned int flags
,
558 unsigned char *output_data
,
559 size_t * output_data_size
)
566 return GNUTLS_E_INVALID_REQUEST
;
570 _gnutls_get_key_id (key
->pk_algorithm
, &key
->params
,
571 output_data
, output_data_size
);
582 * gnutls_pubkey_get_pk_rsa_raw:
583 * @key: Holds the certificate
584 * @m: will hold the modulus
585 * @e: will hold the public exponent
587 * This function will export the RSA public key's parameters found in
588 * the given structure. The new parameters will be allocated using
589 * gnutls_malloc() and will be stored in the appropriate datum.
591 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
596 gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t key
,
597 gnutls_datum_t
* m
, gnutls_datum_t
* e
)
604 return GNUTLS_E_INVALID_REQUEST
;
607 if (key
->pk_algorithm
!= GNUTLS_PK_RSA
)
610 return GNUTLS_E_INVALID_REQUEST
;
613 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[0], m
);
620 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[1], e
);
624 _gnutls_free_datum (m
);
632 * gnutls_pubkey_get_pk_dsa_raw:
633 * @key: Holds the public key
634 * @p: will hold the p
635 * @q: will hold the q
636 * @g: will hold the g
637 * @y: will hold the y
639 * This function will export the DSA public key's parameters found in
640 * the given certificate. The new parameters will be allocated using
641 * gnutls_malloc() and will be stored in the appropriate datum.
643 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
648 gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key
,
649 gnutls_datum_t
* p
, gnutls_datum_t
* q
,
650 gnutls_datum_t
* g
, gnutls_datum_t
* y
)
657 return GNUTLS_E_INVALID_REQUEST
;
660 if (key
->pk_algorithm
!= GNUTLS_PK_DSA
)
663 return GNUTLS_E_INVALID_REQUEST
;
667 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[0], p
);
675 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[1], q
);
679 _gnutls_free_datum (p
);
685 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[2], g
);
689 _gnutls_free_datum (p
);
690 _gnutls_free_datum (q
);
696 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[3], y
);
700 _gnutls_free_datum (p
);
701 _gnutls_free_datum (g
);
702 _gnutls_free_datum (q
);
710 * gnutls_pubkey_get_pk_ecc_raw:
711 * @key: Holds the public key
712 * @curve: will hold the curve
716 * This function will export the ECC public key's parameters found in
717 * the given certificate. The new parameters will be allocated using
718 * gnutls_malloc() and will be stored in the appropriate datum.
720 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
725 gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key
, gnutls_ecc_curve_t
*curve
,
726 gnutls_datum_t
* x
, gnutls_datum_t
* y
)
733 return GNUTLS_E_INVALID_REQUEST
;
736 if (key
->pk_algorithm
!= GNUTLS_PK_EC
)
739 return GNUTLS_E_INVALID_REQUEST
;
742 *curve
= key
->params
.flags
;
745 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[ECC_X
], x
);
753 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[ECC_Y
], y
);
757 _gnutls_free_datum (x
);
765 * gnutls_pubkey_get_pk_ecc_x962:
766 * @key: Holds the public key
767 * @parameters: DER encoding of an ANSI X9.62 parameters
768 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
770 * This function will export the ECC public key's parameters found in
771 * the given certificate. The new parameters will be allocated using
772 * gnutls_malloc() and will be stored in the appropriate datum.
774 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
778 int gnutls_pubkey_get_pk_ecc_x962 (gnutls_pubkey_t key
, gnutls_datum_t
* parameters
,
779 gnutls_datum_t
* ecpoint
)
783 if (key
== NULL
|| key
->pk_algorithm
!= GNUTLS_PK_EC
)
784 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST
);
786 ret
= _gnutls_x509_write_ecc_pubkey(&key
->params
, ecpoint
);
788 return gnutls_assert_val(ret
);
790 ret
= _gnutls_x509_write_ecc_params(&key
->params
, parameters
);
793 _gnutls_free_datum(ecpoint
);
794 return gnutls_assert_val(ret
);
801 * gnutls_pubkey_import:
802 * @key: The structure to store the parsed public key.
803 * @data: The DER or PEM encoded certificate.
804 * @format: One of DER or PEM
806 * This function will import the provided public key in
807 * a SubjectPublicKeyInfo X.509 structure to a native
808 * %gnutls_pubkey_t structure. The output will be stored
809 * in @key. If the public key is PEM encoded it should have a header
812 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
813 * negative error value.
818 gnutls_pubkey_import (gnutls_pubkey_t key
,
819 const gnutls_datum_t
* data
,
820 gnutls_x509_crt_fmt_t format
)
822 int result
= 0, need_free
= 0;
823 gnutls_datum_t _data
;
829 return GNUTLS_E_INVALID_REQUEST
;
832 _data
.data
= data
->data
;
833 _data
.size
= data
->size
;
835 /* If the Certificate is in PEM format then decode it
837 if (format
== GNUTLS_X509_FMT_PEM
)
841 /* Try the first header */
843 _gnutls_fbase64_decode (PK_PEM_HEADER
, data
->data
, data
->size
, &out
);
848 result
= GNUTLS_E_INTERNAL_ERROR
;
859 if ((result
= asn1_create_element
860 (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk
))
864 result
= _gnutls_asn2err (result
);
868 result
= asn1_der_decoding (&spk
, _data
.data
, _data
.size
, NULL
);
869 if (result
!= ASN1_SUCCESS
)
872 result
= _gnutls_asn2err (result
);
876 result
= _gnutls_get_asn_mpis (spk
, "", &key
->params
);
883 /* this has already been called by get_asn_mpis() thus it cannot
886 key
->pk_algorithm
= _gnutls_x509_get_pk_algorithm (spk
, "", NULL
);
887 key
->bits
= pubkey_to_bits(key
->pk_algorithm
, &key
->params
);
892 asn1_delete_structure (&spk
);
895 _gnutls_free_datum (&_data
);
900 * gnutls_x509_crt_set_pubkey:
901 * @crt: should contain a #gnutls_x509_crt_t structure
902 * @key: holds a public key
904 * This function will set the public parameters from the given public
905 * key to the request.
907 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
908 * negative error value.
913 gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt
, gnutls_pubkey_t key
)
920 return GNUTLS_E_INVALID_REQUEST
;
923 result
= _gnutls_x509_encode_and_copy_PKI_params (crt
->cert
,
924 "tbsCertificate.subjectPublicKeyInfo",
935 gnutls_x509_crt_set_key_usage (crt
, key
->key_usage
);
941 * gnutls_x509_crq_set_pubkey:
942 * @crq: should contain a #gnutls_x509_crq_t structure
943 * @key: holds a public key
945 * This function will set the public parameters from the given public
946 * key to the request.
948 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
949 * negative error value.
954 gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq
, gnutls_pubkey_t key
)
961 return GNUTLS_E_INVALID_REQUEST
;
964 result
= _gnutls_x509_encode_and_copy_PKI_params
966 "certificationRequestInfo.subjectPKInfo",
967 key
->pk_algorithm
, &key
->params
);
976 gnutls_x509_crq_set_key_usage (crq
, key
->key_usage
);
982 * gnutls_pubkey_set_key_usage:
983 * @key: a certificate of type #gnutls_x509_crt_t
984 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
986 * This function will set the key usage flags of the public key. This
987 * is only useful if the key is to be exported to a certificate or
988 * certificate request.
990 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
991 * negative error value.
996 gnutls_pubkey_set_key_usage (gnutls_pubkey_t key
, unsigned int usage
)
998 key
->key_usage
= usage
;
1003 #ifdef ENABLE_PKCS11
1006 * gnutls_pubkey_import_pkcs11_url:
1007 * @key: A key of type #gnutls_pubkey_t
1008 * @url: A PKCS 11 url
1009 * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1011 * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
1014 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1015 * negative error value.
1020 gnutls_pubkey_import_pkcs11_url (gnutls_pubkey_t key
, const char *url
,
1023 gnutls_pkcs11_obj_t pcrt
;
1026 ret
= gnutls_pkcs11_obj_init (&pcrt
);
1033 ret
= gnutls_pkcs11_obj_import_url (pcrt
, url
, flags
);
1040 ret
= gnutls_pubkey_import_pkcs11 (key
, pcrt
, 0);
1050 gnutls_pkcs11_obj_deinit (pcrt
);
1055 #endif /* ENABLE_PKCS11 */
1058 * gnutls_pubkey_import_rsa_raw:
1059 * @key: Is a structure will hold the parameters
1060 * @m: holds the modulus
1061 * @e: holds the public exponent
1063 * This function will replace the parameters in the given structure.
1064 * The new parameters should be stored in the appropriate
1067 * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
1072 gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key
,
1073 const gnutls_datum_t
* m
,
1074 const gnutls_datum_t
* e
)
1081 return GNUTLS_E_INVALID_REQUEST
;
1084 gnutls_pk_params_init(&key
->params
);
1087 if (_gnutls_mpi_scan_nz (&key
->params
.params
[0], m
->data
, siz
))
1090 return GNUTLS_E_MPI_SCAN_FAILED
;
1094 if (_gnutls_mpi_scan_nz (&key
->params
.params
[1], e
->data
, siz
))
1097 _gnutls_mpi_release (&key
->params
.params
[0]);
1098 return GNUTLS_E_MPI_SCAN_FAILED
;
1101 key
->params
.params_nr
= RSA_PUBLIC_PARAMS
;
1102 key
->pk_algorithm
= GNUTLS_PK_RSA
;
1103 key
->bits
= pubkey_to_bits(GNUTLS_PK_RSA
, &key
->params
);
1109 * gnutls_pubkey_import_ecc_raw:
1110 * @key: The structure to store the parsed key
1111 * @curve: holds the curve
1115 * This function will convert the given elliptic curve parameters to a
1116 * #gnutls_pubkey_t. The output will be stored in @key.
1118 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1119 * negative error value.
1124 gnutls_pubkey_import_ecc_raw (gnutls_pubkey_t key
,
1125 gnutls_ecc_curve_t curve
,
1126 const gnutls_datum_t
* x
,
1127 const gnutls_datum_t
* y
)
1134 return GNUTLS_E_INVALID_REQUEST
;
1137 key
->params
.flags
= curve
;
1139 ret
= _gnutls_ecc_curve_fill_params(curve
, &key
->params
);
1141 return gnutls_assert_val(ret
);
1143 if (_gnutls_mpi_scan_nz (&key
->params
.params
[ECC_X
], x
->data
, x
->size
))
1146 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
1149 key
->params
.params_nr
++;
1151 if (_gnutls_mpi_scan_nz (&key
->params
.params
[ECC_Y
], y
->data
, y
->size
))
1154 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
1157 key
->params
.params_nr
++;
1158 key
->pk_algorithm
= GNUTLS_PK_EC
;
1163 gnutls_pk_params_release(&key
->params
);
1168 * gnutls_pubkey_import_ecc_x962:
1169 * @key: The structure to store the parsed key
1170 * @parameters: DER encoding of an ANSI X9.62 parameters
1171 * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1173 * This function will convert the given elliptic curve parameters to a
1174 * #gnutls_pubkey_t. The output will be stored in @key.
1176 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1177 * negative error value.
1182 gnutls_pubkey_import_ecc_x962 (gnutls_pubkey_t key
,
1183 const gnutls_datum_t
* parameters
,
1184 const gnutls_datum_t
* ecpoint
)
1191 return GNUTLS_E_INVALID_REQUEST
;
1194 key
->params
.params_nr
= 0;
1196 ret
= _gnutls_x509_read_ecc_params(parameters
->data
, parameters
->size
,
1204 ret
= _gnutls_ecc_ansi_x963_import(ecpoint
->data
, ecpoint
->size
,
1205 &key
->params
.params
[ECC_X
], &key
->params
.params
[ECC_Y
]);
1211 key
->params
.params_nr
+=2;
1212 key
->pk_algorithm
= GNUTLS_PK_EC
;
1217 gnutls_pk_params_release(&key
->params
);
1222 * gnutls_pubkey_import_dsa_raw:
1223 * @key: The structure to store the parsed key
1229 * This function will convert the given DSA raw parameters to the
1230 * native #gnutls_pubkey_t format. The output will be stored
1233 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1234 * negative error value.
1239 gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key
,
1240 const gnutls_datum_t
* p
,
1241 const gnutls_datum_t
* q
,
1242 const gnutls_datum_t
* g
,
1243 const gnutls_datum_t
* y
)
1250 return GNUTLS_E_INVALID_REQUEST
;
1253 gnutls_pk_params_init(&key
->params
);
1256 if (_gnutls_mpi_scan_nz (&key
->params
.params
[0], p
->data
, siz
))
1259 return GNUTLS_E_MPI_SCAN_FAILED
;
1263 if (_gnutls_mpi_scan_nz (&key
->params
.params
[1], q
->data
, siz
))
1266 _gnutls_mpi_release (&key
->params
.params
[0]);
1267 return GNUTLS_E_MPI_SCAN_FAILED
;
1271 if (_gnutls_mpi_scan_nz (&key
->params
.params
[2], g
->data
, siz
))
1274 _gnutls_mpi_release (&key
->params
.params
[1]);
1275 _gnutls_mpi_release (&key
->params
.params
[0]);
1276 return GNUTLS_E_MPI_SCAN_FAILED
;
1280 if (_gnutls_mpi_scan_nz (&key
->params
.params
[3], y
->data
, siz
))
1283 _gnutls_mpi_release (&key
->params
.params
[2]);
1284 _gnutls_mpi_release (&key
->params
.params
[1]);
1285 _gnutls_mpi_release (&key
->params
.params
[0]);
1286 return GNUTLS_E_MPI_SCAN_FAILED
;
1289 key
->params
.params_nr
= DSA_PUBLIC_PARAMS
;
1290 key
->pk_algorithm
= GNUTLS_PK_DSA
;
1291 key
->bits
= pubkey_to_bits(GNUTLS_PK_DSA
, &key
->params
);
1298 * gnutls_pubkey_verify_data:
1299 * @pubkey: Holds the public key
1300 * @flags: should be 0 for now
1301 * @data: holds the signed data
1302 * @signature: contains the signature
1304 * This function will verify the given signed data, using the
1305 * parameters from the certificate.
1307 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1308 * is returned, and zero or positive code on success.
1313 gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey
, unsigned int flags
,
1314 const gnutls_datum_t
* data
,
1315 const gnutls_datum_t
* signature
)
1322 return GNUTLS_E_INVALID_REQUEST
;
1325 ret
= pubkey_verify_data( pubkey
->pk_algorithm
, GNUTLS_DIG_UNKNOWN
, data
, signature
,
1336 * gnutls_pubkey_verify_data2:
1337 * @pubkey: Holds the public key
1338 * @algo: The signature algorithm used
1339 * @flags: should be 0 for now
1340 * @data: holds the signed data
1341 * @signature: contains the signature
1343 * This function will verify the given signed data, using the
1344 * parameters from the certificate.
1346 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1347 * is returned, and zero or positive code on success.
1352 gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey
,
1353 gnutls_sign_algorithm_t algo
,
1355 const gnutls_datum_t
* data
,
1356 const gnutls_datum_t
* signature
)
1363 return GNUTLS_E_INVALID_REQUEST
;
1366 ret
= pubkey_verify_data( pubkey
->pk_algorithm
, _gnutls_sign_get_hash_algorithm(algo
), data
, signature
,
1377 * gnutls_pubkey_verify_hash:
1378 * @key: Holds the public key
1379 * @flags: should be 0 for now
1380 * @hash: holds the hash digest to be verified
1381 * @signature: contains the signature
1383 * This function will verify the given signed digest, using the
1384 * parameters from the public key. Use gnutls_pubkey_verify_hash2()
1385 * instead of this function.
1387 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1388 * is returned, and zero or positive code on success.
1393 gnutls_pubkey_verify_hash (gnutls_pubkey_t key
, unsigned int flags
,
1394 const gnutls_datum_t
* hash
,
1395 const gnutls_datum_t
* signature
)
1397 gnutls_digest_algorithm_t algo
;
1400 ret
= gnutls_pubkey_get_verify_algorithm (key
, signature
, &algo
);
1402 return gnutls_assert_val(ret
);
1404 return gnutls_pubkey_verify_hash2(key
, gnutls_pk_to_sign(key
->pk_algorithm
, algo
),
1405 flags
, hash
, signature
);
1410 * gnutls_pubkey_verify_hash:
1411 * @key: Holds the public key
1412 * @algo: The signature algorithm used
1413 * @flags: should be 0 for now
1414 * @hash: holds the hash digest to be verified
1415 * @signature: contains the signature
1417 * This function will verify the given signed digest, using the
1418 * parameters from the public key.
1420 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1421 * is returned, and zero or positive code on success.
1426 gnutls_pubkey_verify_hash2 (gnutls_pubkey_t key
,
1427 gnutls_sign_algorithm_t algo
,
1429 const gnutls_datum_t
* hash
,
1430 const gnutls_datum_t
* signature
)
1435 return GNUTLS_E_INVALID_REQUEST
;
1438 if (flags
& GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA
)
1439 return _gnutls_rsa_verify (hash
, signature
, &key
->params
, 1);
1442 return pubkey_verify_hashed_data (key
->pk_algorithm
, _gnutls_sign_get_hash_algorithm(algo
),
1443 hash
, signature
, &key
->params
);
1448 * gnutls_pubkey_encrypt_data:
1449 * @key: Holds the public key
1450 * @flags: should be 0 for now
1451 * @plaintext: The data to be encrypted
1452 * @ciphertext: contains the encrypted data
1454 * This function will encrypt the given data, using the public
1457 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1458 * negative error value.
1463 gnutls_pubkey_encrypt_data (gnutls_pubkey_t key
, unsigned int flags
,
1464 const gnutls_datum_t
* plaintext
,
1465 gnutls_datum_t
* ciphertext
)
1467 if (key
== NULL
|| key
->pk_algorithm
!= GNUTLS_PK_RSA
)
1470 return GNUTLS_E_INVALID_REQUEST
;
1473 return _gnutls_pkcs1_rsa_encrypt (ciphertext
, plaintext
,
1479 * gnutls_pubkey_get_verify_algorithm:
1480 * @key: Holds the certificate
1481 * @signature: contains the signature
1482 * @hash: The result of the call with the hash algorithm used for signature
1484 * This function will read the certifcate and the signed data to
1485 * determine the hash algorithm used to generate the signature.
1487 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1488 * negative error value.
1493 gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key
,
1494 const gnutls_datum_t
* signature
,
1495 gnutls_digest_algorithm_t
* hash
)
1500 return GNUTLS_E_INVALID_REQUEST
;
1503 return _gnutls_x509_verify_algorithm (hash
, signature
,
1510 int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey
, gnutls_protocol_t ver
,
1511 gnutls_sign_algorithm_t sign
)
1513 unsigned int hash_size
;
1514 unsigned int hash_algo
;
1516 if (pubkey
->pk_algorithm
== GNUTLS_PK_DSA
)
1518 hash_algo
= _gnutls_dsa_q_to_hash (pubkey
->pk_algorithm
, &pubkey
->params
, &hash_size
);
1520 /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
1521 if (!_gnutls_version_has_selectable_sighash (ver
))
1523 if (hash_algo
!= GNUTLS_DIG_SHA1
)
1524 return gnutls_assert_val(GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL
);
1526 else if (sign
!= GNUTLS_SIGN_UNKNOWN
)
1528 if (_gnutls_hash_get_algo_len(_gnutls_sign_get_hash_algorithm(sign
)) < hash_size
)
1529 return GNUTLS_E_UNWANTED_ALGORITHM
;
1533 else if (pubkey
->pk_algorithm
== GNUTLS_PK_EC
)
1535 if (_gnutls_version_has_selectable_sighash (ver
) && sign
!= GNUTLS_SIGN_UNKNOWN
)
1537 hash_algo
= _gnutls_dsa_q_to_hash (pubkey
->pk_algorithm
, &pubkey
->params
, &hash_size
);
1539 if (_gnutls_hash_get_algo_len(_gnutls_sign_get_hash_algorithm(sign
)) < hash_size
)
1540 return GNUTLS_E_UNWANTED_ALGORITHM
;
1548 /* Returns zero if the public key has more than 512 bits */
1549 int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey
)
1551 if (pubkey
->pk_algorithm
== GNUTLS_PK_RSA
&& _gnutls_mpi_get_nbits (pubkey
->params
.params
[0]) > 512)
1554 return GNUTLS_E_INVALID_REQUEST
; /* doesn't matter */
1558 /* Returns the public key.
1561 _gnutls_pubkey_get_mpis (gnutls_pubkey_t key
,
1562 gnutls_pk_params_st
* params
)
1564 return _gnutls_pk_params_copy(params
, &key
->params
);
1567 /* if hash==MD5 then we do RSA-MD5
1568 * if hash==SHA then we do RSA-SHA
1569 * params[0] is modulus
1570 * params[1] is public key
1573 _pkcs1_rsa_verify_sig (gnutls_digest_algorithm_t hash_algo
,
1574 const gnutls_datum_t
* text
,
1575 const gnutls_datum_t
* prehash
,
1576 const gnutls_datum_t
* signature
,
1577 gnutls_pk_params_st
* params
)
1579 gnutls_digest_algorithm_t hash
= GNUTLS_DIG_UNKNOWN
;
1581 uint8_t digest
[MAX_HASH_SIZE
], md
[MAX_HASH_SIZE
], *cmp
;
1582 unsigned int digest_size
;
1584 gnutls_datum_t decrypted
;
1587 _gnutls_pkcs1_rsa_decrypt (&decrypted
, signature
, params
, 1);
1594 /* decrypted is a BER encoded data of type DigestInfo
1597 digest_size
= sizeof (digest
);
1599 decode_ber_digest_info (&decrypted
, &hash
, digest
, &digest_size
)) != 0)
1602 _gnutls_free_datum (&decrypted
);
1606 _gnutls_free_datum (&decrypted
);
1608 if (hash_algo
!= GNUTLS_DIG_UNKNOWN
&& hash_algo
!= hash
)
1609 return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED
);
1611 if (digest_size
!= _gnutls_hash_get_algo_len (hash
))
1614 return GNUTLS_E_ASN1_GENERIC_ERROR
;
1617 if (prehash
&& prehash
->data
&& prehash
->size
== digest_size
)
1619 cmp
= prehash
->data
;
1626 return GNUTLS_E_INVALID_REQUEST
;
1629 ret
= _gnutls_hash_init (&hd
, hash
);
1636 _gnutls_hash (&hd
, text
->data
, text
->size
);
1637 _gnutls_hash_deinit (&hd
, md
);
1642 if (memcmp (cmp
, digest
, digest_size
) != 0)
1645 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
1651 /* Hashes input data and verifies a signature.
1654 dsa_verify_hashed_data (const gnutls_datum_t
* hash
,
1655 const gnutls_datum_t
* signature
,
1656 gnutls_pk_algorithm_t pk
,
1657 gnutls_pk_params_st
* params
)
1659 gnutls_datum_t digest
;
1661 unsigned int hash_len
;
1663 algo
= _gnutls_dsa_q_to_hash (pk
, params
, &hash_len
);
1665 /* SHA1 or better allowed */
1666 if (!hash
->data
|| hash
->size
< hash_len
)
1669 _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
);
1671 if (hash
->size
!= 20) /* SHA1 is allowed */
1672 return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED
);
1675 digest
.data
= hash
->data
;
1676 digest
.size
= hash
->size
;
1678 return _gnutls_pk_verify (pk
, &digest
, signature
, params
);
1682 dsa_verify_data (gnutls_pk_algorithm_t pk
,
1683 gnutls_digest_algorithm_t algo
,
1684 const gnutls_datum_t
* data
,
1685 const gnutls_datum_t
* signature
,
1686 gnutls_pk_params_st
* params
)
1689 uint8_t _digest
[MAX_HASH_SIZE
];
1690 gnutls_datum_t digest
;
1693 if (algo
== GNUTLS_DIG_UNKNOWN
)
1694 algo
= _gnutls_dsa_q_to_hash (pk
, params
, NULL
);
1696 ret
= _gnutls_hash_init (&hd
, algo
);
1698 return gnutls_assert_val(ret
);
1700 _gnutls_hash (&hd
, data
->data
, data
->size
);
1701 _gnutls_hash_deinit (&hd
, _digest
);
1703 digest
.data
= _digest
;
1704 digest
.size
= _gnutls_hash_get_algo_len(algo
);
1706 return _gnutls_pk_verify (pk
, &digest
, signature
, params
);
1709 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
1710 * not verified, or 1 otherwise.
1713 pubkey_verify_hashed_data (gnutls_pk_algorithm_t pk
,
1714 gnutls_digest_algorithm_t hash_algo
,
1715 const gnutls_datum_t
* hash
,
1716 const gnutls_datum_t
* signature
,
1717 gnutls_pk_params_st
* issuer_params
)
1724 if (_pkcs1_rsa_verify_sig
1725 (hash_algo
, NULL
, hash
, signature
, issuer_params
) != 0)
1728 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
1736 if (dsa_verify_hashed_data(hash
, signature
, pk
, issuer_params
) != 0)
1739 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
1746 return GNUTLS_E_INTERNAL_ERROR
;
1751 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
1752 * not verified, or 1 otherwise.
1755 pubkey_verify_data (gnutls_pk_algorithm_t pk
,
1756 gnutls_digest_algorithm_t algo
,
1757 const gnutls_datum_t
* data
,
1758 const gnutls_datum_t
* signature
,
1759 gnutls_pk_params_st
* issuer_params
)
1766 if (_pkcs1_rsa_verify_sig
1767 (algo
, data
, NULL
, signature
, issuer_params
) != 0)
1770 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
1778 if (dsa_verify_data(pk
, algo
, data
, signature
, issuer_params
) != 0)
1781 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
1788 return GNUTLS_E_INTERNAL_ERROR
;
1793 gnutls_digest_algorithm_t
1794 _gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo
, const gnutls_pk_params_st
* params
,
1795 unsigned int* hash_len
)
1799 if (algo
== GNUTLS_PK_DSA
)
1800 bits
= _gnutls_mpi_get_nbits (params
->params
[1]);
1801 else if (algo
== GNUTLS_PK_EC
)
1802 bits
= gnutls_ecc_curve_get_size(params
->flags
)*8;
1806 if (hash_len
) *hash_len
= 20;
1807 return GNUTLS_DIG_SHA1
;
1809 else if (bits
<= 192)
1811 if (hash_len
) *hash_len
= 24;
1812 return GNUTLS_DIG_SHA256
;
1814 else if (bits
<= 224)
1816 if (hash_len
) *hash_len
= 28;
1817 return GNUTLS_DIG_SHA256
;
1819 else if (bits
<= 256)
1821 if (hash_len
) *hash_len
= 32;
1822 return GNUTLS_DIG_SHA256
;
1824 else if (bits
<= 384)
1826 if (hash_len
) *hash_len
= 48;
1827 return GNUTLS_DIG_SHA384
;
1831 if (hash_len
) *hash_len
= 64;
1832 return GNUTLS_DIG_SHA512
;