minor update to the fix.
[gnutls.git] / lib / auth_cert.c
blob7c36ea402488e9a444cc7081528faa2493ca59a5
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 #ifdef ENABLE_PKCS11
66 static gnutls_privkey_t alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t
67 key, int deinit);
68 #endif
70 /* Copies data from a internal certificate struct (gnutls_cert) to
71 * exported certificate struct (cert_auth_info_t)
73 static int
74 _gnutls_copy_certificate_auth_info (cert_auth_info_t info,
75 gnutls_cert * cert, size_t ncerts)
77 /* Copy peer's information to auth_info_t
79 int ret;
80 size_t i, j;
82 if (info->raw_certificate_list != NULL)
84 for (j = 0; j < info->ncerts; j++)
85 _gnutls_free_datum (&info->raw_certificate_list[j]);
86 gnutls_free (info->raw_certificate_list);
89 if (ncerts == 0)
91 info->raw_certificate_list = NULL;
92 info->ncerts = 0;
93 return 0;
96 info->raw_certificate_list =
97 gnutls_calloc (ncerts, sizeof (gnutls_datum_t));
98 if (info->raw_certificate_list == NULL)
100 gnutls_assert ();
101 return GNUTLS_E_MEMORY_ERROR;
104 for (i = 0; i < ncerts; i++)
106 if (cert->raw.size > 0)
108 ret =
109 _gnutls_set_datum (&info->raw_certificate_list[i],
110 cert[i].raw.data, cert[i].raw.size);
111 if (ret < 0)
113 gnutls_assert ();
114 goto clear;
118 info->ncerts = ncerts;
120 info->cert_type = cert[0].cert_type;
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 #endif
572 break;
573 case GNUTLS_PRIVKEY_PKCS11:
574 #ifdef ENABLE_PKCS11
575 if (st2.key.pkcs11 != NULL)
577 local_key =
578 alloc_and_load_pkcs11_key (st2.key.pkcs11, st2.deinit_all);
579 if (local_key == NULL)
581 gnutls_assert ();
582 ret = GNUTLS_E_INTERNAL_ERROR;
583 goto cleanup;
586 #endif
587 break;
588 case GNUTLS_PRIVKEY_X509:
589 if (st2.key.x509 != NULL)
591 local_key = alloc_and_load_x509_key (st2.key.x509, st2.deinit_all);
592 if (local_key == NULL)
594 gnutls_assert ();
595 ret = GNUTLS_E_INTERNAL_ERROR;
596 goto cleanup;
599 break;
602 _gnutls_selected_certs_set (session, local_certs,
603 (local_certs != NULL) ? st2.ncerts : 0,
604 local_key, 1);
606 ret = 0;
608 cleanup:
610 if (st2.cert_type == GNUTLS_CRT_X509)
612 if (st2.deinit_all)
614 for (i = 0; i < st2.ncerts; i++)
616 gnutls_x509_crt_deinit (st2.cert.x509[i]);
618 gnutls_free(st2.cert.x509);
621 else
623 #ifdef ENABLE_OPENPGP
624 if (st2.deinit_all)
626 gnutls_openpgp_crt_deinit (st2.cert.pgp);
628 #endif
631 if (ret < 0)
633 if (local_key != NULL)
634 gnutls_privkey_deinit (local_key);
637 return ret;
640 /* Finds the appropriate certificate depending on the cA Distinguished name
641 * advertized by the server. If none matches then returns 0 and -1 as index.
642 * In case of an error a negative value, is returned.
644 * 20020128: added ability to select a certificate depending on the SIGN
645 * algorithm (only in automatic mode).
647 static int
648 _select_client_cert (gnutls_session_t session,
649 opaque * _data, size_t _data_size,
650 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
652 int result;
653 int indx = -1;
654 gnutls_certificate_credentials_t cred;
655 opaque *data = _data;
656 ssize_t data_size = _data_size;
657 int issuers_dn_length;
658 gnutls_datum_t *issuers_dn = NULL;
660 cred = (gnutls_certificate_credentials_t)
661 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
662 if (cred == NULL)
664 gnutls_assert ();
665 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
668 if (cred->client_get_cert_callback != NULL
669 || cred->get_cert_callback != NULL)
672 /* use a callback to get certificate
674 if (session->security_parameters.cert_type != GNUTLS_CRT_X509)
675 issuers_dn_length = 0;
676 else
678 issuers_dn_length = get_issuers_num (session, data, data_size);
679 if (issuers_dn_length < 0)
681 gnutls_assert ();
682 return issuers_dn_length;
685 if (issuers_dn_length > 0)
687 issuers_dn =
688 gnutls_malloc (sizeof (gnutls_datum_t) * issuers_dn_length);
689 if (issuers_dn == NULL)
691 gnutls_assert ();
692 return GNUTLS_E_MEMORY_ERROR;
695 result =
696 get_issuers (session, issuers_dn, issuers_dn_length,
697 data, data_size);
698 if (result < 0)
700 gnutls_assert ();
701 goto cleanup;
706 result =
707 call_get_cert_callback (session, issuers_dn, issuers_dn_length,
708 pk_algos, pk_algos_length);
709 goto cleanup;
712 else
714 /* If we have no callbacks, try to guess.
716 result = 0;
718 if (session->security_parameters.cert_type == GNUTLS_CRT_X509)
719 result =
720 _find_x509_cert (cred, _data, _data_size,
721 pk_algos, pk_algos_length, &indx);
723 #ifdef ENABLE_OPENPGP
724 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP)
725 result = _find_openpgp_cert (cred, pk_algos, pk_algos_length, &indx);
726 #endif
728 if (result < 0)
730 gnutls_assert ();
731 return result;
734 if (indx >= 0)
736 _gnutls_selected_certs_set (session,
737 &cred->cert_list[indx][0],
738 cred->cert_list_length[indx],
739 cred->pkey[indx], 0);
741 else
743 _gnutls_selected_certs_set (session, NULL, 0, NULL, 0);
746 result = 0;
749 cleanup:
750 gnutls_free (issuers_dn);
751 return result;
755 /* Generate client certificate
758 static int
759 _gnutls_gen_x509_crt (gnutls_session_t session, opaque ** data)
761 int ret, i;
762 opaque *pdata;
763 gnutls_cert *apr_cert_list;
764 gnutls_privkey_t apr_pkey;
765 int apr_cert_list_length;
767 /* find the appropriate certificate
769 if ((ret =
770 _gnutls_get_selected_cert (session, &apr_cert_list,
771 &apr_cert_list_length, &apr_pkey)) < 0)
773 gnutls_assert ();
774 return ret;
777 ret = 3;
778 for (i = 0; i < apr_cert_list_length; i++)
780 ret += apr_cert_list[i].raw.size + 3;
781 /* hold size
782 * for uint24 */
785 /* if no certificates were found then send:
786 * 0B 00 00 03 00 00 00 // Certificate with no certs
787 * instead of:
788 * 0B 00 00 00 // empty certificate handshake
790 * ( the above is the whole handshake message, not
791 * the one produced here )
794 (*data) = gnutls_malloc (ret);
795 pdata = (*data);
797 if (pdata == NULL)
799 gnutls_assert ();
800 return GNUTLS_E_MEMORY_ERROR;
802 _gnutls_write_uint24 (ret - 3, pdata);
803 pdata += 3;
804 for (i = 0; i < apr_cert_list_length; i++)
806 _gnutls_write_datum24 (pdata, apr_cert_list[i].raw);
807 pdata += (3 + apr_cert_list[i].raw.size);
810 return ret;
813 enum PGPKeyDescriptorType
814 { PGP_KEY_FINGERPRINT, PGP_KEY, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
816 #ifdef ENABLE_OPENPGP
817 static int
818 _gnutls_gen_openpgp_certificate (gnutls_session_t session, opaque ** data)
820 int ret;
821 opaque *pdata;
822 gnutls_cert *apr_cert_list;
823 gnutls_privkey_t apr_pkey;
824 int apr_cert_list_length;
826 /* find the appropriate certificate */
827 if ((ret =
828 _gnutls_get_selected_cert (session, &apr_cert_list,
829 &apr_cert_list_length, &apr_pkey)) < 0)
831 gnutls_assert ();
832 return ret;
835 ret = 3 + 1 + 3;
838 if (apr_cert_list_length > 0)
840 if (apr_cert_list[0].use_subkey != 0)
841 ret += 1 + sizeof (apr_cert_list[0].subkey_id); /* for the keyid */
843 ret += apr_cert_list[0].raw.size;
846 (*data) = gnutls_malloc (ret);
847 pdata = (*data);
849 if (pdata == NULL)
851 gnutls_assert ();
852 return GNUTLS_E_MEMORY_ERROR;
855 _gnutls_write_uint24 (ret - 3, pdata);
856 pdata += 3;
859 if (apr_cert_list_length > 0)
861 if (apr_cert_list[0].use_subkey != 0)
863 *pdata = PGP_KEY_SUBKEY;
864 pdata++;
865 *pdata = sizeof (apr_cert_list[0].subkey_id);
866 pdata++;
867 memcpy (pdata, apr_cert_list[0].subkey_id,
868 sizeof (apr_cert_list[0].subkey_id));
869 pdata += sizeof (apr_cert_list[0].subkey_id);
871 else
873 *pdata = PGP_KEY;
874 pdata++;
877 _gnutls_write_datum24 (pdata, apr_cert_list[0].raw);
878 pdata += (3 + apr_cert_list[0].raw.size);
880 else /* empty - no certificate */
882 *pdata = PGP_KEY;
883 pdata++;
884 _gnutls_write_uint24 (0, pdata);
887 return ret;
890 static int
891 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, opaque ** data)
893 int ret, packet_size;
894 size_t fpr_size;
895 opaque *pdata;
896 gnutls_cert *apr_cert_list;
897 gnutls_privkey_t apr_pkey;
898 int apr_cert_list_length;
900 /* find the appropriate certificate */
901 if ((ret =
902 _gnutls_get_selected_cert (session, &apr_cert_list,
903 &apr_cert_list_length, &apr_pkey)) < 0)
905 gnutls_assert ();
906 return ret;
909 packet_size = 3 + 1;
911 if (apr_cert_list[0].use_subkey)
912 packet_size += 1 + sizeof (apr_cert_list[0].subkey_id); /* for the keyid */
914 /* Only v4 fingerprints are sent
916 if (apr_cert_list_length > 0 && apr_cert_list[0].version == 4)
917 packet_size += 20 + 1;
918 else /* empty certificate case */
919 return _gnutls_gen_openpgp_certificate (session, data);
921 (*data) = gnutls_malloc (packet_size);
922 pdata = (*data);
924 if (pdata == NULL)
926 gnutls_assert ();
927 return GNUTLS_E_MEMORY_ERROR;
930 _gnutls_write_uint24 (packet_size - 3, pdata);
931 pdata += 3;
933 if (apr_cert_list[0].use_subkey)
935 *pdata = PGP_KEY_FINGERPRINT_SUBKEY;
936 pdata++;
937 *pdata = sizeof (apr_cert_list[0].subkey_id);
938 pdata++;
939 memcpy (pdata, apr_cert_list[0].subkey_id,
940 sizeof (apr_cert_list[0].subkey_id));
941 pdata += sizeof (apr_cert_list[0].subkey_id);
943 else
945 *pdata = PGP_KEY_FINGERPRINT; /* key fingerprint */
946 pdata++;
949 *pdata = 20;
950 pdata++;
952 fpr_size = 20;
954 if ((ret =
955 _gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, pdata,
956 &fpr_size)) < 0)
958 gnutls_assert ();
959 return ret;
962 return packet_size;
964 #endif
968 _gnutls_gen_cert_client_certificate (gnutls_session_t session, opaque ** data)
970 switch (session->security_parameters.cert_type)
972 #ifdef ENABLE_OPENPGP
973 case GNUTLS_CRT_OPENPGP:
974 if (_gnutls_openpgp_send_fingerprint (session) == 0)
975 return _gnutls_gen_openpgp_certificate (session, data);
976 else
977 return _gnutls_gen_openpgp_certificate_fpr (session, data);
978 #endif
979 case GNUTLS_CRT_X509:
980 return _gnutls_gen_x509_crt (session, data);
982 default:
983 gnutls_assert ();
984 return GNUTLS_E_INTERNAL_ERROR;
989 _gnutls_gen_cert_server_certificate (gnutls_session_t session, opaque ** data)
991 switch (session->security_parameters.cert_type)
993 #ifdef ENABLE_OPENPGP
994 case GNUTLS_CRT_OPENPGP:
995 return _gnutls_gen_openpgp_certificate (session, data);
996 #endif
997 case GNUTLS_CRT_X509:
998 return _gnutls_gen_x509_crt (session, data);
999 default:
1000 gnutls_assert ();
1001 return GNUTLS_E_INTERNAL_ERROR;
1005 /* Process server certificate
1008 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
1009 static int
1010 _gnutls_proc_x509_server_certificate (gnutls_session_t session,
1011 opaque * data, size_t data_size)
1013 int size, len, ret;
1014 opaque *p = data;
1015 cert_auth_info_t info;
1016 gnutls_certificate_credentials_t cred;
1017 ssize_t dsize = data_size;
1018 int i;
1019 gnutls_cert *peer_certificate_list;
1020 size_t peer_certificate_list_size = 0, j, x;
1021 gnutls_datum_t tmp;
1023 cred = (gnutls_certificate_credentials_t)
1024 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1025 if (cred == NULL)
1027 gnutls_assert ();
1028 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1032 if ((ret =
1033 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1034 sizeof (cert_auth_info_st), 1)) < 0)
1036 gnutls_assert ();
1037 return ret;
1040 info = _gnutls_get_auth_info (session);
1042 if (data == NULL || data_size == 0)
1044 gnutls_assert ();
1045 /* no certificate was sent */
1046 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1049 DECR_LEN (dsize, 3);
1050 size = _gnutls_read_uint24 (p);
1051 p += 3;
1053 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
1054 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
1056 if (size == 0 || size == 3)
1058 gnutls_assert ();
1059 /* no certificate was sent */
1060 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1063 i = dsize;
1064 while (i > 0)
1066 DECR_LEN (dsize, 3);
1067 len = _gnutls_read_uint24 (p);
1068 p += 3;
1069 DECR_LEN (dsize, len);
1070 peer_certificate_list_size++;
1071 p += len;
1072 i -= len + 3;
1075 if (peer_certificate_list_size == 0)
1077 gnutls_assert ();
1078 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1081 /* Ok we now allocate the memory to hold the
1082 * certificate list
1085 peer_certificate_list =
1086 gnutls_malloc (sizeof (gnutls_cert) * (peer_certificate_list_size));
1088 if (peer_certificate_list == NULL)
1090 gnutls_assert ();
1091 return GNUTLS_E_MEMORY_ERROR;
1093 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
1094 peer_certificate_list_size);
1096 p = data + 3;
1098 /* Now we start parsing the list (again).
1099 * We don't use DECR_LEN since the list has
1100 * been parsed before.
1103 for (j = 0; j < peer_certificate_list_size; j++)
1105 len = _gnutls_read_uint24 (p);
1106 p += 3;
1108 tmp.size = len;
1109 tmp.data = p;
1111 if ((ret =
1112 _gnutls_x509_raw_cert_to_gcert (&peer_certificate_list
1113 [j], &tmp,
1114 CERT_ONLY_EXTENSIONS)) < 0)
1116 gnutls_assert ();
1117 goto cleanup;
1120 /* check if signature algorithm is supported */
1121 ret =
1122 _gnutls_session_sign_algo_enabled (session,
1123 peer_certificate_list
1124 [j].sign_algo);
1125 if (ret < 0)
1127 gnutls_assert ();
1128 goto cleanup;
1131 p += len;
1135 if ((ret =
1136 _gnutls_copy_certificate_auth_info (info,
1137 peer_certificate_list,
1138 peer_certificate_list_size)) < 0)
1140 gnutls_assert ();
1141 goto cleanup;
1144 if ((ret =
1145 _gnutls_check_key_usage (&peer_certificate_list[0],
1146 gnutls_kx_get (session))) < 0)
1148 gnutls_assert ();
1149 goto cleanup;
1152 ret = 0;
1154 cleanup:
1155 CLEAR_CERTS;
1156 gnutls_free (peer_certificate_list);
1157 return ret;
1161 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
1162 #ifdef ENABLE_OPENPGP
1163 static int
1164 _gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
1165 opaque * data, size_t data_size)
1167 int size, ret, len;
1168 opaque *p = data;
1169 cert_auth_info_t info;
1170 gnutls_certificate_credentials_t cred;
1171 ssize_t dsize = data_size;
1172 int x, key_type;
1173 gnutls_cert *peer_certificate_list = NULL;
1174 int peer_certificate_list_size = 0;
1175 gnutls_datum_t tmp, akey = { NULL, 0 };
1176 uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE];
1177 unsigned int subkey_id_set = 0;
1179 cred = (gnutls_certificate_credentials_t)
1180 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1181 if (cred == NULL)
1183 gnutls_assert ();
1184 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1187 if ((ret =
1188 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1189 sizeof (cert_auth_info_st), 1)) < 0)
1191 gnutls_assert ();
1192 return ret;
1195 info = _gnutls_get_auth_info (session);
1197 if (data == NULL || data_size == 0)
1199 gnutls_assert ();
1200 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1203 DECR_LEN (dsize, 3);
1204 size = _gnutls_read_uint24 (p);
1205 p += 3;
1207 if (size == 0)
1209 gnutls_assert ();
1210 /* no certificate was sent */
1211 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1214 /* Read PGPKeyDescriptor */
1215 DECR_LEN (dsize, 1);
1216 key_type = *p;
1217 p++;
1219 /* Try to read the keyid if present */
1220 if (key_type == PGP_KEY_FINGERPRINT_SUBKEY || key_type == PGP_KEY_SUBKEY)
1222 /* check size */
1223 if (*p != sizeof (subkey_id))
1225 gnutls_assert ();
1226 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1229 DECR_LEN (dsize, 1);
1230 p++;
1232 DECR_LEN (dsize, sizeof (subkey_id));
1233 memcpy (subkey_id, p, sizeof (subkey_id));
1234 p += sizeof (subkey_id);
1236 subkey_id_set = 1;
1240 /* read the actual key or fingerprint */
1241 if (key_type == PGP_KEY_FINGERPRINT
1242 || key_type == PGP_KEY_FINGERPRINT_SUBKEY)
1243 { /* the fingerprint */
1245 DECR_LEN (dsize, 1);
1246 len = (uint8_t) * p;
1247 p++;
1249 if (len != 20)
1251 gnutls_assert ();
1252 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED;
1255 DECR_LEN (dsize, 20);
1257 /* request the actual key from our database, or
1258 * a key server or anything.
1260 if ((ret =
1261 _gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
1263 gnutls_assert ();
1264 return ret;
1266 tmp = akey;
1267 peer_certificate_list_size++;
1270 else if (key_type == PGP_KEY || key_type == PGP_KEY_SUBKEY)
1271 { /* the whole key */
1273 /* Read the actual certificate */
1274 DECR_LEN (dsize, 3);
1275 len = _gnutls_read_uint24 (p);
1276 p += 3;
1278 if (len == 0)
1280 gnutls_assert ();
1281 /* no certificate was sent */
1282 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1285 DECR_LEN (dsize, len);
1286 peer_certificate_list_size++;
1288 tmp.size = len;
1289 tmp.data = p;
1292 else
1294 gnutls_assert ();
1295 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1298 /* ok we now have the peer's key in tmp datum
1301 if (peer_certificate_list_size == 0)
1303 gnutls_assert ();
1304 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1307 peer_certificate_list =
1308 gnutls_malloc (sizeof (gnutls_cert) * (peer_certificate_list_size));
1309 if (peer_certificate_list == NULL)
1311 gnutls_assert ();
1312 ret = GNUTLS_E_MEMORY_ERROR;
1313 goto cleanup;
1315 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
1316 peer_certificate_list_size);
1318 if ((ret =
1319 _gnutls_openpgp_raw_crt_to_gcert (&peer_certificate_list[0],
1320 &tmp,
1321 subkey_id_set ? subkey_id : NULL)) <
1324 gnutls_assert ();
1325 goto cleanup;
1328 if ((ret =
1329 _gnutls_copy_certificate_auth_info (info,
1330 peer_certificate_list,
1331 peer_certificate_list_size)) < 0)
1333 gnutls_assert ();
1334 goto cleanup;
1337 if ((ret =
1338 _gnutls_check_key_usage (&peer_certificate_list[0],
1339 gnutls_kx_get (session))) < 0)
1341 gnutls_assert ();
1342 goto cleanup;
1345 ret = 0;
1347 cleanup:
1349 _gnutls_free_datum (&akey);
1350 CLEAR_CERTS;
1351 gnutls_free (peer_certificate_list);
1352 return ret;
1355 #endif
1358 _gnutls_proc_cert_server_certificate (gnutls_session_t session,
1359 opaque * data, size_t data_size)
1361 int ret;
1362 gnutls_certificate_credentials_t cred;
1364 cred =
1365 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
1366 GNUTLS_CRD_CERTIFICATE,
1367 NULL);
1368 if (cred == NULL)
1370 gnutls_assert ();
1371 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1374 switch (session->security_parameters.cert_type)
1376 #ifdef ENABLE_OPENPGP
1377 case GNUTLS_CRT_OPENPGP:
1378 ret = _gnutls_proc_openpgp_server_certificate (session,
1379 data, data_size);
1380 break;
1381 #endif
1382 case GNUTLS_CRT_X509:
1383 ret = _gnutls_proc_x509_server_certificate (session, data, data_size);
1384 break;
1385 default:
1386 gnutls_assert ();
1387 return GNUTLS_E_INTERNAL_ERROR;
1390 if (ret == 0 && cred->verify_callback != NULL)
1392 ret = cred->verify_callback (session);
1393 if (ret != 0)
1394 ret = GNUTLS_E_CERTIFICATE_ERROR;
1397 return ret;
1400 #define MAX_SIGN_ALGOS 2
1401 typedef enum CertificateSigType
1402 { RSA_SIGN = 1, DSA_SIGN
1403 } CertificateSigType;
1405 /* Checks if we support the given signature algorithm
1406 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1407 * if true;
1409 inline static int
1410 _gnutls_check_supported_sign_algo (CertificateSigType algo)
1412 switch (algo)
1414 case RSA_SIGN:
1415 return GNUTLS_PK_RSA;
1416 case DSA_SIGN:
1417 return GNUTLS_PK_DSA;
1420 return -1;
1424 _gnutls_proc_cert_cert_req (gnutls_session_t session, opaque * data,
1425 size_t data_size)
1427 int size, ret;
1428 opaque *p;
1429 gnutls_certificate_credentials_t cred;
1430 ssize_t dsize;
1431 int i, j;
1432 gnutls_pk_algorithm_t pk_algos[MAX_SIGN_ALGOS];
1433 int pk_algos_length;
1434 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1436 cred = (gnutls_certificate_credentials_t)
1437 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1438 if (cred == NULL)
1440 gnutls_assert ();
1441 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1444 if ((ret =
1445 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1446 sizeof (cert_auth_info_st), 0)) < 0)
1448 gnutls_assert ();
1449 return ret;
1452 p = data;
1453 dsize = data_size;
1455 DECR_LEN (dsize, 1);
1456 size = p[0];
1457 p++;
1458 /* check if the sign algorithm is supported.
1460 pk_algos_length = j = 0;
1461 for (i = 0; i < size; i++, p++)
1463 DECR_LEN (dsize, 1);
1464 if ((ret = _gnutls_check_supported_sign_algo (*p)) > 0)
1466 if (j < MAX_SIGN_ALGOS)
1468 pk_algos[j++] = ret;
1469 pk_algos_length++;
1474 if (pk_algos_length == 0)
1476 gnutls_assert ();
1477 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1480 if (_gnutls_version_has_selectable_sighash (ver))
1482 /* read supported hashes */
1483 int hash_num;
1484 DECR_LEN (dsize, 2);
1485 hash_num = _gnutls_read_uint16 (p);
1486 p += 2;
1487 DECR_LEN (dsize, hash_num);
1489 ret = _gnutls_sign_algorithm_parse_data (session, p, hash_num);
1490 if (ret < 0)
1492 gnutls_assert ();
1493 return ret;
1496 p += hash_num;
1499 /* read the certificate authorities */
1500 DECR_LEN (dsize, 2);
1501 size = _gnutls_read_uint16 (p);
1502 p += 2;
1504 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP
1505 && size != 0)
1507 gnutls_assert ();
1508 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1511 DECR_LEN (dsize, size);
1513 /* now we ask the user to tell which one
1514 * he wants to use.
1516 if ((ret =
1517 _select_client_cert (session, p, size, pk_algos, pk_algos_length)) < 0)
1519 gnutls_assert ();
1520 return ret;
1523 /* We should reply with a certificate message,
1524 * even if we have no certificate to send.
1526 session->key->certificate_requested = 1;
1528 return 0;
1532 _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data)
1534 int ret;
1535 gnutls_cert *apr_cert_list;
1536 gnutls_privkey_t apr_pkey;
1537 int apr_cert_list_length, size;
1538 gnutls_datum_t signature = { NULL, 0 };
1539 int total_data;
1540 opaque *p;
1541 gnutls_sign_algorithm_t sign_algo;
1542 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1544 *data = NULL;
1546 /* find the appropriate certificate */
1547 if ((ret =
1548 _gnutls_get_selected_cert (session, &apr_cert_list,
1549 &apr_cert_list_length, &apr_pkey)) < 0)
1551 gnutls_assert ();
1552 return ret;
1555 if (apr_cert_list_length > 0)
1557 if ((ret =
1558 _gnutls_handshake_sign_cert_vrfy (session,
1559 &apr_cert_list[0],
1560 apr_pkey, &signature)) < 0)
1562 gnutls_assert ();
1563 return ret;
1565 sign_algo = ret;
1567 else
1569 return 0;
1572 total_data = signature.size + 2;
1574 /* add hash and signature algorithms */
1575 if (_gnutls_version_has_selectable_sighash (ver))
1577 total_data += 2;
1580 *data = gnutls_malloc (total_data);
1581 if (*data == NULL)
1583 _gnutls_free_datum (&signature);
1584 return GNUTLS_E_MEMORY_ERROR;
1587 p = *data;
1588 if (_gnutls_version_has_selectable_sighash (ver))
1590 const sign_algorithm_st *aid;
1591 /* error checking is not needed here since we have used those algorithms */
1592 aid = _gnutls_sign_to_tls_aid (sign_algo);
1593 if (aid == NULL)
1595 ret = GNUTLS_E_UNKNOWN_ALGORITHM;
1596 goto cleanup;
1599 p[0] = aid->hash_algorithm;
1600 p[1] = aid->sign_algorithm;
1601 p += 2;
1604 size = signature.size;
1605 _gnutls_write_uint16 (size, p);
1607 p += 2;
1608 memcpy (p, signature.data, size);
1610 _gnutls_free_datum (&signature);
1612 return total_data;
1614 cleanup:
1615 _gnutls_free_datum (&signature);
1616 gnutls_free(*data);
1617 return ret;
1621 _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session,
1622 opaque * data, size_t data_size)
1624 int size, ret;
1625 ssize_t dsize = data_size;
1626 opaque *pdata = data;
1627 gnutls_datum_t sig;
1628 cert_auth_info_t info = _gnutls_get_auth_info (session);
1629 gnutls_cert peer_cert;
1630 gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
1631 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1633 if (info == NULL || info->ncerts == 0)
1635 gnutls_assert ();
1636 /* we need this in order to get peer's certificate */
1637 return GNUTLS_E_INTERNAL_ERROR;
1640 if (_gnutls_version_has_selectable_sighash (ver))
1642 sign_algorithm_st aid;
1644 DECR_LEN (dsize, 2);
1645 aid.hash_algorithm = pdata[0];
1646 aid.sign_algorithm = pdata[1];
1648 sign_algo = _gnutls_tls_aid_to_sign (&aid);
1649 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
1651 gnutls_assert ();
1652 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1654 pdata += 2;
1657 ret = _gnutls_session_sign_algo_enabled (session, sign_algo);
1658 if (ret < 0)
1660 gnutls_assert ();
1661 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1664 DECR_LEN (dsize, 2);
1665 size = _gnutls_read_uint16 (pdata);
1666 pdata += 2;
1668 DECR_LEN (dsize, size);
1670 sig.data = pdata;
1671 sig.size = size;
1673 ret = _gnutls_get_auth_info_gcert (&peer_cert,
1674 session->security_parameters.cert_type,
1675 info, CERT_NO_COPY);
1677 if (ret < 0)
1679 gnutls_assert ();
1680 return ret;
1683 if ((ret =
1684 _gnutls_handshake_verify_cert_vrfy (session, &peer_cert, &sig,
1685 sign_algo)) < 0)
1687 gnutls_assert ();
1688 _gnutls_gcert_deinit (&peer_cert);
1689 return ret;
1691 _gnutls_gcert_deinit (&peer_cert);
1693 return 0;
1697 #define CERTTYPE_SIZE 3
1699 _gnutls_gen_cert_server_cert_req (gnutls_session_t session, opaque ** data)
1701 gnutls_certificate_credentials_t cred;
1702 int size, ret;
1703 opaque *pdata;
1704 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1705 const int signalgosize = 2 + MAX_SIGNATURE_ALGORITHMS * 2;
1707 /* Now we need to generate the RDN sequence. This is
1708 * already in the CERTIFICATE_CRED structure, to improve
1709 * performance.
1712 cred = (gnutls_certificate_credentials_t)
1713 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1714 if (cred == NULL)
1716 gnutls_assert ();
1717 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1720 size = CERTTYPE_SIZE + 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1723 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1724 session->internals.ignore_rdn_sequence == 0)
1725 size += cred->x509_rdn_sequence.size;
1727 if (_gnutls_version_has_selectable_sighash (ver))
1728 /* Need two bytes to announce the number of supported hash
1729 functions (see below). */
1730 size += signalgosize;
1732 (*data) = gnutls_malloc (size);
1733 pdata = (*data);
1735 if (pdata == NULL)
1737 gnutls_assert ();
1738 return GNUTLS_E_MEMORY_ERROR;
1741 pdata[0] = CERTTYPE_SIZE - 1;
1743 pdata[1] = RSA_SIGN;
1744 pdata[2] = DSA_SIGN; /* only these for now */
1745 pdata += CERTTYPE_SIZE;
1747 if (_gnutls_version_has_selectable_sighash (ver))
1749 ret =
1750 _gnutls_sign_algorithm_write_params (session, pdata, signalgosize);
1751 if (ret < 0)
1753 gnutls_assert ();
1754 return ret;
1757 /* recalculate size */
1758 size = size - signalgosize + ret;
1759 pdata += ret;
1762 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1763 session->internals.ignore_rdn_sequence == 0)
1765 _gnutls_write_datum16 (pdata, cred->x509_rdn_sequence);
1766 /* pdata += cred->x509_rdn_sequence.size + 2; */
1768 else
1770 _gnutls_write_uint16 (0, pdata);
1771 /* pdata+=2; */
1774 return size;
1778 /* This function will return the appropriate certificate to use.
1779 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1780 * The return value is a negative value on error.
1782 * It is normal to return 0 with no certificates in client side.
1786 _gnutls_get_selected_cert (gnutls_session_t session,
1787 gnutls_cert ** apr_cert_list,
1788 int *apr_cert_list_length,
1789 gnutls_privkey_t * apr_pkey)
1791 if (session->security_parameters.entity == GNUTLS_SERVER)
1794 /* select_client_cert() has been called before.
1797 *apr_cert_list = session->internals.selected_cert_list;
1798 *apr_pkey = session->internals.selected_key;
1799 *apr_cert_list_length = session->internals.selected_cert_list_length;
1801 if (*apr_cert_list_length == 0 || *apr_cert_list == NULL)
1803 gnutls_assert ();
1804 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1808 else
1809 { /* CLIENT SIDE
1812 /* we have already decided which certificate
1813 * to send.
1815 *apr_cert_list = session->internals.selected_cert_list;
1816 *apr_cert_list_length = session->internals.selected_cert_list_length;
1817 *apr_pkey = session->internals.selected_key;
1821 return 0;
1824 /* converts the given x509 certificate to gnutls_cert* and allocates
1825 * space for them.
1827 static gnutls_cert *
1828 alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, unsigned ncerts)
1830 gnutls_cert *local_certs;
1831 int ret = 0;
1832 unsigned i, j;
1834 if (certs == NULL)
1835 return NULL;
1837 local_certs = gnutls_malloc (sizeof (gnutls_cert) * ncerts);
1838 if (local_certs == NULL)
1840 gnutls_assert ();
1841 return NULL;
1844 for (i = 0; i < ncerts; i++)
1846 ret = _gnutls_x509_crt_to_gcert (&local_certs[i], certs[i], 0);
1847 if (ret < 0)
1848 break;
1851 if (ret < 0)
1853 gnutls_assert ();
1854 for (j = 0; j < i; j++)
1856 _gnutls_gcert_deinit (&local_certs[j]);
1858 gnutls_free (local_certs);
1859 return NULL;
1862 return local_certs;
1865 /* converts the given x509 key to gnutls_privkey* and allocates
1866 * space for it.
1868 static gnutls_privkey_t
1869 alloc_and_load_x509_key (gnutls_x509_privkey_t key, int deinit)
1871 gnutls_privkey_t local_key;
1872 int ret = 0;
1874 if (key == NULL)
1875 return NULL;
1877 ret = gnutls_privkey_init (&local_key);
1878 if (ret < 0)
1880 gnutls_assert ();
1881 return NULL;
1884 ret =
1885 gnutls_privkey_import_x509 (local_key, key,
1886 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE :
1888 if (ret < 0)
1890 gnutls_assert ();
1891 gnutls_privkey_deinit (local_key);
1892 return NULL;
1895 return local_key;
1898 /* converts the given pgp certificate to gnutls_cert* and allocates
1899 * space for them.
1901 #ifdef ENABLE_OPENPGP
1902 static gnutls_cert *
1903 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
1905 gnutls_cert *local_certs;
1906 int ret = 0;
1908 if (cert == NULL)
1909 return NULL;
1911 local_certs = gnutls_malloc (sizeof (gnutls_cert));
1912 if (local_certs == NULL)
1914 gnutls_assert ();
1915 return NULL;
1918 ret = _gnutls_openpgp_crt_to_gcert (local_certs, cert);
1919 if (ret < 0)
1921 gnutls_assert ();
1922 return NULL;
1925 if (ret < 0)
1927 gnutls_assert ();
1928 _gnutls_gcert_deinit (local_certs);
1929 gnutls_free (local_certs);
1930 return NULL;
1933 ret =
1934 gnutls_openpgp_crt_get_preferred_key_id (cert, local_certs->subkey_id);
1935 if (ret < 0)
1936 local_certs->use_subkey = 0;
1937 else
1938 local_certs->use_subkey = 1;
1940 return local_certs;
1943 /* converts the given raw key to gnutls_privkey* and allocates
1944 * space for it.
1946 static gnutls_privkey_t
1947 alloc_and_load_pgp_key (gnutls_openpgp_privkey_t key, int deinit)
1949 gnutls_privkey_t local_key;
1950 int ret = 0;
1952 if (key == NULL)
1953 return NULL;
1955 ret = gnutls_privkey_init (&local_key);
1956 if (ret < 0)
1958 gnutls_assert ();
1959 return NULL;
1962 ret =
1963 gnutls_privkey_import_openpgp (local_key, key,
1964 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
1965 : 0);
1966 if (ret < 0)
1968 gnutls_assert ();
1969 gnutls_privkey_deinit (local_key);
1970 return NULL;
1973 return local_key;
1975 #endif
1977 #ifdef ENABLE_PKCS11
1979 /* converts the given raw key to gnutls_privkey* and allocates
1980 * space for it.
1982 static gnutls_privkey_t
1983 alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t key, int deinit)
1985 gnutls_privkey_t local_key;
1986 int ret = 0;
1988 if (key == NULL)
1989 return NULL;
1991 ret = gnutls_privkey_init (&local_key);
1992 if (ret < 0)
1994 gnutls_assert ();
1995 return NULL;
1998 ret =
1999 gnutls_privkey_import_pkcs11 (local_key, key,
2000 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
2001 : 0);
2002 if (ret < 0)
2004 gnutls_assert ();
2005 gnutls_privkey_deinit (local_key);
2006 return NULL;
2009 return local_key;
2012 #endif
2014 void
2015 _gnutls_selected_certs_deinit (gnutls_session_t session)
2017 if (session->internals.selected_need_free != 0)
2019 int i;
2021 for (i = 0; i < session->internals.selected_cert_list_length; i++)
2023 _gnutls_gcert_deinit (&session->internals.selected_cert_list[i]);
2025 gnutls_free (session->internals.selected_cert_list);
2026 session->internals.selected_cert_list = NULL;
2027 session->internals.selected_cert_list_length = 0;
2029 gnutls_privkey_deinit(session->internals.selected_key);
2030 session->internals.selected_key = NULL;
2033 return;
2036 void
2037 _gnutls_selected_certs_set (gnutls_session_t session,
2038 gnutls_cert * certs, int ncerts,
2039 gnutls_privkey_t key, int need_free)
2041 _gnutls_selected_certs_deinit (session);
2043 session->internals.selected_cert_list = certs;
2044 session->internals.selected_cert_list_length = ncerts;
2045 session->internals.selected_key = key;
2046 session->internals.selected_need_free = need_free;
2051 /* finds the most appropriate certificate in the cert list.
2052 * The 'appropriate' is defined by the user.
2054 * requested_algo holds the parameters required by the peer (RSA, DSA
2055 * or -1 for any).
2057 * Returns 0 on success and a negative value on error. The
2058 * selected certificate will be in session->internals.selected_*.
2062 _gnutls_server_select_cert (gnutls_session_t session,
2063 gnutls_pk_algorithm_t requested_algo)
2065 unsigned i;
2066 int idx;
2067 gnutls_certificate_credentials_t cred;
2069 cred = (gnutls_certificate_credentials_t)
2070 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
2071 if (cred == NULL)
2073 gnutls_assert ();
2074 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2077 /* If the callback which retrieves certificate has been set,
2078 * use it and leave.
2080 if (cred->server_get_cert_callback != NULL ||
2081 cred->get_cert_callback != NULL)
2082 return call_get_cert_callback (session, NULL, 0, NULL, 0);
2084 /* Otherwise... */
2086 idx = -1; /* default is use no certificate */
2089 for (i = 0; i < cred->ncerts; i++)
2091 /* find one compatible certificate
2093 if (requested_algo == GNUTLS_PK_ANY ||
2094 requested_algo == cred->cert_list[i][0].subject_pk_algorithm)
2096 /* if cert type and signature algorithm matches
2098 /* *INDENT-OFF* */
2099 if (session->security_parameters.cert_type
2100 == cred->cert_list[i][0].cert_type
2101 && (cred->cert_list[i][0].cert_type == GNUTLS_CRT_OPENPGP
2102 || /* FIXME: make this a check for certificate
2103 type capabilities */
2104 !_gnutls_version_has_selectable_sighash
2105 (gnutls_protocol_get_version (session))
2107 _gnutls_session_sign_algo_requested
2108 (session, cred->cert_list[i][0].sign_algo) == 0))
2110 idx = i;
2111 break;
2113 /* *INDENT-ON* */
2117 /* store the certificate pointer for future use, in the handshake.
2118 * (This will allow not calling this callback again.)
2120 if (idx >= 0)
2122 _gnutls_selected_certs_set (session,
2123 &cred->cert_list[idx][0],
2124 cred->cert_list_length[idx],
2125 cred->pkey[idx], 0);
2127 else
2128 /* Certificate does not support REQUESTED_ALGO. */
2129 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2131 return 0;
2134 /* Frees the rsa_info_st structure.
2136 void
2137 _gnutls_free_rsa_info (rsa_info_st * rsa)
2139 _gnutls_free_datum (&rsa->modulus);
2140 _gnutls_free_datum (&rsa->exponent);