Added missing elf part.
[gnutls.git] / lib / auth / cert.c
blob7582c759ae720454fea32804cd18dbf8e7633d50
1 /*
2 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* The certificate authentication functions which are needed in the handshake,
24 * and are common to RSA and DHE key exchange, are in this file.
27 #include <gnutls_int.h>
28 #include "gnutls_auth.h"
29 #include "gnutls_errors.h"
30 #include <auth/cert.h>
31 #include "gnutls_dh.h"
32 #include "gnutls_num.h"
33 #include "libtasn1.h"
34 #include "gnutls_datum.h"
35 #include "ext/signature.h"
36 #include <gnutls_pk.h>
37 #include <algorithms.h>
38 #include <gnutls_global.h>
39 #include <gnutls_record.h>
40 #include <gnutls_sig.h>
41 #include <gnutls_state.h>
42 #include <gnutls_pk.h>
43 #include <gnutls_x509.h>
44 #include <gnutls/abstract.h>
45 #include "debug.h"
47 #ifdef ENABLE_OPENPGP
48 #include "openpgp/gnutls_openpgp.h"
50 static gnutls_privkey_t alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t
51 key, int deinit);
52 static gnutls_pcert_st *alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert);
54 #endif
56 static gnutls_pcert_st *alloc_and_load_x509_certs (gnutls_x509_crt_t * certs,
57 unsigned);
58 static gnutls_privkey_t alloc_and_load_x509_key (gnutls_x509_privkey_t key,
59 int deinit);
61 #ifdef ENABLE_PKCS11
62 static gnutls_privkey_t alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t
63 key, int deinit);
64 #endif
66 #define MAX_CLIENT_SIGN_ALGOS 3
67 #define CERTTYPE_SIZE (MAX_CLIENT_SIGN_ALGOS+1)
68 typedef enum CertificateSigType
69 { RSA_SIGN = 1, DSA_SIGN = 2, ECDSA_SIGN = 64
70 } CertificateSigType;
72 /* Copies data from a internal certificate struct (gnutls_pcert_st) to
73 * exported certificate struct (cert_auth_info_t)
75 static int
76 _gnutls_copy_certificate_auth_info (cert_auth_info_t info, gnutls_pcert_st * certs, size_t ncerts, int subkey_used, /* openpgp only */
77 void *keyid)
79 /* Copy peer's information to auth_info_t
81 int ret;
82 size_t i, j;
84 if (info->raw_certificate_list != NULL)
86 for (j = 0; j < info->ncerts; j++)
87 _gnutls_free_datum (&info->raw_certificate_list[j]);
88 gnutls_free (info->raw_certificate_list);
91 if (ncerts == 0)
93 info->raw_certificate_list = NULL;
94 info->ncerts = 0;
95 return 0;
98 info->raw_certificate_list =
99 gnutls_calloc (ncerts, sizeof (gnutls_datum_t));
100 if (info->raw_certificate_list == NULL)
102 gnutls_assert ();
103 return GNUTLS_E_MEMORY_ERROR;
106 for (i = 0; i < ncerts; i++)
108 if (certs[i].cert.size > 0)
110 ret =
111 _gnutls_set_datum (&info->raw_certificate_list[i],
112 certs[i].cert.data, certs[i].cert.size);
113 if (ret < 0)
115 gnutls_assert ();
116 goto clear;
120 info->ncerts = ncerts;
121 info->cert_type = certs[0].type;
123 #ifdef ENABLE_OPENPGP
124 if (certs[0].type == GNUTLS_CRT_OPENPGP)
126 info->use_subkey = subkey_used;
127 if (keyid)
128 memcpy (info->subkey_id, keyid, GNUTLS_OPENPGP_KEYID_SIZE);
130 #endif
132 return 0;
134 clear:
136 for (j = 0; j < i; j++)
137 _gnutls_free_datum (&info->raw_certificate_list[j]);
139 gnutls_free (info->raw_certificate_list);
140 info->raw_certificate_list = NULL;
142 return ret;
148 /* returns 0 if the algo_to-check exists in the pk_algos list,
149 * -1 otherwise.
151 inline static int
152 _gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t *
153 pk_algos, int pk_algos_length,
154 gnutls_pk_algorithm_t algo_to_check)
156 int i;
157 for (i = 0; i < pk_algos_length; i++)
159 if (algo_to_check == pk_algos[i])
161 return 0;
164 return -1;
168 /* Returns the issuer's Distinguished name in odn, of the certificate
169 * specified in cert.
171 static int
172 _gnutls_cert_get_issuer_dn (gnutls_pcert_st * cert, gnutls_datum_t * odn)
174 ASN1_TYPE dn;
175 int len, result;
176 int start, end;
178 if ((result = asn1_create_element
179 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS)
181 gnutls_assert ();
182 return _gnutls_asn2err (result);
185 result = asn1_der_decoding (&dn, cert->cert.data, cert->cert.size, NULL);
186 if (result != ASN1_SUCCESS)
188 /* couldn't decode DER */
189 gnutls_assert ();
190 asn1_delete_structure (&dn);
191 return _gnutls_asn2err (result);
194 result = asn1_der_decoding_startEnd (dn, cert->cert.data, cert->cert.size,
195 "tbsCertificate.issuer", &start, &end);
197 if (result != ASN1_SUCCESS)
199 /* couldn't decode DER */
200 gnutls_assert ();
201 asn1_delete_structure (&dn);
202 return _gnutls_asn2err (result);
204 asn1_delete_structure (&dn);
206 len = end - start + 1;
208 odn->size = len;
209 odn->data = &cert->cert.data[start];
211 return 0;
215 /* Locates the most appropriate x509 certificate using the
216 * given DN. If indx == -1 then no certificate was found.
218 * That is to guess which certificate to use, based on the
219 * CAs and sign algorithms supported by the peer server.
221 static int
222 _find_x509_cert (const gnutls_certificate_credentials_t cred,
223 uint8_t * _data, size_t _data_size,
224 const gnutls_pk_algorithm_t * pk_algos,
225 int pk_algos_length, int *indx)
227 unsigned size;
228 gnutls_datum_t odn = { NULL, 0 };
229 uint8_t *data = _data;
230 ssize_t data_size = _data_size;
231 unsigned i, j;
232 int result, cert_pk;
234 *indx = -1;
236 /* If peer doesn't send any issuers and we have a single certificate
237 * then send that one.
239 if (data_size == 0 && cred->ncerts == 1)
241 *indx = 0;
242 return 0;
247 DECR_LENGTH_RET (data_size, 2, 0);
248 size = _gnutls_read_uint16 (data);
249 DECR_LENGTH_RET (data_size, size, 0);
250 data += 2;
252 for (i = 0; i < cred->ncerts; i++)
254 for (j = 0; j < cred->certs[i].cert_list_length; j++)
256 if ((result =
257 _gnutls_cert_get_issuer_dn (&cred->certs[i].cert_list[j],
258 &odn)) < 0)
260 gnutls_assert ();
261 return result;
264 if (odn.size != size)
265 continue;
267 /* If the DN matches and
268 * the *_SIGN algorithm matches
269 * the cert is our cert!
271 cert_pk =
272 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
273 NULL);
275 if ((memcmp (odn.data, data, size) == 0) &&
276 (_gnutls_check_pk_algo_in_list
277 (pk_algos, pk_algos_length, cert_pk) == 0))
279 *indx = i;
280 break;
283 if (*indx != -1)
284 break;
287 if (*indx != -1)
288 break;
290 /* move to next record */
291 data += size;
293 while (1);
295 return 0;
299 #ifdef ENABLE_OPENPGP
300 /* Locates the most appropriate openpgp cert
302 static int
303 _find_openpgp_cert (const gnutls_certificate_credentials_t cred,
304 gnutls_pk_algorithm_t * pk_algos,
305 int pk_algos_length, int *indx)
307 unsigned i, j;
309 *indx = -1;
311 for (i = 0; i < cred->ncerts; i++)
313 for (j = 0; j < cred->certs[i].cert_list_length; j++)
316 /* If the *_SIGN algorithm matches
317 * the cert is our cert!
319 if ((_gnutls_check_pk_algo_in_list
320 (pk_algos, pk_algos_length,
321 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
322 NULL)) == 0)
323 && (cred->certs[i].cert_list[0].type == GNUTLS_CRT_OPENPGP))
325 *indx = i;
326 break;
329 if (*indx != -1)
330 break;
333 return 0;
335 #endif
337 /* Returns the number of issuers in the server's
338 * certificate request packet.
340 static int
341 get_issuers_num (gnutls_session_t session, uint8_t * data, ssize_t data_size)
343 int issuers_dn_len = 0, result;
344 unsigned size;
346 /* Count the number of the given issuers;
347 * This is used to allocate the issuers_dn without
348 * using realloc().
351 if (data_size == 0 || data == NULL)
352 return 0;
354 if (data_size > 0)
357 /* This works like DECR_LEN()
359 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
360 DECR_LENGTH_COM (data_size, 2, goto error);
361 size = _gnutls_read_uint16 (data);
363 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
364 DECR_LENGTH_COM (data_size, size, goto error);
366 data += 2;
368 if (size > 0)
370 issuers_dn_len++;
371 data += size;
374 if (data_size == 0)
375 break;
378 while (1);
380 return issuers_dn_len;
382 error:
383 return result;
386 /* Returns the issuers in the server's certificate request
387 * packet.
389 static int
390 get_issuers (gnutls_session_t session,
391 gnutls_datum_t * issuers_dn, int issuers_len,
392 uint8_t * data, size_t data_size)
394 int i;
395 unsigned size;
397 if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
398 return 0;
400 /* put the requested DNs to req_dn, only in case
401 * of X509 certificates.
403 if (issuers_len > 0)
406 for (i = 0; i < issuers_len; i++)
408 /* The checks here for the buffer boundaries
409 * are not needed since the buffer has been
410 * parsed above.
412 data_size -= 2;
414 size = _gnutls_read_uint16 (data);
416 data += 2;
418 issuers_dn[i].data = data;
419 issuers_dn[i].size = size;
421 data += size;
425 return 0;
428 static void
429 st_to_st2 (gnutls_retr2_st * st2, gnutls_retr_st * st)
431 st2->cert_type = st->type;
432 if (st->type == GNUTLS_CRT_OPENPGP)
434 st2->key_type = GNUTLS_PRIVKEY_OPENPGP;
436 else
438 st2->key_type = GNUTLS_PRIVKEY_X509;
440 st2->ncerts = st->ncerts;
441 st2->deinit_all = st->deinit_all;
443 switch (st2->cert_type)
445 case GNUTLS_CRT_OPENPGP:
446 st2->cert.pgp = st->cert.pgp;
447 st2->key.pgp = st->key.pgp;
448 break;
449 case GNUTLS_CRT_X509:
450 st2->cert.x509 = st->cert.x509;
451 st2->key.x509 = st->key.x509;
452 break;
453 default:
454 return;
459 /* Calls the client get callback.
461 static int
462 call_get_cert_callback (gnutls_session_t session,
463 const gnutls_datum_t * issuers_dn,
464 int issuers_dn_length,
465 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
467 unsigned i;
468 gnutls_pcert_st *local_certs = NULL;
469 gnutls_privkey_t local_key = NULL;
470 int ret = GNUTLS_E_INTERNAL_ERROR;
471 gnutls_certificate_type_t type = gnutls_certificate_type_get (session);
472 gnutls_certificate_credentials_t cred;
473 gnutls_retr2_st st2;
474 gnutls_pcert_st *pcert = NULL;
475 unsigned int pcert_length = 0;
477 cred = (gnutls_certificate_credentials_t)
478 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
479 if (cred == NULL)
481 gnutls_assert ();
482 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
485 memset (&st2, 0, sizeof (st2));
487 if (cred->get_cert_callback2)
489 /* we avoid all allocations and transformations */
490 ret = cred->get_cert_callback2 (session, issuers_dn, issuers_dn_length,
491 pk_algos, pk_algos_length,
492 &pcert, &pcert_length, &local_key);
493 if (ret < 0)
494 return gnutls_assert_val (GNUTLS_E_USER_ERROR);
496 if (pcert_length > 0 && type != pcert[0].type)
497 return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST);
499 if (pcert_length == 0)
501 pcert = NULL;
502 local_key = NULL;
504 _gnutls_selected_certs_set (session, pcert, pcert_length, local_key, 0);
506 return 0;
509 else if (cred->get_cert_callback)
511 ret = cred->get_cert_callback (session, issuers_dn, issuers_dn_length,
512 pk_algos, pk_algos_length, &st2);
515 else
516 { /* compatibility mode */
517 gnutls_retr_st st;
518 memset (&st, 0, sizeof (st));
519 if (session->security_parameters.entity == GNUTLS_SERVER)
521 if (cred->server_get_cert_callback == NULL)
523 gnutls_assert ();
524 return GNUTLS_E_INTERNAL_ERROR;
526 ret = cred->server_get_cert_callback (session, &st);
527 if (ret >= 0)
528 st_to_st2 (&st2, &st);
530 else
531 { /* CLIENT */
533 if (cred->client_get_cert_callback == NULL)
535 gnutls_assert ();
536 return GNUTLS_E_INTERNAL_ERROR;
538 ret = cred->client_get_cert_callback (session,
539 issuers_dn, issuers_dn_length,
540 pk_algos, pk_algos_length,
541 &st);
542 if (ret >= 0)
543 st_to_st2 (&st2, &st);
547 if (ret < 0)
549 gnutls_assert ();
550 return GNUTLS_E_USER_ERROR;
553 if (st2.ncerts == 0)
554 return 0; /* no certificate was selected */
556 if (type != st2.cert_type)
558 gnutls_assert ();
559 ret = GNUTLS_E_INVALID_REQUEST;
560 goto cleanup;
564 if (type == GNUTLS_CRT_X509)
566 local_certs = alloc_and_load_x509_certs (st2.cert.x509, st2.ncerts);
568 else
569 { /* PGP */
570 if (st2.ncerts > 1)
572 gnutls_assert ();
573 ret = GNUTLS_E_INVALID_REQUEST;
574 goto cleanup;
576 #ifdef ENABLE_OPENPGP
578 local_certs = alloc_and_load_pgp_certs (st2.cert.pgp);
580 #else
581 ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
582 goto cleanup;
583 #endif
586 if (local_certs == NULL)
588 gnutls_assert ();
589 ret = GNUTLS_E_MEMORY_ERROR;
590 goto cleanup;
593 switch (st2.key_type)
595 case GNUTLS_PRIVKEY_OPENPGP:
596 #ifdef ENABLE_OPENPGP
597 if (st2.key.pgp != NULL)
599 local_key = alloc_and_load_pgp_key (st2.key.pgp, st2.deinit_all);
600 if (local_key == NULL)
602 gnutls_assert ();
603 ret = GNUTLS_E_INTERNAL_ERROR;
604 goto cleanup;
607 #endif
608 break;
609 case GNUTLS_PRIVKEY_PKCS11:
610 #ifdef ENABLE_PKCS11
611 if (st2.key.pkcs11 != NULL)
613 local_key =
614 alloc_and_load_pkcs11_key (st2.key.pkcs11, st2.deinit_all);
615 if (local_key == NULL)
617 gnutls_assert ();
618 ret = GNUTLS_E_INTERNAL_ERROR;
619 goto cleanup;
622 #endif
623 break;
624 case GNUTLS_PRIVKEY_X509:
625 if (st2.key.x509 != NULL)
627 local_key = alloc_and_load_x509_key (st2.key.x509, st2.deinit_all);
628 if (local_key == NULL)
630 gnutls_assert ();
631 ret = GNUTLS_E_INTERNAL_ERROR;
632 goto cleanup;
635 break;
636 default:
637 gnutls_assert();
638 ret = GNUTLS_E_INVALID_REQUEST;
639 goto cleanup;
642 _gnutls_selected_certs_set (session, local_certs,
643 (local_certs != NULL) ? st2.ncerts : 0,
644 local_key, 1);
646 ret = 0;
648 cleanup:
650 if (st2.cert_type == GNUTLS_CRT_X509)
652 if (st2.deinit_all)
654 for (i = 0; i < st2.ncerts; i++)
656 gnutls_x509_crt_deinit (st2.cert.x509[i]);
658 gnutls_free(st2.cert.x509);
661 else
663 #ifdef ENABLE_OPENPGP
664 if (st2.deinit_all)
666 gnutls_openpgp_crt_deinit (st2.cert.pgp);
668 #endif
671 if (ret < 0)
673 if (local_key != NULL)
674 gnutls_privkey_deinit (local_key);
677 return ret;
680 /* Finds the appropriate certificate depending on the cA Distinguished name
681 * advertized by the server. If none matches then returns 0 and -1 as index.
682 * In case of an error a negative error code, is returned.
684 * 20020128: added ability to select a certificate depending on the SIGN
685 * algorithm (only in automatic mode).
687 static int
688 _select_client_cert (gnutls_session_t session,
689 uint8_t * _data, size_t _data_size,
690 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
692 int result;
693 int indx = -1;
694 gnutls_certificate_credentials_t cred;
695 uint8_t *data = _data;
696 ssize_t data_size = _data_size;
697 int issuers_dn_length;
698 gnutls_datum_t *issuers_dn = NULL;
700 cred = (gnutls_certificate_credentials_t)
701 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
702 if (cred == NULL)
704 gnutls_assert ();
705 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
708 if (cred->client_get_cert_callback != NULL
709 || cred->get_cert_callback != NULL || cred->get_cert_callback2 != NULL)
712 /* use a callback to get certificate
714 if (session->security_parameters.cert_type != GNUTLS_CRT_X509)
715 issuers_dn_length = 0;
716 else
718 issuers_dn_length = get_issuers_num (session, data, data_size);
719 if (issuers_dn_length < 0)
721 gnutls_assert ();
722 return issuers_dn_length;
725 if (issuers_dn_length > 0)
727 issuers_dn =
728 gnutls_malloc (sizeof (gnutls_datum_t) * issuers_dn_length);
729 if (issuers_dn == NULL)
731 gnutls_assert ();
732 return GNUTLS_E_MEMORY_ERROR;
735 result =
736 get_issuers (session, issuers_dn, issuers_dn_length,
737 data, data_size);
738 if (result < 0)
740 gnutls_assert ();
741 goto cleanup;
746 result =
747 call_get_cert_callback (session, issuers_dn, issuers_dn_length,
748 pk_algos, pk_algos_length);
749 goto cleanup;
752 else
754 /* If we have no callbacks, try to guess.
756 result = 0;
758 if (session->security_parameters.cert_type == GNUTLS_CRT_X509)
759 result =
760 _find_x509_cert (cred, _data, _data_size,
761 pk_algos, pk_algos_length, &indx);
762 #ifdef ENABLE_OPENPGP
763 else if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP)
764 result = _find_openpgp_cert (cred, pk_algos, pk_algos_length, &indx);
765 #endif
767 if (result < 0)
769 gnutls_assert ();
770 return result;
773 if (indx >= 0)
775 _gnutls_selected_certs_set (session,
776 &cred->certs[indx].cert_list[0],
777 cred->certs[indx].cert_list_length,
778 cred->pkey[indx], 0);
780 else
782 _gnutls_selected_certs_set (session, NULL, 0, NULL, 0);
785 result = 0;
788 cleanup:
789 gnutls_free (issuers_dn);
790 return result;
794 /* Generate client certificate
797 static int
798 _gnutls_gen_x509_crt (gnutls_session_t session, gnutls_buffer_st * data)
800 int ret, i;
801 gnutls_pcert_st *apr_cert_list;
802 gnutls_privkey_t apr_pkey;
803 int apr_cert_list_length;
805 /* find the appropriate certificate
807 if ((ret =
808 _gnutls_get_selected_cert (session, &apr_cert_list,
809 &apr_cert_list_length, &apr_pkey)) < 0)
811 gnutls_assert ();
812 return ret;
815 ret = 3;
816 for (i = 0; i < apr_cert_list_length; i++)
818 ret += apr_cert_list[i].cert.size + 3;
819 /* hold size
820 * for uint24 */
823 /* if no certificates were found then send:
824 * 0B 00 00 03 00 00 00 // Certificate with no certs
825 * instead of:
826 * 0B 00 00 00 // empty certificate handshake
828 * ( the above is the whole handshake message, not
829 * the one produced here )
832 ret = _gnutls_buffer_append_prefix (data, 24, ret - 3);
833 if (ret < 0)
834 return gnutls_assert_val (ret);
836 for (i = 0; i < apr_cert_list_length; i++)
838 ret =
839 _gnutls_buffer_append_data_prefix (data, 24,
840 apr_cert_list[i].cert.data,
841 apr_cert_list[i].cert.size);
842 if (ret < 0)
843 return gnutls_assert_val (ret);
846 return data->length;
849 enum PGPKeyDescriptorType
850 { PGP_KEY_FINGERPRINT, PGP_KEY, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
852 #ifdef ENABLE_OPENPGP
853 static int
854 _gnutls_gen_openpgp_certificate (gnutls_session_t session,
855 gnutls_buffer_st * data)
857 int ret;
858 gnutls_pcert_st *apr_cert_list;
859 gnutls_privkey_t apr_pkey;
860 int apr_cert_list_length;
861 uint8_t type;
862 uint8_t fpr[20];
863 size_t fpr_size;
864 unsigned int use_subkey = 0;
866 /* find the appropriate certificate */
867 if ((ret =
868 _gnutls_get_selected_cert (session, &apr_cert_list,
869 &apr_cert_list_length, &apr_pkey)) < 0)
871 gnutls_assert ();
872 return ret;
875 ret = 3 + 1 + 3;
879 if (apr_cert_list_length > 0)
881 fpr_size = sizeof (fpr);
882 ret =
883 gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
884 &fpr_size, &use_subkey);
885 if (ret < 0)
886 return gnutls_assert_val (ret);
888 if (use_subkey != 0)
889 ret += 1 + fpr_size; /* for the keyid */
891 ret += apr_cert_list[0].cert.size;
894 ret = _gnutls_buffer_append_prefix (data, 24, ret - 3);
895 if (ret < 0)
896 return gnutls_assert_val (ret);
899 if (apr_cert_list_length > 0)
901 if (use_subkey != 0)
903 type = PGP_KEY_SUBKEY;
905 ret = _gnutls_buffer_append_data (data, &type, 1);
906 if (ret < 0)
907 return gnutls_assert_val (ret);
909 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
910 if (ret < 0)
911 return gnutls_assert_val (ret);
913 else
915 type = PGP_KEY;
916 ret = _gnutls_buffer_append_data (data, &type, 1);
917 if (ret < 0)
918 return gnutls_assert_val (ret);
921 ret =
922 _gnutls_buffer_append_data_prefix (data, 24,
923 apr_cert_list[0].cert.data,
924 apr_cert_list[0].cert.size);
925 if (ret < 0)
926 return gnutls_assert_val (ret);
928 else /* empty - no certificate */
930 type = PGP_KEY;
932 ret = _gnutls_buffer_append_data (data, &type, 1);
933 if (ret < 0)
934 return gnutls_assert_val (ret);
936 ret = _gnutls_buffer_append_prefix (data, 24, 0);
937 if (ret < 0)
938 return gnutls_assert_val (ret);
941 return data->length;
944 static int
945 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session,
946 gnutls_buffer_st * data)
948 int ret, packet_size;
949 uint8_t type, fpr[20];
950 size_t fpr_size;
951 gnutls_pcert_st *apr_cert_list;
952 gnutls_privkey_t apr_pkey;
953 int apr_cert_list_length;
954 unsigned int use_subkey = 0;
956 /* find the appropriate certificate */
957 if ((ret =
958 _gnutls_get_selected_cert (session, &apr_cert_list,
959 &apr_cert_list_length, &apr_pkey)) < 0)
961 gnutls_assert ();
962 return ret;
965 fpr_size = sizeof (fpr);
966 ret =
967 gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
968 &fpr_size, &use_subkey);
969 if (ret < 0)
970 return gnutls_assert_val (ret);
972 packet_size = 3 + 1;
974 if (use_subkey)
975 packet_size += 1 + fpr_size; /* for the keyid */
977 /* Only v4 fingerprints are sent
979 if (apr_cert_list_length > 0)
980 packet_size += 20 + 1;
981 else /* empty certificate case */
982 return _gnutls_gen_openpgp_certificate (session, data);
984 ret = _gnutls_buffer_append_prefix (data, 24, packet_size - 3);
985 if (ret < 0)
986 return gnutls_assert_val (ret);
988 if (use_subkey)
990 type = PGP_KEY_FINGERPRINT_SUBKEY;
991 ret = _gnutls_buffer_append_data (data, &type, 1);
992 if (ret < 0)
993 return gnutls_assert_val (ret);
995 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
996 if (ret < 0)
997 return gnutls_assert_val (ret);
999 else
1001 type = PGP_KEY_FINGERPRINT; /* key fingerprint */
1002 ret = _gnutls_buffer_append_data (data, &type, 1);
1003 if (ret < 0)
1004 return gnutls_assert_val (ret);
1007 fpr_size = sizeof (fpr);
1008 if ((ret =
1009 _gnutls_openpgp_fingerprint (&apr_cert_list[0].cert, fpr,
1010 &fpr_size)) < 0)
1012 gnutls_assert ();
1013 return ret;
1016 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
1017 if (ret < 0)
1018 return gnutls_assert_val (ret);
1020 return data->length;
1022 #endif
1026 _gnutls_gen_cert_client_certificate (gnutls_session_t session,
1027 gnutls_buffer_st * data)
1029 switch (session->security_parameters.cert_type)
1031 #ifdef ENABLE_OPENPGP
1032 case GNUTLS_CRT_OPENPGP:
1033 if (_gnutls_openpgp_send_fingerprint (session) == 0)
1034 return _gnutls_gen_openpgp_certificate (session, data);
1035 else
1036 return _gnutls_gen_openpgp_certificate_fpr (session, data);
1037 #endif
1038 case GNUTLS_CRT_X509:
1039 return _gnutls_gen_x509_crt (session, data);
1041 default:
1042 gnutls_assert ();
1043 return GNUTLS_E_INTERNAL_ERROR;
1048 _gnutls_gen_cert_server_certificate (gnutls_session_t session,
1049 gnutls_buffer_st * data)
1051 switch (session->security_parameters.cert_type)
1053 #ifdef ENABLE_OPENPGP
1054 case GNUTLS_CRT_OPENPGP:
1055 return _gnutls_gen_openpgp_certificate (session, data);
1056 #endif
1057 case GNUTLS_CRT_X509:
1058 return _gnutls_gen_x509_crt (session, data);
1059 default:
1060 gnutls_assert ();
1061 return GNUTLS_E_INTERNAL_ERROR;
1065 /* Process server certificate
1068 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) gnutls_pcert_deinit(&peer_certificate_list[x])
1069 static int
1070 _gnutls_proc_x509_server_certificate (gnutls_session_t session,
1071 uint8_t * data, size_t data_size)
1073 int size, len, ret;
1074 uint8_t *p = data;
1075 cert_auth_info_t info;
1076 gnutls_certificate_credentials_t cred;
1077 ssize_t dsize = data_size;
1078 int i;
1079 gnutls_pcert_st *peer_certificate_list;
1080 size_t peer_certificate_list_size = 0, j, x;
1081 gnutls_datum_t tmp;
1083 cred = (gnutls_certificate_credentials_t)
1084 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1085 if (cred == NULL)
1087 gnutls_assert ();
1088 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1092 if ((ret =
1093 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1094 sizeof (cert_auth_info_st), 1)) < 0)
1096 gnutls_assert ();
1097 return ret;
1100 info = _gnutls_get_auth_info (session);
1102 if (data == NULL || data_size == 0)
1104 gnutls_assert ();
1105 /* no certificate was sent */
1106 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1109 DECR_LEN (dsize, 3);
1110 size = _gnutls_read_uint24 (p);
1111 p += 3;
1113 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
1114 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
1116 if (size == 0 || size == 3)
1118 gnutls_assert ();
1119 /* no certificate was sent */
1120 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1123 i = dsize;
1124 while (i > 0)
1126 DECR_LEN (dsize, 3);
1127 len = _gnutls_read_uint24 (p);
1128 p += 3;
1129 DECR_LEN (dsize, len);
1130 peer_certificate_list_size++;
1131 p += len;
1132 i -= len + 3;
1135 if (peer_certificate_list_size == 0)
1137 gnutls_assert ();
1138 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1141 /* Ok we now allocate the memory to hold the
1142 * certificate list
1145 peer_certificate_list =
1146 gnutls_calloc (1,
1147 sizeof (gnutls_pcert_st) * (peer_certificate_list_size));
1148 if (peer_certificate_list == NULL)
1150 gnutls_assert ();
1151 return GNUTLS_E_MEMORY_ERROR;
1154 p = data + 3;
1156 /* Now we start parsing the list (again).
1157 * We don't use DECR_LEN since the list has
1158 * been parsed before.
1161 for (j = 0; j < peer_certificate_list_size; j++)
1163 len = _gnutls_read_uint24 (p);
1164 p += 3;
1166 tmp.size = len;
1167 tmp.data = p;
1169 ret =
1170 gnutls_pcert_import_x509_raw (&peer_certificate_list
1171 [j], &tmp, GNUTLS_X509_FMT_DER, 0);
1172 if (ret < 0)
1174 gnutls_assert ();
1175 peer_certificate_list_size = j;
1176 goto cleanup;
1179 p += len;
1183 if ((ret =
1184 _gnutls_copy_certificate_auth_info (info,
1185 peer_certificate_list,
1186 peer_certificate_list_size, 0,
1187 NULL)) < 0)
1189 gnutls_assert ();
1190 goto cleanup;
1193 if ((ret =
1194 _gnutls_check_key_usage (&peer_certificate_list[0],
1195 gnutls_kx_get (session))) < 0)
1197 gnutls_assert ();
1198 goto cleanup;
1201 ret = 0;
1203 cleanup:
1204 CLEAR_CERTS;
1205 gnutls_free (peer_certificate_list);
1206 return ret;
1210 #ifdef ENABLE_OPENPGP
1211 static int
1212 _gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
1213 uint8_t * data, size_t data_size)
1215 int size, ret, len;
1216 uint8_t *p = data;
1217 cert_auth_info_t info;
1218 gnutls_certificate_credentials_t cred;
1219 ssize_t dsize = data_size;
1220 int x, key_type;
1221 gnutls_pcert_st *peer_certificate_list = NULL;
1222 int peer_certificate_list_size = 0;
1223 gnutls_datum_t tmp, akey = { NULL, 0 };
1224 uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE];
1225 unsigned int subkey_id_set = 0;
1227 cred = (gnutls_certificate_credentials_t)
1228 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1229 if (cred == NULL)
1231 gnutls_assert ();
1232 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1235 if ((ret =
1236 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1237 sizeof (cert_auth_info_st), 1)) < 0)
1239 gnutls_assert ();
1240 return ret;
1243 info = _gnutls_get_auth_info (session);
1245 if (data == NULL || data_size == 0)
1247 gnutls_assert ();
1248 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1251 DECR_LEN (dsize, 3);
1252 size = _gnutls_read_uint24 (p);
1253 p += 3;
1255 if (size == 0)
1257 gnutls_assert ();
1258 /* no certificate was sent */
1259 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1262 /* Read PGPKeyDescriptor */
1263 DECR_LEN (dsize, 1);
1264 key_type = *p;
1265 p++;
1267 /* Try to read the keyid if present */
1268 if (key_type == PGP_KEY_FINGERPRINT_SUBKEY || key_type == PGP_KEY_SUBKEY)
1270 /* check size */
1271 if (*p != GNUTLS_OPENPGP_KEYID_SIZE)
1273 gnutls_assert ();
1274 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1277 DECR_LEN (dsize, 1);
1278 p++;
1280 DECR_LEN (dsize, GNUTLS_OPENPGP_KEYID_SIZE);
1281 memcpy (subkey_id, p, GNUTLS_OPENPGP_KEYID_SIZE);
1282 p += GNUTLS_OPENPGP_KEYID_SIZE;
1284 subkey_id_set = 1;
1288 /* read the actual key or fingerprint */
1289 if (key_type == PGP_KEY_FINGERPRINT
1290 || key_type == PGP_KEY_FINGERPRINT_SUBKEY)
1291 { /* the fingerprint */
1293 DECR_LEN (dsize, 1);
1294 len = (uint8_t) * p;
1295 p++;
1297 if (len != 20)
1299 gnutls_assert ();
1300 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED;
1303 DECR_LEN (dsize, 20);
1305 /* request the actual key from our database, or
1306 * a key server or anything.
1308 if ((ret =
1309 _gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
1311 gnutls_assert ();
1312 return ret;
1314 tmp = akey;
1315 peer_certificate_list_size++;
1318 else if (key_type == PGP_KEY || key_type == PGP_KEY_SUBKEY)
1319 { /* the whole key */
1321 /* Read the actual certificate */
1322 DECR_LEN (dsize, 3);
1323 len = _gnutls_read_uint24 (p);
1324 p += 3;
1326 if (len == 0)
1328 gnutls_assert ();
1329 /* no certificate was sent */
1330 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1333 DECR_LEN (dsize, len);
1334 peer_certificate_list_size++;
1336 tmp.size = len;
1337 tmp.data = p;
1340 else
1342 gnutls_assert ();
1343 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1346 /* ok we now have the peer's key in tmp datum
1349 if (peer_certificate_list_size == 0)
1351 gnutls_assert ();
1352 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1355 peer_certificate_list =
1356 gnutls_calloc (1,
1357 sizeof (gnutls_pcert_st) * (peer_certificate_list_size));
1358 if (peer_certificate_list == NULL)
1360 gnutls_assert ();
1361 ret = GNUTLS_E_MEMORY_ERROR;
1362 goto cleanup;
1365 ret =
1366 gnutls_pcert_import_openpgp_raw (&peer_certificate_list[0],
1367 &tmp,
1368 GNUTLS_OPENPGP_FMT_RAW,
1369 (subkey_id_set != 0) ? subkey_id : NULL,
1371 if (ret < 0)
1373 gnutls_assert ();
1374 goto cleanup;
1377 ret =
1378 _gnutls_copy_certificate_auth_info (info,
1379 peer_certificate_list,
1380 peer_certificate_list_size,
1381 subkey_id_set,
1382 (subkey_id_set !=
1383 0) ? subkey_id : NULL);
1384 if (ret < 0)
1386 gnutls_assert ();
1387 goto cleanup;
1390 if ((ret =
1391 _gnutls_check_key_usage (&peer_certificate_list[0],
1392 gnutls_kx_get (session))) < 0)
1394 gnutls_assert ();
1395 goto cleanup;
1398 ret = 0;
1400 cleanup:
1402 _gnutls_free_datum (&akey);
1403 CLEAR_CERTS;
1404 gnutls_free (peer_certificate_list);
1405 return ret;
1408 #endif
1411 _gnutls_proc_certificate (gnutls_session_t session,
1412 uint8_t * data, size_t data_size)
1414 int ret;
1415 gnutls_certificate_credentials_t cred;
1417 cred =
1418 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
1419 GNUTLS_CRD_CERTIFICATE,
1420 NULL);
1421 if (cred == NULL)
1423 gnutls_assert ();
1424 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1427 switch (session->security_parameters.cert_type)
1429 #ifdef ENABLE_OPENPGP
1430 case GNUTLS_CRT_OPENPGP:
1431 ret = _gnutls_proc_openpgp_server_certificate (session,
1432 data, data_size);
1433 break;
1434 #endif
1435 case GNUTLS_CRT_X509:
1436 ret = _gnutls_proc_x509_server_certificate (session, data, data_size);
1437 break;
1438 default:
1439 gnutls_assert ();
1440 return GNUTLS_E_INTERNAL_ERROR;
1443 if (ret == 0 && cred->verify_callback != NULL)
1445 ret = cred->verify_callback (session);
1446 if (ret != 0)
1447 ret = GNUTLS_E_CERTIFICATE_ERROR;
1450 return ret;
1454 /* Checks if we support the given signature algorithm
1455 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1456 * if true;
1458 inline static int
1459 _gnutls_check_supported_sign_algo (CertificateSigType algo)
1461 switch (algo)
1463 case RSA_SIGN:
1464 return GNUTLS_PK_RSA;
1465 case DSA_SIGN:
1466 return GNUTLS_PK_DSA;
1467 case ECDSA_SIGN:
1468 return GNUTLS_PK_EC;
1471 return -1;
1475 _gnutls_proc_cert_cert_req (gnutls_session_t session, uint8_t * data,
1476 size_t data_size)
1478 int size, ret;
1479 uint8_t *p;
1480 gnutls_certificate_credentials_t cred;
1481 ssize_t dsize;
1482 int i;
1483 gnutls_pk_algorithm_t pk_algos[MAX_CLIENT_SIGN_ALGOS];
1484 int pk_algos_length;
1485 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1487 cred = (gnutls_certificate_credentials_t)
1488 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1489 if (cred == NULL)
1491 gnutls_assert ();
1492 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1495 if ((ret =
1496 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1497 sizeof (cert_auth_info_st), 0)) < 0)
1499 gnutls_assert ();
1500 return ret;
1503 p = data;
1504 dsize = data_size;
1506 DECR_LEN (dsize, 1);
1507 size = p[0];
1508 p++;
1509 /* check if the sign algorithm is supported.
1511 pk_algos_length = 0;
1512 for (i = 0; i < size; i++, p++)
1514 DECR_LEN (dsize, 1);
1515 if ((ret = _gnutls_check_supported_sign_algo (*p)) > 0)
1517 if (pk_algos_length < MAX_CLIENT_SIGN_ALGOS)
1519 pk_algos[pk_algos_length++] = ret;
1524 if (pk_algos_length == 0)
1526 gnutls_assert ();
1527 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1530 if (_gnutls_version_has_selectable_sighash (ver))
1532 /* read supported hashes */
1533 int hash_num;
1534 DECR_LEN (dsize, 2);
1535 hash_num = _gnutls_read_uint16 (p);
1536 p += 2;
1537 DECR_LEN (dsize, hash_num);
1539 ret = _gnutls_sign_algorithm_parse_data (session, p, hash_num);
1540 if (ret < 0)
1542 gnutls_assert ();
1543 return ret;
1546 p += hash_num;
1549 /* read the certificate authorities */
1550 DECR_LEN (dsize, 2);
1551 size = _gnutls_read_uint16 (p);
1552 p += 2;
1554 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP
1555 && size != 0)
1557 gnutls_assert ();
1558 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1561 DECR_LEN (dsize, size);
1563 /* now we ask the user to tell which one
1564 * he wants to use.
1566 if ((ret =
1567 _select_client_cert (session, p, size, pk_algos, pk_algos_length)) < 0)
1569 gnutls_assert ();
1570 return ret;
1573 /* We should reply with a certificate message,
1574 * even if we have no certificate to send.
1576 session->key->certificate_requested = 1;
1578 return 0;
1582 _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session,
1583 gnutls_buffer_st * data)
1585 int ret;
1586 gnutls_pcert_st *apr_cert_list;
1587 gnutls_privkey_t apr_pkey;
1588 int apr_cert_list_length;
1589 gnutls_datum_t signature = { NULL, 0 };
1590 int total_data;
1591 gnutls_sign_algorithm_t sign_algo;
1592 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1594 /* find the appropriate certificate */
1595 if ((ret =
1596 _gnutls_get_selected_cert (session, &apr_cert_list,
1597 &apr_cert_list_length, &apr_pkey)) < 0)
1599 gnutls_assert ();
1600 return ret;
1603 if (apr_cert_list_length > 0)
1605 if ((ret =
1606 _gnutls_handshake_sign_cert_vrfy (session,
1607 &apr_cert_list[0],
1608 apr_pkey, &signature)) < 0)
1610 gnutls_assert ();
1611 return ret;
1613 sign_algo = ret;
1615 else
1617 return 0;
1620 total_data = signature.size + 2;
1622 /* add hash and signature algorithms */
1623 if (_gnutls_version_has_selectable_sighash (ver))
1625 total_data += 2;
1628 if (_gnutls_version_has_selectable_sighash (ver))
1630 const sign_algorithm_st *aid;
1631 uint8_t p[2];
1632 /* error checking is not needed here since we have used those algorithms */
1633 aid = _gnutls_sign_to_tls_aid (sign_algo);
1634 if (aid == NULL)
1635 return gnutls_assert_val (GNUTLS_E_UNKNOWN_ALGORITHM);
1637 p[0] = aid->hash_algorithm;
1638 p[1] = aid->sign_algorithm;
1639 ret = _gnutls_buffer_append_data (data, p, 2);
1640 if (ret < 0)
1642 gnutls_assert ();
1643 goto cleanup;
1647 ret =
1648 _gnutls_buffer_append_data_prefix (data, 16, signature.data,
1649 signature.size);
1650 if (ret < 0)
1652 gnutls_assert ();
1653 goto cleanup;
1656 ret = data->length;
1658 cleanup:
1659 _gnutls_free_datum (&signature);
1660 return ret;
1664 _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session,
1665 uint8_t * data, size_t data_size)
1667 int size, ret;
1668 ssize_t dsize = data_size;
1669 uint8_t *pdata = data;
1670 gnutls_datum_t sig;
1671 cert_auth_info_t info = _gnutls_get_auth_info (session);
1672 gnutls_pcert_st peer_cert;
1673 gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
1674 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1676 if (info == NULL || info->ncerts == 0)
1678 gnutls_assert ();
1679 /* we need this in order to get peer's certificate */
1680 return GNUTLS_E_INTERNAL_ERROR;
1683 if (_gnutls_version_has_selectable_sighash (ver))
1685 sign_algorithm_st aid;
1687 DECR_LEN (dsize, 2);
1688 aid.hash_algorithm = pdata[0];
1689 aid.sign_algorithm = pdata[1];
1691 sign_algo = _gnutls_tls_aid_to_sign (&aid);
1692 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
1694 gnutls_assert ();
1695 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1697 pdata += 2;
1700 ret = _gnutls_session_sign_algo_enabled (session, sign_algo);
1701 if (ret < 0)
1703 gnutls_assert ();
1704 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1707 DECR_LEN (dsize, 2);
1708 size = _gnutls_read_uint16 (pdata);
1709 pdata += 2;
1711 DECR_LEN (dsize, size);
1713 sig.data = pdata;
1714 sig.size = size;
1716 ret = _gnutls_get_auth_info_pcert (&peer_cert,
1717 session->security_parameters.cert_type,
1718 info);
1720 if (ret < 0)
1722 gnutls_assert ();
1723 return ret;
1726 if ((ret =
1727 _gnutls_handshake_verify_cert_vrfy (session, &peer_cert, &sig,
1728 sign_algo)) < 0)
1730 gnutls_assert ();
1731 gnutls_pcert_deinit (&peer_cert);
1732 return ret;
1734 gnutls_pcert_deinit (&peer_cert);
1736 return 0;
1740 _gnutls_gen_cert_server_cert_req (gnutls_session_t session,
1741 gnutls_buffer_st * data)
1743 gnutls_certificate_credentials_t cred;
1744 int size, ret;
1745 uint8_t tmp_data[CERTTYPE_SIZE];
1746 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1748 /* Now we need to generate the RDN sequence. This is
1749 * already in the CERTIFICATE_CRED structure, to improve
1750 * performance.
1753 cred = (gnutls_certificate_credentials_t)
1754 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1755 if (cred == NULL)
1757 gnutls_assert ();
1758 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1761 size = CERTTYPE_SIZE + 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1764 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1765 session->internals.ignore_rdn_sequence == 0)
1766 size += cred->x509_rdn_sequence.size;
1768 if (_gnutls_version_has_selectable_sighash (ver))
1769 /* Need two bytes to announce the number of supported hash
1770 functions (see below). */
1771 size += MAX_SIGN_ALGO_SIZE;
1773 tmp_data[0] = CERTTYPE_SIZE - 1;
1774 tmp_data[1] = RSA_SIGN;
1775 tmp_data[2] = DSA_SIGN;
1776 tmp_data[3] = ECDSA_SIGN; /* only these for now */
1778 ret = _gnutls_buffer_append_data (data, tmp_data, CERTTYPE_SIZE);
1779 if (ret < 0)
1780 return gnutls_assert_val (ret);
1782 if (_gnutls_version_has_selectable_sighash (ver))
1784 uint8_t p[MAX_SIGN_ALGO_SIZE];
1786 ret =
1787 _gnutls_sign_algorithm_write_params (session, p, MAX_SIGN_ALGO_SIZE);
1788 if (ret < 0)
1790 gnutls_assert ();
1791 return ret;
1794 /* recalculate size */
1795 size -= MAX_SIGN_ALGO_SIZE + ret;
1797 ret = _gnutls_buffer_append_data (data, p, ret);
1798 if (ret < 0)
1799 return gnutls_assert_val (ret);
1802 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1803 session->internals.ignore_rdn_sequence == 0)
1805 ret =
1806 _gnutls_buffer_append_data_prefix (data, 16,
1807 cred->x509_rdn_sequence.data,
1808 cred->x509_rdn_sequence.size);
1809 if (ret < 0)
1810 return gnutls_assert_val (ret);
1812 else
1814 ret = _gnutls_buffer_append_prefix (data, 16, 0);
1815 if (ret < 0)
1816 return gnutls_assert_val (ret);
1819 return data->length;
1823 /* This function will return the appropriate certificate to use.
1824 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1825 * The return value is a negative error code on error.
1827 * It is normal to return 0 with no certificates in client side.
1831 _gnutls_get_selected_cert (gnutls_session_t session,
1832 gnutls_pcert_st ** apr_cert_list,
1833 int *apr_cert_list_length,
1834 gnutls_privkey_t * apr_pkey)
1836 if (session->security_parameters.entity == GNUTLS_SERVER)
1839 /* select_client_cert() has been called before.
1842 *apr_cert_list = session->internals.selected_cert_list;
1843 *apr_pkey = session->internals.selected_key;
1844 *apr_cert_list_length = session->internals.selected_cert_list_length;
1846 if (*apr_cert_list_length == 0 || *apr_cert_list == NULL)
1848 gnutls_assert ();
1849 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1853 else
1854 { /* CLIENT SIDE
1857 /* we have already decided which certificate
1858 * to send.
1860 *apr_cert_list = session->internals.selected_cert_list;
1861 *apr_cert_list_length = session->internals.selected_cert_list_length;
1862 *apr_pkey = session->internals.selected_key;
1866 return 0;
1869 /* converts the given x509 certificate list to gnutls_pcert_st* and allocates
1870 * space for them.
1872 static gnutls_pcert_st *
1873 alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, unsigned ncerts)
1875 gnutls_pcert_st *local_certs;
1876 int ret = 0;
1877 unsigned i, j;
1879 if (certs == NULL)
1880 return NULL;
1882 local_certs = gnutls_malloc (sizeof (gnutls_pcert_st) * ncerts);
1883 if (local_certs == NULL)
1885 gnutls_assert ();
1886 return NULL;
1889 for (i = 0; i < ncerts; i++)
1891 ret = gnutls_pcert_import_x509 (&local_certs[i], certs[i], 0);
1892 if (ret < 0)
1893 break;
1896 if (ret < 0)
1898 gnutls_assert ();
1899 for (j = 0; j < i; j++)
1901 gnutls_pcert_deinit (&local_certs[j]);
1903 gnutls_free (local_certs);
1904 return NULL;
1907 return local_certs;
1910 /* converts the given x509 key to gnutls_privkey* and allocates
1911 * space for it.
1913 static gnutls_privkey_t
1914 alloc_and_load_x509_key (gnutls_x509_privkey_t key, int deinit)
1916 gnutls_privkey_t local_key;
1917 int ret = 0;
1919 if (key == NULL)
1920 return NULL;
1922 ret = gnutls_privkey_init (&local_key);
1923 if (ret < 0)
1925 gnutls_assert ();
1926 return NULL;
1929 ret =
1930 gnutls_privkey_import_x509 (local_key, key,
1931 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE :
1933 if (ret < 0)
1935 gnutls_assert ();
1936 gnutls_privkey_deinit (local_key);
1937 return NULL;
1940 return local_key;
1943 /* converts the given pgp certificate to gnutls_cert* and allocates
1944 * space for them.
1946 #ifdef ENABLE_OPENPGP
1947 static gnutls_pcert_st *
1948 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
1950 gnutls_pcert_st *local_certs;
1951 int ret = 0;
1953 if (cert == NULL)
1954 return NULL;
1956 local_certs = gnutls_malloc (sizeof (gnutls_pcert_st));
1957 if (local_certs == NULL)
1959 gnutls_assert ();
1960 return NULL;
1963 ret = gnutls_pcert_import_openpgp (local_certs, cert, 0);
1964 if (ret < 0)
1966 gnutls_assert ();
1967 return NULL;
1970 if (ret < 0)
1972 gnutls_assert ();
1973 gnutls_pcert_deinit (local_certs);
1974 gnutls_free (local_certs);
1975 return NULL;
1978 return local_certs;
1981 /* converts the given raw key to gnutls_privkey* and allocates
1982 * space for it.
1984 static gnutls_privkey_t
1985 alloc_and_load_pgp_key (gnutls_openpgp_privkey_t key, int deinit)
1987 gnutls_privkey_t local_key;
1988 int ret = 0;
1990 if (key == NULL)
1991 return NULL;
1993 ret = gnutls_privkey_init (&local_key);
1994 if (ret < 0)
1996 gnutls_assert ();
1997 return NULL;
2000 ret =
2001 gnutls_privkey_import_openpgp (local_key, key,
2002 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
2003 : 0);
2004 if (ret < 0)
2006 gnutls_assert ();
2007 gnutls_privkey_deinit (local_key);
2008 return NULL;
2011 return local_key;
2013 #endif
2015 #ifdef ENABLE_PKCS11
2017 /* converts the given raw key to gnutls_privkey* and allocates
2018 * space for it.
2020 static gnutls_privkey_t
2021 alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t key, int deinit)
2023 gnutls_privkey_t local_key;
2024 int ret = 0;
2026 if (key == NULL)
2027 return NULL;
2029 ret = gnutls_privkey_init (&local_key);
2030 if (ret < 0)
2032 gnutls_assert ();
2033 return NULL;
2036 ret =
2037 gnutls_privkey_import_pkcs11 (local_key, key,
2038 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
2039 : 0);
2040 if (ret < 0)
2042 gnutls_assert ();
2043 gnutls_privkey_deinit (local_key);
2044 return NULL;
2047 return local_key;
2050 #endif
2052 void
2053 _gnutls_selected_certs_deinit (gnutls_session_t session)
2055 if (session->internals.selected_need_free != 0)
2057 int i;
2059 for (i = 0; i < session->internals.selected_cert_list_length; i++)
2061 gnutls_pcert_deinit (&session->internals.selected_cert_list[i]);
2063 gnutls_free (session->internals.selected_cert_list);
2064 session->internals.selected_cert_list = NULL;
2065 session->internals.selected_cert_list_length = 0;
2067 gnutls_privkey_deinit(session->internals.selected_key);
2068 session->internals.selected_key = NULL;
2071 return;
2074 void
2075 _gnutls_selected_certs_set (gnutls_session_t session,
2076 gnutls_pcert_st * certs, int ncerts,
2077 gnutls_privkey_t key, int need_free)
2079 _gnutls_selected_certs_deinit (session);
2081 session->internals.selected_cert_list = certs;
2082 session->internals.selected_cert_list_length = ncerts;
2083 session->internals.selected_key = key;
2084 session->internals.selected_need_free = need_free;
2088 static void get_server_name(gnutls_session_t session, uint8_t* name, size_t max_name_size)
2090 int ret, i;
2091 size_t max_name;
2092 unsigned int type;
2094 ret = 0;
2095 for (i=0; !(ret<0);i++)
2097 max_name = max_name_size;
2098 ret = gnutls_server_name_get (session, name, &max_name, &type, i);
2099 if (ret >= 0 && type == GNUTLS_NAME_DNS)
2100 return;
2103 name[0] = 0;
2105 return;
2108 /* finds the most appropriate certificate in the cert list.
2109 * The 'appropriate' is defined by the user.
2111 * requested_algo holds the parameters required by the peer (RSA, DSA
2112 * or -1 for any).
2114 * Returns 0 on success and a negative error code on error. The
2115 * selected certificate will be in session->internals.selected_*.
2119 _gnutls_server_select_cert (gnutls_session_t session,
2120 gnutls_pk_algorithm_t * pk_algos,
2121 size_t pk_algos_size)
2123 unsigned i, j;
2124 int idx, ret;
2125 gnutls_certificate_credentials_t cred;
2126 char server_name[MAX_CN];
2128 cred = (gnutls_certificate_credentials_t)
2129 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
2130 if (cred == NULL)
2132 gnutls_assert ();
2133 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2136 /* If the callback which retrieves certificate has been set,
2137 * use it and leave.
2139 if (cred->server_get_cert_callback || cred->get_cert_callback
2140 || cred->get_cert_callback2)
2142 ret = call_get_cert_callback (session, NULL, 0, NULL, 0);
2143 if (ret < 0)
2144 return gnutls_assert_val (ret);
2145 return ret;
2148 /* Otherwise... */
2150 get_server_name(session, (unsigned char*)server_name, sizeof(server_name));
2152 idx = -1; /* default is use no certificate */
2154 /* find certificates that match the requested server_name
2157 if (server_name[0] != 0)
2159 for (i = 0; i < cred->ncerts; i++)
2161 if (cred->certs[i].names != NULL && _gnutls_str_array_match(cred->certs[i].names, server_name) != 0)
2163 /* if requested algorithms are also compatible select it */
2164 gnutls_pk_algorithm pk =
2165 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
2166 NULL);
2168 _gnutls_handshake_log("HSK[%p]: Requested server name: '%s', ctype: %s (%d)", session, server_name,
2169 gnutls_certificate_type_get_name (session->security_parameters.cert_type),
2170 session->security_parameters.cert_type);
2172 if (session->security_parameters.cert_type == cred->certs[i].cert_list[0].type)
2174 for (j = 0; j < pk_algos_size; j++)
2175 if (pk_algos[j] == pk)
2177 idx = i;
2178 goto finished;
2185 for (j = 0; j < pk_algos_size; j++)
2187 _gnutls_handshake_log
2188 ("HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n",
2189 session, gnutls_pk_get_name (pk_algos[j]), pk_algos[j],
2190 gnutls_certificate_type_get_name (session->security_parameters.
2191 cert_type),
2192 session->security_parameters.cert_type);
2194 for (i = 0; i < cred->ncerts; i++)
2196 gnutls_pk_algorithm pk =
2197 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
2198 NULL);
2199 /* find one compatible certificate
2201 _gnutls_handshake_log
2202 ("HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n",
2203 session, i, gnutls_pk_get_name (pk), pk,
2204 gnutls_certificate_type_get_name (cred->certs[i].cert_list[0].type),
2205 cred->certs[i].cert_list[0].type);
2207 if (pk_algos[j] == pk)
2209 /* if cert type matches
2211 /* *INDENT-OFF* */
2212 if (session->security_parameters.cert_type == cred->certs[i].cert_list[0].type)
2214 idx = i;
2215 goto finished;
2217 /* *INDENT-ON* */
2222 /* store the certificate pointer for future use, in the handshake.
2223 * (This will allow not calling this callback again.)
2225 finished:
2226 if (idx >= 0)
2228 _gnutls_selected_certs_set (session,
2229 &cred->certs[idx].cert_list[0],
2230 cred->certs[idx].cert_list_length,
2231 cred->pkey[idx], 0);
2233 else
2235 gnutls_assert ();
2236 /* Certificate does not support REQUESTED_ALGO. */
2237 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2240 return 0;
2243 /* Frees the rsa_info_st structure.
2245 void
2246 _gnutls_free_rsa_info (rsa_info_st * rsa)
2248 _gnutls_free_datum (&rsa->modulus);
2249 _gnutls_free_datum (&rsa->exponent);