Use the new asn1_read_node_value()
[gnutls.git] / lib / auth / cert.c
blobf8f55beb3a115763eaf2209f2a64fb75cd364cb1
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 certificate message
796 static int
797 _gnutls_gen_x509_crt (gnutls_session_t session, gnutls_buffer_st * data)
799 int ret, i;
800 gnutls_pcert_st *apr_cert_list;
801 gnutls_privkey_t apr_pkey;
802 int apr_cert_list_length;
804 /* find the appropriate certificate
806 if ((ret =
807 _gnutls_get_selected_cert (session, &apr_cert_list,
808 &apr_cert_list_length, &apr_pkey)) < 0)
810 gnutls_assert ();
811 return ret;
814 ret = 3;
815 for (i = 0; i < apr_cert_list_length; i++)
817 ret += apr_cert_list[i].cert.size + 3;
818 /* hold size
819 * for uint24 */
822 /* if no certificates were found then send:
823 * 0B 00 00 03 00 00 00 // Certificate with no certs
824 * instead of:
825 * 0B 00 00 00 // empty certificate handshake
827 * ( the above is the whole handshake message, not
828 * the one produced here )
831 ret = _gnutls_buffer_append_prefix (data, 24, ret - 3);
832 if (ret < 0)
833 return gnutls_assert_val (ret);
835 for (i = 0; i < apr_cert_list_length; i++)
837 ret =
838 _gnutls_buffer_append_data_prefix (data, 24,
839 apr_cert_list[i].cert.data,
840 apr_cert_list[i].cert.size);
841 if (ret < 0)
842 return gnutls_assert_val (ret);
845 return data->length;
848 enum PGPKeyDescriptorType
849 { PGP_KEY_FINGERPRINT, PGP_KEY, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY };
851 #ifdef ENABLE_OPENPGP
852 static int
853 _gnutls_gen_openpgp_certificate (gnutls_session_t session,
854 gnutls_buffer_st * data)
856 int ret;
857 gnutls_pcert_st *apr_cert_list;
858 gnutls_privkey_t apr_pkey;
859 int apr_cert_list_length;
860 uint8_t type;
861 uint8_t fpr[20];
862 size_t fpr_size;
863 unsigned int use_subkey = 0;
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;
878 if (apr_cert_list_length > 0)
880 fpr_size = sizeof (fpr);
881 ret =
882 gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
883 &fpr_size, &use_subkey);
884 if (ret < 0)
885 return gnutls_assert_val (ret);
887 if (use_subkey != 0)
888 ret += 1 + fpr_size; /* for the keyid */
890 ret += apr_cert_list[0].cert.size;
893 ret = _gnutls_buffer_append_prefix (data, 24, ret - 3);
894 if (ret < 0)
895 return gnutls_assert_val (ret);
898 if (apr_cert_list_length > 0)
900 if (use_subkey != 0)
902 type = PGP_KEY_SUBKEY;
904 ret = _gnutls_buffer_append_data (data, &type, 1);
905 if (ret < 0)
906 return gnutls_assert_val (ret);
908 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
909 if (ret < 0)
910 return gnutls_assert_val (ret);
912 else
914 type = PGP_KEY;
915 ret = _gnutls_buffer_append_data (data, &type, 1);
916 if (ret < 0)
917 return gnutls_assert_val (ret);
920 ret =
921 _gnutls_buffer_append_data_prefix (data, 24,
922 apr_cert_list[0].cert.data,
923 apr_cert_list[0].cert.size);
924 if (ret < 0)
925 return gnutls_assert_val (ret);
927 else /* empty - no certificate */
929 type = PGP_KEY;
931 ret = _gnutls_buffer_append_data (data, &type, 1);
932 if (ret < 0)
933 return gnutls_assert_val (ret);
935 ret = _gnutls_buffer_append_prefix (data, 24, 0);
936 if (ret < 0)
937 return gnutls_assert_val (ret);
940 return data->length;
943 static int
944 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session,
945 gnutls_buffer_st * data)
947 int ret, packet_size;
948 uint8_t type, fpr[20];
949 size_t fpr_size;
950 gnutls_pcert_st *apr_cert_list;
951 gnutls_privkey_t apr_pkey;
952 int apr_cert_list_length;
953 unsigned int use_subkey = 0;
955 /* find the appropriate certificate */
956 if ((ret =
957 _gnutls_get_selected_cert (session, &apr_cert_list,
958 &apr_cert_list_length, &apr_pkey)) < 0)
960 gnutls_assert ();
961 return ret;
964 fpr_size = sizeof (fpr);
965 ret =
966 gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr,
967 &fpr_size, &use_subkey);
968 if (ret < 0)
969 return gnutls_assert_val (ret);
971 packet_size = 3 + 1;
973 if (use_subkey)
974 packet_size += 1 + fpr_size; /* for the keyid */
976 /* Only v4 fingerprints are sent
978 if (apr_cert_list_length > 0)
979 packet_size += 20 + 1;
980 else /* empty certificate case */
981 return _gnutls_gen_openpgp_certificate (session, data);
983 ret = _gnutls_buffer_append_prefix (data, 24, packet_size - 3);
984 if (ret < 0)
985 return gnutls_assert_val (ret);
987 if (use_subkey)
989 type = PGP_KEY_FINGERPRINT_SUBKEY;
990 ret = _gnutls_buffer_append_data (data, &type, 1);
991 if (ret < 0)
992 return gnutls_assert_val (ret);
994 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
995 if (ret < 0)
996 return gnutls_assert_val (ret);
998 else
1000 type = PGP_KEY_FINGERPRINT; /* key fingerprint */
1001 ret = _gnutls_buffer_append_data (data, &type, 1);
1002 if (ret < 0)
1003 return gnutls_assert_val (ret);
1006 fpr_size = sizeof (fpr);
1007 if ((ret =
1008 _gnutls_openpgp_fingerprint (&apr_cert_list[0].cert, fpr,
1009 &fpr_size)) < 0)
1011 gnutls_assert ();
1012 return ret;
1015 ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size);
1016 if (ret < 0)
1017 return gnutls_assert_val (ret);
1019 return data->length;
1021 #endif
1025 _gnutls_gen_cert_client_crt (gnutls_session_t session,
1026 gnutls_buffer_st * data)
1028 switch (session->security_parameters.cert_type)
1030 #ifdef ENABLE_OPENPGP
1031 case GNUTLS_CRT_OPENPGP:
1032 if (_gnutls_openpgp_send_fingerprint (session) == 0)
1033 return _gnutls_gen_openpgp_certificate (session, data);
1034 else
1035 return _gnutls_gen_openpgp_certificate_fpr (session, data);
1036 #endif
1037 case GNUTLS_CRT_X509:
1038 return _gnutls_gen_x509_crt (session, data);
1040 default:
1041 gnutls_assert ();
1042 return GNUTLS_E_INTERNAL_ERROR;
1047 _gnutls_gen_cert_server_crt (gnutls_session_t session,
1048 gnutls_buffer_st * data)
1050 switch (session->security_parameters.cert_type)
1052 #ifdef ENABLE_OPENPGP
1053 case GNUTLS_CRT_OPENPGP:
1054 return _gnutls_gen_openpgp_certificate (session, data);
1055 #endif
1056 case GNUTLS_CRT_X509:
1057 return _gnutls_gen_x509_crt (session, data);
1058 default:
1059 gnutls_assert ();
1060 return GNUTLS_E_INTERNAL_ERROR;
1064 /* Process server certificate
1067 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) gnutls_pcert_deinit(&peer_certificate_list[x])
1068 static int
1069 _gnutls_proc_x509_server_crt (gnutls_session_t session,
1070 uint8_t * data, size_t data_size)
1072 int size, len, ret;
1073 uint8_t *p = data;
1074 cert_auth_info_t info;
1075 gnutls_certificate_credentials_t cred;
1076 ssize_t dsize = data_size;
1077 int i;
1078 gnutls_pcert_st *peer_certificate_list;
1079 size_t peer_certificate_list_size = 0, j, x;
1080 gnutls_datum_t tmp;
1082 cred = (gnutls_certificate_credentials_t)
1083 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1084 if (cred == NULL)
1086 gnutls_assert ();
1087 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1091 if ((ret =
1092 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1093 sizeof (cert_auth_info_st), 1)) < 0)
1095 gnutls_assert ();
1096 return ret;
1099 info = _gnutls_get_auth_info (session);
1101 if (data == NULL || data_size == 0)
1103 gnutls_assert ();
1104 /* no certificate was sent */
1105 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1108 DECR_LEN (dsize, 3);
1109 size = _gnutls_read_uint24 (p);
1110 p += 3;
1112 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
1113 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
1115 if (size == 0 || size == 3)
1117 gnutls_assert ();
1118 /* no certificate was sent */
1119 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1122 i = dsize;
1123 while (i > 0)
1125 DECR_LEN (dsize, 3);
1126 len = _gnutls_read_uint24 (p);
1127 p += 3;
1128 DECR_LEN (dsize, len);
1129 peer_certificate_list_size++;
1130 p += len;
1131 i -= len + 3;
1134 if (peer_certificate_list_size == 0)
1136 gnutls_assert ();
1137 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1140 /* Ok we now allocate the memory to hold the
1141 * certificate list
1144 peer_certificate_list =
1145 gnutls_calloc (1,
1146 sizeof (gnutls_pcert_st) * (peer_certificate_list_size));
1147 if (peer_certificate_list == NULL)
1149 gnutls_assert ();
1150 return GNUTLS_E_MEMORY_ERROR;
1153 p = data + 3;
1155 /* Now we start parsing the list (again).
1156 * We don't use DECR_LEN since the list has
1157 * been parsed before.
1160 for (j = 0; j < peer_certificate_list_size; j++)
1162 len = _gnutls_read_uint24 (p);
1163 p += 3;
1165 tmp.size = len;
1166 tmp.data = p;
1168 ret =
1169 gnutls_pcert_import_x509_raw (&peer_certificate_list
1170 [j], &tmp, GNUTLS_X509_FMT_DER, 0);
1171 if (ret < 0)
1173 gnutls_assert ();
1174 peer_certificate_list_size = j;
1175 goto cleanup;
1178 p += len;
1182 if ((ret =
1183 _gnutls_copy_certificate_auth_info (info,
1184 peer_certificate_list,
1185 peer_certificate_list_size, 0,
1186 NULL)) < 0)
1188 gnutls_assert ();
1189 goto cleanup;
1192 if ((ret =
1193 _gnutls_check_key_usage (&peer_certificate_list[0],
1194 gnutls_kx_get (session))) < 0)
1196 gnutls_assert ();
1197 goto cleanup;
1200 ret = 0;
1202 cleanup:
1203 CLEAR_CERTS;
1204 gnutls_free (peer_certificate_list);
1205 return ret;
1209 #ifdef ENABLE_OPENPGP
1210 static int
1211 _gnutls_proc_openpgp_server_crt (gnutls_session_t session,
1212 uint8_t * data, size_t data_size)
1214 int size, ret, len;
1215 uint8_t *p = data;
1216 cert_auth_info_t info;
1217 gnutls_certificate_credentials_t cred;
1218 ssize_t dsize = data_size;
1219 int x, key_type;
1220 gnutls_pcert_st *peer_certificate_list = NULL;
1221 int peer_certificate_list_size = 0;
1222 gnutls_datum_t tmp, akey = { NULL, 0 };
1223 uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE];
1224 unsigned int subkey_id_set = 0;
1226 cred = (gnutls_certificate_credentials_t)
1227 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1228 if (cred == NULL)
1230 gnutls_assert ();
1231 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1234 if ((ret =
1235 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1236 sizeof (cert_auth_info_st), 1)) < 0)
1238 gnutls_assert ();
1239 return ret;
1242 info = _gnutls_get_auth_info (session);
1244 if (data == NULL || data_size == 0)
1246 gnutls_assert ();
1247 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1250 DECR_LEN (dsize, 3);
1251 size = _gnutls_read_uint24 (p);
1252 p += 3;
1254 if (size == 0)
1256 gnutls_assert ();
1257 /* no certificate was sent */
1258 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1261 /* Read PGPKeyDescriptor */
1262 DECR_LEN (dsize, 1);
1263 key_type = *p;
1264 p++;
1266 /* Try to read the keyid if present */
1267 if (key_type == PGP_KEY_FINGERPRINT_SUBKEY || key_type == PGP_KEY_SUBKEY)
1269 /* check size */
1270 if (*p != GNUTLS_OPENPGP_KEYID_SIZE)
1272 gnutls_assert ();
1273 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1276 DECR_LEN (dsize, 1);
1277 p++;
1279 DECR_LEN (dsize, GNUTLS_OPENPGP_KEYID_SIZE);
1280 memcpy (subkey_id, p, GNUTLS_OPENPGP_KEYID_SIZE);
1281 p += GNUTLS_OPENPGP_KEYID_SIZE;
1283 subkey_id_set = 1;
1287 /* read the actual key or fingerprint */
1288 if (key_type == PGP_KEY_FINGERPRINT
1289 || key_type == PGP_KEY_FINGERPRINT_SUBKEY)
1290 { /* the fingerprint */
1292 DECR_LEN (dsize, 1);
1293 len = (uint8_t) * p;
1294 p++;
1296 if (len != 20)
1298 gnutls_assert ();
1299 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED;
1302 DECR_LEN (dsize, 20);
1304 /* request the actual key from our database, or
1305 * a key server or anything.
1307 if ((ret =
1308 _gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
1310 gnutls_assert ();
1311 return ret;
1313 tmp = akey;
1314 peer_certificate_list_size++;
1317 else if (key_type == PGP_KEY || key_type == PGP_KEY_SUBKEY)
1318 { /* the whole key */
1320 /* Read the actual certificate */
1321 DECR_LEN (dsize, 3);
1322 len = _gnutls_read_uint24 (p);
1323 p += 3;
1325 if (len == 0)
1327 gnutls_assert ();
1328 /* no certificate was sent */
1329 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1332 DECR_LEN (dsize, len);
1333 peer_certificate_list_size++;
1335 tmp.size = len;
1336 tmp.data = p;
1339 else
1341 gnutls_assert ();
1342 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1345 /* ok we now have the peer's key in tmp datum
1348 if (peer_certificate_list_size == 0)
1350 gnutls_assert ();
1351 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1354 peer_certificate_list =
1355 gnutls_calloc (1,
1356 sizeof (gnutls_pcert_st) * (peer_certificate_list_size));
1357 if (peer_certificate_list == NULL)
1359 gnutls_assert ();
1360 ret = GNUTLS_E_MEMORY_ERROR;
1361 goto cleanup;
1364 ret =
1365 gnutls_pcert_import_openpgp_raw (&peer_certificate_list[0],
1366 &tmp,
1367 GNUTLS_OPENPGP_FMT_RAW,
1368 (subkey_id_set != 0) ? subkey_id : NULL,
1370 if (ret < 0)
1372 gnutls_assert ();
1373 goto cleanup;
1376 ret =
1377 _gnutls_copy_certificate_auth_info (info,
1378 peer_certificate_list,
1379 peer_certificate_list_size,
1380 subkey_id_set,
1381 (subkey_id_set !=
1382 0) ? subkey_id : NULL);
1383 if (ret < 0)
1385 gnutls_assert ();
1386 goto cleanup;
1389 if ((ret =
1390 _gnutls_check_key_usage (&peer_certificate_list[0],
1391 gnutls_kx_get (session))) < 0)
1393 gnutls_assert ();
1394 goto cleanup;
1397 ret = 0;
1399 cleanup:
1401 _gnutls_free_datum (&akey);
1402 CLEAR_CERTS;
1403 gnutls_free (peer_certificate_list);
1404 return ret;
1407 #endif
1410 _gnutls_proc_crt (gnutls_session_t session,
1411 uint8_t * data, size_t data_size)
1413 int ret;
1414 gnutls_certificate_credentials_t cred;
1416 cred =
1417 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
1418 GNUTLS_CRD_CERTIFICATE,
1419 NULL);
1420 if (cred == NULL)
1422 gnutls_assert ();
1423 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1426 switch (session->security_parameters.cert_type)
1428 #ifdef ENABLE_OPENPGP
1429 case GNUTLS_CRT_OPENPGP:
1430 ret = _gnutls_proc_openpgp_server_crt (session,
1431 data, data_size);
1432 break;
1433 #endif
1434 case GNUTLS_CRT_X509:
1435 ret = _gnutls_proc_x509_server_crt (session, data, data_size);
1436 break;
1437 default:
1438 gnutls_assert ();
1439 return GNUTLS_E_INTERNAL_ERROR;
1442 if (ret == 0 && cred->verify_callback != NULL)
1444 ret = cred->verify_callback (session);
1445 if (ret != 0)
1446 ret = GNUTLS_E_CERTIFICATE_ERROR;
1449 return ret;
1453 /* Checks if we support the given signature algorithm
1454 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1455 * if true;
1457 inline static int
1458 _gnutls_check_supported_sign_algo (CertificateSigType algo)
1460 switch (algo)
1462 case RSA_SIGN:
1463 return GNUTLS_PK_RSA;
1464 case DSA_SIGN:
1465 return GNUTLS_PK_DSA;
1466 case ECDSA_SIGN:
1467 return GNUTLS_PK_EC;
1470 return -1;
1474 _gnutls_proc_cert_cert_req (gnutls_session_t session, uint8_t * data,
1475 size_t data_size)
1477 int size, ret;
1478 uint8_t *p;
1479 gnutls_certificate_credentials_t cred;
1480 ssize_t dsize;
1481 int i;
1482 gnutls_pk_algorithm_t pk_algos[MAX_CLIENT_SIGN_ALGOS];
1483 int pk_algos_length;
1484 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1486 cred = (gnutls_certificate_credentials_t)
1487 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1488 if (cred == NULL)
1490 gnutls_assert ();
1491 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1494 if ((ret =
1495 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1496 sizeof (cert_auth_info_st), 0)) < 0)
1498 gnutls_assert ();
1499 return ret;
1502 p = data;
1503 dsize = data_size;
1505 DECR_LEN (dsize, 1);
1506 size = p[0];
1507 p++;
1508 /* check if the sign algorithm is supported.
1510 pk_algos_length = 0;
1511 for (i = 0; i < size; i++, p++)
1513 DECR_LEN (dsize, 1);
1514 if ((ret = _gnutls_check_supported_sign_algo (*p)) > 0)
1516 if (pk_algos_length < MAX_CLIENT_SIGN_ALGOS)
1518 pk_algos[pk_algos_length++] = ret;
1523 if (pk_algos_length == 0)
1525 gnutls_assert ();
1526 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1529 if (_gnutls_version_has_selectable_sighash (ver))
1531 /* read supported hashes */
1532 int hash_num;
1533 DECR_LEN (dsize, 2);
1534 hash_num = _gnutls_read_uint16 (p);
1535 p += 2;
1536 DECR_LEN (dsize, hash_num);
1538 ret = _gnutls_sign_algorithm_parse_data (session, p, hash_num);
1539 if (ret < 0)
1541 gnutls_assert ();
1542 return ret;
1545 p += hash_num;
1548 /* read the certificate authorities */
1549 DECR_LEN (dsize, 2);
1550 size = _gnutls_read_uint16 (p);
1551 p += 2;
1553 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP
1554 && size != 0)
1556 gnutls_assert ();
1557 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1560 DECR_LEN (dsize, size);
1562 /* now we ask the user to tell which one
1563 * he wants to use.
1565 if ((ret =
1566 _select_client_cert (session, p, size, pk_algos, pk_algos_length)) < 0)
1568 gnutls_assert ();
1569 return ret;
1572 /* We should reply with a certificate message,
1573 * even if we have no certificate to send.
1575 session->key->crt_requested = 1;
1577 return 0;
1581 _gnutls_gen_cert_client_crt_vrfy (gnutls_session_t session,
1582 gnutls_buffer_st * data)
1584 int ret;
1585 gnutls_pcert_st *apr_cert_list;
1586 gnutls_privkey_t apr_pkey;
1587 int apr_cert_list_length;
1588 gnutls_datum_t signature = { NULL, 0 };
1589 int total_data;
1590 gnutls_sign_algorithm_t sign_algo;
1591 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1593 /* find the appropriate certificate */
1594 if ((ret =
1595 _gnutls_get_selected_cert (session, &apr_cert_list,
1596 &apr_cert_list_length, &apr_pkey)) < 0)
1598 gnutls_assert ();
1599 return ret;
1602 if (apr_cert_list_length > 0)
1604 if ((ret =
1605 _gnutls_handshake_sign_crt_vrfy (session,
1606 &apr_cert_list[0],
1607 apr_pkey, &signature)) < 0)
1609 gnutls_assert ();
1610 return ret;
1612 sign_algo = ret;
1614 else
1616 return 0;
1619 total_data = signature.size + 2;
1621 /* add hash and signature algorithms */
1622 if (_gnutls_version_has_selectable_sighash (ver))
1624 total_data += 2;
1627 if (_gnutls_version_has_selectable_sighash (ver))
1629 const sign_algorithm_st *aid;
1630 uint8_t p[2];
1631 /* error checking is not needed here since we have used those algorithms */
1632 aid = _gnutls_sign_to_tls_aid (sign_algo);
1633 if (aid == NULL)
1634 return gnutls_assert_val (GNUTLS_E_UNKNOWN_ALGORITHM);
1636 p[0] = aid->hash_algorithm;
1637 p[1] = aid->sign_algorithm;
1638 ret = _gnutls_buffer_append_data (data, p, 2);
1639 if (ret < 0)
1641 gnutls_assert ();
1642 goto cleanup;
1646 ret =
1647 _gnutls_buffer_append_data_prefix (data, 16, signature.data,
1648 signature.size);
1649 if (ret < 0)
1651 gnutls_assert ();
1652 goto cleanup;
1655 ret = data->length;
1657 cleanup:
1658 _gnutls_free_datum (&signature);
1659 return ret;
1663 _gnutls_proc_cert_client_crt_vrfy (gnutls_session_t session,
1664 uint8_t * data, size_t data_size)
1666 int size, ret;
1667 ssize_t dsize = data_size;
1668 uint8_t *pdata = data;
1669 gnutls_datum_t sig;
1670 cert_auth_info_t info = _gnutls_get_auth_info (session);
1671 gnutls_pcert_st peer_cert;
1672 gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
1673 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1675 if (info == NULL || info->ncerts == 0)
1677 gnutls_assert ();
1678 /* we need this in order to get peer's certificate */
1679 return GNUTLS_E_INTERNAL_ERROR;
1682 if (_gnutls_version_has_selectable_sighash (ver))
1684 sign_algorithm_st aid;
1686 DECR_LEN (dsize, 2);
1687 aid.hash_algorithm = pdata[0];
1688 aid.sign_algorithm = pdata[1];
1690 sign_algo = _gnutls_tls_aid_to_sign (&aid);
1691 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
1693 gnutls_assert ();
1694 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1696 pdata += 2;
1699 ret = _gnutls_session_sign_algo_enabled (session, sign_algo);
1700 if (ret < 0)
1702 gnutls_assert ();
1703 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
1706 DECR_LEN (dsize, 2);
1707 size = _gnutls_read_uint16 (pdata);
1708 pdata += 2;
1710 DECR_LEN (dsize, size);
1712 sig.data = pdata;
1713 sig.size = size;
1715 ret = _gnutls_get_auth_info_pcert (&peer_cert,
1716 session->security_parameters.cert_type,
1717 info);
1719 if (ret < 0)
1721 gnutls_assert ();
1722 return ret;
1725 if ((ret =
1726 _gnutls_handshake_verify_crt_vrfy (session, &peer_cert, &sig,
1727 sign_algo)) < 0)
1729 gnutls_assert ();
1730 gnutls_pcert_deinit (&peer_cert);
1731 return ret;
1733 gnutls_pcert_deinit (&peer_cert);
1735 return 0;
1739 _gnutls_gen_cert_server_cert_req (gnutls_session_t session,
1740 gnutls_buffer_st * data)
1742 gnutls_certificate_credentials_t cred;
1743 int size, ret;
1744 uint8_t tmp_data[CERTTYPE_SIZE];
1745 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1747 /* Now we need to generate the RDN sequence. This is
1748 * already in the CERTIFICATE_CRED structure, to improve
1749 * performance.
1752 cred = (gnutls_certificate_credentials_t)
1753 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1754 if (cred == NULL)
1756 gnutls_assert ();
1757 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1760 size = CERTTYPE_SIZE + 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1763 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1764 session->internals.ignore_rdn_sequence == 0)
1765 size += cred->x509_rdn_sequence.size;
1767 if (_gnutls_version_has_selectable_sighash (ver))
1768 /* Need two bytes to announce the number of supported hash
1769 functions (see below). */
1770 size += MAX_SIGN_ALGO_SIZE;
1772 tmp_data[0] = CERTTYPE_SIZE - 1;
1773 tmp_data[1] = RSA_SIGN;
1774 tmp_data[2] = DSA_SIGN;
1775 tmp_data[3] = ECDSA_SIGN; /* only these for now */
1777 ret = _gnutls_buffer_append_data (data, tmp_data, CERTTYPE_SIZE);
1778 if (ret < 0)
1779 return gnutls_assert_val (ret);
1781 if (_gnutls_version_has_selectable_sighash (ver))
1783 uint8_t p[MAX_SIGN_ALGO_SIZE];
1785 ret =
1786 _gnutls_sign_algorithm_write_params (session, p, MAX_SIGN_ALGO_SIZE);
1787 if (ret < 0)
1789 gnutls_assert ();
1790 return ret;
1793 /* recalculate size */
1794 size -= MAX_SIGN_ALGO_SIZE + ret;
1796 ret = _gnutls_buffer_append_data (data, p, ret);
1797 if (ret < 0)
1798 return gnutls_assert_val (ret);
1801 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1802 session->internals.ignore_rdn_sequence == 0)
1804 ret =
1805 _gnutls_buffer_append_data_prefix (data, 16,
1806 cred->x509_rdn_sequence.data,
1807 cred->x509_rdn_sequence.size);
1808 if (ret < 0)
1809 return gnutls_assert_val (ret);
1811 else
1813 ret = _gnutls_buffer_append_prefix (data, 16, 0);
1814 if (ret < 0)
1815 return gnutls_assert_val (ret);
1818 return data->length;
1822 /* This function will return the appropriate certificate to use.
1823 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1824 * The return value is a negative error code on error.
1826 * It is normal to return 0 with no certificates in client side.
1830 _gnutls_get_selected_cert (gnutls_session_t session,
1831 gnutls_pcert_st ** apr_cert_list,
1832 int *apr_cert_list_length,
1833 gnutls_privkey_t * apr_pkey)
1835 if (session->security_parameters.entity == GNUTLS_SERVER)
1838 /* select_client_cert() has been called before.
1841 *apr_cert_list = session->internals.selected_cert_list;
1842 *apr_pkey = session->internals.selected_key;
1843 *apr_cert_list_length = session->internals.selected_cert_list_length;
1845 if (*apr_cert_list_length == 0 || *apr_cert_list == NULL)
1847 gnutls_assert ();
1848 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1852 else
1853 { /* CLIENT SIDE
1856 /* we have already decided which certificate
1857 * to send.
1859 *apr_cert_list = session->internals.selected_cert_list;
1860 *apr_cert_list_length = session->internals.selected_cert_list_length;
1861 *apr_pkey = session->internals.selected_key;
1865 return 0;
1868 /* converts the given x509 certificate list to gnutls_pcert_st* and allocates
1869 * space for them.
1871 static gnutls_pcert_st *
1872 alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, unsigned ncerts)
1874 gnutls_pcert_st *local_certs;
1875 int ret = 0;
1876 unsigned i, j;
1878 if (certs == NULL)
1879 return NULL;
1881 local_certs = gnutls_malloc (sizeof (gnutls_pcert_st) * ncerts);
1882 if (local_certs == NULL)
1884 gnutls_assert ();
1885 return NULL;
1888 for (i = 0; i < ncerts; i++)
1890 ret = gnutls_pcert_import_x509 (&local_certs[i], certs[i], 0);
1891 if (ret < 0)
1892 break;
1895 if (ret < 0)
1897 gnutls_assert ();
1898 for (j = 0; j < i; j++)
1900 gnutls_pcert_deinit (&local_certs[j]);
1902 gnutls_free (local_certs);
1903 return NULL;
1906 return local_certs;
1909 /* converts the given x509 key to gnutls_privkey* and allocates
1910 * space for it.
1912 static gnutls_privkey_t
1913 alloc_and_load_x509_key (gnutls_x509_privkey_t key, int deinit)
1915 gnutls_privkey_t local_key;
1916 int ret = 0;
1918 if (key == NULL)
1919 return NULL;
1921 ret = gnutls_privkey_init (&local_key);
1922 if (ret < 0)
1924 gnutls_assert ();
1925 return NULL;
1928 ret =
1929 gnutls_privkey_import_x509 (local_key, key,
1930 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE :
1932 if (ret < 0)
1934 gnutls_assert ();
1935 gnutls_privkey_deinit (local_key);
1936 return NULL;
1939 return local_key;
1942 /* converts the given pgp certificate to gnutls_cert* and allocates
1943 * space for them.
1945 #ifdef ENABLE_OPENPGP
1946 static gnutls_pcert_st *
1947 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
1949 gnutls_pcert_st *local_certs;
1950 int ret = 0;
1952 if (cert == NULL)
1953 return NULL;
1955 local_certs = gnutls_malloc (sizeof (gnutls_pcert_st));
1956 if (local_certs == NULL)
1958 gnutls_assert ();
1959 return NULL;
1962 ret = gnutls_pcert_import_openpgp (local_certs, cert, 0);
1963 if (ret < 0)
1965 gnutls_assert ();
1966 return NULL;
1969 if (ret < 0)
1971 gnutls_assert ();
1972 gnutls_pcert_deinit (local_certs);
1973 gnutls_free (local_certs);
1974 return NULL;
1977 return local_certs;
1980 /* converts the given raw key to gnutls_privkey* and allocates
1981 * space for it.
1983 static gnutls_privkey_t
1984 alloc_and_load_pgp_key (gnutls_openpgp_privkey_t key, int deinit)
1986 gnutls_privkey_t local_key;
1987 int ret = 0;
1989 if (key == NULL)
1990 return NULL;
1992 ret = gnutls_privkey_init (&local_key);
1993 if (ret < 0)
1995 gnutls_assert ();
1996 return NULL;
1999 ret =
2000 gnutls_privkey_import_openpgp (local_key, key,
2001 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
2002 : 0);
2003 if (ret < 0)
2005 gnutls_assert ();
2006 gnutls_privkey_deinit (local_key);
2007 return NULL;
2010 return local_key;
2012 #endif
2014 #ifdef ENABLE_PKCS11
2016 /* converts the given raw key to gnutls_privkey* and allocates
2017 * space for it.
2019 static gnutls_privkey_t
2020 alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t key, int deinit)
2022 gnutls_privkey_t local_key;
2023 int ret = 0;
2025 if (key == NULL)
2026 return NULL;
2028 ret = gnutls_privkey_init (&local_key);
2029 if (ret < 0)
2031 gnutls_assert ();
2032 return NULL;
2035 ret =
2036 gnutls_privkey_import_pkcs11 (local_key, key,
2037 deinit ? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
2038 : 0);
2039 if (ret < 0)
2041 gnutls_assert ();
2042 gnutls_privkey_deinit (local_key);
2043 return NULL;
2046 return local_key;
2049 #endif
2051 void
2052 _gnutls_selected_certs_deinit (gnutls_session_t session)
2054 if (session->internals.selected_need_free != 0)
2056 int i;
2058 for (i = 0; i < session->internals.selected_cert_list_length; i++)
2060 gnutls_pcert_deinit (&session->internals.selected_cert_list[i]);
2062 gnutls_free (session->internals.selected_cert_list);
2063 session->internals.selected_cert_list = NULL;
2064 session->internals.selected_cert_list_length = 0;
2066 gnutls_privkey_deinit(session->internals.selected_key);
2067 session->internals.selected_key = NULL;
2070 return;
2073 void
2074 _gnutls_selected_certs_set (gnutls_session_t session,
2075 gnutls_pcert_st * certs, int ncerts,
2076 gnutls_privkey_t key, int need_free)
2078 _gnutls_selected_certs_deinit (session);
2080 session->internals.selected_cert_list = certs;
2081 session->internals.selected_cert_list_length = ncerts;
2082 session->internals.selected_key = key;
2083 session->internals.selected_need_free = need_free;
2087 static void get_server_name(gnutls_session_t session, uint8_t* name, size_t max_name_size)
2089 int ret, i;
2090 size_t max_name;
2091 unsigned int type;
2093 ret = 0;
2094 for (i=0; !(ret<0);i++)
2096 max_name = max_name_size;
2097 ret = gnutls_server_name_get (session, name, &max_name, &type, i);
2098 if (ret >= 0 && type == GNUTLS_NAME_DNS)
2099 return;
2102 name[0] = 0;
2104 return;
2107 /* finds the most appropriate certificate in the cert list.
2108 * The 'appropriate' is defined by the user.
2110 * requested_algo holds the parameters required by the peer (RSA, DSA
2111 * or -1 for any).
2113 * Returns 0 on success and a negative error code on error. The
2114 * selected certificate will be in session->internals.selected_*.
2118 _gnutls_server_select_cert (gnutls_session_t session,
2119 gnutls_pk_algorithm_t * pk_algos,
2120 size_t pk_algos_size)
2122 unsigned i, j;
2123 int idx, ret;
2124 gnutls_certificate_credentials_t cred;
2125 char server_name[MAX_CN];
2127 cred = (gnutls_certificate_credentials_t)
2128 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
2129 if (cred == NULL)
2131 gnutls_assert ();
2132 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2135 /* If the callback which retrieves certificate has been set,
2136 * use it and leave.
2138 if (cred->server_get_cert_callback || cred->get_cert_callback
2139 || cred->get_cert_callback2)
2141 ret = call_get_cert_callback (session, NULL, 0, NULL, 0);
2142 if (ret < 0)
2143 return gnutls_assert_val (ret);
2144 return ret;
2147 /* Otherwise... */
2149 get_server_name(session, (unsigned char*)server_name, sizeof(server_name));
2151 idx = -1; /* default is use no certificate */
2153 /* find certificates that match the requested server_name
2156 if (server_name[0] != 0)
2158 for (i = 0; i < cred->ncerts; i++)
2160 if (cred->certs[i].names != NULL && _gnutls_str_array_match(cred->certs[i].names, server_name) != 0)
2162 /* if requested algorithms are also compatible select it */
2163 gnutls_pk_algorithm pk =
2164 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
2165 NULL);
2167 _gnutls_handshake_log("HSK[%p]: Requested server name: '%s', ctype: %s (%d)", session, server_name,
2168 gnutls_certificate_type_get_name (session->security_parameters.cert_type),
2169 session->security_parameters.cert_type);
2171 if (session->security_parameters.cert_type == cred->certs[i].cert_list[0].type)
2173 for (j = 0; j < pk_algos_size; j++)
2174 if (pk_algos[j] == pk)
2176 idx = i;
2177 goto finished;
2184 for (j = 0; j < pk_algos_size; j++)
2186 _gnutls_handshake_log
2187 ("HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n",
2188 session, gnutls_pk_get_name (pk_algos[j]), pk_algos[j],
2189 gnutls_certificate_type_get_name (session->security_parameters.
2190 cert_type),
2191 session->security_parameters.cert_type);
2193 for (i = 0; i < cred->ncerts; i++)
2195 gnutls_pk_algorithm pk =
2196 gnutls_pubkey_get_pk_algorithm (cred->certs[i].cert_list[0].pubkey,
2197 NULL);
2198 /* find one compatible certificate
2200 _gnutls_handshake_log
2201 ("HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n",
2202 session, i, gnutls_pk_get_name (pk), pk,
2203 gnutls_certificate_type_get_name (cred->certs[i].cert_list[0].type),
2204 cred->certs[i].cert_list[0].type);
2206 if (pk_algos[j] == pk)
2208 /* if cert type matches
2210 /* *INDENT-OFF* */
2211 if (session->security_parameters.cert_type == cred->certs[i].cert_list[0].type)
2213 idx = i;
2214 goto finished;
2216 /* *INDENT-ON* */
2221 /* store the certificate pointer for future use, in the handshake.
2222 * (This will allow not calling this callback again.)
2224 finished:
2225 if (idx >= 0)
2227 _gnutls_selected_certs_set (session,
2228 &cred->certs[idx].cert_list[0],
2229 cred->certs[idx].cert_list_length,
2230 cred->pkey[idx], 0);
2232 else
2234 gnutls_assert ();
2235 /* Certificate does not support REQUESTED_ALGO. */
2236 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
2239 return 0;
2242 /* Frees the rsa_info_st structure.
2244 void
2245 _gnutls_free_rsa_info (rsa_info_st * rsa)
2247 _gnutls_free_datum (&rsa->modulus);
2248 _gnutls_free_datum (&rsa->exponent);