Add `gnutls/dtls.h' to the distribution.
[gnutls.git] / lib / auth_cert.c
blob9f644b18d8055c0eb14979bfff16e63fde2bc6a9
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;
120 info->sign_algo = cert[0].sign_algo;
122 #ifdef ENABLE_OPENPGP
123 if (cert[0].cert_type == GNUTLS_CRT_OPENPGP)
125 info->use_subkey = cert[0].use_subkey;
126 memcpy (info->subkey_id, cert[0].subkey_id, sizeof (info->subkey_id));
128 #endif
130 return 0;
132 clear:
134 for (j = 0; j < i; j++)
135 _gnutls_free_datum (&info->raw_certificate_list[j]);
137 gnutls_free (info->raw_certificate_list);
138 info->raw_certificate_list = NULL;
140 return ret;
146 /* returns 0 if the algo_to-check exists in the pk_algos list,
147 * -1 otherwise.
149 inline static int
150 _gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t *
151 pk_algos, int pk_algos_length,
152 gnutls_pk_algorithm_t algo_to_check)
154 int i;
155 for (i = 0; i < pk_algos_length; i++)
157 if (algo_to_check == pk_algos[i])
159 return 0;
162 return -1;
166 /* Returns the issuer's Distinguished name in odn, of the certificate
167 * specified in cert.
169 static int
170 _gnutls_cert_get_issuer_dn (gnutls_cert * cert, gnutls_datum_t * odn)
172 ASN1_TYPE dn;
173 int len, result;
174 int start, end;
176 if ((result = asn1_create_element
177 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS)
179 gnutls_assert ();
180 return _gnutls_asn2err (result);
183 result = asn1_der_decoding (&dn, cert->raw.data, cert->raw.size, NULL);
184 if (result != ASN1_SUCCESS)
186 /* couldn't decode DER */
187 gnutls_assert ();
188 asn1_delete_structure (&dn);
189 return _gnutls_asn2err (result);
192 result = asn1_der_decoding_startEnd (dn, cert->raw.data, cert->raw.size,
193 "tbsCertificate.issuer", &start, &end);
195 if (result != ASN1_SUCCESS)
197 /* couldn't decode DER */
198 gnutls_assert ();
199 asn1_delete_structure (&dn);
200 return _gnutls_asn2err (result);
202 asn1_delete_structure (&dn);
204 len = end - start + 1;
206 odn->size = len;
207 odn->data = &cert->raw.data[start];
209 return 0;
213 /* Locates the most appropriate x509 certificate using the
214 * given DN. If indx == -1 then no certificate was found.
216 * That is to guess which certificate to use, based on the
217 * CAs and sign algorithms supported by the peer server.
219 static int
220 _find_x509_cert (const gnutls_certificate_credentials_t cred,
221 opaque * _data, size_t _data_size,
222 const gnutls_pk_algorithm_t * pk_algos,
223 int pk_algos_length, int *indx)
225 unsigned size;
226 gnutls_datum_t odn = { NULL, 0 };
227 opaque *data = _data;
228 ssize_t data_size = _data_size;
229 unsigned i, j;
230 int result, cert_pk;
232 *indx = -1;
237 DECR_LENGTH_RET (data_size, 2, 0);
238 size = _gnutls_read_uint16 (data);
239 DECR_LENGTH_RET (data_size, size, 0);
240 data += 2;
242 for (i = 0; i < cred->ncerts; i++)
244 for (j = 0; j < cred->cert_list_length[i]; j++)
246 if ((result =
247 _gnutls_cert_get_issuer_dn (&cred->cert_list[i][j],
248 &odn)) < 0)
250 gnutls_assert ();
251 return result;
254 if (odn.size != size)
255 continue;
257 /* If the DN matches and
258 * the *_SIGN algorithm matches
259 * the cert is our cert!
261 cert_pk = cred->cert_list[i][0].subject_pk_algorithm;
263 if ((memcmp (odn.data, data, size) == 0) &&
264 (_gnutls_check_pk_algo_in_list
265 (pk_algos, pk_algos_length, cert_pk) == 0))
267 *indx = i;
268 break;
271 if (*indx != -1)
272 break;
275 if (*indx != -1)
276 break;
278 /* move to next record */
279 data += size;
282 while (1);
284 return 0;
288 #ifdef ENABLE_OPENPGP
289 /* Locates the most appropriate openpgp cert
291 static int
292 _find_openpgp_cert (const gnutls_certificate_credentials_t cred,
293 gnutls_pk_algorithm_t * pk_algos,
294 int pk_algos_length, int *indx)
296 unsigned i, j;
298 *indx = -1;
300 for (i = 0; i < cred->ncerts; i++)
302 for (j = 0; j < cred->cert_list_length[i]; j++)
305 /* If the *_SIGN algorithm matches
306 * the cert is our cert!
308 if ((_gnutls_check_pk_algo_in_list
309 (pk_algos, pk_algos_length,
310 cred->cert_list[i][0].subject_pk_algorithm) == 0)
311 && (cred->cert_list[i][0].cert_type == GNUTLS_CRT_OPENPGP))
313 *indx = i;
314 break;
317 if (*indx != -1)
318 break;
321 return 0;
323 #endif
325 /* Returns the number of issuers in the server's
326 * certificate request packet.
328 static int
329 get_issuers_num (gnutls_session_t session, opaque * data, ssize_t data_size)
331 int issuers_dn_len = 0, result;
332 unsigned size;
334 /* Count the number of the given issuers;
335 * This is used to allocate the issuers_dn without
336 * using realloc().
339 if (data_size == 0 || data == NULL)
340 return 0;
342 if (data_size > 0)
345 /* This works like DECR_LEN()
347 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
348 DECR_LENGTH_COM (data_size, 2, goto error);
349 size = _gnutls_read_uint16 (data);
351 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
352 DECR_LENGTH_COM (data_size, size, goto error);
354 data += 2;
356 if (size > 0)
358 issuers_dn_len++;
359 data += size;
362 if (data_size == 0)
363 break;
366 while (1);
368 return issuers_dn_len;
370 error:
371 return result;
374 /* Returns the issuers in the server's certificate request
375 * packet.
377 static int
378 get_issuers (gnutls_session_t session,
379 gnutls_datum_t * issuers_dn, int issuers_len,
380 opaque * data, size_t data_size)
382 int i;
383 unsigned size;
385 if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
386 return 0;
388 /* put the requested DNs to req_dn, only in case
389 * of X509 certificates.
391 if (issuers_len > 0)
394 for (i = 0; i < issuers_len; i++)
396 /* The checks here for the buffer boundaries
397 * are not needed since the buffer has been
398 * parsed above.
400 data_size -= 2;
402 size = _gnutls_read_uint16 (data);
404 data += 2;
406 issuers_dn[i].data = data;
407 issuers_dn[i].size = size;
409 data += size;
413 return 0;
416 static void
417 st_to_st2 (gnutls_retr2_st * st2, gnutls_retr_st * st)
419 st2->cert_type = st->type;
420 if (st->type == GNUTLS_CRT_OPENPGP)
422 st2->key_type = GNUTLS_PRIVKEY_OPENPGP;
424 else
426 st2->key_type = GNUTLS_PRIVKEY_X509;
428 st2->ncerts = st->ncerts;
429 st2->deinit_all = st->deinit_all;
431 switch (st2->cert_type)
433 case GNUTLS_CRT_OPENPGP:
434 st2->cert.pgp = st->cert.pgp;
435 st2->key.pgp = st->key.pgp;
436 break;
437 case GNUTLS_CRT_X509:
438 st2->cert.x509 = st->cert.x509;
439 st2->key.x509 = st->key.x509;
440 break;
441 default:
442 return;
447 /* Calls the client get callback.
449 static int
450 call_get_cert_callback (gnutls_session_t session,
451 const gnutls_datum_t * issuers_dn,
452 int issuers_dn_length,
453 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
455 unsigned i;
456 gnutls_cert *local_certs = NULL;
457 gnutls_privkey_t local_key = NULL;
458 int ret = GNUTLS_E_INTERNAL_ERROR;
459 gnutls_certificate_type_t type = gnutls_certificate_type_get (session);
460 gnutls_certificate_credentials_t cred;
461 gnutls_retr2_st st2;
463 cred = (gnutls_certificate_credentials_t)
464 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
465 if (cred == NULL)
467 gnutls_assert ();
468 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
471 memset (&st2, 0, sizeof (st2));
473 if (cred->get_cert_callback)
475 ret = cred->get_cert_callback (session, issuers_dn, issuers_dn_length,
476 pk_algos, pk_algos_length, &st2);
479 else
480 { /* compatibility mode */
481 gnutls_retr_st st;
482 memset (&st, 0, sizeof (st));
483 if (session->security_parameters.entity == GNUTLS_SERVER)
485 if (cred->server_get_cert_callback == NULL)
487 gnutls_assert ();
488 return GNUTLS_E_INTERNAL_ERROR;
490 ret = cred->server_get_cert_callback (session, &st);
491 if (ret >= 0)
492 st_to_st2 (&st2, &st);
494 else
495 { /* CLIENT */
497 if (cred->client_get_cert_callback == NULL)
499 gnutls_assert ();
500 return GNUTLS_E_INTERNAL_ERROR;
502 ret = cred->client_get_cert_callback (session,
503 issuers_dn, issuers_dn_length,
504 pk_algos, pk_algos_length,
505 &st);
506 if (ret >= 0)
507 st_to_st2 (&st2, &st);
511 if (ret < 0)
513 gnutls_assert ();
514 return GNUTLS_E_INTERNAL_ERROR;
517 if (st2.ncerts == 0)
518 return 0; /* no certificate was selected */
520 if (type != st2.cert_type)
522 gnutls_assert ();
523 ret = GNUTLS_E_INVALID_REQUEST;
524 goto cleanup;
528 if (type == GNUTLS_CRT_X509)
530 local_certs = alloc_and_load_x509_certs (st2.cert.x509, st2.ncerts);
532 else
533 { /* PGP */
534 if (st2.ncerts > 1)
536 gnutls_assert ();
537 ret = GNUTLS_E_INVALID_REQUEST;
538 goto cleanup;
540 #ifdef ENABLE_OPENPGP
542 local_certs = alloc_and_load_pgp_certs (st2.cert.pgp);
544 #else
545 ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
546 goto cleanup;
547 #endif
550 if (local_certs == NULL)
552 gnutls_assert ();
553 ret = GNUTLS_E_MEMORY_ERROR;
554 goto cleanup;
557 switch (st2.key_type)
559 case GNUTLS_PRIVKEY_OPENPGP:
560 #ifdef ENABLE_OPENPGP
561 if (st2.key.pgp != NULL)
563 local_key = alloc_and_load_pgp_key (st2.key.pgp, st2.deinit_all);
564 if (local_key == NULL)
566 gnutls_assert ();
567 ret = GNUTLS_E_INTERNAL_ERROR;
568 goto cleanup;
571 break;
572 #endif
573 case GNUTLS_PRIVKEY_PKCS11:
574 if (st2.key.pkcs11 != NULL)
576 local_key =
577 alloc_and_load_pkcs11_key (st2.key.pkcs11, st2.deinit_all);
578 if (local_key == NULL)
580 gnutls_assert ();
581 ret = GNUTLS_E_INTERNAL_ERROR;
582 goto cleanup;
585 break;
586 case GNUTLS_PRIVKEY_X509:
587 if (st2.key.x509 != NULL)
589 local_key = alloc_and_load_x509_key (st2.key.x509, st2.deinit_all);
590 if (local_key == NULL)
592 gnutls_assert ();
593 ret = GNUTLS_E_INTERNAL_ERROR;
594 goto cleanup;
597 break;
600 _gnutls_selected_certs_set (session, local_certs,
601 (local_certs != NULL) ? st2.ncerts : 0,
602 local_key, 1);
604 ret = 0;
606 cleanup:
608 if (st2.cert_type == GNUTLS_CRT_X509)
610 if (st2.deinit_all)
612 for (i = 0; i < st2.ncerts; i++)
614 gnutls_x509_crt_deinit (st2.cert.x509[i]);
618 else
620 #ifdef ENABLE_OPENPGP
621 if (st2.deinit_all)
623 gnutls_openpgp_crt_deinit (st2.cert.pgp);
625 #endif
628 if (ret < 0)
630 if (local_key != NULL)
631 gnutls_privkey_deinit (local_key);
634 return ret;
637 /* Finds the appropriate certificate depending on the cA Distinguished name
638 * advertized by the server. If none matches then returns 0 and -1 as index.
639 * In case of an error a negative value, is returned.
641 * 20020128: added ability to select a certificate depending on the SIGN
642 * algorithm (only in automatic mode).
644 static int
645 _select_client_cert (gnutls_session_t session,
646 opaque * _data, size_t _data_size,
647 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
649 int result;
650 int indx = -1;
651 gnutls_certificate_credentials_t cred;
652 opaque *data = _data;
653 ssize_t data_size = _data_size;
654 int issuers_dn_length;
655 gnutls_datum_t *issuers_dn = NULL;
657 cred = (gnutls_certificate_credentials_t)
658 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
659 if (cred == NULL)
661 gnutls_assert ();
662 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
665 if (cred->client_get_cert_callback != NULL
666 || cred->get_cert_callback != NULL)
669 /* use a callback to get certificate
671 if (session->security_parameters.cert_type != GNUTLS_CRT_X509)
672 issuers_dn_length = 0;
673 else
675 issuers_dn_length = get_issuers_num (session, data, data_size);
676 if (issuers_dn_length < 0)
678 gnutls_assert ();
679 return issuers_dn_length;
682 if (issuers_dn_length > 0)
684 issuers_dn =
685 gnutls_malloc (sizeof (gnutls_datum_t) * issuers_dn_length);
686 if (issuers_dn == NULL)
688 gnutls_assert ();
689 return GNUTLS_E_MEMORY_ERROR;
692 result =
693 get_issuers (session, issuers_dn, issuers_dn_length,
694 data, data_size);
695 if (result < 0)
697 gnutls_assert ();
698 goto cleanup;
703 result =
704 call_get_cert_callback (session, issuers_dn, issuers_dn_length,
705 pk_algos, pk_algos_length);
706 goto cleanup;
709 else
711 /* If we have no callbacks, try to guess.
713 result = 0;
715 if (session->security_parameters.cert_type == GNUTLS_CRT_X509)
716 result =
717 _find_x509_cert (cred, _data, _data_size,
718 pk_algos, pk_algos_length, &indx);
720 #ifdef ENABLE_OPENPGP
721 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP)
722 result = _find_openpgp_cert (cred, pk_algos, pk_algos_length, &indx);
723 #endif
725 if (result < 0)
727 gnutls_assert ();
728 return result;
731 if (indx >= 0)
733 _gnutls_selected_certs_set (session,
734 &cred->cert_list[indx][0],
735 cred->cert_list_length[indx],
736 cred->pkey[indx], 0);
738 else
740 _gnutls_selected_certs_set (session, NULL, 0, NULL, 0);
743 result = 0;
746 cleanup:
747 gnutls_free (issuers_dn);
748 return result;
752 /* Generate client certificate
755 static int
756 _gnutls_gen_x509_crt (gnutls_session_t session, gnutls_buffer_st * data)
758 int ret, i;
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 ret = _gnutls_buffer_append_prefix(data, 24, ret - 3);
791 if (ret < 0)
792 return gnutls_assert_val(ret);
794 for (i = 0; i < apr_cert_list_length; i++)
796 ret = _gnutls_buffer_append_data_prefix( data, 24, apr_cert_list[i].raw.data,
797 apr_cert_list[i].raw.size);
798 if (ret < 0)
799 return gnutls_assert_val(ret);
802 return data->length;
805 enum PGPKeyDescriptorType
806 { PGP_KEY_FINGERPRINT, PGP_KEY, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
808 #ifdef ENABLE_OPENPGP
809 static int
810 _gnutls_gen_openpgp_certificate (gnutls_session_t session, gnutls_buffer_st * data)
812 int ret;
813 gnutls_cert *apr_cert_list;
814 gnutls_privkey_t apr_pkey;
815 int apr_cert_list_length;
816 uint8_t type;
818 /* find the appropriate certificate */
819 if ((ret =
820 _gnutls_get_selected_cert (session, &apr_cert_list,
821 &apr_cert_list_length, &apr_pkey)) < 0)
823 gnutls_assert ();
824 return ret;
827 ret = 3 + 1 + 3;
830 if (apr_cert_list_length > 0)
832 if (apr_cert_list[0].use_subkey != 0)
833 ret += 1 + sizeof (apr_cert_list[0].subkey_id); /* for the keyid */
835 ret += apr_cert_list[0].raw.size;
838 ret = _gnutls_buffer_append_prefix( data, 24, ret - 3);
839 if (ret < 0)
840 return gnutls_assert_val(ret);
843 if (apr_cert_list_length > 0)
845 if (apr_cert_list[0].use_subkey != 0)
847 type = PGP_KEY_SUBKEY;
849 ret = _gnutls_buffer_append_data( data, &type, 1);
850 if (ret < 0)
851 return gnutls_assert_val(ret);
853 ret = _gnutls_buffer_append_data_prefix( data, 8, apr_cert_list[0].subkey_id,
854 sizeof (apr_cert_list[0].subkey_id));
855 if (ret < 0)
856 return gnutls_assert_val(ret);
858 else
860 type = PGP_KEY;
861 ret = _gnutls_buffer_append_data( data, &type, 1);
862 if (ret < 0)
863 return gnutls_assert_val(ret);
866 ret = _gnutls_buffer_append_data_prefix( data, 24, apr_cert_list[0].raw.data,
867 apr_cert_list[0].raw.size);
868 if (ret < 0)
869 return gnutls_assert_val(ret);
871 else /* empty - no certificate */
873 ret = _gnutls_buffer_append_data( data, &type, 1);
874 if (ret < 0)
875 return gnutls_assert_val(ret);
877 ret = _gnutls_buffer_append_prefix( data, 24, 0);
878 if (ret < 0)
879 return gnutls_assert_val(ret);
882 return data->length;
885 static int
886 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, gnutls_buffer_st * data)
888 int ret, packet_size;
889 uint8_t type, fpr[20];
890 size_t fpr_size;
891 gnutls_cert *apr_cert_list;
892 gnutls_privkey_t apr_pkey;
893 int apr_cert_list_length;
895 /* find the appropriate certificate */
896 if ((ret =
897 _gnutls_get_selected_cert (session, &apr_cert_list,
898 &apr_cert_list_length, &apr_pkey)) < 0)
900 gnutls_assert ();
901 return ret;
904 packet_size = 3 + 1;
906 if (apr_cert_list[0].use_subkey)
907 packet_size += 1 + sizeof (apr_cert_list[0].subkey_id); /* for the keyid */
909 /* Only v4 fingerprints are sent
911 if (apr_cert_list_length > 0 && apr_cert_list[0].version == 4)
912 packet_size += 20 + 1;
913 else /* empty certificate case */
914 return _gnutls_gen_openpgp_certificate (session, data);
916 ret = _gnutls_buffer_append_prefix( data, 24, packet_size - 3);
917 if (ret < 0)
918 return gnutls_assert_val(ret);
920 if (apr_cert_list[0].use_subkey)
922 type = PGP_KEY_FINGERPRINT_SUBKEY;
923 ret = _gnutls_buffer_append_data( data, &type, 1);
924 if (ret < 0)
925 return gnutls_assert_val(ret);
927 ret = _gnutls_buffer_append_data_prefix( data, 8,
928 apr_cert_list[0].subkey_id, sizeof(apr_cert_list[0].subkey_id));
929 if (ret < 0)
930 return gnutls_assert_val(ret);
932 else
934 type = PGP_KEY_FINGERPRINT; /* key fingerprint */
935 ret = _gnutls_buffer_append_data( data, &type, 1);
936 if (ret < 0)
937 return gnutls_assert_val(ret);
940 fpr_size = sizeof(fpr);
941 if ((ret =
942 _gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, fpr,
943 &fpr_size)) < 0)
945 gnutls_assert ();
946 return ret;
949 ret = _gnutls_buffer_append_data_prefix( data, 8, fpr, fpr_size);
950 if (ret < 0)
951 return gnutls_assert_val(ret);
953 return data->length;
955 #endif
959 _gnutls_gen_cert_client_certificate (gnutls_session_t session, gnutls_buffer_st * data)
961 switch (session->security_parameters.cert_type)
963 #ifdef ENABLE_OPENPGP
964 case GNUTLS_CRT_OPENPGP:
965 if (_gnutls_openpgp_send_fingerprint (session) == 0)
966 return _gnutls_gen_openpgp_certificate (session, data);
967 else
968 return _gnutls_gen_openpgp_certificate_fpr (session, data);
969 #endif
970 case GNUTLS_CRT_X509:
971 return _gnutls_gen_x509_crt (session, data);
973 default:
974 gnutls_assert ();
975 return GNUTLS_E_INTERNAL_ERROR;
980 _gnutls_gen_cert_server_certificate (gnutls_session_t session, gnutls_buffer_st * data)
982 switch (session->security_parameters.cert_type)
984 #ifdef ENABLE_OPENPGP
985 case GNUTLS_CRT_OPENPGP:
986 return _gnutls_gen_openpgp_certificate (session, data);
987 #endif
988 case GNUTLS_CRT_X509:
989 return _gnutls_gen_x509_crt (session, data);
990 default:
991 gnutls_assert ();
992 return GNUTLS_E_INTERNAL_ERROR;
996 /* Process server certificate
999 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
1000 static int
1001 _gnutls_proc_x509_server_certificate (gnutls_session_t session,
1002 opaque * data, size_t data_size)
1004 int size, len, ret;
1005 opaque *p = data;
1006 cert_auth_info_t info;
1007 gnutls_certificate_credentials_t cred;
1008 ssize_t dsize = data_size;
1009 int i;
1010 gnutls_cert *peer_certificate_list;
1011 size_t peer_certificate_list_size = 0, j, x;
1012 gnutls_datum_t tmp;
1014 cred = (gnutls_certificate_credentials_t)
1015 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1016 if (cred == NULL)
1018 gnutls_assert ();
1019 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1023 if ((ret =
1024 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1025 sizeof (cert_auth_info_st), 1)) < 0)
1027 gnutls_assert ();
1028 return ret;
1031 info = _gnutls_get_auth_info (session);
1033 if (data == NULL || data_size == 0)
1035 gnutls_assert ();
1036 /* no certificate was sent */
1037 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1040 DECR_LEN (dsize, 3);
1041 size = _gnutls_read_uint24 (p);
1042 p += 3;
1044 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
1045 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
1047 if (size == 0 || size == 3)
1049 gnutls_assert ();
1050 /* no certificate was sent */
1051 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1054 i = dsize;
1055 while (i > 0)
1057 DECR_LEN (dsize, 3);
1058 len = _gnutls_read_uint24 (p);
1059 p += 3;
1060 DECR_LEN (dsize, len);
1061 peer_certificate_list_size++;
1062 p += len;
1063 i -= len + 3;
1066 if (peer_certificate_list_size == 0)
1068 gnutls_assert ();
1069 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1072 /* Ok we now allocate the memory to hold the
1073 * certificate list
1076 peer_certificate_list =
1077 gnutls_malloc (sizeof (gnutls_cert) * (peer_certificate_list_size));
1079 if (peer_certificate_list == NULL)
1081 gnutls_assert ();
1082 return GNUTLS_E_MEMORY_ERROR;
1084 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
1085 peer_certificate_list_size);
1087 p = data + 3;
1089 /* Now we start parsing the list (again).
1090 * We don't use DECR_LEN since the list has
1091 * been parsed before.
1094 for (j = 0; j < peer_certificate_list_size; j++)
1096 len = _gnutls_read_uint24 (p);
1097 p += 3;
1099 tmp.size = len;
1100 tmp.data = p;
1102 if ((ret =
1103 _gnutls_x509_raw_cert_to_gcert (&peer_certificate_list
1104 [j], &tmp,
1105 CERT_ONLY_EXTENSIONS)) < 0)
1107 gnutls_assert ();
1108 goto cleanup;
1111 /* check if signature algorithm is supported */
1112 ret =
1113 _gnutls_session_sign_algo_enabled (session,
1114 peer_certificate_list
1115 [j].sign_algo);
1116 if (ret < 0)
1118 gnutls_assert ();
1119 goto cleanup;
1122 p += len;
1126 if ((ret =
1127 _gnutls_copy_certificate_auth_info (info,
1128 peer_certificate_list,
1129 peer_certificate_list_size)) < 0)
1131 gnutls_assert ();
1132 goto cleanup;
1135 if ((ret =
1136 _gnutls_check_key_usage (&peer_certificate_list[0],
1137 gnutls_kx_get (session))) < 0)
1139 gnutls_assert ();
1140 goto cleanup;
1143 ret = 0;
1145 cleanup:
1146 CLEAR_CERTS;
1147 gnutls_free (peer_certificate_list);
1148 return ret;
1152 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
1153 #ifdef ENABLE_OPENPGP
1154 static int
1155 _gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
1156 opaque * data, size_t data_size)
1158 int size, ret, len;
1159 opaque *p = data;
1160 cert_auth_info_t info;
1161 gnutls_certificate_credentials_t cred;
1162 ssize_t dsize = data_size;
1163 int x, key_type;
1164 gnutls_cert *peer_certificate_list = NULL;
1165 int peer_certificate_list_size = 0;
1166 gnutls_datum_t tmp, akey = { NULL, 0 };
1167 gnutls_openpgp_keyid_t subkey_id;
1168 unsigned int subkey_id_set = 0;
1170 cred = (gnutls_certificate_credentials_t)
1171 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1172 if (cred == NULL)
1174 gnutls_assert ();
1175 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1178 if ((ret =
1179 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1180 sizeof (cert_auth_info_st), 1)) < 0)
1182 gnutls_assert ();
1183 return ret;
1186 info = _gnutls_get_auth_info (session);
1188 if (data == NULL || data_size == 0)
1190 gnutls_assert ();
1191 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1194 DECR_LEN (dsize, 3);
1195 size = _gnutls_read_uint24 (p);
1196 p += 3;
1198 if (size == 0)
1200 gnutls_assert ();
1201 /* no certificate was sent */
1202 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1205 /* Read PGPKeyDescriptor */
1206 DECR_LEN (dsize, 1);
1207 key_type = *p;
1208 p++;
1210 /* Try to read the keyid if present */
1211 if (key_type == PGP_KEY_FINGERPRINT_SUBKEY || key_type == PGP_KEY_SUBKEY)
1213 /* check size */
1214 if (*p != sizeof (subkey_id))
1216 gnutls_assert ();
1217 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1220 DECR_LEN (dsize, 1);
1221 p++;
1223 DECR_LEN (dsize, sizeof (subkey_id));
1224 memcpy (subkey_id, p, sizeof (subkey_id));
1225 p += sizeof (subkey_id);
1227 subkey_id_set = 1;
1231 /* read the actual key or fingerprint */
1232 if (key_type == PGP_KEY_FINGERPRINT
1233 || key_type == PGP_KEY_FINGERPRINT_SUBKEY)
1234 { /* the fingerprint */
1236 DECR_LEN (dsize, 1);
1237 len = (uint8_t) * p;
1238 p++;
1240 if (len != 20)
1242 gnutls_assert ();
1243 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED;
1246 DECR_LEN (dsize, 20);
1248 /* request the actual key from our database, or
1249 * a key server or anything.
1251 if ((ret =
1252 _gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
1254 gnutls_assert ();
1255 return ret;
1257 tmp = akey;
1258 peer_certificate_list_size++;
1261 else if (key_type == PGP_KEY || key_type == PGP_KEY_SUBKEY)
1262 { /* the whole key */
1264 /* Read the actual certificate */
1265 DECR_LEN (dsize, 3);
1266 len = _gnutls_read_uint24 (p);
1267 p += 3;
1269 if (len == 0)
1271 gnutls_assert ();
1272 /* no certificate was sent */
1273 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1276 DECR_LEN (dsize, len);
1277 peer_certificate_list_size++;
1279 tmp.size = len;
1280 tmp.data = p;
1283 else
1285 gnutls_assert ();
1286 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1289 /* ok we now have the peer's key in tmp datum
1292 if (peer_certificate_list_size == 0)
1294 gnutls_assert ();
1295 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1298 peer_certificate_list =
1299 gnutls_malloc (sizeof (gnutls_cert) * (peer_certificate_list_size));
1300 if (peer_certificate_list == NULL)
1302 gnutls_assert ();
1303 ret = GNUTLS_E_MEMORY_ERROR;
1304 goto cleanup;
1306 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
1307 peer_certificate_list_size);
1309 if ((ret =
1310 _gnutls_openpgp_raw_crt_to_gcert (&peer_certificate_list[0],
1311 &tmp,
1312 subkey_id_set ? subkey_id : NULL)) <
1315 gnutls_assert ();
1316 goto cleanup;
1319 if ((ret =
1320 _gnutls_copy_certificate_auth_info (info,
1321 peer_certificate_list,
1322 peer_certificate_list_size)) < 0)
1324 gnutls_assert ();
1325 goto cleanup;
1328 if ((ret =
1329 _gnutls_check_key_usage (&peer_certificate_list[0],
1330 gnutls_kx_get (session))) < 0)
1332 gnutls_assert ();
1333 goto cleanup;
1336 ret = 0;
1338 cleanup:
1340 _gnutls_free_datum (&akey);
1341 CLEAR_CERTS;
1342 gnutls_free (peer_certificate_list);
1343 return ret;
1346 #endif
1349 _gnutls_proc_cert_server_certificate (gnutls_session_t session,
1350 opaque * data, size_t data_size)
1352 int ret;
1353 gnutls_certificate_credentials_t cred;
1355 cred =
1356 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
1357 GNUTLS_CRD_CERTIFICATE,
1358 NULL);
1359 if (cred == NULL)
1361 gnutls_assert ();
1362 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1365 switch (session->security_parameters.cert_type)
1367 #ifdef ENABLE_OPENPGP
1368 case GNUTLS_CRT_OPENPGP:
1369 ret = _gnutls_proc_openpgp_server_certificate (session,
1370 data, data_size);
1371 break;
1372 #endif
1373 case GNUTLS_CRT_X509:
1374 ret = _gnutls_proc_x509_server_certificate (session, data, data_size);
1375 break;
1376 default:
1377 gnutls_assert ();
1378 return GNUTLS_E_INTERNAL_ERROR;
1381 if (ret == 0 && cred->verify_callback != NULL)
1383 ret = cred->verify_callback (session);
1384 if (ret != 0)
1385 ret = GNUTLS_E_CERTIFICATE_ERROR;
1388 return ret;
1391 #define MAX_SIGN_ALGOS 2
1392 typedef enum CertificateSigType
1393 { RSA_SIGN = 1, DSA_SIGN
1394 } CertificateSigType;
1396 /* Checks if we support the given signature algorithm
1397 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1398 * if true;
1400 inline static int
1401 _gnutls_check_supported_sign_algo (CertificateSigType algo)
1403 switch (algo)
1405 case RSA_SIGN:
1406 return GNUTLS_PK_RSA;
1407 case DSA_SIGN:
1408 return GNUTLS_PK_DSA;
1411 return -1;
1415 _gnutls_proc_cert_cert_req (gnutls_session_t session, opaque * data,
1416 size_t data_size)
1418 int size, ret;
1419 opaque *p;
1420 gnutls_certificate_credentials_t cred;
1421 ssize_t dsize;
1422 int i, j;
1423 gnutls_pk_algorithm_t pk_algos[MAX_SIGN_ALGOS];
1424 int pk_algos_length;
1425 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1427 cred = (gnutls_certificate_credentials_t)
1428 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1429 if (cred == NULL)
1431 gnutls_assert ();
1432 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1435 if ((ret =
1436 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1437 sizeof (cert_auth_info_st), 0)) < 0)
1439 gnutls_assert ();
1440 return ret;
1443 p = data;
1444 dsize = data_size;
1446 DECR_LEN (dsize, 1);
1447 size = p[0];
1448 p++;
1449 /* check if the sign algorithm is supported.
1451 pk_algos_length = j = 0;
1452 for (i = 0; i < size; i++, p++)
1454 DECR_LEN (dsize, 1);
1455 if ((ret = _gnutls_check_supported_sign_algo (*p)) > 0)
1457 if (j < MAX_SIGN_ALGOS)
1459 pk_algos[j++] = ret;
1460 pk_algos_length++;
1465 if (pk_algos_length == 0)
1467 gnutls_assert ();
1468 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1471 if (_gnutls_version_has_selectable_sighash (ver))
1473 /* read supported hashes */
1474 int hash_num;
1475 DECR_LEN (dsize, 2);
1476 hash_num = _gnutls_read_uint16 (p);
1477 p += 2;
1478 DECR_LEN (dsize, hash_num);
1480 ret = _gnutls_sign_algorithm_parse_data (session, p, hash_num);
1481 if (ret < 0)
1483 gnutls_assert ();
1484 return ret;
1487 p += hash_num;
1490 /* read the certificate authorities */
1491 DECR_LEN (dsize, 2);
1492 size = _gnutls_read_uint16 (p);
1493 p += 2;
1495 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP
1496 && size != 0)
1498 gnutls_assert ();
1499 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1502 DECR_LEN (dsize, size);
1504 /* now we ask the user to tell which one
1505 * he wants to use.
1507 if ((ret =
1508 _select_client_cert (session, p, size, pk_algos, pk_algos_length)) < 0)
1510 gnutls_assert ();
1511 return ret;
1514 /* We should reply with a certificate message,
1515 * even if we have no certificate to send.
1517 session->key->certificate_requested = 1;
1519 return 0;
1523 _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, gnutls_buffer_st * data)
1525 int ret;
1526 gnutls_cert *apr_cert_list;
1527 gnutls_privkey_t apr_pkey;
1528 int apr_cert_list_length;
1529 gnutls_datum_t signature = { NULL, 0 };
1530 int total_data;
1531 gnutls_sign_algorithm_t sign_algo;
1532 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1534 /* find the appropriate certificate */
1535 if ((ret =
1536 _gnutls_get_selected_cert (session, &apr_cert_list,
1537 &apr_cert_list_length, &apr_pkey)) < 0)
1539 gnutls_assert ();
1540 return ret;
1543 if (apr_cert_list_length > 0)
1545 if ((ret =
1546 _gnutls_handshake_sign_cert_vrfy (session,
1547 &apr_cert_list[0],
1548 apr_pkey, &signature)) < 0)
1550 gnutls_assert ();
1551 return ret;
1553 sign_algo = ret;
1555 else
1557 return 0;
1560 total_data = signature.size + 2;
1562 /* add hash and signature algorithms */
1563 if (_gnutls_version_has_selectable_sighash (ver))
1565 total_data += 2;
1568 if (_gnutls_version_has_selectable_sighash (ver))
1570 const sign_algorithm_st *aid;
1571 uint8_t p[2];
1572 /* error checking is not needed here since we have used those algorithms */
1573 aid = _gnutls_sign_to_tls_aid (sign_algo);
1574 if (aid == NULL)
1575 return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM);
1577 p[0] = aid->hash_algorithm;
1578 p[1] = aid->sign_algorithm;
1579 ret = _gnutls_buffer_append_data(data, p, 2);
1580 if (ret < 0)
1582 gnutls_assert();
1583 goto cleanup;
1587 ret = _gnutls_buffer_append_data_prefix(data, 16, signature.data, signature.size);
1588 if (ret < 0)
1590 gnutls_assert();
1591 goto cleanup;
1594 return data->length;
1596 cleanup:
1597 _gnutls_free_datum (&signature);
1598 return ret;
1602 _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session,
1603 opaque * data, size_t data_size)
1605 int size, ret;
1606 ssize_t dsize = data_size;
1607 opaque *pdata = data;
1608 gnutls_datum_t sig;
1609 cert_auth_info_t info = _gnutls_get_auth_info (session);
1610 gnutls_cert peer_cert;
1611 gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
1612 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1614 if (info == NULL || info->ncerts == 0)
1616 gnutls_assert ();
1617 /* we need this in order to get peer's certificate */
1618 return GNUTLS_E_INTERNAL_ERROR;
1621 if (_gnutls_version_has_selectable_sighash (ver))
1623 sign_algorithm_st aid;
1625 DECR_LEN (dsize, 2);
1626 aid.hash_algorithm = pdata[0];
1627 aid.sign_algorithm = pdata[1];
1629 sign_algo = _gnutls_tls_aid_to_sign (&aid);
1630 if (sign_algo == GNUTLS_PK_UNKNOWN)
1632 gnutls_assert ();
1633 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1635 pdata += 2;
1638 ret = _gnutls_session_sign_algo_enabled (session, sign_algo);
1639 if (ret < 0)
1641 gnutls_assert ();
1642 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1645 DECR_LEN (dsize, 2);
1646 size = _gnutls_read_uint16 (pdata);
1647 pdata += 2;
1649 DECR_LEN (dsize, size);
1651 sig.data = pdata;
1652 sig.size = size;
1654 ret = _gnutls_get_auth_info_gcert (&peer_cert,
1655 session->security_parameters.cert_type,
1656 info, CERT_NO_COPY);
1658 if (ret < 0)
1660 gnutls_assert ();
1661 return ret;
1664 if ((ret =
1665 _gnutls_handshake_verify_cert_vrfy (session, &peer_cert, &sig,
1666 sign_algo)) < 0)
1668 gnutls_assert ();
1669 _gnutls_gcert_deinit (&peer_cert);
1670 return ret;
1672 _gnutls_gcert_deinit (&peer_cert);
1674 return 0;
1677 #define CERTTYPE_SIZE 3
1679 _gnutls_gen_cert_server_cert_req (gnutls_session_t session, gnutls_buffer_st * data)
1681 gnutls_certificate_credentials_t cred;
1682 int size, ret;
1683 uint8_t tmp_data[CERTTYPE_SIZE];
1684 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1686 /* Now we need to generate the RDN sequence. This is
1687 * already in the CERTIFICATE_CRED structure, to improve
1688 * performance.
1691 cred = (gnutls_certificate_credentials_t)
1692 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1693 if (cred == NULL)
1695 gnutls_assert ();
1696 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1699 size = CERTTYPE_SIZE + 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1702 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1703 session->internals.ignore_rdn_sequence == 0)
1704 size += cred->x509_rdn_sequence.size;
1706 if (_gnutls_version_has_selectable_sighash (ver))
1707 /* Need two bytes to announce the number of supported hash
1708 functions (see below). */
1709 size += MAX_SIGN_ALGO_SIZE;
1711 tmp_data[0] = CERTTYPE_SIZE - 1;
1712 tmp_data[1] = RSA_SIGN;
1713 tmp_data[2] = DSA_SIGN; /* only these for now */
1715 ret = _gnutls_buffer_append_data( data, tmp_data, CERTTYPE_SIZE);
1716 if (ret < 0)
1717 return gnutls_assert_val(ret);
1719 if (_gnutls_version_has_selectable_sighash (ver))
1721 uint8_t p[MAX_SIGN_ALGO_SIZE];
1723 ret =
1724 _gnutls_sign_algorithm_write_params (session, p, MAX_SIGN_ALGO_SIZE);
1725 if (ret < 0)
1727 gnutls_assert ();
1728 return ret;
1731 /* recalculate size */
1732 size -= MAX_SIGN_ALGO_SIZE + ret;
1734 ret = _gnutls_buffer_append_data( data, p, ret);
1735 if (ret < 0)
1736 return gnutls_assert_val(ret);
1739 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1740 session->internals.ignore_rdn_sequence == 0)
1742 ret = _gnutls_buffer_append_data_prefix( data, 16, cred->x509_rdn_sequence.data,
1743 cred->x509_rdn_sequence.size);
1744 if (ret < 0)
1745 return gnutls_assert_val(ret);
1747 else
1749 ret = _gnutls_buffer_append_prefix( data, 16, 0);
1750 if (ret < 0)
1751 return gnutls_assert_val(ret);
1754 return data->length;
1758 /* This function will return the appropriate certificate to use.
1759 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1760 * The return value is a negative value on error.
1762 * It is normal to return 0 with no certificates in client side.
1766 _gnutls_get_selected_cert (gnutls_session_t session,
1767 gnutls_cert ** apr_cert_list,
1768 int *apr_cert_list_length,
1769 gnutls_privkey_t * apr_pkey)
1771 if (session->security_parameters.entity == GNUTLS_SERVER)
1774 /* select_client_cert() has been called before.
1777 *apr_cert_list = session->internals.selected_cert_list;
1778 *apr_pkey = session->internals.selected_key;
1779 *apr_cert_list_length = session->internals.selected_cert_list_length;
1781 if (*apr_cert_list_length == 0 || *apr_cert_list == NULL)
1783 gnutls_assert ();
1784 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1788 else
1789 { /* CLIENT SIDE
1792 /* we have already decided which certificate
1793 * to send.
1795 *apr_cert_list = session->internals.selected_cert_list;
1796 *apr_cert_list_length = session->internals.selected_cert_list_length;
1797 *apr_pkey = session->internals.selected_key;
1801 return 0;
1804 /* converts the given x509 certificate to gnutls_cert* and allocates
1805 * space for them.
1807 static gnutls_cert *
1808 alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, unsigned ncerts)
1810 gnutls_cert *local_certs;
1811 int ret = 0;
1812 unsigned i, j;
1814 if (certs == NULL)
1815 return NULL;
1817 local_certs = gnutls_malloc (sizeof (gnutls_cert) * ncerts);
1818 if (local_certs == NULL)
1820 gnutls_assert ();
1821 return NULL;
1824 for (i = 0; i < ncerts; i++)
1826 ret = _gnutls_x509_crt_to_gcert (&local_certs[i], certs[i], 0);
1827 if (ret < 0)
1828 break;
1831 if (ret < 0)
1833 gnutls_assert ();
1834 for (j = 0; j < i; j++)
1836 _gnutls_gcert_deinit (&local_certs[j]);
1838 gnutls_free (local_certs);
1839 return NULL;
1842 return local_certs;
1845 /* converts the given x509 key to gnutls_privkey* and allocates
1846 * space for it.
1848 static gnutls_privkey_t
1849 alloc_and_load_x509_key (gnutls_x509_privkey_t key, int deinit)
1851 gnutls_privkey_t local_key;
1852 int ret = 0;
1854 if (key == NULL)
1855 return NULL;
1857 ret = gnutls_privkey_init (&local_key);
1858 if (ret < 0)
1860 gnutls_assert ();
1861 return NULL;
1864 ret =
1865 gnutls_privkey_import_x509 (local_key, key,
1866 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE :
1868 if (ret < 0)
1870 gnutls_assert ();
1871 gnutls_privkey_deinit (local_key);
1872 return NULL;
1875 return local_key;
1878 /* converts the given pgp certificate to gnutls_cert* and allocates
1879 * space for them.
1881 #ifdef ENABLE_OPENPGP
1882 static gnutls_cert *
1883 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
1885 gnutls_cert *local_certs;
1886 int ret = 0;
1888 if (cert == NULL)
1889 return NULL;
1891 local_certs = gnutls_malloc (sizeof (gnutls_cert));
1892 if (local_certs == NULL)
1894 gnutls_assert ();
1895 return NULL;
1898 ret = _gnutls_openpgp_crt_to_gcert (local_certs, cert);
1899 if (ret < 0)
1901 gnutls_assert ();
1902 return NULL;
1905 if (ret < 0)
1907 gnutls_assert ();
1908 _gnutls_gcert_deinit (local_certs);
1909 gnutls_free (local_certs);
1910 return NULL;
1913 ret =
1914 gnutls_openpgp_crt_get_preferred_key_id (cert, local_certs->subkey_id);
1915 if (ret < 0)
1916 local_certs->use_subkey = 0;
1917 else
1918 local_certs->use_subkey = 1;
1920 return local_certs;
1923 /* converts the given raw key to gnutls_privkey* and allocates
1924 * space for it.
1926 static gnutls_privkey_t
1927 alloc_and_load_pgp_key (gnutls_openpgp_privkey_t key, int deinit)
1929 gnutls_privkey_t local_key;
1930 int ret = 0;
1932 if (key == NULL)
1933 return NULL;
1935 ret = gnutls_privkey_init (&local_key);
1936 if (ret < 0)
1938 gnutls_assert ();
1939 return NULL;
1942 ret =
1943 gnutls_privkey_import_openpgp (local_key, key,
1944 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
1945 : 0);
1946 if (ret < 0)
1948 gnutls_assert ();
1949 gnutls_privkey_deinit (local_key);
1950 return NULL;
1953 return local_key;
1955 #endif
1957 /* converts the given raw key to gnutls_privkey* and allocates
1958 * space for it.
1960 static gnutls_privkey_t
1961 alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t key, int deinit)
1963 gnutls_privkey_t local_key;
1964 int ret = 0;
1966 if (key == NULL)
1967 return NULL;
1969 ret = gnutls_privkey_init (&local_key);
1970 if (ret < 0)
1972 gnutls_assert ();
1973 return NULL;
1976 ret =
1977 gnutls_privkey_import_pkcs11 (local_key, key,
1978 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
1979 : 0);
1980 if (ret < 0)
1982 gnutls_assert ();
1983 gnutls_privkey_deinit (local_key);
1984 return NULL;
1987 return local_key;
1990 void
1991 _gnutls_selected_certs_deinit (gnutls_session_t session)
1993 if (session->internals.selected_need_free != 0)
1995 int i;
1997 for (i = 0; i < session->internals.selected_cert_list_length; i++)
1999 _gnutls_gcert_deinit (&session->internals.selected_cert_list[i]);
2001 gnutls_free (session->internals.selected_cert_list);
2002 session->internals.selected_cert_list = NULL;
2003 session->internals.selected_cert_list_length = 0;
2005 session->internals.selected_key = NULL;
2008 return;
2011 void
2012 _gnutls_selected_certs_set (gnutls_session_t session,
2013 gnutls_cert * certs, int ncerts,
2014 gnutls_privkey_t key, int need_free)
2016 _gnutls_selected_certs_deinit (session);
2018 session->internals.selected_cert_list = certs;
2019 session->internals.selected_cert_list_length = ncerts;
2020 session->internals.selected_key = key;
2021 session->internals.selected_need_free = need_free;
2026 /* finds the most appropriate certificate in the cert list.
2027 * The 'appropriate' is defined by the user.
2029 * requested_algo holds the parameters required by the peer (RSA, DSA
2030 * or -1 for any).
2032 * Returns 0 on success and a negative value on error. The
2033 * selected certificate will be in session->internals.selected_*.
2037 _gnutls_server_select_cert (gnutls_session_t session,
2038 gnutls_pk_algorithm_t requested_algo)
2040 unsigned i;
2041 int idx, ret;
2042 gnutls_certificate_credentials_t cred;
2044 cred = (gnutls_certificate_credentials_t)
2045 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
2046 if (cred == NULL)
2048 gnutls_assert ();
2049 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2052 /* If the callback which retrieves certificate has been set,
2053 * use it and leave.
2055 if (cred->server_get_cert_callback != NULL)
2057 ret = call_get_cert_callback (session, NULL, 0, NULL, 0);
2058 if (ret < 0)
2059 return gnutls_assert_val(ret);
2060 return ret;
2063 /* Otherwise... */
2065 idx = -1; /* default is use no certificate */
2067 _gnutls_handshake_log("HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n", session,
2068 gnutls_pk_get_name(requested_algo), requested_algo,
2069 gnutls_certificate_type_get_name(session->security_parameters.cert_type), session->security_parameters.cert_type);
2071 for (i = 0; i < cred->ncerts; i++)
2073 /* find one compatible certificate
2075 _gnutls_handshake_log("HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d) - sig: %s (%d)\n", session, i,
2076 gnutls_pk_get_name(cred->cert_list[i][0].subject_pk_algorithm), cred->cert_list[i][0].subject_pk_algorithm,
2077 gnutls_certificate_type_get_name(cred->cert_list[i][0].cert_type), cred->cert_list[i][0].cert_type,
2078 gnutls_sign_get_name(cred->cert_list[i][0].sign_algo), cred->cert_list[i][0].sign_algo);
2080 if (requested_algo == GNUTLS_PK_ANY ||
2081 requested_algo == cred->cert_list[i][0].subject_pk_algorithm)
2083 /* if cert type and signature algorithm matches
2085 /* *INDENT-OFF* */
2086 if (session->security_parameters.cert_type
2087 == cred->cert_list[i][0].cert_type
2088 && (cred->cert_list[i][0].cert_type == GNUTLS_CRT_OPENPGP
2089 || /* FIXME: make this a check for certificate
2090 type capabilities */
2091 _gnutls_session_sign_algo_requested
2092 (session, cred->cert_list[i][0].sign_algo) == 0))
2094 idx = i;
2095 break;
2097 /* *INDENT-ON* */
2101 /* store the certificate pointer for future use, in the handshake.
2102 * (This will allow not calling this callback again.)
2104 if (idx >= 0)
2106 _gnutls_selected_certs_set (session,
2107 &cred->cert_list[idx][0],
2108 cred->cert_list_length[idx],
2109 cred->pkey[idx], 0);
2111 else
2113 gnutls_assert();
2114 /* Certificate does not support REQUESTED_ALGO. */
2115 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2118 return 0;
2121 /* Frees the rsa_info_st structure.
2123 void
2124 _gnutls_free_rsa_info (rsa_info_st * rsa)
2126 _gnutls_free_datum (&rsa->modulus);
2127 _gnutls_free_datum (&rsa->exponent);