check for either iconv or libiconv.
[gnutls.git] / lib / auth / cert.c
blobb431b0addfaf27ef2b707a3bf1bb229aafd5b3ed
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, /* 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 if (keyid)
127 memcpy (info->subkey_id, keyid, GNUTLS_OPENPGP_KEYID_SIZE);
129 #endif
131 return 0;
133 clear:
135 for (j = 0; j < i; j++)
136 _gnutls_free_datum (&info->raw_certificate_list[j]);
138 gnutls_free (info->raw_certificate_list);
139 info->raw_certificate_list = NULL;
141 return ret;
147 /* returns 0 if the algo_to-check exists in the pk_algos list,
148 * -1 otherwise.
150 inline static int
151 _gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t *
152 pk_algos, int pk_algos_length,
153 gnutls_pk_algorithm_t algo_to_check)
155 int i;
156 for (i = 0; i < pk_algos_length; i++)
158 if (algo_to_check == pk_algos[i])
160 return 0;
163 return -1;
167 /* Returns the issuer's Distinguished name in odn, of the certificate
168 * specified in cert.
170 static int
171 _gnutls_cert_get_issuer_dn (gnutls_pcert_st * cert, gnutls_datum_t * odn)
173 ASN1_TYPE dn;
174 int len, result;
175 int start, end;
177 if ((result = asn1_create_element
178 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS)
180 gnutls_assert ();
181 return _gnutls_asn2err (result);
184 result = asn1_der_decoding (&dn, cert->cert.data, cert->cert.size, NULL);
185 if (result != ASN1_SUCCESS)
187 /* couldn't decode DER */
188 gnutls_assert ();
189 asn1_delete_structure (&dn);
190 return _gnutls_asn2err (result);
193 result = asn1_der_decoding_startEnd (dn, cert->cert.data, cert->cert.size,
194 "tbsCertificate.issuer", &start, &end);
196 if (result != ASN1_SUCCESS)
198 /* couldn't decode DER */
199 gnutls_assert ();
200 asn1_delete_structure (&dn);
201 return _gnutls_asn2err (result);
203 asn1_delete_structure (&dn);
205 len = end - start + 1;
207 odn->size = len;
208 odn->data = &cert->cert.data[start];
210 return 0;
214 /* Locates the most appropriate x509 certificate using the
215 * given DN. If indx == -1 then no certificate was found.
217 * That is to guess which certificate to use, based on the
218 * CAs and sign algorithms supported by the peer server.
220 static int
221 _find_x509_cert (const gnutls_certificate_credentials_t cred,
222 uint8_t * _data, size_t _data_size,
223 const gnutls_pk_algorithm_t * pk_algos,
224 int pk_algos_length, int *indx)
226 unsigned size;
227 gnutls_datum_t odn = { NULL, 0 };
228 uint8_t *data = _data;
229 ssize_t data_size = _data_size;
230 unsigned i, j;
231 int result, cert_pk;
233 *indx = -1;
235 /* If peer doesn't send any issuers and we have a single certificate
236 * then send that one.
238 if (data_size == 0 && cred->ncerts == 1)
240 *indx = 0;
241 return 0;
246 DECR_LENGTH_RET (data_size, 2, 0);
247 size = _gnutls_read_uint16 (data);
248 DECR_LENGTH_RET (data_size, size, 0);
249 data += 2;
251 for (i = 0; i < cred->ncerts; i++)
253 for (j = 0; j < cred->certs[i].cert_list_length; j++)
255 if ((result =
256 _gnutls_cert_get_issuer_dn (&cred->certs[i].cert_list[j],
257 &odn)) < 0)
259 gnutls_assert ();
260 return result;
263 if (odn.size != size)
264 continue;
266 /* If the DN matches and
267 * the *_SIGN algorithm matches
268 * the cert is our cert!
270 cert_pk =
271 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
272 NULL);
274 if ((memcmp (odn.data, data, size) == 0) &&
275 (_gnutls_check_pk_algo_in_list
276 (pk_algos, pk_algos_length, cert_pk) == 0))
278 *indx = i;
279 break;
282 if (*indx != -1)
283 break;
286 if (*indx != -1)
287 break;
289 /* move to next record */
290 data += size;
292 while (1);
294 return 0;
298 #ifdef ENABLE_OPENPGP
299 /* Locates the most appropriate openpgp cert
301 static int
302 _find_openpgp_cert (const gnutls_certificate_credentials_t cred,
303 gnutls_pk_algorithm_t * pk_algos,
304 int pk_algos_length, int *indx)
306 unsigned i, j;
308 *indx = -1;
310 for (i = 0; i < cred->ncerts; i++)
312 for (j = 0; j < cred->certs[i].cert_list_length; j++)
315 /* If the *_SIGN algorithm matches
316 * the cert is our cert!
318 if ((_gnutls_check_pk_algo_in_list
319 (pk_algos, pk_algos_length,
320 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
321 NULL)) == 0)
322 && (cred->certs[i].cert_list[0].type == GNUTLS_CRT_OPENPGP))
324 *indx = i;
325 break;
328 if (*indx != -1)
329 break;
332 return 0;
334 #endif
336 /* Returns the number of issuers in the server's
337 * certificate request packet.
339 static int
340 get_issuers_num (gnutls_session_t session, uint8_t * data, ssize_t data_size)
342 int issuers_dn_len = 0, result;
343 unsigned size;
345 /* Count the number of the given issuers;
346 * This is used to allocate the issuers_dn without
347 * using realloc().
350 if (data_size == 0 || data == NULL)
351 return 0;
353 if (data_size > 0)
356 /* This works like DECR_LEN()
358 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
359 DECR_LENGTH_COM (data_size, 2, goto error);
360 size = _gnutls_read_uint16 (data);
362 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
363 DECR_LENGTH_COM (data_size, size, goto error);
365 data += 2;
367 if (size > 0)
369 issuers_dn_len++;
370 data += size;
373 if (data_size == 0)
374 break;
377 while (1);
379 return issuers_dn_len;
381 error:
382 return result;
385 /* Returns the issuers in the server's certificate request
386 * packet.
388 static int
389 get_issuers (gnutls_session_t session,
390 gnutls_datum_t * issuers_dn, int issuers_len,
391 uint8_t * data, size_t data_size)
393 int i;
394 unsigned size;
396 if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
397 return 0;
399 /* put the requested DNs to req_dn, only in case
400 * of X509 certificates.
402 if (issuers_len > 0)
405 for (i = 0; i < issuers_len; i++)
407 /* The checks here for the buffer boundaries
408 * are not needed since the buffer has been
409 * parsed above.
411 data_size -= 2;
413 size = _gnutls_read_uint16 (data);
415 data += 2;
417 issuers_dn[i].data = data;
418 issuers_dn[i].size = size;
420 data += size;
424 return 0;
427 static void
428 st_to_st2 (gnutls_retr2_st * st2, gnutls_retr_st * st)
430 st2->cert_type = st->type;
431 if (st->type == GNUTLS_CRT_OPENPGP)
433 st2->key_type = GNUTLS_PRIVKEY_OPENPGP;
435 else
437 st2->key_type = GNUTLS_PRIVKEY_X509;
439 st2->ncerts = st->ncerts;
440 st2->deinit_all = st->deinit_all;
442 switch (st2->cert_type)
444 case GNUTLS_CRT_OPENPGP:
445 st2->cert.pgp = st->cert.pgp;
446 st2->key.pgp = st->key.pgp;
447 break;
448 case GNUTLS_CRT_X509:
449 st2->cert.x509 = st->cert.x509;
450 st2->key.x509 = st->key.x509;
451 break;
452 default:
453 return;
458 /* Calls the client get callback.
460 static int
461 call_get_cert_callback (gnutls_session_t session,
462 const gnutls_datum_t * issuers_dn,
463 int issuers_dn_length,
464 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
466 unsigned i;
467 gnutls_pcert_st *local_certs = NULL;
468 gnutls_privkey_t local_key = NULL;
469 int ret = GNUTLS_E_INTERNAL_ERROR;
470 gnutls_certificate_type_t type = gnutls_certificate_type_get (session);
471 gnutls_certificate_credentials_t cred;
472 gnutls_retr2_st st2;
473 gnutls_pcert_st *pcert = NULL;
474 unsigned int pcert_length = 0;
476 cred = (gnutls_certificate_credentials_t)
477 _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
478 if (cred == NULL)
480 gnutls_assert ();
481 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
484 memset (&st2, 0, sizeof (st2));
486 if (cred->get_cert_callback2)
488 /* we avoid all allocations and transformations */
489 ret = cred->get_cert_callback2 (session, issuers_dn, issuers_dn_length,
490 pk_algos, pk_algos_length,
491 &pcert, &pcert_length, &local_key);
492 if (ret < 0)
493 return gnutls_assert_val (GNUTLS_E_USER_ERROR);
495 if (pcert_length > 0 && type != pcert[0].type)
496 return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST);
498 if (pcert_length == 0)
500 pcert = NULL;
501 local_key = NULL;
503 _gnutls_selected_certs_set (session, pcert, pcert_length, local_key, 0);
505 return 0;
508 else if (cred->get_cert_callback)
510 ret = cred->get_cert_callback (session, issuers_dn, issuers_dn_length,
511 pk_algos, pk_algos_length, &st2);
514 else
515 { /* compatibility mode */
516 gnutls_retr_st st;
517 memset (&st, 0, sizeof (st));
518 if (session->security_parameters.entity == GNUTLS_SERVER)
520 if (cred->server_get_cert_callback == NULL)
522 gnutls_assert ();
523 return GNUTLS_E_INTERNAL_ERROR;
525 ret = cred->server_get_cert_callback (session, &st);
526 if (ret >= 0)
527 st_to_st2 (&st2, &st);
529 else
530 { /* CLIENT */
532 if (cred->client_get_cert_callback == NULL)
534 gnutls_assert ();
535 return GNUTLS_E_INTERNAL_ERROR;
537 ret = cred->client_get_cert_callback (session,
538 issuers_dn, issuers_dn_length,
539 pk_algos, pk_algos_length,
540 &st);
541 if (ret >= 0)
542 st_to_st2 (&st2, &st);
546 if (ret < 0)
548 gnutls_assert ();
549 return GNUTLS_E_USER_ERROR;
552 if (st2.ncerts == 0)
553 return 0; /* no certificate was selected */
555 if (type != st2.cert_type)
557 gnutls_assert ();
558 ret = GNUTLS_E_INVALID_REQUEST;
559 goto cleanup;
563 if (type == GNUTLS_CRT_X509)
565 local_certs = alloc_and_load_x509_certs (st2.cert.x509, st2.ncerts);
567 else
568 { /* PGP */
569 if (st2.ncerts > 1)
571 gnutls_assert ();
572 ret = GNUTLS_E_INVALID_REQUEST;
573 goto cleanup;
575 #ifdef ENABLE_OPENPGP
577 local_certs = alloc_and_load_pgp_certs (st2.cert.pgp);
579 #else
580 ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
581 goto cleanup;
582 #endif
585 if (local_certs == NULL)
587 gnutls_assert ();
588 ret = GNUTLS_E_MEMORY_ERROR;
589 goto cleanup;
592 switch (st2.key_type)
594 case GNUTLS_PRIVKEY_OPENPGP:
595 #ifdef ENABLE_OPENPGP
596 if (st2.key.pgp != NULL)
598 local_key = alloc_and_load_pgp_key (st2.key.pgp, st2.deinit_all);
599 if (local_key == NULL)
601 gnutls_assert ();
602 ret = GNUTLS_E_INTERNAL_ERROR;
603 goto cleanup;
606 #endif
607 break;
608 case GNUTLS_PRIVKEY_PKCS11:
609 #ifdef ENABLE_PKCS11
610 if (st2.key.pkcs11 != NULL)
612 local_key =
613 alloc_and_load_pkcs11_key (st2.key.pkcs11, st2.deinit_all);
614 if (local_key == NULL)
616 gnutls_assert ();
617 ret = GNUTLS_E_INTERNAL_ERROR;
618 goto cleanup;
621 #endif
622 break;
623 case GNUTLS_PRIVKEY_X509:
624 if (st2.key.x509 != NULL)
626 local_key = alloc_and_load_x509_key (st2.key.x509, st2.deinit_all);
627 if (local_key == NULL)
629 gnutls_assert ();
630 ret = GNUTLS_E_INTERNAL_ERROR;
631 goto cleanup;
634 break;
635 default:
636 gnutls_assert();
637 ret = GNUTLS_E_INVALID_REQUEST;
638 goto cleanup;
641 _gnutls_selected_certs_set (session, local_certs,
642 (local_certs != NULL) ? st2.ncerts : 0,
643 local_key, 1);
645 ret = 0;
647 cleanup:
649 if (st2.cert_type == GNUTLS_CRT_X509)
651 if (st2.deinit_all)
653 for (i = 0; i < st2.ncerts; i++)
655 gnutls_x509_crt_deinit (st2.cert.x509[i]);
657 gnutls_free(st2.cert.x509);
660 else
662 #ifdef ENABLE_OPENPGP
663 if (st2.deinit_all)
665 gnutls_openpgp_crt_deinit (st2.cert.pgp);
667 #endif
670 if (ret < 0)
672 if (local_key != NULL)
673 gnutls_privkey_deinit (local_key);
676 return ret;
679 /* Finds the appropriate certificate depending on the cA Distinguished name
680 * advertized by the server. If none matches then returns 0 and -1 as index.
681 * In case of an error a negative error code, is returned.
683 * 20020128: added ability to select a certificate depending on the SIGN
684 * algorithm (only in automatic mode).
686 static int
687 _select_client_cert (gnutls_session_t session,
688 uint8_t * _data, size_t _data_size,
689 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
691 int result;
692 int indx = -1;
693 gnutls_certificate_credentials_t cred;
694 uint8_t *data = _data;
695 ssize_t data_size = _data_size;
696 int issuers_dn_length;
697 gnutls_datum_t *issuers_dn = NULL;
699 cred = (gnutls_certificate_credentials_t)
700 _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
701 if (cred == NULL)
703 gnutls_assert ();
704 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
707 if (cred->client_get_cert_callback != NULL
708 || cred->get_cert_callback != NULL || cred->get_cert_callback2 != NULL)
711 /* use a callback to get certificate
713 if (session->security_parameters.cert_type != GNUTLS_CRT_X509)
714 issuers_dn_length = 0;
715 else
717 issuers_dn_length = get_issuers_num (session, data, data_size);
718 if (issuers_dn_length < 0)
720 gnutls_assert ();
721 return issuers_dn_length;
724 if (issuers_dn_length > 0)
726 issuers_dn =
727 gnutls_malloc (sizeof (gnutls_datum_t) * issuers_dn_length);
728 if (issuers_dn == NULL)
730 gnutls_assert ();
731 return GNUTLS_E_MEMORY_ERROR;
734 result =
735 get_issuers (session, issuers_dn, issuers_dn_length,
736 data, data_size);
737 if (result < 0)
739 gnutls_assert ();
740 goto cleanup;
745 result =
746 call_get_cert_callback (session, issuers_dn, issuers_dn_length,
747 pk_algos, pk_algos_length);
748 goto cleanup;
751 else
753 /* If we have no callbacks, try to guess.
755 result = 0;
757 if (session->security_parameters.cert_type == GNUTLS_CRT_X509)
758 result =
759 _find_x509_cert (cred, _data, _data_size,
760 pk_algos, pk_algos_length, &indx);
761 #ifdef ENABLE_OPENPGP
762 else if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP)
763 result = _find_openpgp_cert (cred, pk_algos, pk_algos_length, &indx);
764 #endif
766 if (result < 0)
768 gnutls_assert ();
769 return result;
772 if (indx >= 0)
774 _gnutls_selected_certs_set (session,
775 &cred->certs[indx].cert_list[0],
776 cred->certs[indx].cert_list_length,
777 cred->pkey[indx], 0);
779 else
781 _gnutls_selected_certs_set (session, NULL, 0, NULL, 0);
784 result = 0;
787 cleanup:
788 gnutls_free (issuers_dn);
789 return result;
793 /* Generate certificate message
795 static int
796 _gnutls_gen_x509_crt (gnutls_session_t session, gnutls_buffer_st * data)
798 int ret, i;
799 gnutls_pcert_st *apr_cert_list;
800 gnutls_privkey_t apr_pkey;
801 int apr_cert_list_length;
803 /* find the appropriate certificate
805 if ((ret =
806 _gnutls_get_selected_cert (session, &apr_cert_list,
807 &apr_cert_list_length, &apr_pkey)) < 0)
809 gnutls_assert ();
810 return ret;
813 ret = 3;
814 for (i = 0; i < apr_cert_list_length; i++)
816 ret += apr_cert_list[i].cert.size + 3;
817 /* hold size
818 * for uint24 */
821 /* if no certificates were found then send:
822 * 0B 00 00 03 00 00 00 // Certificate with no certs
823 * instead of:
824 * 0B 00 00 00 // empty certificate handshake
826 * ( the above is the whole handshake message, not
827 * the one produced here )
830 ret = _gnutls_buffer_append_prefix (data, 24, ret - 3);
831 if (ret < 0)
832 return gnutls_assert_val (ret);
834 for (i = 0; i < apr_cert_list_length; i++)
836 ret =
837 _gnutls_buffer_append_data_prefix (data, 24,
838 apr_cert_list[i].cert.data,
839 apr_cert_list[i].cert.size);
840 if (ret < 0)
841 return gnutls_assert_val (ret);
844 return data->length;
847 enum PGPKeyDescriptorType
848 { PGP_EMPTY_KEY=1, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
850 #ifdef ENABLE_OPENPGP
851 static int
852 _gnutls_gen_openpgp_certificate (gnutls_session_t session,
853 gnutls_buffer_st * data)
855 int ret;
856 gnutls_pcert_st *apr_cert_list;
857 gnutls_privkey_t apr_pkey;
858 int apr_cert_list_length;
859 unsigned int subkey;
860 uint8_t type;
861 uint8_t fpr[20];
862 char buf[2*GNUTLS_OPENPGP_KEYID_SIZE+1];
863 size_t fpr_size;
865 /* find the appropriate certificate */
866 if ((ret =
867 _gnutls_get_selected_cert (session, &apr_cert_list,
868 &apr_cert_list_length, &apr_pkey)) < 0)
870 gnutls_assert ();
871 return ret;
874 ret = 3 + 1 + 3;
876 if (apr_cert_list_length > 0)
878 fpr_size = sizeof (fpr);
879 ret =
880 gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
881 &fpr_size, &subkey);
882 if (ret < 0)
883 return gnutls_assert_val (ret);
885 ret += 1 + fpr_size; /* for the keyid */
886 _gnutls_handshake_log("Sending PGP key ID %s (%s)\n", _gnutls_bin2hex(fpr, GNUTLS_OPENPGP_KEYID_SIZE, buf, sizeof(buf), NULL),
887 subkey?"subkey":"master");
889 ret += apr_cert_list[0].cert.size;
892 ret = _gnutls_buffer_append_prefix (data, 24, ret - 3);
893 if (ret < 0)
894 return gnutls_assert_val (ret);
897 if (apr_cert_list_length > 0)
899 type = PGP_KEY_SUBKEY;
901 ret = _gnutls_buffer_append_data (data, &type, 1);
902 if (ret < 0)
903 return gnutls_assert_val (ret);
905 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
906 if (ret < 0)
907 return gnutls_assert_val (ret);
909 ret =
910 _gnutls_buffer_append_data_prefix (data, 24,
911 apr_cert_list[0].cert.data,
912 apr_cert_list[0].cert.size);
913 if (ret < 0)
914 return gnutls_assert_val (ret);
916 else /* empty - no certificate */
918 type = PGP_EMPTY_KEY;
920 ret = _gnutls_buffer_append_data (data, &type, 1);
921 if (ret < 0)
922 return gnutls_assert_val (ret);
924 ret = _gnutls_buffer_append_prefix (data, 24, 0);
925 if (ret < 0)
926 return gnutls_assert_val (ret);
929 return data->length;
932 static int
933 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session,
934 gnutls_buffer_st * data)
936 int ret, packet_size;
937 uint8_t type, fpr[20];
938 size_t fpr_size;
939 gnutls_pcert_st *apr_cert_list;
940 gnutls_privkey_t apr_pkey;
941 int apr_cert_list_length;
943 /* find the appropriate certificate */
944 if ((ret =
945 _gnutls_get_selected_cert (session, &apr_cert_list,
946 &apr_cert_list_length, &apr_pkey)) < 0)
948 gnutls_assert ();
949 return ret;
952 fpr_size = sizeof (fpr);
953 ret =
954 gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
955 &fpr_size, NULL);
956 if (ret < 0)
957 return gnutls_assert_val (ret);
959 packet_size = 3 + 1;
960 packet_size += 1 + fpr_size; /* for the keyid */
962 /* Only v4 fingerprints are sent
964 if (apr_cert_list_length > 0)
965 packet_size += 20 + 1;
966 else /* empty certificate case */
967 return _gnutls_gen_openpgp_certificate (session, data);
969 ret = _gnutls_buffer_append_prefix (data, 24, packet_size - 3);
970 if (ret < 0)
971 return gnutls_assert_val (ret);
973 type = PGP_KEY_FINGERPRINT_SUBKEY;
974 ret = _gnutls_buffer_append_data (data, &type, 1);
975 if (ret < 0)
976 return gnutls_assert_val (ret);
978 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
979 if (ret < 0)
980 return gnutls_assert_val (ret);
982 return data->length;
984 #endif
988 _gnutls_gen_cert_client_crt (gnutls_session_t session,
989 gnutls_buffer_st * data)
991 switch (session->security_parameters.cert_type)
993 #ifdef ENABLE_OPENPGP
994 case GNUTLS_CRT_OPENPGP:
995 if (_gnutls_openpgp_send_fingerprint (session) == 0)
996 return _gnutls_gen_openpgp_certificate (session, data);
997 else
998 return _gnutls_gen_openpgp_certificate_fpr (session, data);
999 #endif
1000 case GNUTLS_CRT_X509:
1001 return _gnutls_gen_x509_crt (session, data);
1003 default:
1004 gnutls_assert ();
1005 return GNUTLS_E_INTERNAL_ERROR;
1010 _gnutls_gen_cert_server_crt (gnutls_session_t session,
1011 gnutls_buffer_st * data)
1013 switch (session->security_parameters.cert_type)
1015 #ifdef ENABLE_OPENPGP
1016 case GNUTLS_CRT_OPENPGP:
1017 return _gnutls_gen_openpgp_certificate (session, data);
1018 #endif
1019 case GNUTLS_CRT_X509:
1020 return _gnutls_gen_x509_crt (session, data);
1021 default:
1022 gnutls_assert ();
1023 return GNUTLS_E_INTERNAL_ERROR;
1027 /* Process server certificate
1030 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) gnutls_pcert_deinit(&peer_certificate_list[x])
1031 static int
1032 _gnutls_proc_x509_server_crt (gnutls_session_t session,
1033 uint8_t * data, size_t data_size)
1035 int size, len, ret;
1036 uint8_t *p = data;
1037 cert_auth_info_t info;
1038 gnutls_certificate_credentials_t cred;
1039 ssize_t dsize = data_size;
1040 int i;
1041 gnutls_pcert_st *peer_certificate_list;
1042 size_t peer_certificate_list_size = 0, j, x;
1043 gnutls_datum_t tmp;
1045 cred = (gnutls_certificate_credentials_t)
1046 _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
1047 if (cred == NULL)
1049 gnutls_assert ();
1050 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1054 if ((ret =
1055 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1056 sizeof (cert_auth_info_st), 1)) < 0)
1058 gnutls_assert ();
1059 return ret;
1062 info = _gnutls_get_auth_info (session);
1064 if (data == NULL || data_size == 0)
1066 gnutls_assert ();
1067 /* no certificate was sent */
1068 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1071 DECR_LEN (dsize, 3);
1072 size = _gnutls_read_uint24 (p);
1073 p += 3;
1075 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
1076 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
1078 if (size == 0 || size == 3)
1080 gnutls_assert ();
1081 /* no certificate was sent */
1082 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1085 i = dsize;
1086 while (i > 0)
1088 DECR_LEN (dsize, 3);
1089 len = _gnutls_read_uint24 (p);
1090 p += 3;
1091 DECR_LEN (dsize, len);
1092 peer_certificate_list_size++;
1093 p += len;
1094 i -= len + 3;
1097 if (peer_certificate_list_size == 0)
1099 gnutls_assert ();
1100 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1103 /* Ok we now allocate the memory to hold the
1104 * certificate list
1107 peer_certificate_list =
1108 gnutls_calloc (1,
1109 sizeof (gnutls_pcert_st) * (peer_certificate_list_size));
1110 if (peer_certificate_list == NULL)
1112 gnutls_assert ();
1113 return GNUTLS_E_MEMORY_ERROR;
1116 p = data + 3;
1118 /* Now we start parsing the list (again).
1119 * We don't use DECR_LEN since the list has
1120 * been parsed before.
1123 for (j = 0; j < peer_certificate_list_size; j++)
1125 len = _gnutls_read_uint24 (p);
1126 p += 3;
1128 tmp.size = len;
1129 tmp.data = p;
1131 ret =
1132 gnutls_pcert_import_x509_raw (&peer_certificate_list
1133 [j], &tmp, GNUTLS_X509_FMT_DER, 0);
1134 if (ret < 0)
1136 gnutls_assert ();
1137 peer_certificate_list_size = j;
1138 goto cleanup;
1141 p += len;
1145 if ((ret =
1146 _gnutls_copy_certificate_auth_info (info,
1147 peer_certificate_list,
1148 peer_certificate_list_size,
1149 NULL)) < 0)
1151 gnutls_assert ();
1152 goto cleanup;
1155 if ((ret =
1156 _gnutls_check_key_usage (&peer_certificate_list[0],
1157 gnutls_kx_get (session))) < 0)
1159 gnutls_assert ();
1160 goto cleanup;
1163 ret = 0;
1165 cleanup:
1166 CLEAR_CERTS;
1167 gnutls_free (peer_certificate_list);
1168 return ret;
1172 #ifdef ENABLE_OPENPGP
1173 static int
1174 _gnutls_proc_openpgp_server_crt (gnutls_session_t session,
1175 uint8_t * data, size_t data_size)
1177 int size, ret, len;
1178 uint8_t *p = data;
1179 cert_auth_info_t info;
1180 gnutls_certificate_credentials_t cred;
1181 ssize_t dsize = data_size;
1182 int key_type;
1183 gnutls_pcert_st *peer_certificate_list = NULL;
1184 gnutls_datum_t tmp, akey = { NULL, 0 };
1185 unsigned int compat = 0;
1186 uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE];
1188 cred = (gnutls_certificate_credentials_t)
1189 _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
1190 if (cred == NULL)
1192 gnutls_assert ();
1193 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1196 if ((ret =
1197 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1198 sizeof (cert_auth_info_st), 1)) < 0)
1200 gnutls_assert ();
1201 return ret;
1204 info = _gnutls_get_auth_info (session);
1206 if (data == NULL || data_size == 0)
1208 gnutls_assert ();
1209 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1212 DECR_LEN (dsize, 3);
1213 size = _gnutls_read_uint24 (p);
1214 p += 3;
1216 if (size == 0)
1218 gnutls_assert ();
1219 /* no certificate was sent */
1220 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1223 /* Read PGPKeyDescriptor */
1224 DECR_LEN (dsize, 1);
1225 key_type = *p;
1226 p++;
1228 /* Try to read the keyid if present */
1229 if (key_type == PGP_KEY_FINGERPRINT_SUBKEY || key_type == PGP_KEY_SUBKEY)
1231 /* check size */
1232 if (*p != GNUTLS_OPENPGP_KEYID_SIZE)
1234 gnutls_assert ();
1235 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1238 DECR_LEN (dsize, 1);
1239 p++;
1241 DECR_LEN (dsize, GNUTLS_OPENPGP_KEYID_SIZE);
1242 memcpy (subkey_id, p, GNUTLS_OPENPGP_KEYID_SIZE);
1243 p += GNUTLS_OPENPGP_KEYID_SIZE;
1246 if (key_type == PGP_KEY_FINGERPRINT_SUBKEY)
1248 DECR_LEN (dsize, 1);
1249 len = (uint8_t) * p;
1250 p++;
1252 if (len != 20)
1254 gnutls_assert ();
1255 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED;
1258 DECR_LEN (dsize, 20);
1260 /* request the actual key from our database, or
1261 * a key server or anything.
1263 if ((ret =
1264 _gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
1266 gnutls_assert ();
1267 return ret;
1269 tmp = akey;
1271 else if (key_type == PGP_KEY_SUBKEY)
1272 { /* the whole key */
1274 /* Read the actual certificate */
1275 DECR_LEN (dsize, 3);
1276 len = _gnutls_read_uint24 (p);
1277 p += 3;
1279 if (len == 0)
1281 gnutls_assert ();
1282 /* no certificate was sent */
1283 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
1286 DECR_LEN (dsize, len);
1288 tmp.size = len;
1289 tmp.data = p;
1292 else if (key_type == PGP_EMPTY_KEY)
1293 { /* the whole key */
1295 /* Read the actual certificate */
1296 DECR_LEN (dsize, 3);
1297 len = _gnutls_read_uint24 (p);
1298 p += 3;
1300 if (len == 0) /* PGP_EMPTY_KEY */
1301 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1302 /* Uncomment to remove compatibility with RFC5081.
1303 else
1304 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);*/
1306 DECR_LEN (dsize, len);
1308 tmp.size = len;
1309 tmp.data = p;
1311 compat = 1;
1313 else
1315 gnutls_assert ();
1316 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1319 /* ok we now have the peer's key in tmp datum
1321 peer_certificate_list =
1322 gnutls_calloc (1, sizeof (gnutls_pcert_st));
1323 if (peer_certificate_list == NULL)
1325 gnutls_assert ();
1326 ret = GNUTLS_E_MEMORY_ERROR;
1327 goto cleanup;
1330 ret =
1331 gnutls_pcert_import_openpgp_raw (&peer_certificate_list[0],
1332 &tmp,
1333 GNUTLS_OPENPGP_FMT_RAW,
1334 (compat==0)?subkey_id:NULL,
1336 if (ret < 0)
1338 gnutls_assert ();
1339 goto cleanup;
1342 if (compat != 0)
1344 size_t t = sizeof(subkey_id);
1345 gnutls_pubkey_get_openpgp_key_id(peer_certificate_list[0].pubkey, 0, subkey_id, &t, NULL);
1348 ret =
1349 _gnutls_copy_certificate_auth_info (info,
1350 peer_certificate_list,
1351 1, subkey_id);
1352 if (ret < 0)
1354 gnutls_assert ();
1355 goto cleanup;
1358 if ((ret =
1359 _gnutls_check_key_usage (&peer_certificate_list[0],
1360 gnutls_kx_get (session))) < 0)
1362 gnutls_assert ();
1363 goto cleanup;
1366 ret = 0;
1368 cleanup:
1370 _gnutls_free_datum (&akey);
1371 gnutls_pcert_deinit(&peer_certificate_list[0]);
1372 gnutls_free (peer_certificate_list);
1373 return ret;
1376 #endif
1379 _gnutls_proc_crt (gnutls_session_t session, uint8_t * data, size_t data_size)
1381 int ret;
1382 gnutls_certificate_credentials_t cred;
1384 cred =
1385 (gnutls_certificate_credentials_t) _gnutls_get_cred (session,
1386 GNUTLS_CRD_CERTIFICATE,
1387 NULL);
1388 if (cred == NULL)
1390 gnutls_assert ();
1391 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1394 switch (session->security_parameters.cert_type)
1396 #ifdef ENABLE_OPENPGP
1397 case GNUTLS_CRT_OPENPGP:
1398 ret = _gnutls_proc_openpgp_server_crt (session,
1399 data, data_size);
1400 break;
1401 #endif
1402 case GNUTLS_CRT_X509:
1403 ret = _gnutls_proc_x509_server_crt (session, data, data_size);
1404 break;
1405 default:
1406 gnutls_assert ();
1407 return GNUTLS_E_INTERNAL_ERROR;
1410 return ret;
1414 /* Checks if we support the given signature algorithm
1415 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1416 * if true;
1418 inline static int
1419 _gnutls_check_supported_sign_algo (CertificateSigType algo)
1421 switch (algo)
1423 case RSA_SIGN:
1424 return GNUTLS_PK_RSA;
1425 case DSA_SIGN:
1426 return GNUTLS_PK_DSA;
1427 case ECDSA_SIGN:
1428 return GNUTLS_PK_EC;
1431 return -1;
1435 _gnutls_proc_cert_cert_req (gnutls_session_t session, uint8_t * data,
1436 size_t data_size)
1438 int size, ret;
1439 uint8_t *p;
1440 gnutls_certificate_credentials_t cred;
1441 ssize_t dsize;
1442 int i;
1443 gnutls_pk_algorithm_t pk_algos[MAX_CLIENT_SIGN_ALGOS];
1444 int pk_algos_length;
1445 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1447 cred = (gnutls_certificate_credentials_t)
1448 _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
1449 if (cred == NULL)
1451 gnutls_assert ();
1452 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1455 if ((ret =
1456 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1457 sizeof (cert_auth_info_st), 0)) < 0)
1459 gnutls_assert ();
1460 return ret;
1463 p = data;
1464 dsize = data_size;
1466 DECR_LEN (dsize, 1);
1467 size = p[0];
1468 p++;
1469 /* check if the sign algorithm is supported.
1471 pk_algos_length = 0;
1472 for (i = 0; i < size; i++, p++)
1474 DECR_LEN (dsize, 1);
1475 if ((ret = _gnutls_check_supported_sign_algo (*p)) > 0)
1477 if (pk_algos_length < MAX_CLIENT_SIGN_ALGOS)
1479 pk_algos[pk_algos_length++] = ret;
1484 if (pk_algos_length == 0)
1486 gnutls_assert ();
1487 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1490 if (_gnutls_version_has_selectable_sighash (ver))
1492 /* read supported hashes */
1493 int hash_num;
1494 DECR_LEN (dsize, 2);
1495 hash_num = _gnutls_read_uint16 (p);
1496 p += 2;
1497 DECR_LEN (dsize, hash_num);
1499 ret = _gnutls_sign_algorithm_parse_data (session, p, hash_num);
1500 if (ret < 0)
1502 gnutls_assert ();
1503 return ret;
1506 p += hash_num;
1509 /* read the certificate authorities */
1510 DECR_LEN (dsize, 2);
1511 size = _gnutls_read_uint16 (p);
1512 p += 2;
1514 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP
1515 && size != 0)
1517 gnutls_assert ();
1518 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1521 DECR_LEN (dsize, size);
1523 /* now we ask the user to tell which one
1524 * he wants to use.
1526 if ((ret =
1527 _select_client_cert (session, p, size, pk_algos, pk_algos_length)) < 0)
1529 gnutls_assert ();
1530 return ret;
1533 /* We should reply with a certificate message,
1534 * even if we have no certificate to send.
1536 session->key.crt_requested = 1;
1538 return 0;
1542 _gnutls_gen_cert_client_crt_vrfy (gnutls_session_t session,
1543 gnutls_buffer_st * data)
1545 int ret;
1546 gnutls_pcert_st *apr_cert_list;
1547 gnutls_privkey_t apr_pkey;
1548 int apr_cert_list_length;
1549 gnutls_datum_t signature = { NULL, 0 };
1550 gnutls_sign_algorithm_t sign_algo;
1551 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1553 /* find the appropriate certificate */
1554 if ((ret =
1555 _gnutls_get_selected_cert (session, &apr_cert_list,
1556 &apr_cert_list_length, &apr_pkey)) < 0)
1558 gnutls_assert ();
1559 return ret;
1562 if (apr_cert_list_length > 0)
1564 if ((ret =
1565 _gnutls_handshake_sign_crt_vrfy (session,
1566 &apr_cert_list[0],
1567 apr_pkey, &signature)) < 0)
1569 gnutls_assert ();
1570 return ret;
1572 sign_algo = ret;
1574 else
1576 return 0;
1579 if (_gnutls_version_has_selectable_sighash (ver))
1581 const sign_algorithm_st *aid;
1582 uint8_t p[2];
1583 /* error checking is not needed here since we have used those algorithms */
1584 aid = _gnutls_sign_to_tls_aid (sign_algo);
1585 if (aid == NULL)
1586 return gnutls_assert_val (GNUTLS_E_UNKNOWN_ALGORITHM);
1588 p[0] = aid->hash_algorithm;
1589 p[1] = aid->sign_algorithm;
1590 ret = _gnutls_buffer_append_data (data, p, 2);
1591 if (ret < 0)
1593 gnutls_assert ();
1594 goto cleanup;
1598 ret =
1599 _gnutls_buffer_append_data_prefix (data, 16, signature.data,
1600 signature.size);
1601 if (ret < 0)
1603 gnutls_assert ();
1604 goto cleanup;
1607 ret = data->length;
1609 cleanup:
1610 _gnutls_free_datum (&signature);
1611 return ret;
1615 _gnutls_proc_cert_client_crt_vrfy (gnutls_session_t session,
1616 uint8_t * data, size_t data_size)
1618 int size, ret;
1619 ssize_t dsize = data_size;
1620 uint8_t *pdata = data;
1621 gnutls_datum_t sig;
1622 cert_auth_info_t info = _gnutls_get_auth_info (session);
1623 gnutls_pcert_st peer_cert;
1624 gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
1625 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1627 if (info == NULL || info->ncerts == 0)
1629 gnutls_assert ();
1630 /* we need this in order to get peer's certificate */
1631 return GNUTLS_E_INTERNAL_ERROR;
1634 if (_gnutls_version_has_selectable_sighash (ver))
1636 sign_algorithm_st aid;
1638 DECR_LEN (dsize, 2);
1639 aid.hash_algorithm = pdata[0];
1640 aid.sign_algorithm = pdata[1];
1642 sign_algo = _gnutls_tls_aid_to_sign (&aid);
1643 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
1645 gnutls_assert ();
1646 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1648 pdata += 2;
1651 ret = _gnutls_session_sign_algo_enabled (session, sign_algo);
1652 if (ret < 0)
1654 gnutls_assert ();
1655 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1658 DECR_LEN (dsize, 2);
1659 size = _gnutls_read_uint16 (pdata);
1660 pdata += 2;
1662 DECR_LEN (dsize, size);
1664 sig.data = pdata;
1665 sig.size = size;
1667 ret = _gnutls_get_auth_info_pcert (&peer_cert,
1668 session->security_parameters.cert_type,
1669 info);
1671 if (ret < 0)
1673 gnutls_assert ();
1674 return ret;
1677 if ((ret =
1678 _gnutls_handshake_verify_crt_vrfy (session, &peer_cert, &sig,
1679 sign_algo)) < 0)
1681 gnutls_assert ();
1682 gnutls_pcert_deinit (&peer_cert);
1683 return ret;
1685 gnutls_pcert_deinit (&peer_cert);
1687 return 0;
1691 _gnutls_gen_cert_server_cert_req (gnutls_session_t session,
1692 gnutls_buffer_st * data)
1694 gnutls_certificate_credentials_t cred;
1695 int ret;
1696 uint8_t tmp_data[CERTTYPE_SIZE];
1697 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1699 /* Now we need to generate the RDN sequence. This is
1700 * already in the CERTIFICATE_CRED structure, to improve
1701 * performance.
1704 cred = (gnutls_certificate_credentials_t)
1705 _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
1706 if (cred == NULL)
1708 gnutls_assert ();
1709 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1712 tmp_data[0] = CERTTYPE_SIZE - 1;
1713 tmp_data[1] = RSA_SIGN;
1714 tmp_data[2] = DSA_SIGN;
1715 tmp_data[3] = ECDSA_SIGN; /* only these for now */
1717 ret = _gnutls_buffer_append_data (data, tmp_data, CERTTYPE_SIZE);
1718 if (ret < 0)
1719 return gnutls_assert_val (ret);
1721 if (_gnutls_version_has_selectable_sighash (ver))
1723 uint8_t p[MAX_SIGN_ALGO_SIZE];
1725 ret =
1726 _gnutls_sign_algorithm_write_params (session, p, MAX_SIGN_ALGO_SIZE);
1727 if (ret < 0)
1729 gnutls_assert ();
1730 return ret;
1733 ret = _gnutls_buffer_append_data (data, p, ret);
1734 if (ret < 0)
1735 return gnutls_assert_val (ret);
1738 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1739 session->internals.ignore_rdn_sequence == 0)
1741 ret =
1742 _gnutls_buffer_append_data_prefix (data, 16,
1743 cred->x509_rdn_sequence.data,
1744 cred->x509_rdn_sequence.size);
1745 if (ret < 0)
1746 return gnutls_assert_val (ret);
1748 else
1750 ret = _gnutls_buffer_append_prefix (data, 16, 0);
1751 if (ret < 0)
1752 return gnutls_assert_val (ret);
1755 return data->length;
1759 /* This function will return the appropriate certificate to use.
1760 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1761 * The return value is a negative error code on error.
1763 * It is normal to return 0 with no certificates in client side.
1767 _gnutls_get_selected_cert (gnutls_session_t session,
1768 gnutls_pcert_st ** apr_cert_list,
1769 int *apr_cert_list_length,
1770 gnutls_privkey_t * apr_pkey)
1772 if (session->security_parameters.entity == GNUTLS_SERVER)
1775 /* select_client_cert() has been called before.
1778 *apr_cert_list = session->internals.selected_cert_list;
1779 *apr_pkey = session->internals.selected_key;
1780 *apr_cert_list_length = session->internals.selected_cert_list_length;
1782 if (*apr_cert_list_length == 0 || *apr_cert_list == NULL)
1784 gnutls_assert ();
1785 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1789 else
1790 { /* CLIENT SIDE
1793 /* we have already decided which certificate
1794 * to send.
1796 *apr_cert_list = session->internals.selected_cert_list;
1797 *apr_cert_list_length = session->internals.selected_cert_list_length;
1798 *apr_pkey = session->internals.selected_key;
1802 return 0;
1805 /* converts the given x509 certificate list to gnutls_pcert_st* and allocates
1806 * space for them.
1808 static gnutls_pcert_st *
1809 alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, unsigned ncerts)
1811 gnutls_pcert_st *local_certs;
1812 int ret = 0;
1813 unsigned i, j;
1815 if (certs == NULL)
1816 return NULL;
1818 local_certs = gnutls_malloc (sizeof (gnutls_pcert_st) * ncerts);
1819 if (local_certs == NULL)
1821 gnutls_assert ();
1822 return NULL;
1825 for (i = 0; i < ncerts; i++)
1827 ret = gnutls_pcert_import_x509 (&local_certs[i], certs[i], 0);
1828 if (ret < 0)
1829 break;
1832 if (ret < 0)
1834 gnutls_assert ();
1835 for (j = 0; j < i; j++)
1837 gnutls_pcert_deinit (&local_certs[j]);
1839 gnutls_free (local_certs);
1840 return NULL;
1843 return local_certs;
1846 /* converts the given x509 key to gnutls_privkey* and allocates
1847 * space for it.
1849 static gnutls_privkey_t
1850 alloc_and_load_x509_key (gnutls_x509_privkey_t key, int deinit)
1852 gnutls_privkey_t local_key;
1853 int ret = 0;
1855 if (key == NULL)
1856 return NULL;
1858 ret = gnutls_privkey_init (&local_key);
1859 if (ret < 0)
1861 gnutls_assert ();
1862 return NULL;
1865 ret =
1866 gnutls_privkey_import_x509 (local_key, key,
1867 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE :
1869 if (ret < 0)
1871 gnutls_assert ();
1872 gnutls_privkey_deinit (local_key);
1873 return NULL;
1876 return local_key;
1879 /* converts the given pgp certificate to gnutls_cert* and allocates
1880 * space for them.
1882 #ifdef ENABLE_OPENPGP
1883 static gnutls_pcert_st *
1884 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
1886 gnutls_pcert_st *local_certs;
1887 int ret = 0;
1889 if (cert == NULL)
1890 return NULL;
1892 local_certs = gnutls_malloc (sizeof (gnutls_pcert_st));
1893 if (local_certs == NULL)
1895 gnutls_assert ();
1896 return NULL;
1899 ret = gnutls_pcert_import_openpgp (local_certs, cert, 0);
1900 if (ret < 0)
1902 gnutls_assert ();
1903 return NULL;
1906 if (ret < 0)
1908 gnutls_assert ();
1909 gnutls_pcert_deinit (local_certs);
1910 gnutls_free (local_certs);
1911 return NULL;
1914 return local_certs;
1917 /* converts the given raw key to gnutls_privkey* and allocates
1918 * space for it.
1920 static gnutls_privkey_t
1921 alloc_and_load_pgp_key (gnutls_openpgp_privkey_t key, int deinit)
1923 gnutls_privkey_t local_key;
1924 int ret = 0;
1926 if (key == NULL)
1927 return NULL;
1929 ret = gnutls_privkey_init (&local_key);
1930 if (ret < 0)
1932 gnutls_assert ();
1933 return NULL;
1936 ret =
1937 gnutls_privkey_import_openpgp (local_key, key,
1938 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
1939 : 0);
1940 if (ret < 0)
1942 gnutls_assert ();
1943 gnutls_privkey_deinit (local_key);
1944 return NULL;
1947 return local_key;
1949 #endif
1951 #ifdef ENABLE_PKCS11
1953 /* converts the given raw key to gnutls_privkey* and allocates
1954 * space for it.
1956 static gnutls_privkey_t
1957 alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t key, int deinit)
1959 gnutls_privkey_t local_key;
1960 int ret = 0;
1962 if (key == NULL)
1963 return NULL;
1965 ret = gnutls_privkey_init (&local_key);
1966 if (ret < 0)
1968 gnutls_assert ();
1969 return NULL;
1972 ret =
1973 gnutls_privkey_import_pkcs11 (local_key, key,
1974 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
1975 : 0);
1976 if (ret < 0)
1978 gnutls_assert ();
1979 gnutls_privkey_deinit (local_key);
1980 return NULL;
1983 return local_key;
1986 #endif
1988 void
1989 _gnutls_selected_certs_deinit (gnutls_session_t session)
1991 if (session->internals.selected_need_free != 0)
1993 int i;
1995 for (i = 0; i < session->internals.selected_cert_list_length; i++)
1997 gnutls_pcert_deinit (&session->internals.selected_cert_list[i]);
1999 gnutls_free (session->internals.selected_cert_list);
2000 session->internals.selected_cert_list = NULL;
2001 session->internals.selected_cert_list_length = 0;
2003 gnutls_privkey_deinit(session->internals.selected_key);
2004 session->internals.selected_key = NULL;
2007 return;
2010 void
2011 _gnutls_selected_certs_set (gnutls_session_t session,
2012 gnutls_pcert_st * certs, int ncerts,
2013 gnutls_privkey_t key, int need_free)
2015 _gnutls_selected_certs_deinit (session);
2017 session->internals.selected_cert_list = certs;
2018 session->internals.selected_cert_list_length = ncerts;
2019 session->internals.selected_key = key;
2020 session->internals.selected_need_free = need_free;
2024 static void get_server_name(gnutls_session_t session, uint8_t* name, size_t max_name_size)
2026 int ret, i;
2027 size_t max_name;
2028 unsigned int type;
2030 ret = 0;
2031 for (i=0; !(ret<0);i++)
2033 max_name = max_name_size;
2034 ret = gnutls_server_name_get (session, name, &max_name, &type, i);
2035 if (ret >= 0 && type == GNUTLS_NAME_DNS)
2036 return;
2039 name[0] = 0;
2041 return;
2044 /* finds the most appropriate certificate in the cert list.
2045 * The 'appropriate' is defined by the user.
2047 * requested_algo holds the parameters required by the peer (RSA, DSA
2048 * or -1 for any).
2050 * Returns 0 on success and a negative error code on error. The
2051 * selected certificate will be in session->internals.selected_*.
2055 _gnutls_server_select_cert (gnutls_session_t session,
2056 gnutls_pk_algorithm_t * pk_algos,
2057 size_t pk_algos_size)
2059 unsigned i, j;
2060 int idx, ret;
2061 gnutls_certificate_credentials_t cred;
2062 char server_name[MAX_CN];
2064 cred = (gnutls_certificate_credentials_t)
2065 _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL);
2066 if (cred == NULL)
2068 gnutls_assert ();
2069 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2072 /* If the callback which retrieves certificate has been set,
2073 * use it and leave.
2075 if (cred->server_get_cert_callback || cred->get_cert_callback
2076 || cred->get_cert_callback2)
2078 ret = call_get_cert_callback (session, NULL, 0, NULL, 0);
2079 if (ret < 0)
2080 return gnutls_assert_val (ret);
2081 return ret;
2084 /* Otherwise... */
2086 get_server_name(session, (unsigned char*)server_name, sizeof(server_name));
2088 idx = -1; /* default is use no certificate */
2090 /* find certificates that match the requested server_name
2093 if (server_name[0] != 0)
2095 for (i = 0; i < cred->ncerts; i++)
2097 if (cred->certs[i].names != NULL && _gnutls_str_array_match(cred->certs[i].names, server_name) != 0)
2099 /* if requested algorithms are also compatible select it */
2100 gnutls_pk_algorithm pk =
2101 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
2102 NULL);
2104 _gnutls_handshake_log("HSK[%p]: Requested server name: '%s', ctype: %s (%d)", session, server_name,
2105 gnutls_certificate_type_get_name (session->security_parameters.cert_type),
2106 session->security_parameters.cert_type);
2108 if (session->security_parameters.cert_type == cred->certs[i].cert_list[0].type)
2110 for (j = 0; j < pk_algos_size; j++)
2111 if (pk_algos[j] == pk)
2113 idx = i;
2114 goto finished;
2121 for (j = 0; j < pk_algos_size; j++)
2123 _gnutls_handshake_log
2124 ("HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n",
2125 session, gnutls_pk_get_name (pk_algos[j]), pk_algos[j],
2126 gnutls_certificate_type_get_name (session->security_parameters.
2127 cert_type),
2128 session->security_parameters.cert_type);
2130 for (i = 0; i < cred->ncerts; i++)
2132 gnutls_pk_algorithm pk =
2133 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
2134 NULL);
2135 /* find one compatible certificate
2137 _gnutls_handshake_log
2138 ("HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n",
2139 session, i, gnutls_pk_get_name (pk), pk,
2140 gnutls_certificate_type_get_name (cred->certs[i].cert_list[0].type),
2141 cred->certs[i].cert_list[0].type);
2143 if (pk_algos[j] == pk)
2145 /* if cert type matches
2147 /* *INDENT-OFF* */
2148 if (session->security_parameters.cert_type == cred->certs[i].cert_list[0].type)
2150 idx = i;
2151 goto finished;
2153 /* *INDENT-ON* */
2158 /* store the certificate pointer for future use, in the handshake.
2159 * (This will allow not calling this callback again.)
2161 finished:
2162 if (idx >= 0)
2164 _gnutls_selected_certs_set (session,
2165 &cred->certs[idx].cert_list[0],
2166 cred->certs[idx].cert_list_length,
2167 cred->pkey[idx], 0);
2169 else
2171 gnutls_assert ();
2172 /* Certificate does not support REQUESTED_ALGO. */
2173 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2176 return 0;
2179 /* Frees the rsa_info_st structure.
2181 void
2182 _gnutls_free_rsa_info (rsa_info_st * rsa)
2184 _gnutls_free_datum (&rsa->modulus);
2185 _gnutls_free_datum (&rsa->exponent);