Honor uninitialized private key in destructor
[gnutls.git] / lib / auth_cert.c
blob978621155a625f1dcb65b82925e26d4b0f19f413
1 /*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3 * 2010 Free Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 /* The certificate authentication functions which are needed in the handshake,
27 * and are common to RSA and DHE key exchange, are in this file.
30 #include <gnutls_int.h>
31 #include "gnutls_auth.h"
32 #include "gnutls_errors.h"
33 #include <gnutls_cert.h>
34 #include <auth_cert.h>
35 #include "gnutls_dh.h"
36 #include "gnutls_num.h"
37 #include "libtasn1.h"
38 #include "gnutls_datum.h"
39 #include "ext_signature.h"
40 #include <gnutls_pk.h>
41 #include <gnutls_algorithms.h>
42 #include <gnutls_global.h>
43 #include <gnutls_record.h>
44 #include <gnutls_sig.h>
45 #include <gnutls_state.h>
46 #include <gnutls_pk.h>
47 #include <gnutls_x509.h>
48 #include <gnutls/abstract.h>
49 #include "debug.h"
51 #ifdef ENABLE_OPENPGP
52 #include "openpgp/gnutls_openpgp.h"
54 static gnutls_privkey_t alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t
55 key, int deinit);
56 static gnutls_cert *alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert);
58 #endif
60 static gnutls_cert *alloc_and_load_x509_certs (gnutls_x509_crt_t * certs,
61 unsigned);
62 static gnutls_privkey_t alloc_and_load_x509_key (gnutls_x509_privkey_t key,
63 int deinit);
65 static gnutls_privkey_t alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t
66 key, int deinit);
69 /* Copies data from a internal certificate struct (gnutls_cert) to
70 * exported certificate struct (cert_auth_info_t)
72 static int
73 _gnutls_copy_certificate_auth_info (cert_auth_info_t info,
74 gnutls_cert * cert, size_t ncerts)
76 /* Copy peer's information to auth_info_t
78 int ret;
79 size_t i, j;
81 if (info->raw_certificate_list != NULL)
83 for (j = 0; j < info->ncerts; j++)
84 _gnutls_free_datum (&info->raw_certificate_list[j]);
85 gnutls_free (info->raw_certificate_list);
88 if (ncerts == 0)
90 info->raw_certificate_list = NULL;
91 info->ncerts = 0;
92 return 0;
95 info->raw_certificate_list =
96 gnutls_calloc (ncerts, sizeof (gnutls_datum_t));
97 if (info->raw_certificate_list == NULL)
99 gnutls_assert ();
100 return GNUTLS_E_MEMORY_ERROR;
103 for (i = 0; i < ncerts; i++)
105 if (cert->raw.size > 0)
107 ret =
108 _gnutls_set_datum (&info->raw_certificate_list[i],
109 cert[i].raw.data, cert[i].raw.size);
110 if (ret < 0)
112 gnutls_assert ();
113 goto clear;
117 info->ncerts = ncerts;
119 info->cert_type = cert[0].cert_type;
121 #ifdef ENABLE_OPENPGP
122 if (cert[0].cert_type == GNUTLS_CRT_OPENPGP)
124 info->use_subkey = cert[0].use_subkey;
125 memcpy (info->subkey_id, cert[0].subkey_id, sizeof (info->subkey_id));
127 #endif
129 return 0;
131 clear:
133 for (j = 0; j < i; j++)
134 _gnutls_free_datum (&info->raw_certificate_list[j]);
136 gnutls_free (info->raw_certificate_list);
137 info->raw_certificate_list = NULL;
139 return ret;
145 /* returns 0 if the algo_to-check exists in the pk_algos list,
146 * -1 otherwise.
148 inline static int
149 _gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t *
150 pk_algos, int pk_algos_length,
151 gnutls_pk_algorithm_t algo_to_check)
153 int i;
154 for (i = 0; i < pk_algos_length; i++)
156 if (algo_to_check == pk_algos[i])
158 return 0;
161 return -1;
165 /* Returns the issuer's Distinguished name in odn, of the certificate
166 * specified in cert.
168 static int
169 _gnutls_cert_get_issuer_dn (gnutls_cert * cert, gnutls_datum_t * odn)
171 ASN1_TYPE dn;
172 int len, result;
173 int start, end;
175 if ((result = asn1_create_element
176 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS)
178 gnutls_assert ();
179 return _gnutls_asn2err (result);
182 result = asn1_der_decoding (&dn, cert->raw.data, cert->raw.size, NULL);
183 if (result != ASN1_SUCCESS)
185 /* couldn't decode DER */
186 gnutls_assert ();
187 asn1_delete_structure (&dn);
188 return _gnutls_asn2err (result);
191 result = asn1_der_decoding_startEnd (dn, cert->raw.data, cert->raw.size,
192 "tbsCertificate.issuer", &start, &end);
194 if (result != ASN1_SUCCESS)
196 /* couldn't decode DER */
197 gnutls_assert ();
198 asn1_delete_structure (&dn);
199 return _gnutls_asn2err (result);
201 asn1_delete_structure (&dn);
203 len = end - start + 1;
205 odn->size = len;
206 odn->data = &cert->raw.data[start];
208 return 0;
212 /* Locates the most appropriate x509 certificate using the
213 * given DN. If indx == -1 then no certificate was found.
215 * That is to guess which certificate to use, based on the
216 * CAs and sign algorithms supported by the peer server.
218 static int
219 _find_x509_cert (const gnutls_certificate_credentials_t cred,
220 opaque * _data, size_t _data_size,
221 const gnutls_pk_algorithm_t * pk_algos,
222 int pk_algos_length, int *indx)
224 unsigned size;
225 gnutls_datum_t odn = { NULL, 0 };
226 opaque *data = _data;
227 ssize_t data_size = _data_size;
228 unsigned i, j;
229 int result, cert_pk;
231 *indx = -1;
236 DECR_LENGTH_RET (data_size, 2, 0);
237 size = _gnutls_read_uint16 (data);
238 DECR_LENGTH_RET (data_size, size, 0);
239 data += 2;
241 for (i = 0; i < cred->ncerts; i++)
243 for (j = 0; j < cred->cert_list_length[i]; j++)
245 if ((result =
246 _gnutls_cert_get_issuer_dn (&cred->cert_list[i][j],
247 &odn)) < 0)
249 gnutls_assert ();
250 return result;
253 if (odn.size != size)
254 continue;
256 /* If the DN matches and
257 * the *_SIGN algorithm matches
258 * the cert is our cert!
260 cert_pk = cred->cert_list[i][0].subject_pk_algorithm;
262 if ((memcmp (odn.data, data, size) == 0) &&
263 (_gnutls_check_pk_algo_in_list
264 (pk_algos, pk_algos_length, cert_pk) == 0))
266 *indx = i;
267 break;
270 if (*indx != -1)
271 break;
274 if (*indx != -1)
275 break;
277 /* move to next record */
278 data += size;
281 while (1);
283 return 0;
287 #ifdef ENABLE_OPENPGP
288 /* Locates the most appropriate openpgp cert
290 static int
291 _find_openpgp_cert (const gnutls_certificate_credentials_t cred,
292 gnutls_pk_algorithm_t * pk_algos,
293 int pk_algos_length, int *indx)
295 unsigned i, j;
297 *indx = -1;
299 for (i = 0; i < cred->ncerts; i++)
301 for (j = 0; j < cred->cert_list_length[i]; j++)
304 /* If the *_SIGN algorithm matches
305 * the cert is our cert!
307 if ((_gnutls_check_pk_algo_in_list
308 (pk_algos, pk_algos_length,
309 cred->cert_list[i][0].subject_pk_algorithm) == 0)
310 && (cred->cert_list[i][0].cert_type == GNUTLS_CRT_OPENPGP))
312 *indx = i;
313 break;
316 if (*indx != -1)
317 break;
320 return 0;
322 #endif
324 /* Returns the number of issuers in the server's
325 * certificate request packet.
327 static int
328 get_issuers_num (gnutls_session_t session, opaque * data, ssize_t data_size)
330 int issuers_dn_len = 0, result;
331 unsigned size;
333 /* Count the number of the given issuers;
334 * This is used to allocate the issuers_dn without
335 * using realloc().
338 if (data_size == 0 || data == NULL)
339 return 0;
341 if (data_size > 0)
344 /* This works like DECR_LEN()
346 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
347 DECR_LENGTH_COM (data_size, 2, goto error);
348 size = _gnutls_read_uint16 (data);
350 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
351 DECR_LENGTH_COM (data_size, size, goto error);
353 data += 2;
355 if (size > 0)
357 issuers_dn_len++;
358 data += size;
361 if (data_size == 0)
362 break;
365 while (1);
367 return issuers_dn_len;
369 error:
370 return result;
373 /* Returns the issuers in the server's certificate request
374 * packet.
376 static int
377 get_issuers (gnutls_session_t session,
378 gnutls_datum_t * issuers_dn, int issuers_len,
379 opaque * data, size_t data_size)
381 int i;
382 unsigned size;
384 if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
385 return 0;
387 /* put the requested DNs to req_dn, only in case
388 * of X509 certificates.
390 if (issuers_len > 0)
393 for (i = 0; i < issuers_len; i++)
395 /* The checks here for the buffer boundaries
396 * are not needed since the buffer has been
397 * parsed above.
399 data_size -= 2;
401 size = _gnutls_read_uint16 (data);
403 data += 2;
405 issuers_dn[i].data = data;
406 issuers_dn[i].size = size;
408 data += size;
412 return 0;
415 static void
416 st_to_st2 (gnutls_retr2_st * st2, gnutls_retr_st * st)
418 st2->cert_type = st->type;
419 if (st->type == GNUTLS_CRT_OPENPGP)
421 st2->key_type = GNUTLS_PRIVKEY_OPENPGP;
423 else
425 st2->key_type = GNUTLS_PRIVKEY_X509;
427 st2->ncerts = st->ncerts;
428 st2->deinit_all = st->deinit_all;
430 switch (st2->cert_type)
432 case GNUTLS_CRT_OPENPGP:
433 st2->cert.pgp = st->cert.pgp;
434 st2->key.pgp = st->key.pgp;
435 break;
436 case GNUTLS_CRT_X509:
437 st2->cert.x509 = st->cert.x509;
438 st2->key.x509 = st->key.x509;
439 break;
440 default:
441 return;
446 /* Calls the client get callback.
448 static int
449 call_get_cert_callback (gnutls_session_t session,
450 const gnutls_datum_t * issuers_dn,
451 int issuers_dn_length,
452 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
454 unsigned i;
455 gnutls_cert *local_certs = NULL;
456 gnutls_privkey_t local_key = NULL;
457 int ret = GNUTLS_E_INTERNAL_ERROR;
458 gnutls_certificate_type_t type = gnutls_certificate_type_get (session);
459 gnutls_certificate_credentials_t cred;
460 gnutls_retr2_st st2;
462 cred = (gnutls_certificate_credentials_t)
463 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
464 if (cred == NULL)
466 gnutls_assert ();
467 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
470 memset (&st2, 0, sizeof (st2));
472 if (cred->get_cert_callback)
474 ret = cred->get_cert_callback (session, issuers_dn, issuers_dn_length,
475 pk_algos, pk_algos_length, &st2);
478 else
479 { /* compatibility mode */
480 gnutls_retr_st st;
481 memset (&st, 0, sizeof (st));
482 if (session->security_parameters.entity == GNUTLS_SERVER)
484 if (cred->server_get_cert_callback == NULL)
486 gnutls_assert ();
487 return GNUTLS_E_INTERNAL_ERROR;
489 ret = cred->server_get_cert_callback (session, &st);
490 if (ret >= 0)
491 st_to_st2 (&st2, &st);
493 else
494 { /* CLIENT */
496 if (cred->client_get_cert_callback == NULL)
498 gnutls_assert ();
499 return GNUTLS_E_INTERNAL_ERROR;
501 ret = cred->client_get_cert_callback (session,
502 issuers_dn, issuers_dn_length,
503 pk_algos, pk_algos_length,
504 &st);
505 if (ret >= 0)
506 st_to_st2 (&st2, &st);
510 if (ret < 0)
512 gnutls_assert ();
513 return GNUTLS_E_INTERNAL_ERROR;
516 if (st2.ncerts == 0)
517 return 0; /* no certificate was selected */
519 if (type != st2.cert_type)
521 gnutls_assert ();
522 ret = GNUTLS_E_INVALID_REQUEST;
523 goto cleanup;
527 if (type == GNUTLS_CRT_X509)
529 local_certs = alloc_and_load_x509_certs (st2.cert.x509, st2.ncerts);
531 else
532 { /* PGP */
533 if (st2.ncerts > 1)
535 gnutls_assert ();
536 ret = GNUTLS_E_INVALID_REQUEST;
537 goto cleanup;
539 #ifdef ENABLE_OPENPGP
541 local_certs = alloc_and_load_pgp_certs (st2.cert.pgp);
543 #else
544 ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
545 goto cleanup;
546 #endif
549 if (local_certs == NULL)
551 gnutls_assert ();
552 ret = GNUTLS_E_MEMORY_ERROR;
553 goto cleanup;
556 switch (st2.key_type)
558 case GNUTLS_PRIVKEY_OPENPGP:
559 #ifdef ENABLE_OPENPGP
560 if (st2.key.pgp != NULL)
562 local_key = alloc_and_load_pgp_key (st2.key.pgp, st2.deinit_all);
563 if (local_key == NULL)
565 gnutls_assert ();
566 ret = GNUTLS_E_INTERNAL_ERROR;
567 goto cleanup;
570 break;
571 #endif
572 case GNUTLS_PRIVKEY_PKCS11:
573 if (st2.key.pkcs11 != NULL)
575 local_key =
576 alloc_and_load_pkcs11_key (st2.key.pkcs11, st2.deinit_all);
577 if (local_key == NULL)
579 gnutls_assert ();
580 ret = GNUTLS_E_INTERNAL_ERROR;
581 goto cleanup;
584 break;
585 case GNUTLS_PRIVKEY_X509:
586 if (st2.key.x509 != NULL)
588 local_key = alloc_and_load_x509_key (st2.key.x509, st2.deinit_all);
589 if (local_key == NULL)
591 gnutls_assert ();
592 ret = GNUTLS_E_INTERNAL_ERROR;
593 goto cleanup;
596 break;
599 _gnutls_selected_certs_set (session, local_certs,
600 (local_certs != NULL) ? st2.ncerts : 0,
601 local_key, 1);
603 ret = 0;
605 cleanup:
607 if (st2.cert_type == GNUTLS_CRT_X509)
609 if (st2.deinit_all)
611 for (i = 0; i < st2.ncerts; i++)
613 gnutls_x509_crt_deinit (st2.cert.x509[i]);
617 else
619 #ifdef ENABLE_OPENPGP
620 if (st2.deinit_all)
622 gnutls_openpgp_crt_deinit (st2.cert.pgp);
624 #endif
627 if (ret < 0)
629 if (local_key != NULL)
630 gnutls_privkey_deinit (local_key);
633 return ret;
636 /* Finds the appropriate certificate depending on the cA Distinguished name
637 * advertized by the server. If none matches then returns 0 and -1 as index.
638 * In case of an error a negative value, is returned.
640 * 20020128: added ability to select a certificate depending on the SIGN
641 * algorithm (only in automatic mode).
643 static int
644 _select_client_cert (gnutls_session_t session,
645 opaque * _data, size_t _data_size,
646 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
648 int result;
649 int indx = -1;
650 gnutls_certificate_credentials_t cred;
651 opaque *data = _data;
652 ssize_t data_size = _data_size;
653 int issuers_dn_length;
654 gnutls_datum_t *issuers_dn = NULL;
656 cred = (gnutls_certificate_credentials_t)
657 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
658 if (cred == NULL)
660 gnutls_assert ();
661 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
664 if (cred->client_get_cert_callback != NULL
665 || cred->get_cert_callback != NULL)
668 /* use a callback to get certificate
670 if (session->security_parameters.cert_type != GNUTLS_CRT_X509)
671 issuers_dn_length = 0;
672 else
674 issuers_dn_length = get_issuers_num (session, data, data_size);
675 if (issuers_dn_length < 0)
677 gnutls_assert ();
678 return issuers_dn_length;
681 if (issuers_dn_length > 0)
683 issuers_dn =
684 gnutls_malloc (sizeof (gnutls_datum_t) * issuers_dn_length);
685 if (issuers_dn == NULL)
687 gnutls_assert ();
688 return GNUTLS_E_MEMORY_ERROR;
691 result =
692 get_issuers (session, issuers_dn, issuers_dn_length,
693 data, data_size);
694 if (result < 0)
696 gnutls_assert ();
697 goto cleanup;
702 result =
703 call_get_cert_callback (session, issuers_dn, issuers_dn_length,
704 pk_algos, pk_algos_length);
705 goto cleanup;
708 else
710 /* If we have no callbacks, try to guess.
712 result = 0;
714 if (session->security_parameters.cert_type == GNUTLS_CRT_X509)
715 result =
716 _find_x509_cert (cred, _data, _data_size,
717 pk_algos, pk_algos_length, &indx);
719 #ifdef ENABLE_OPENPGP
720 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP)
721 result = _find_openpgp_cert (cred, pk_algos, pk_algos_length, &indx);
722 #endif
724 if (result < 0)
726 gnutls_assert ();
727 return result;
730 if (indx >= 0)
732 _gnutls_selected_certs_set (session,
733 &cred->cert_list[indx][0],
734 cred->cert_list_length[indx],
735 cred->pkey[indx], 0);
737 else
739 _gnutls_selected_certs_set (session, NULL, 0, NULL, 0);
742 result = 0;
745 cleanup:
746 gnutls_free (issuers_dn);
747 return result;
751 /* Generate client certificate
754 static int
755 _gnutls_gen_x509_crt (gnutls_session_t session, opaque ** data)
757 int ret, i;
758 opaque *pdata;
759 gnutls_cert *apr_cert_list;
760 gnutls_privkey_t apr_pkey;
761 int apr_cert_list_length;
763 /* find the appropriate certificate
765 if ((ret =
766 _gnutls_get_selected_cert (session, &apr_cert_list,
767 &apr_cert_list_length, &apr_pkey)) < 0)
769 gnutls_assert ();
770 return ret;
773 ret = 3;
774 for (i = 0; i < apr_cert_list_length; i++)
776 ret += apr_cert_list[i].raw.size + 3;
777 /* hold size
778 * for uint24 */
781 /* if no certificates were found then send:
782 * 0B 00 00 03 00 00 00 // Certificate with no certs
783 * instead of:
784 * 0B 00 00 00 // empty certificate handshake
786 * ( the above is the whole handshake message, not
787 * the one produced here )
790 (*data) = gnutls_malloc (ret);
791 pdata = (*data);
793 if (pdata == NULL)
795 gnutls_assert ();
796 return GNUTLS_E_MEMORY_ERROR;
798 _gnutls_write_uint24 (ret - 3, pdata);
799 pdata += 3;
800 for (i = 0; i < apr_cert_list_length; i++)
802 _gnutls_write_datum24 (pdata, apr_cert_list[i].raw);
803 pdata += (3 + apr_cert_list[i].raw.size);
806 return ret;
809 enum PGPKeyDescriptorType
810 { PGP_KEY_FINGERPRINT, PGP_KEY, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
812 #ifdef ENABLE_OPENPGP
813 static int
814 _gnutls_gen_openpgp_certificate (gnutls_session_t session, opaque ** data)
816 int ret;
817 opaque *pdata;
818 gnutls_cert *apr_cert_list;
819 gnutls_privkey_t apr_pkey;
820 int apr_cert_list_length;
822 /* find the appropriate certificate */
823 if ((ret =
824 _gnutls_get_selected_cert (session, &apr_cert_list,
825 &apr_cert_list_length, &apr_pkey)) < 0)
827 gnutls_assert ();
828 return ret;
831 ret = 3 + 1 + 3;
834 if (apr_cert_list_length > 0)
836 if (apr_cert_list[0].use_subkey != 0)
837 ret += 1 + sizeof (apr_cert_list[0].subkey_id); /* for the keyid */
839 ret += apr_cert_list[0].raw.size;
842 (*data) = gnutls_malloc (ret);
843 pdata = (*data);
845 if (pdata == NULL)
847 gnutls_assert ();
848 return GNUTLS_E_MEMORY_ERROR;
851 _gnutls_write_uint24 (ret - 3, pdata);
852 pdata += 3;
855 if (apr_cert_list_length > 0)
857 if (apr_cert_list[0].use_subkey != 0)
859 *pdata = PGP_KEY_SUBKEY;
860 pdata++;
861 *pdata = sizeof (apr_cert_list[0].subkey_id);
862 pdata++;
863 memcpy (pdata, apr_cert_list[0].subkey_id,
864 sizeof (apr_cert_list[0].subkey_id));
865 pdata += sizeof (apr_cert_list[0].subkey_id);
867 else
869 *pdata = PGP_KEY;
870 pdata++;
873 _gnutls_write_datum24 (pdata, apr_cert_list[0].raw);
874 pdata += (3 + apr_cert_list[0].raw.size);
876 else /* empty - no certificate */
878 *pdata = PGP_KEY;
879 pdata++;
880 _gnutls_write_uint24 (0, pdata);
883 return ret;
886 static int
887 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, opaque ** data)
889 int ret, packet_size;
890 size_t fpr_size;
891 opaque *pdata;
892 gnutls_cert *apr_cert_list;
893 gnutls_privkey_t apr_pkey;
894 int apr_cert_list_length;
896 /* find the appropriate certificate */
897 if ((ret =
898 _gnutls_get_selected_cert (session, &apr_cert_list,
899 &apr_cert_list_length, &apr_pkey)) < 0)
901 gnutls_assert ();
902 return ret;
905 packet_size = 3 + 1;
907 if (apr_cert_list[0].use_subkey)
908 packet_size += 1 + sizeof (apr_cert_list[0].subkey_id); /* for the keyid */
910 /* Only v4 fingerprints are sent
912 if (apr_cert_list_length > 0 && apr_cert_list[0].version == 4)
913 packet_size += 20 + 1;
914 else /* empty certificate case */
915 return _gnutls_gen_openpgp_certificate (session, data);
917 (*data) = gnutls_malloc (packet_size);
918 pdata = (*data);
920 if (pdata == NULL)
922 gnutls_assert ();
923 return GNUTLS_E_MEMORY_ERROR;
926 _gnutls_write_uint24 (packet_size - 3, pdata);
927 pdata += 3;
929 if (apr_cert_list[0].use_subkey)
931 *pdata = PGP_KEY_FINGERPRINT_SUBKEY;
932 pdata++;
933 *pdata = sizeof (apr_cert_list[0].subkey_id);
934 pdata++;
935 memcpy (pdata, apr_cert_list[0].subkey_id,
936 sizeof (apr_cert_list[0].subkey_id));
937 pdata += sizeof (apr_cert_list[0].subkey_id);
939 else
941 *pdata = PGP_KEY_FINGERPRINT; /* key fingerprint */
942 pdata++;
945 *pdata = 20;
946 pdata++;
948 fpr_size = 20;
950 if ((ret =
951 _gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, pdata,
952 &fpr_size)) < 0)
954 gnutls_assert ();
955 return ret;
958 return packet_size;
960 #endif
964 _gnutls_gen_cert_client_certificate (gnutls_session_t session, opaque ** data)
966 switch (session->security_parameters.cert_type)
968 #ifdef ENABLE_OPENPGP
969 case GNUTLS_CRT_OPENPGP:
970 if (_gnutls_openpgp_send_fingerprint (session) == 0)
971 return _gnutls_gen_openpgp_certificate (session, data);
972 else
973 return _gnutls_gen_openpgp_certificate_fpr (session, data);
974 #endif
975 case GNUTLS_CRT_X509:
976 return _gnutls_gen_x509_crt (session, data);
978 default:
979 gnutls_assert ();
980 return GNUTLS_E_INTERNAL_ERROR;
985 _gnutls_gen_cert_server_certificate (gnutls_session_t session, opaque ** data)
987 switch (session->security_parameters.cert_type)
989 #ifdef ENABLE_OPENPGP
990 case GNUTLS_CRT_OPENPGP:
991 return _gnutls_gen_openpgp_certificate (session, data);
992 #endif
993 case GNUTLS_CRT_X509:
994 return _gnutls_gen_x509_crt (session, data);
995 default:
996 gnutls_assert ();
997 return GNUTLS_E_INTERNAL_ERROR;
1001 /* Process server certificate
1004 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
1005 static int
1006 _gnutls_proc_x509_server_certificate (gnutls_session_t session,
1007 opaque * data, size_t data_size)
1009 int size, len, ret;
1010 opaque *p = data;
1011 cert_auth_info_t info;
1012 gnutls_certificate_credentials_t cred;
1013 ssize_t dsize = data_size;
1014 int i;
1015 gnutls_cert *peer_certificate_list;
1016 size_t peer_certificate_list_size = 0, j, x;
1017 gnutls_datum_t tmp;
1019 cred = (gnutls_certificate_credentials_t)
1020 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1021 if (cred == NULL)
1023 gnutls_assert ();
1024 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1028 if ((ret =
1029 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1030 sizeof (cert_auth_info_st), 1)) < 0)
1032 gnutls_assert ();
1033 return ret;
1036 info = _gnutls_get_auth_info (session);
1038 if (data == NULL || data_size == 0)
1040 gnutls_assert ();
1041 /* no certificate was sent */
1042 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1045 DECR_LEN (dsize, 3);
1046 size = _gnutls_read_uint24 (p);
1047 p += 3;
1049 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
1050 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
1052 if (size == 0 || size == 3)
1054 gnutls_assert ();
1055 /* no certificate was sent */
1056 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1059 i = dsize;
1060 while (i > 0)
1062 DECR_LEN (dsize, 3);
1063 len = _gnutls_read_uint24 (p);
1064 p += 3;
1065 DECR_LEN (dsize, len);
1066 peer_certificate_list_size++;
1067 p += len;
1068 i -= len + 3;
1071 if (peer_certificate_list_size == 0)
1073 gnutls_assert ();
1074 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1077 /* Ok we now allocate the memory to hold the
1078 * certificate list
1081 peer_certificate_list =
1082 gnutls_malloc (sizeof (gnutls_cert) * (peer_certificate_list_size));
1084 if (peer_certificate_list == NULL)
1086 gnutls_assert ();
1087 return GNUTLS_E_MEMORY_ERROR;
1089 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
1090 peer_certificate_list_size);
1092 p = data + 3;
1094 /* Now we start parsing the list (again).
1095 * We don't use DECR_LEN since the list has
1096 * been parsed before.
1099 for (j = 0; j < peer_certificate_list_size; j++)
1101 len = _gnutls_read_uint24 (p);
1102 p += 3;
1104 tmp.size = len;
1105 tmp.data = p;
1107 if ((ret =
1108 _gnutls_x509_raw_cert_to_gcert (&peer_certificate_list
1109 [j], &tmp,
1110 CERT_ONLY_EXTENSIONS)) < 0)
1112 gnutls_assert ();
1113 goto cleanup;
1116 /* check if signature algorithm is supported */
1117 ret =
1118 _gnutls_session_sign_algo_enabled (session,
1119 peer_certificate_list
1120 [j].sign_algo);
1121 if (ret < 0)
1123 gnutls_assert ();
1124 goto cleanup;
1127 p += len;
1131 if ((ret =
1132 _gnutls_copy_certificate_auth_info (info,
1133 peer_certificate_list,
1134 peer_certificate_list_size)) < 0)
1136 gnutls_assert ();
1137 goto cleanup;
1140 if ((ret =
1141 _gnutls_check_key_usage (&peer_certificate_list[0],
1142 gnutls_kx_get (session))) < 0)
1144 gnutls_assert ();
1145 goto cleanup;
1148 ret = 0;
1150 cleanup:
1151 CLEAR_CERTS;
1152 gnutls_free (peer_certificate_list);
1153 return ret;
1157 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
1158 #ifdef ENABLE_OPENPGP
1159 static int
1160 _gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
1161 opaque * data, size_t data_size)
1163 int size, ret, len;
1164 opaque *p = data;
1165 cert_auth_info_t info;
1166 gnutls_certificate_credentials_t cred;
1167 ssize_t dsize = data_size;
1168 int x, key_type;
1169 gnutls_cert *peer_certificate_list = NULL;
1170 int peer_certificate_list_size = 0;
1171 gnutls_datum_t tmp, akey = { NULL, 0 };
1172 uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE];
1173 unsigned int subkey_id_set = 0;
1175 cred = (gnutls_certificate_credentials_t)
1176 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1177 if (cred == NULL)
1179 gnutls_assert ();
1180 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1183 if ((ret =
1184 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1185 sizeof (cert_auth_info_st), 1)) < 0)
1187 gnutls_assert ();
1188 return ret;
1191 info = _gnutls_get_auth_info (session);
1193 if (data == NULL || data_size == 0)
1195 gnutls_assert ();
1196 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1199 DECR_LEN (dsize, 3);
1200 size = _gnutls_read_uint24 (p);
1201 p += 3;
1203 if (size == 0)
1205 gnutls_assert ();
1206 /* no certificate was sent */
1207 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1210 /* Read PGPKeyDescriptor */
1211 DECR_LEN (dsize, 1);
1212 key_type = *p;
1213 p++;
1215 /* Try to read the keyid if present */
1216 if (key_type == PGP_KEY_FINGERPRINT_SUBKEY || key_type == PGP_KEY_SUBKEY)
1218 /* check size */
1219 if (*p != sizeof (subkey_id))
1221 gnutls_assert ();
1222 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1225 DECR_LEN (dsize, 1);
1226 p++;
1228 DECR_LEN (dsize, sizeof (subkey_id));
1229 memcpy (subkey_id, p, sizeof (subkey_id));
1230 p += sizeof (subkey_id);
1232 subkey_id_set = 1;
1236 /* read the actual key or fingerprint */
1237 if (key_type == PGP_KEY_FINGERPRINT
1238 || key_type == PGP_KEY_FINGERPRINT_SUBKEY)
1239 { /* the fingerprint */
1241 DECR_LEN (dsize, 1);
1242 len = (uint8_t) * p;
1243 p++;
1245 if (len != 20)
1247 gnutls_assert ();
1248 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED;
1251 DECR_LEN (dsize, 20);
1253 /* request the actual key from our database, or
1254 * a key server or anything.
1256 if ((ret =
1257 _gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
1259 gnutls_assert ();
1260 return ret;
1262 tmp = akey;
1263 peer_certificate_list_size++;
1266 else if (key_type == PGP_KEY || key_type == PGP_KEY_SUBKEY)
1267 { /* the whole key */
1269 /* Read the actual certificate */
1270 DECR_LEN (dsize, 3);
1271 len = _gnutls_read_uint24 (p);
1272 p += 3;
1274 if (len == 0)
1276 gnutls_assert ();
1277 /* no certificate was sent */
1278 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1281 DECR_LEN (dsize, len);
1282 peer_certificate_list_size++;
1284 tmp.size = len;
1285 tmp.data = p;
1288 else
1290 gnutls_assert ();
1291 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1294 /* ok we now have the peer's key in tmp datum
1297 if (peer_certificate_list_size == 0)
1299 gnutls_assert ();
1300 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1303 peer_certificate_list =
1304 gnutls_malloc (sizeof (gnutls_cert) * (peer_certificate_list_size));
1305 if (peer_certificate_list == NULL)
1307 gnutls_assert ();
1308 ret = GNUTLS_E_MEMORY_ERROR;
1309 goto cleanup;
1311 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
1312 peer_certificate_list_size);
1314 if ((ret =
1315 _gnutls_openpgp_raw_crt_to_gcert (&peer_certificate_list[0],
1316 &tmp,
1317 subkey_id_set ? subkey_id : NULL)) <
1320 gnutls_assert ();
1321 goto cleanup;
1324 if ((ret =
1325 _gnutls_copy_certificate_auth_info (info,
1326 peer_certificate_list,
1327 peer_certificate_list_size)) < 0)
1329 gnutls_assert ();
1330 goto cleanup;
1333 if ((ret =
1334 _gnutls_check_key_usage (&peer_certificate_list[0],
1335 gnutls_kx_get (session))) < 0)
1337 gnutls_assert ();
1338 goto cleanup;
1341 ret = 0;
1343 cleanup:
1345 _gnutls_free_datum (&akey);
1346 CLEAR_CERTS;
1347 gnutls_free (peer_certificate_list);
1348 return ret;
1351 #endif
1354 _gnutls_proc_cert_server_certificate (gnutls_session_t session,
1355 opaque * data, size_t data_size)
1357 int ret;
1358 gnutls_certificate_credentials_t cred;
1360 cred =
1361 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
1362 GNUTLS_CRD_CERTIFICATE,
1363 NULL);
1364 if (cred == NULL)
1366 gnutls_assert ();
1367 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1370 switch (session->security_parameters.cert_type)
1372 #ifdef ENABLE_OPENPGP
1373 case GNUTLS_CRT_OPENPGP:
1374 ret = _gnutls_proc_openpgp_server_certificate (session,
1375 data, data_size);
1376 break;
1377 #endif
1378 case GNUTLS_CRT_X509:
1379 ret = _gnutls_proc_x509_server_certificate (session, data, data_size);
1380 break;
1381 default:
1382 gnutls_assert ();
1383 return GNUTLS_E_INTERNAL_ERROR;
1386 if (ret == 0 && cred->verify_callback != NULL)
1388 ret = cred->verify_callback (session);
1389 if (ret != 0)
1390 ret = GNUTLS_E_CERTIFICATE_ERROR;
1393 return ret;
1396 #define MAX_SIGN_ALGOS 2
1397 typedef enum CertificateSigType
1398 { RSA_SIGN = 1, DSA_SIGN
1399 } CertificateSigType;
1401 /* Checks if we support the given signature algorithm
1402 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1403 * if true;
1405 inline static int
1406 _gnutls_check_supported_sign_algo (CertificateSigType algo)
1408 switch (algo)
1410 case RSA_SIGN:
1411 return GNUTLS_PK_RSA;
1412 case DSA_SIGN:
1413 return GNUTLS_PK_DSA;
1416 return -1;
1420 _gnutls_proc_cert_cert_req (gnutls_session_t session, opaque * data,
1421 size_t data_size)
1423 int size, ret;
1424 opaque *p;
1425 gnutls_certificate_credentials_t cred;
1426 ssize_t dsize;
1427 int i, j;
1428 gnutls_pk_algorithm_t pk_algos[MAX_SIGN_ALGOS];
1429 int pk_algos_length;
1430 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1432 cred = (gnutls_certificate_credentials_t)
1433 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1434 if (cred == NULL)
1436 gnutls_assert ();
1437 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1440 if ((ret =
1441 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1442 sizeof (cert_auth_info_st), 0)) < 0)
1444 gnutls_assert ();
1445 return ret;
1448 p = data;
1449 dsize = data_size;
1451 DECR_LEN (dsize, 1);
1452 size = p[0];
1453 p++;
1454 /* check if the sign algorithm is supported.
1456 pk_algos_length = j = 0;
1457 for (i = 0; i < size; i++, p++)
1459 DECR_LEN (dsize, 1);
1460 if ((ret = _gnutls_check_supported_sign_algo (*p)) > 0)
1462 if (j < MAX_SIGN_ALGOS)
1464 pk_algos[j++] = ret;
1465 pk_algos_length++;
1470 if (pk_algos_length == 0)
1472 gnutls_assert ();
1473 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1476 if (_gnutls_version_has_selectable_sighash (ver))
1478 /* read supported hashes */
1479 int hash_num;
1480 DECR_LEN (dsize, 2);
1481 hash_num = _gnutls_read_uint16 (p);
1482 p += 2;
1483 DECR_LEN (dsize, hash_num);
1485 ret = _gnutls_sign_algorithm_parse_data (session, p, hash_num);
1486 if (ret < 0)
1488 gnutls_assert ();
1489 return ret;
1492 p += hash_num;
1495 /* read the certificate authorities */
1496 DECR_LEN (dsize, 2);
1497 size = _gnutls_read_uint16 (p);
1498 p += 2;
1500 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP
1501 && size != 0)
1503 gnutls_assert ();
1504 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1507 DECR_LEN (dsize, size);
1509 /* now we ask the user to tell which one
1510 * he wants to use.
1512 if ((ret =
1513 _select_client_cert (session, p, size, pk_algos, pk_algos_length)) < 0)
1515 gnutls_assert ();
1516 return ret;
1519 /* We should reply with a certificate message,
1520 * even if we have no certificate to send.
1522 session->key->certificate_requested = 1;
1524 return 0;
1528 _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data)
1530 int ret;
1531 gnutls_cert *apr_cert_list;
1532 gnutls_privkey_t apr_pkey;
1533 int apr_cert_list_length, size;
1534 gnutls_datum_t signature = { NULL, 0 };
1535 int total_data;
1536 opaque *p;
1537 gnutls_sign_algorithm_t sign_algo;
1538 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1540 *data = NULL;
1542 /* find the appropriate certificate */
1543 if ((ret =
1544 _gnutls_get_selected_cert (session, &apr_cert_list,
1545 &apr_cert_list_length, &apr_pkey)) < 0)
1547 gnutls_assert ();
1548 return ret;
1551 if (apr_cert_list_length > 0)
1553 if ((ret =
1554 _gnutls_handshake_sign_cert_vrfy (session,
1555 &apr_cert_list[0],
1556 apr_pkey, &signature)) < 0)
1558 gnutls_assert ();
1559 return ret;
1561 sign_algo = ret;
1563 else
1565 return 0;
1568 total_data = signature.size + 2;
1570 /* add hash and signature algorithms */
1571 if (_gnutls_version_has_selectable_sighash (ver))
1573 total_data += 2;
1576 *data = gnutls_malloc (total_data);
1577 if (*data == NULL)
1579 _gnutls_free_datum (&signature);
1580 return GNUTLS_E_MEMORY_ERROR;
1583 p = *data;
1584 if (_gnutls_version_has_selectable_sighash (ver))
1586 const sign_algorithm_st *aid;
1587 /* error checking is not needed here since we have used those algorithms */
1588 aid = _gnutls_sign_to_tls_aid (sign_algo);
1589 if (aid == NULL)
1591 ret = GNUTLS_E_UNKNOWN_ALGORITHM;
1592 goto cleanup;
1595 p[0] = aid->hash_algorithm;
1596 p[1] = aid->sign_algorithm;
1597 p += 2;
1600 size = signature.size;
1601 _gnutls_write_uint16 (size, p);
1603 p += 2;
1604 memcpy (p, signature.data, size);
1606 _gnutls_free_datum (&signature);
1608 return total_data;
1610 cleanup:
1611 _gnutls_free_datum (&signature);
1612 gnutls_free(*data);
1613 return ret;
1617 _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session,
1618 opaque * data, size_t data_size)
1620 int size, ret;
1621 ssize_t dsize = data_size;
1622 opaque *pdata = data;
1623 gnutls_datum_t sig;
1624 cert_auth_info_t info = _gnutls_get_auth_info (session);
1625 gnutls_cert peer_cert;
1626 gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
1627 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1629 if (info == NULL || info->ncerts == 0)
1631 gnutls_assert ();
1632 /* we need this in order to get peer's certificate */
1633 return GNUTLS_E_INTERNAL_ERROR;
1636 if (_gnutls_version_has_selectable_sighash (ver))
1638 sign_algorithm_st aid;
1640 DECR_LEN (dsize, 2);
1641 aid.hash_algorithm = pdata[0];
1642 aid.sign_algorithm = pdata[1];
1644 sign_algo = _gnutls_tls_aid_to_sign (&aid);
1645 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
1647 gnutls_assert ();
1648 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1650 pdata += 2;
1653 ret = _gnutls_session_sign_algo_enabled (session, sign_algo);
1654 if (ret < 0)
1656 gnutls_assert ();
1657 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1660 DECR_LEN (dsize, 2);
1661 size = _gnutls_read_uint16 (pdata);
1662 pdata += 2;
1664 DECR_LEN (dsize, size);
1666 sig.data = pdata;
1667 sig.size = size;
1669 ret = _gnutls_get_auth_info_gcert (&peer_cert,
1670 session->security_parameters.cert_type,
1671 info, CERT_NO_COPY);
1673 if (ret < 0)
1675 gnutls_assert ();
1676 return ret;
1679 if ((ret =
1680 _gnutls_handshake_verify_cert_vrfy (session, &peer_cert, &sig,
1681 sign_algo)) < 0)
1683 gnutls_assert ();
1684 _gnutls_gcert_deinit (&peer_cert);
1685 return ret;
1687 _gnutls_gcert_deinit (&peer_cert);
1689 return 0;
1693 #define CERTTYPE_SIZE 3
1695 _gnutls_gen_cert_server_cert_req (gnutls_session_t session, opaque ** data)
1697 gnutls_certificate_credentials_t cred;
1698 int size, ret;
1699 opaque *pdata;
1700 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1701 const int signalgosize = 2 + MAX_SIGNATURE_ALGORITHMS * 2;
1703 /* Now we need to generate the RDN sequence. This is
1704 * already in the CERTIFICATE_CRED structure, to improve
1705 * performance.
1708 cred = (gnutls_certificate_credentials_t)
1709 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1710 if (cred == NULL)
1712 gnutls_assert ();
1713 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1716 size = CERTTYPE_SIZE + 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1719 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1720 session->internals.ignore_rdn_sequence == 0)
1721 size += cred->x509_rdn_sequence.size;
1723 if (_gnutls_version_has_selectable_sighash (ver))
1724 /* Need two bytes to announce the number of supported hash
1725 functions (see below). */
1726 size += signalgosize;
1728 (*data) = gnutls_malloc (size);
1729 pdata = (*data);
1731 if (pdata == NULL)
1733 gnutls_assert ();
1734 return GNUTLS_E_MEMORY_ERROR;
1737 pdata[0] = CERTTYPE_SIZE - 1;
1739 pdata[1] = RSA_SIGN;
1740 pdata[2] = DSA_SIGN; /* only these for now */
1741 pdata += CERTTYPE_SIZE;
1743 if (_gnutls_version_has_selectable_sighash (ver))
1745 ret =
1746 _gnutls_sign_algorithm_write_params (session, pdata, signalgosize);
1747 if (ret < 0)
1749 gnutls_assert ();
1750 return ret;
1753 /* recalculate size */
1754 size = size - signalgosize + ret;
1755 pdata += ret;
1758 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1759 session->internals.ignore_rdn_sequence == 0)
1761 _gnutls_write_datum16 (pdata, cred->x509_rdn_sequence);
1762 /* pdata += cred->x509_rdn_sequence.size + 2; */
1764 else
1766 _gnutls_write_uint16 (0, pdata);
1767 /* pdata+=2; */
1770 return size;
1774 /* This function will return the appropriate certificate to use.
1775 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1776 * The return value is a negative value on error.
1778 * It is normal to return 0 with no certificates in client side.
1782 _gnutls_get_selected_cert (gnutls_session_t session,
1783 gnutls_cert ** apr_cert_list,
1784 int *apr_cert_list_length,
1785 gnutls_privkey_t * apr_pkey)
1787 if (session->security_parameters.entity == GNUTLS_SERVER)
1790 /* select_client_cert() has been called before.
1793 *apr_cert_list = session->internals.selected_cert_list;
1794 *apr_pkey = session->internals.selected_key;
1795 *apr_cert_list_length = session->internals.selected_cert_list_length;
1797 if (*apr_cert_list_length == 0 || *apr_cert_list == NULL)
1799 gnutls_assert ();
1800 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1804 else
1805 { /* CLIENT SIDE
1808 /* we have already decided which certificate
1809 * to send.
1811 *apr_cert_list = session->internals.selected_cert_list;
1812 *apr_cert_list_length = session->internals.selected_cert_list_length;
1813 *apr_pkey = session->internals.selected_key;
1817 return 0;
1820 /* converts the given x509 certificate to gnutls_cert* and allocates
1821 * space for them.
1823 static gnutls_cert *
1824 alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, unsigned ncerts)
1826 gnutls_cert *local_certs;
1827 int ret = 0;
1828 unsigned i, j;
1830 if (certs == NULL)
1831 return NULL;
1833 local_certs = gnutls_malloc (sizeof (gnutls_cert) * ncerts);
1834 if (local_certs == NULL)
1836 gnutls_assert ();
1837 return NULL;
1840 for (i = 0; i < ncerts; i++)
1842 ret = _gnutls_x509_crt_to_gcert (&local_certs[i], certs[i], 0);
1843 if (ret < 0)
1844 break;
1847 if (ret < 0)
1849 gnutls_assert ();
1850 for (j = 0; j < i; j++)
1852 _gnutls_gcert_deinit (&local_certs[j]);
1854 gnutls_free (local_certs);
1855 return NULL;
1858 return local_certs;
1861 /* converts the given x509 key to gnutls_privkey* and allocates
1862 * space for it.
1864 static gnutls_privkey_t
1865 alloc_and_load_x509_key (gnutls_x509_privkey_t key, int deinit)
1867 gnutls_privkey_t local_key;
1868 int ret = 0;
1870 if (key == NULL)
1871 return NULL;
1873 ret = gnutls_privkey_init (&local_key);
1874 if (ret < 0)
1876 gnutls_assert ();
1877 return NULL;
1880 ret =
1881 gnutls_privkey_import_x509 (local_key, key,
1882 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE :
1884 if (ret < 0)
1886 gnutls_assert ();
1887 gnutls_privkey_deinit (local_key);
1888 return NULL;
1891 return local_key;
1894 /* converts the given pgp certificate to gnutls_cert* and allocates
1895 * space for them.
1897 #ifdef ENABLE_OPENPGP
1898 static gnutls_cert *
1899 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
1901 gnutls_cert *local_certs;
1902 int ret = 0;
1904 if (cert == NULL)
1905 return NULL;
1907 local_certs = gnutls_malloc (sizeof (gnutls_cert));
1908 if (local_certs == NULL)
1910 gnutls_assert ();
1911 return NULL;
1914 ret = _gnutls_openpgp_crt_to_gcert (local_certs, cert);
1915 if (ret < 0)
1917 gnutls_assert ();
1918 return NULL;
1921 if (ret < 0)
1923 gnutls_assert ();
1924 _gnutls_gcert_deinit (local_certs);
1925 gnutls_free (local_certs);
1926 return NULL;
1929 ret =
1930 gnutls_openpgp_crt_get_preferred_key_id (cert, local_certs->subkey_id);
1931 if (ret < 0)
1932 local_certs->use_subkey = 0;
1933 else
1934 local_certs->use_subkey = 1;
1936 return local_certs;
1939 /* converts the given raw key to gnutls_privkey* and allocates
1940 * space for it.
1942 static gnutls_privkey_t
1943 alloc_and_load_pgp_key (gnutls_openpgp_privkey_t key, int deinit)
1945 gnutls_privkey_t local_key;
1946 int ret = 0;
1948 if (key == NULL)
1949 return NULL;
1951 ret = gnutls_privkey_init (&local_key);
1952 if (ret < 0)
1954 gnutls_assert ();
1955 return NULL;
1958 ret =
1959 gnutls_privkey_import_openpgp (local_key, key,
1960 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
1961 : 0);
1962 if (ret < 0)
1964 gnutls_assert ();
1965 gnutls_privkey_deinit (local_key);
1966 return NULL;
1969 return local_key;
1971 #endif
1973 /* converts the given raw key to gnutls_privkey* and allocates
1974 * space for it.
1976 static gnutls_privkey_t
1977 alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t key, int deinit)
1979 gnutls_privkey_t local_key;
1980 int ret = 0;
1982 if (key == NULL)
1983 return NULL;
1985 ret = gnutls_privkey_init (&local_key);
1986 if (ret < 0)
1988 gnutls_assert ();
1989 return NULL;
1992 ret =
1993 gnutls_privkey_import_pkcs11 (local_key, key,
1994 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
1995 : 0);
1996 if (ret < 0)
1998 gnutls_assert ();
1999 gnutls_privkey_deinit (local_key);
2000 return NULL;
2003 return local_key;
2006 void
2007 _gnutls_selected_certs_deinit (gnutls_session_t session)
2009 if (session->internals.selected_need_free != 0)
2011 int i;
2013 for (i = 0; i < session->internals.selected_cert_list_length; i++)
2015 _gnutls_gcert_deinit (&session->internals.selected_cert_list[i]);
2017 gnutls_free (session->internals.selected_cert_list);
2018 session->internals.selected_cert_list = NULL;
2019 session->internals.selected_cert_list_length = 0;
2021 session->internals.selected_key = NULL;
2024 return;
2027 void
2028 _gnutls_selected_certs_set (gnutls_session_t session,
2029 gnutls_cert * certs, int ncerts,
2030 gnutls_privkey_t key, int need_free)
2032 _gnutls_selected_certs_deinit (session);
2034 session->internals.selected_cert_list = certs;
2035 session->internals.selected_cert_list_length = ncerts;
2036 session->internals.selected_key = key;
2037 session->internals.selected_need_free = need_free;
2042 /* finds the most appropriate certificate in the cert list.
2043 * The 'appropriate' is defined by the user.
2045 * requested_algo holds the parameters required by the peer (RSA, DSA
2046 * or -1 for any).
2048 * Returns 0 on success and a negative value on error. The
2049 * selected certificate will be in session->internals.selected_*.
2053 _gnutls_server_select_cert (gnutls_session_t session,
2054 gnutls_pk_algorithm_t requested_algo)
2056 unsigned i;
2057 int idx;
2058 gnutls_certificate_credentials_t cred;
2060 cred = (gnutls_certificate_credentials_t)
2061 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
2062 if (cred == NULL)
2064 gnutls_assert ();
2065 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2068 /* If the callback which retrieves certificate has been set,
2069 * use it and leave.
2071 if (cred->server_get_cert_callback != NULL ||
2072 cred->get_cert_callback != NULL)
2073 return call_get_cert_callback (session, NULL, 0, NULL, 0);
2075 /* Otherwise... */
2077 idx = -1; /* default is use no certificate */
2080 for (i = 0; i < cred->ncerts; i++)
2082 /* find one compatible certificate
2084 if (requested_algo == GNUTLS_PK_ANY ||
2085 requested_algo == cred->cert_list[i][0].subject_pk_algorithm)
2087 /* if cert type and signature algorithm matches
2089 /* *INDENT-OFF* */
2090 if (session->security_parameters.cert_type
2091 == cred->cert_list[i][0].cert_type
2092 && (cred->cert_list[i][0].cert_type == GNUTLS_CRT_OPENPGP
2093 || /* FIXME: make this a check for certificate
2094 type capabilities */
2095 !_gnutls_version_has_selectable_sighash
2096 (gnutls_protocol_get_version (session))
2098 _gnutls_session_sign_algo_requested
2099 (session, cred->cert_list[i][0].sign_algo) == 0))
2101 idx = i;
2102 break;
2104 /* *INDENT-ON* */
2108 /* store the certificate pointer for future use, in the handshake.
2109 * (This will allow not calling this callback again.)
2111 if (idx >= 0)
2113 _gnutls_selected_certs_set (session,
2114 &cred->cert_list[idx][0],
2115 cred->cert_list_length[idx],
2116 cred->pkey[idx], 0);
2118 else
2119 /* Certificate does not support REQUESTED_ALGO. */
2120 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2122 return 0;
2125 /* Frees the rsa_info_st structure.
2127 void
2128 _gnutls_free_rsa_info (rsa_info_st * rsa)
2130 _gnutls_free_datum (&rsa->modulus);
2131 _gnutls_free_datum (&rsa->exponent);