Add.
[gnutls.git] / lib / auth_cert.c
blobf0cb4272055eff91601d9f91b1e18e0c3ce57f08
1 /*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
4 * Author: Nikos Mavroyanopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library 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 2.1 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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
25 /* The certificate authentication functions which are needed in the handshake,
26 * and are common to RSA and DHE key exchange, are in this file.
29 #include <gnutls_int.h>
30 #include "gnutls_auth_int.h"
31 #include "gnutls_errors.h"
32 #include <gnutls_cert.h>
33 #include <auth_cert.h>
34 #include "gnutls_dh.h"
35 #include "gnutls_num.h"
36 #include "libtasn1.h"
37 #include "gnutls_datum.h"
38 #include <gnutls_pk.h>
39 #include <gnutls_algorithms.h>
40 #include <gnutls_global.h>
41 #include <gnutls_record.h>
42 #include <gnutls_sig.h>
43 #include <gnutls_state.h>
44 #include <gnutls_pk.h>
45 #include <gnutls_x509.h>
46 #include <gnutls_extra_hooks.h>
47 #include "debug.h"
49 static gnutls_cert *alloc_and_load_x509_certs (gnutls_x509_crt_t * certs,
50 unsigned);
51 static gnutls_privkey *alloc_and_load_x509_key (gnutls_x509_privkey_t key);
52 static gnutls_cert *alloc_and_load_pgp_certs (gnutls_openpgp_key_t cert);
53 static gnutls_privkey *alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t
54 key);
57 /* Copies data from a internal certificate struct (gnutls_cert) to
58 * exported certificate struct (cert_auth_info_t)
60 static int
61 _gnutls_copy_certificate_auth_info (cert_auth_info_t info,
62 gnutls_cert * cert, int ncerts)
64 /* Copy peer's information to auth_info_t
66 int ret, i, j;
68 if (ncerts == 0)
70 info->raw_certificate_list = NULL;
71 info->ncerts = 0;
72 return 0;
75 info->raw_certificate_list =
76 gnutls_calloc (1, sizeof (gnutls_datum_t) * ncerts);
77 if (info->raw_certificate_list == NULL)
79 gnutls_assert ();
80 return GNUTLS_E_MEMORY_ERROR;
83 for (i = 0; i < ncerts; i++)
85 if (cert->raw.size > 0)
87 ret =
88 _gnutls_set_datum (&info->
89 raw_certificate_list[i],
90 cert[i].raw.data, cert[i].raw.size);
91 if (ret < 0)
93 gnutls_assert ();
94 goto clear;
98 info->ncerts = ncerts;
100 return 0;
102 clear:
104 for (j = 0; j < i; j++)
105 _gnutls_free_datum (&info->raw_certificate_list[j]);
107 gnutls_free (info->raw_certificate_list);
108 info->raw_certificate_list = NULL;
110 return ret;
116 /* returns 0 if the algo_to-check exists in the pk_algos list,
117 * -1 otherwise.
119 inline static int
120 _gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t *
121 pk_algos, int pk_algos_length,
122 gnutls_pk_algorithm_t algo_to_check)
124 int i;
125 for (i = 0; i < pk_algos_length; i++)
127 if (algo_to_check == pk_algos[i])
129 return 0;
132 return -1;
136 /* Returns the issuer's Distinguished name in odn, of the certificate
137 * specified in cert.
139 static int
140 _gnutls_cert_get_issuer_dn (gnutls_cert * cert, gnutls_datum_t * odn)
142 ASN1_TYPE dn;
143 int len, result;
144 int start, end;
146 if ((result = asn1_create_element
147 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS)
149 gnutls_assert ();
150 return _gnutls_asn2err (result);
153 result = asn1_der_decoding (&dn, cert->raw.data, cert->raw.size, NULL);
154 if (result != ASN1_SUCCESS)
156 /* couldn't decode DER */
157 gnutls_assert ();
158 asn1_delete_structure (&dn);
159 return _gnutls_asn2err (result);
162 result = asn1_der_decoding_startEnd (dn, cert->raw.data, cert->raw.size,
163 "tbsCertificate.issuer", &start, &end);
165 if (result != ASN1_SUCCESS)
167 /* couldn't decode DER */
168 gnutls_assert ();
169 asn1_delete_structure (&dn);
170 return _gnutls_asn2err (result);
172 asn1_delete_structure (&dn);
174 len = end - start + 1;
176 odn->size = len;
177 odn->data = &cert->raw.data[start];
179 return 0;
183 /* Locates the most appropriate x509 certificate using the
184 * given DN. If indx == -1 then no certificate was found.
186 * That is to guess which certificate to use, based on the
187 * CAs and sign algorithms supported by the peer server.
189 static int
190 _find_x509_cert (const gnutls_certificate_credentials_t cred,
191 opaque * _data, size_t _data_size,
192 const gnutls_pk_algorithm_t * pk_algos,
193 int pk_algos_length, int *indx)
195 unsigned size;
196 gnutls_datum_t odn;
197 opaque *data = _data;
198 ssize_t data_size = _data_size;
199 unsigned i, j;
200 int result, cert_pk;
202 *indx = -1;
207 DECR_LENGTH_RET (data_size, 2, 0);
208 size = _gnutls_read_uint16 (data);
209 DECR_LENGTH_RET (data_size, size, 0);
210 data += 2;
212 for (i = 0; i < cred->ncerts; i++)
214 for (j = 0; j < cred->cert_list_length[i]; j++)
216 if ((result =
217 _gnutls_cert_get_issuer_dn (&cred->
218 cert_list[i][j], &odn)) < 0)
220 gnutls_assert ();
221 return result;
224 if (odn.size != size)
225 continue;
227 /* If the DN matches and
228 * the *_SIGN algorithm matches
229 * the cert is our cert!
231 cert_pk = cred->cert_list[i][0].subject_pk_algorithm;
233 if ((memcmp (odn.data, data, size) == 0) &&
234 (_gnutls_check_pk_algo_in_list
235 (pk_algos, pk_algos_length, cert_pk) == 0))
237 *indx = i;
238 break;
241 if (*indx != -1)
242 break;
245 if (*indx != -1)
246 break;
248 /* move to next record */
249 data += size;
252 while (1);
254 return 0;
258 /* Locates the most appropriate openpgp cert
260 static int
261 _find_openpgp_cert (const gnutls_certificate_credentials_t cred,
262 gnutls_pk_algorithm_t * pk_algos,
263 int pk_algos_length, int *indx)
265 unsigned i, j;
267 *indx = -1;
269 for (i = 0; i < cred->ncerts; i++)
271 for (j = 0; j < cred->cert_list_length[i]; j++)
274 /* If the *_SIGN algorithm matches
275 * the cert is our cert!
277 if ((_gnutls_check_pk_algo_in_list
278 (pk_algos, pk_algos_length,
279 cred->cert_list[i][0].subject_pk_algorithm) == 0)
280 && (cred->cert_list[i][0].cert_type == GNUTLS_CRT_OPENPGP))
282 *indx = i;
283 break;
286 if (*indx != -1)
287 break;
290 return 0;
293 /* Returns the number of issuers in the server's
294 * certificate request packet.
296 static int
297 get_issuers_num (gnutls_session_t session, opaque * data, ssize_t data_size)
299 int issuers_dn_len = 0, result;
300 unsigned size;
302 /* Count the number of the given issuers;
303 * This is used to allocate the issuers_dn without
304 * using realloc().
307 if (data_size == 0 || data == NULL)
308 return 0;
310 if (data_size > 0)
313 /* This works like DECR_LEN()
315 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
316 DECR_LENGTH_COM (data_size, 2, goto error);
317 size = _gnutls_read_uint16 (data);
319 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
320 DECR_LENGTH_COM (data_size, size, goto error);
322 data += 2;
324 if (size > 0)
326 issuers_dn_len++;
327 data += size;
330 if (data_size == 0)
331 break;
334 while (1);
336 return issuers_dn_len;
338 error:
339 return result;
342 /* Returns the issuers in the server's certificate request
343 * packet.
345 static int
346 get_issuers (gnutls_session_t session,
347 gnutls_datum_t * issuers_dn, int issuers_len,
348 opaque * data, size_t data_size)
350 int i;
351 unsigned size;
353 if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
354 return 0;
356 /* put the requested DNs to req_dn, only in case
357 * of X509 certificates.
359 if (issuers_len > 0)
362 for (i = 0; i < issuers_len; i++)
364 /* The checks here for the buffer boundaries
365 * are not needed since the buffer has been
366 * parsed above.
368 data_size -= 2;
370 size = _gnutls_read_uint16 (data);
372 data += 2;
374 issuers_dn[i].data = data;
375 issuers_dn[i].size = size;
377 data += size;
381 return 0;
384 /* Calls the client get callback.
386 static int
387 call_get_cert_callback (gnutls_session_t session,
388 gnutls_datum_t * issuers_dn,
389 int issuers_dn_length,
390 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
392 unsigned i;
393 gnutls_cert *local_certs = NULL;
394 gnutls_privkey *local_key = NULL;
395 gnutls_retr_st st;
396 int ret;
397 gnutls_certificate_type_t type = gnutls_certificate_type_get (session);
398 gnutls_certificate_credentials_t cred;
400 cred = (gnutls_certificate_credentials_t)
401 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
402 if (cred == NULL)
404 gnutls_assert ();
405 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
408 memset (&st, 0, sizeof (st));
410 if (session->security_parameters.entity == GNUTLS_SERVER)
412 ret = cred->server_get_cert_callback (session, &st);
414 else
415 { /* CLIENT */
416 ret =
417 cred->client_get_cert_callback (session,
418 issuers_dn, issuers_dn_length,
419 pk_algos, pk_algos_length, &st);
422 if (ret < 0)
424 gnutls_assert ();
425 return GNUTLS_E_INTERNAL_ERROR;
428 if (st.ncerts == 0)
429 return 0; /* no certificate was selected */
431 if (type != st.type)
433 gnutls_assert ();
434 ret = GNUTLS_E_INVALID_REQUEST;
435 goto cleanup;
438 if (type == GNUTLS_CRT_X509)
440 local_certs = alloc_and_load_x509_certs (st.cert.x509, st.ncerts);
441 if (local_certs != NULL)
442 local_key = alloc_and_load_x509_key (st.key.x509);
445 else
446 { /* PGP */
447 if (st.ncerts > 1)
449 gnutls_assert ();
450 ret = GNUTLS_E_INVALID_REQUEST;
451 goto cleanup;
454 local_certs = alloc_and_load_pgp_certs (st.cert.pgp);
455 if (local_certs != NULL)
456 local_key = alloc_and_load_pgp_key (st.key.pgp);
460 _gnutls_selected_certs_set (session, local_certs,
461 (local_certs != NULL) ? st.ncerts : 0,
462 local_key, 1);
464 ret = 0;
466 cleanup:
468 if (st.type == GNUTLS_CRT_X509)
470 if (st.deinit_all)
472 for (i = 0; i < st.ncerts; i++)
474 gnutls_x509_crt_deinit (st.cert.x509[i]);
476 gnutls_free (st.cert.x509);
477 gnutls_x509_privkey_deinit (st.key.x509);
480 else
482 if (st.deinit_all)
484 if (_E_gnutls_openpgp_key_deinit == NULL ||
485 _E_gnutls_openpgp_privkey_deinit == NULL)
487 gnutls_assert ();
488 return GNUTLS_E_INIT_LIBEXTRA;
491 _E_gnutls_openpgp_key_deinit (st.cert.pgp);
492 _E_gnutls_openpgp_privkey_deinit (st.key.pgp);
496 return ret;
499 /* Finds the appropriate certificate depending on the cA Distinguished name
500 * advertized by the server. If none matches then returns 0 and -1 as index.
501 * In case of an error a negative value, is returned.
503 * 20020128: added ability to select a certificate depending on the SIGN
504 * algorithm (only in automatic mode).
506 static int
507 _select_client_cert (gnutls_session_t session,
508 opaque * _data, size_t _data_size,
509 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
511 int result;
512 int indx = -1;
513 gnutls_certificate_credentials_t cred;
514 opaque *data = _data;
515 ssize_t data_size = _data_size;
516 int issuers_dn_length;
517 gnutls_datum_t *issuers_dn = NULL;
519 cred = (gnutls_certificate_credentials_t)
520 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
521 if (cred == NULL)
523 gnutls_assert ();
524 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
527 if (cred->client_get_cert_callback != NULL)
530 /* use a callback to get certificate
532 if (session->security_parameters.cert_type != GNUTLS_CRT_X509)
533 issuers_dn_length = 0;
534 else
536 issuers_dn_length = get_issuers_num (session, data, data_size);
537 if (issuers_dn_length < 0)
539 gnutls_assert ();
540 return issuers_dn_length;
543 if (issuers_dn_length > 0)
545 issuers_dn =
546 gnutls_malloc (sizeof (gnutls_datum_t) * issuers_dn_length);
547 if (issuers_dn == NULL)
549 gnutls_assert ();
550 return GNUTLS_E_MEMORY_ERROR;
553 result =
554 get_issuers (session, issuers_dn, issuers_dn_length,
555 data, data_size);
556 if (result < 0)
558 gnutls_assert ();
559 goto cleanup;
564 result =
565 call_get_cert_callback (session, issuers_dn, issuers_dn_length,
566 pk_algos, pk_algos_length);
567 goto cleanup;
570 else
572 /* If we have no callbacks, try to guess.
574 result = 0;
576 if (session->security_parameters.cert_type == GNUTLS_CRT_X509)
577 result =
578 _find_x509_cert (cred, _data, _data_size,
579 pk_algos, pk_algos_length, &indx);
581 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP)
582 result = _find_openpgp_cert (cred, pk_algos, pk_algos_length, &indx);
585 if (result < 0)
587 gnutls_assert ();
588 return result;
591 if (indx >= 0)
593 _gnutls_selected_certs_set (session,
594 &cred->cert_list[indx][0],
595 cred->cert_list_length[indx],
596 &cred->pkey[indx], 0);
598 else
600 _gnutls_selected_certs_set (session, NULL, 0, NULL, 0);
603 result = 0;
606 cleanup:
607 gnutls_free (issuers_dn);
608 return result;
612 /* Generate client certificate
616 _gnutls_gen_x509_crt (gnutls_session_t session, opaque ** data)
618 int ret, i;
619 opaque *pdata;
620 gnutls_cert *apr_cert_list;
621 gnutls_privkey *apr_pkey;
622 int apr_cert_list_length;
624 /* find the appropriate certificate
626 if ((ret =
627 _gnutls_get_selected_cert (session, &apr_cert_list,
628 &apr_cert_list_length, &apr_pkey)) < 0)
630 gnutls_assert ();
631 return ret;
634 ret = 3;
635 for (i = 0; i < apr_cert_list_length; i++)
637 ret += apr_cert_list[i].raw.size + 3;
638 /* hold size
639 * for uint24 */
642 /* if no certificates were found then send:
643 * 0B 00 00 03 00 00 00 // Certificate with no certs
644 * instead of:
645 * 0B 00 00 00 // empty certificate handshake
647 * ( the above is the whole handshake message, not
648 * the one produced here )
651 (*data) = gnutls_malloc (ret);
652 pdata = (*data);
654 if (pdata == NULL)
656 gnutls_assert ();
657 return GNUTLS_E_MEMORY_ERROR;
659 _gnutls_write_uint24 (ret - 3, pdata);
660 pdata += 3;
661 for (i = 0; i < apr_cert_list_length; i++)
663 _gnutls_write_datum24 (pdata, apr_cert_list[i].raw);
664 pdata += (3 + apr_cert_list[i].raw.size);
667 return ret;
670 enum PGPKeyDescriptorType
671 { PGP_KEY_FINGERPRINT, PGP_KEY };
674 _gnutls_gen_openpgp_certificate (gnutls_session_t session, opaque ** data)
676 int ret;
677 opaque *pdata;
678 gnutls_cert *apr_cert_list;
679 gnutls_privkey *apr_pkey;
680 int apr_cert_list_length;
682 /* find the appropriate certificate */
683 if ((ret =
684 _gnutls_get_selected_cert (session, &apr_cert_list,
685 &apr_cert_list_length, &apr_pkey)) < 0)
687 gnutls_assert ();
688 return ret;
691 ret = 3 + 1 + 3;
693 if (apr_cert_list_length > 0)
694 ret += apr_cert_list[0].raw.size;
696 (*data) = gnutls_malloc (ret);
697 pdata = (*data);
699 if (pdata == NULL)
701 gnutls_assert ();
702 return GNUTLS_E_MEMORY_ERROR;
705 _gnutls_write_uint24 (ret - 3, pdata);
706 pdata += 3;
708 *pdata = PGP_KEY; /* whole key */
709 pdata++;
711 if (apr_cert_list_length > 0)
713 _gnutls_write_datum24 (pdata, apr_cert_list[0].raw);
714 pdata += (3 + apr_cert_list[0].raw.size);
716 else /* empty - no certificate */
717 _gnutls_write_uint24 (0, pdata);
719 return ret;
723 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, opaque ** data)
725 int ret, packet_size;
726 size_t fpr_size;
727 opaque *pdata;
728 gnutls_cert *apr_cert_list;
729 gnutls_privkey *apr_pkey;
730 int apr_cert_list_length;
732 /* find the appropriate certificate */
733 if ((ret =
734 _gnutls_get_selected_cert (session, &apr_cert_list,
735 &apr_cert_list_length, &apr_pkey)) < 0)
737 gnutls_assert ();
738 return ret;
741 packet_size = 3 + 1;
743 /* Only v4 fingerprints are sent
745 if (apr_cert_list_length > 0 && apr_cert_list[0].version == 4)
746 packet_size += 20 + 1;
747 else /* empty certificate case */
748 return _gnutls_gen_openpgp_certificate (session, data);
750 (*data) = gnutls_malloc (packet_size);
751 pdata = (*data);
753 if (pdata == NULL)
755 gnutls_assert ();
756 return GNUTLS_E_MEMORY_ERROR;
759 _gnutls_write_uint24 (packet_size - 3, pdata);
760 pdata += 3;
762 *pdata = PGP_KEY_FINGERPRINT; /* key fingerprint */
763 pdata++;
765 *pdata = 20;
766 pdata++;
768 fpr_size = 20;
770 if (_E_gnutls_openpgp_fingerprint == NULL)
772 gnutls_assert ();
773 return GNUTLS_E_INIT_LIBEXTRA;
776 if ((ret =
777 _E_gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, pdata,
778 &fpr_size)) < 0)
780 gnutls_assert ();
781 return ret;
784 return packet_size;
790 _gnutls_gen_cert_client_certificate (gnutls_session_t session, opaque ** data)
792 switch (session->security_parameters.cert_type)
794 case GNUTLS_CRT_OPENPGP:
795 if (_gnutls_openpgp_send_fingerprint (session) == 0)
796 return _gnutls_gen_openpgp_certificate (session, data);
797 else
798 return _gnutls_gen_openpgp_certificate_fpr (session, data);
800 case GNUTLS_CRT_X509:
801 return _gnutls_gen_x509_crt (session, data);
803 default:
804 gnutls_assert ();
805 return GNUTLS_E_INTERNAL_ERROR;
810 _gnutls_gen_cert_server_certificate (gnutls_session_t session, opaque ** data)
812 switch (session->security_parameters.cert_type)
814 case GNUTLS_CRT_OPENPGP:
815 return _gnutls_gen_openpgp_certificate (session, data);
816 case GNUTLS_CRT_X509:
817 return _gnutls_gen_x509_crt (session, data);
818 default:
819 gnutls_assert ();
820 return GNUTLS_E_INTERNAL_ERROR;
824 /* Process server certificate
827 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
829 _gnutls_proc_x509_server_certificate (gnutls_session_t session,
830 opaque * data, size_t data_size)
832 int size, len, ret;
833 opaque *p = data;
834 cert_auth_info_t info;
835 gnutls_certificate_credentials_t cred;
836 ssize_t dsize = data_size;
837 int i, j, x;
838 gnutls_cert *peer_certificate_list;
839 int peer_certificate_list_size = 0;
840 gnutls_datum_t tmp;
842 cred = (gnutls_certificate_credentials_t)
843 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
844 if (cred == NULL)
846 gnutls_assert ();
847 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
851 if ((ret =
852 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
853 sizeof (cert_auth_info_st), 1)) < 0)
855 gnutls_assert ();
856 return ret;
859 info = _gnutls_get_auth_info (session);
861 if (data == NULL || data_size == 0)
863 gnutls_assert ();
864 /* no certificate was sent */
865 return GNUTLS_E_NO_CERTIFICATE_FOUND;
868 DECR_LEN (dsize, 3);
869 size = _gnutls_read_uint24 (p);
870 p += 3;
872 if (size == 0)
874 gnutls_assert ();
875 /* no certificate was sent */
876 return GNUTLS_E_NO_CERTIFICATE_FOUND;
879 i = dsize;
880 while (i > 0)
882 DECR_LEN (dsize, 3);
883 len = _gnutls_read_uint24 (p);
884 p += 3;
885 DECR_LEN (dsize, len);
886 peer_certificate_list_size++;
887 p += len;
888 i -= len + 3;
891 if (peer_certificate_list_size == 0)
893 gnutls_assert ();
894 return GNUTLS_E_NO_CERTIFICATE_FOUND;
897 /* Ok we now allocate the memory to hold the
898 * certificate list
901 peer_certificate_list =
902 gnutls_malloc (sizeof (gnutls_cert) * (peer_certificate_list_size));
904 if (peer_certificate_list == NULL)
906 gnutls_assert ();
907 return GNUTLS_E_MEMORY_ERROR;
909 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
910 peer_certificate_list_size);
912 p = data + 3;
914 /* Now we start parsing the list (again).
915 * We don't use DECR_LEN since the list has
916 * been parsed before.
919 for (j = 0; j < peer_certificate_list_size; j++)
921 len = _gnutls_read_uint24 (p);
922 p += 3;
924 tmp.size = len;
925 tmp.data = p;
927 if ((ret =
928 _gnutls_x509_raw_cert_to_gcert (&peer_certificate_list
929 [j], &tmp,
930 CERT_ONLY_EXTENSIONS)) < 0)
932 gnutls_assert ();
933 goto cleanup;
936 p += len;
940 if ((ret =
941 _gnutls_copy_certificate_auth_info (info,
942 peer_certificate_list,
943 peer_certificate_list_size)) < 0)
945 gnutls_assert ();
946 goto cleanup;
949 if ((ret =
950 _gnutls_check_key_usage (&peer_certificate_list[0],
951 gnutls_kx_get (session))) < 0)
953 gnutls_assert ();
954 goto cleanup;
957 ret = 0;
959 cleanup:
960 CLEAR_CERTS;
961 gnutls_free (peer_certificate_list);
962 return ret;
966 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
968 _gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
969 opaque * data, size_t data_size)
971 int size, ret, len;
972 opaque *p = data;
973 cert_auth_info_t info;
974 gnutls_certificate_credentials_t cred;
975 ssize_t dsize = data_size;
976 int i, x;
977 gnutls_cert *peer_certificate_list = NULL;
978 int peer_certificate_list_size = 0;
979 gnutls_datum_t tmp, akey = { NULL, 0 };
981 cred = (gnutls_certificate_credentials_t)
982 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
983 if (cred == NULL)
985 gnutls_assert ();
986 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
989 if ((ret =
990 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
991 sizeof (cert_auth_info_st), 1)) < 0)
993 gnutls_assert ();
994 return ret;
997 info = _gnutls_get_auth_info (session);
999 if (data == NULL || data_size == 0)
1001 gnutls_assert ();
1002 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1005 DECR_LEN (dsize, 3);
1006 size = _gnutls_read_uint24 (p);
1007 p += 3;
1009 if (size == 0)
1011 gnutls_assert ();
1012 /* no certificate was sent */
1013 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1015 i = dsize;
1017 /* Read PGPKeyDescriptor */
1018 DECR_LEN (dsize, 1);
1019 if (*p == PGP_KEY_FINGERPRINT)
1020 { /* the fingerprint */
1021 p++;
1023 DECR_LEN (dsize, 1);
1024 len = (uint8_t) * p;
1025 p++;
1027 if (len != 20)
1029 gnutls_assert ();
1030 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED;
1033 DECR_LEN (dsize, 20);
1035 /* request the actual key from our database, or
1036 * a key server or anything.
1038 if (_E_gnutls_openpgp_request_key == NULL)
1040 gnutls_assert ();
1041 return GNUTLS_E_INIT_LIBEXTRA;
1043 if ((ret =
1044 _E_gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
1046 gnutls_assert ();
1047 return ret;
1049 tmp = akey;
1050 peer_certificate_list_size++;
1053 else if (*p == PGP_KEY)
1054 { /* the whole key */
1056 p++;
1058 /* Read the actual certificate */
1059 DECR_LEN (dsize, 3);
1060 len = _gnutls_read_uint24 (p);
1061 p += 3;
1063 if (len == 0)
1065 gnutls_assert ();
1066 /* no certificate was sent */
1067 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1070 DECR_LEN (dsize, len);
1071 peer_certificate_list_size++;
1073 tmp.size = len;
1074 tmp.data = p;
1077 else
1079 gnutls_assert ();
1080 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1083 /* ok we now have the peer's key in tmp datum
1086 if (peer_certificate_list_size == 0)
1088 gnutls_assert ();
1089 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1092 peer_certificate_list =
1093 gnutls_alloca (sizeof (gnutls_cert) * (peer_certificate_list_size));
1094 if (peer_certificate_list == NULL)
1096 gnutls_assert ();
1097 ret = GNUTLS_E_MEMORY_ERROR;
1098 goto cleanup;
1100 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
1101 peer_certificate_list_size);
1103 if (_E_gnutls_openpgp_raw_key_to_gcert == NULL)
1105 gnutls_assert ();
1106 ret = GNUTLS_E_INIT_LIBEXTRA;
1107 goto cleanup;
1110 if ((ret =
1111 _E_gnutls_openpgp_raw_key_to_gcert (&peer_certificate_list[0],
1112 &tmp)) < 0)
1114 gnutls_assert ();
1115 goto cleanup;
1118 if ((ret =
1119 _gnutls_copy_certificate_auth_info (info,
1120 peer_certificate_list,
1121 peer_certificate_list_size)) < 0)
1123 gnutls_assert ();
1124 goto cleanup;
1127 if ((ret =
1128 _gnutls_check_key_usage (&peer_certificate_list[0],
1129 gnutls_kx_get (session))) < 0)
1131 gnutls_assert ();
1132 goto cleanup;
1135 ret = 0;
1137 cleanup:
1139 _gnutls_free_datum (&akey);
1140 CLEAR_CERTS;
1141 gnutls_afree (peer_certificate_list);
1142 return ret;
1147 _gnutls_proc_cert_server_certificate (gnutls_session_t session,
1148 opaque * data, size_t data_size)
1150 switch (session->security_parameters.cert_type)
1152 case GNUTLS_CRT_OPENPGP:
1153 return _gnutls_proc_openpgp_server_certificate (session,
1154 data, data_size);
1155 case GNUTLS_CRT_X509:
1156 return _gnutls_proc_x509_server_certificate (session, data, data_size);
1157 default:
1158 gnutls_assert ();
1159 return GNUTLS_E_INTERNAL_ERROR;
1163 #define MAX_SIGN_ALGOS 2
1164 typedef enum CertificateSigType
1165 { RSA_SIGN = 1, DSA_SIGN
1166 } CertificateSigType;
1168 /* Checks if we support the given signature algorithm
1169 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1170 * if true;
1172 inline static int
1173 _gnutls_check_supported_sign_algo (CertificateSigType algo)
1175 switch (algo)
1177 case RSA_SIGN:
1178 return GNUTLS_PK_RSA;
1179 case DSA_SIGN:
1180 return GNUTLS_PK_DSA;
1183 return -1;
1187 _gnutls_proc_cert_cert_req (gnutls_session_t session, opaque * data,
1188 size_t data_size)
1190 int size, ret;
1191 opaque *p;
1192 gnutls_certificate_credentials_t cred;
1193 cert_auth_info_t info;
1194 ssize_t dsize;
1195 int i, j;
1196 gnutls_pk_algorithm_t pk_algos[MAX_SIGN_ALGOS];
1197 int pk_algos_length;
1198 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1200 cred = (gnutls_certificate_credentials_t)
1201 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1202 if (cred == NULL)
1204 gnutls_assert ();
1205 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1208 if ((ret =
1209 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1210 sizeof (cert_auth_info_st), 0)) < 0)
1212 gnutls_assert ();
1213 return ret;
1216 info = _gnutls_get_auth_info (session);
1218 p = data;
1219 dsize = data_size;
1221 DECR_LEN (dsize, 1);
1222 size = p[0];
1223 p++;
1224 /* check if the sign algorithm is supported.
1226 pk_algos_length = j = 0;
1227 for (i = 0; i < size; i++, p++)
1229 DECR_LEN (dsize, 1);
1230 if ((ret = _gnutls_check_supported_sign_algo (*p)) > 0)
1232 if (j < MAX_SIGN_ALGOS)
1234 pk_algos[j++] = ret;
1235 pk_algos_length++;
1240 if (pk_algos_length == 0)
1242 gnutls_assert ();
1243 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1246 if (ver == GNUTLS_TLS1_2)
1248 /* read supported hashes */
1249 int hash_num;
1250 DECR_LEN (dsize, 1);
1252 hash_num = p[0] & 0xFF;
1253 p++;
1255 DECR_LEN (dsize, hash_num);
1256 p+=hash_num;
1259 /* read the certificate authorities */
1260 DECR_LEN (dsize, 2);
1261 size = _gnutls_read_uint16 (p);
1262 p += 2;
1264 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP && size != 0)
1266 gnutls_assert(); // size should be zero
1267 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1270 DECR_LEN (dsize, size);
1272 /* now we ask the user to tell which one
1273 * he wants to use.
1275 if ((ret =
1276 _select_client_cert (session, p, size, pk_algos, pk_algos_length)) < 0)
1278 gnutls_assert ();
1279 return ret;
1282 /* We should reply with a certificate message,
1283 * even if we have no certificate to send.
1285 session->key->certificate_requested = 1;
1287 return 0;
1291 _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data)
1293 int ret;
1294 gnutls_cert *apr_cert_list;
1295 gnutls_privkey *apr_pkey;
1296 int apr_cert_list_length, size;
1297 gnutls_datum_t signature;
1299 *data = NULL;
1301 /* find the appropriate certificate */
1302 if ((ret =
1303 _gnutls_get_selected_cert (session, &apr_cert_list,
1304 &apr_cert_list_length, &apr_pkey)) < 0)
1306 gnutls_assert ();
1307 return ret;
1310 if (apr_pkey != NULL)
1312 if ((ret =
1313 _gnutls_tls_sign_hdata (session,
1314 &apr_cert_list[0],
1315 apr_pkey, &signature)) < 0)
1317 gnutls_assert ();
1318 return ret;
1321 else
1323 return 0;
1326 *data = gnutls_malloc (signature.size + 2);
1327 if (*data == NULL)
1329 _gnutls_free_datum (&signature);
1330 return GNUTLS_E_MEMORY_ERROR;
1332 size = signature.size;
1333 _gnutls_write_uint16 (size, *data);
1335 memcpy (&(*data)[2], signature.data, size);
1337 _gnutls_free_datum (&signature);
1339 return size + 2;
1343 _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session,
1344 opaque * data, size_t data_size)
1346 int size, ret;
1347 ssize_t dsize = data_size;
1348 opaque *pdata = data;
1349 gnutls_datum_t sig;
1350 cert_auth_info_t info = _gnutls_get_auth_info (session);
1351 gnutls_cert peer_cert;
1353 if (info == NULL || info->ncerts == 0)
1355 gnutls_assert ();
1356 /* we need this in order to get peer's certificate */
1357 return GNUTLS_E_INTERNAL_ERROR;
1360 DECR_LEN (dsize, 2);
1361 size = _gnutls_read_uint16 (pdata);
1362 pdata += 2;
1364 DECR_LEN (dsize, size);
1366 sig.data = pdata;
1367 sig.size = size;
1369 ret = _gnutls_raw_cert_to_gcert (&peer_cert,
1370 session->security_parameters.cert_type,
1371 &info->raw_certificate_list[0],
1372 CERT_NO_COPY);
1374 if (ret < 0)
1376 gnutls_assert ();
1377 return ret;
1380 if ((ret = _gnutls_verify_sig_hdata (session, &peer_cert, &sig)) < 0)
1382 gnutls_assert ();
1383 _gnutls_gcert_deinit (&peer_cert);
1384 return ret;
1386 _gnutls_gcert_deinit (&peer_cert);
1388 return 0;
1391 #define CERTTYPE_SIZE 3
1393 _gnutls_gen_cert_server_cert_req (gnutls_session_t session, opaque ** data)
1395 gnutls_certificate_credentials_t cred;
1396 int size;
1397 opaque *pdata;
1398 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1400 /* Now we need to generate the RDN sequence. This is
1401 * already in the CERTIFICATE_CRED structure, to improve
1402 * performance.
1405 cred = (gnutls_certificate_credentials_t)
1406 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1407 if (cred == NULL)
1409 gnutls_assert ();
1410 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1413 size = CERTTYPE_SIZE + 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1416 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1417 session->internals.ignore_rdn_sequence == 0)
1418 size += cred->x509_rdn_sequence.size;
1420 if (ver == GNUTLS_TLS1_2)
1421 /* Need at least one byte to announce the number of supported hash
1422 functions (see below). */
1423 size += 1;
1425 (*data) = gnutls_malloc (size);
1426 pdata = (*data);
1428 if (pdata == NULL)
1430 gnutls_assert ();
1431 return GNUTLS_E_MEMORY_ERROR;
1434 pdata[0] = CERTTYPE_SIZE - 1;
1436 pdata[1] = RSA_SIGN;
1437 pdata[2] = DSA_SIGN; /* only these for now */
1438 pdata += CERTTYPE_SIZE;
1440 if (ver == GNUTLS_TLS1_2)
1442 /* Supported hashes (nothing for now -- FIXME). */
1443 *pdata = 0;
1444 pdata++;
1447 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1448 session->internals.ignore_rdn_sequence == 0)
1450 _gnutls_write_datum16 (pdata, cred->x509_rdn_sequence);
1451 /* pdata += cred->x509_rdn_sequence.size + 2; */
1453 else
1455 _gnutls_write_uint16( 0, pdata);
1456 /* pdata+=2; */
1459 return size;
1463 /* This function will return the appropriate certificate to use.
1464 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1465 * The return value is a negative value on error.
1467 * It is normal to return 0 with no certificates in client side.
1471 _gnutls_get_selected_cert (gnutls_session_t session,
1472 gnutls_cert ** apr_cert_list,
1473 int *apr_cert_list_length,
1474 gnutls_privkey ** apr_pkey)
1476 if (session->security_parameters.entity == GNUTLS_SERVER)
1479 /* select_client_cert() has been called before.
1482 *apr_cert_list = session->internals.selected_cert_list;
1483 *apr_pkey = session->internals.selected_key;
1484 *apr_cert_list_length = session->internals.selected_cert_list_length;
1486 if (*apr_cert_list_length == 0 || *apr_pkey == NULL ||
1487 *apr_cert_list == NULL)
1489 gnutls_assert ();
1490 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1494 else
1495 { /* CLIENT SIDE
1498 /* we have already decided which certificate
1499 * to send.
1501 *apr_cert_list = session->internals.selected_cert_list;
1502 *apr_cert_list_length = session->internals.selected_cert_list_length;
1503 *apr_pkey = session->internals.selected_key;
1507 return 0;
1510 /* converts the given x509 certificate to gnutls_cert* and allocates
1511 * space for them.
1513 static gnutls_cert *
1514 alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, unsigned ncerts)
1516 gnutls_cert *local_certs;
1517 int ret = 0;
1518 unsigned i, j;
1520 if (certs == NULL)
1521 return NULL;
1523 local_certs = gnutls_malloc (sizeof (gnutls_cert) * ncerts);
1524 if (local_certs == NULL)
1526 gnutls_assert ();
1527 return NULL;
1530 for (i = 0; i < ncerts; i++)
1532 ret = _gnutls_x509_crt_to_gcert (&local_certs[i], certs[i], 0);
1533 if (ret < 0)
1534 break;
1537 if (ret < 0)
1539 gnutls_assert ();
1540 for (j = 0; j < i; j++)
1542 _gnutls_gcert_deinit (&local_certs[j]);
1544 gnutls_free (local_certs);
1545 return NULL;
1548 return local_certs;
1551 /* converts the given x509 key to gnutls_privkey* and allocates
1552 * space for it.
1554 static gnutls_privkey *
1555 alloc_and_load_x509_key (gnutls_x509_privkey_t key)
1557 gnutls_privkey *local_key;
1558 int ret = 0;
1560 if (key == NULL)
1561 return NULL;
1563 local_key = gnutls_malloc (sizeof (gnutls_privkey));
1564 if (local_key == NULL)
1566 gnutls_assert ();
1567 return NULL;
1570 ret = _gnutls_x509_privkey_to_gkey (local_key, key);
1571 if (ret < 0)
1573 gnutls_assert ();
1574 return NULL;
1577 return local_key;
1580 /* converts the given pgp certificate to gnutls_cert* and allocates
1581 * space for them.
1583 static gnutls_cert *
1584 alloc_and_load_pgp_certs (gnutls_openpgp_key_t cert)
1586 gnutls_cert *local_certs;
1587 int ret = 0;
1589 if (cert == NULL)
1590 return NULL;
1592 local_certs = gnutls_malloc (sizeof (gnutls_cert));
1593 if (local_certs == NULL)
1595 gnutls_assert ();
1596 return NULL;
1599 if (_E_gnutls_openpgp_key_to_gcert == NULL)
1601 gnutls_assert ();
1602 return NULL;
1605 ret = _E_gnutls_openpgp_key_to_gcert (local_certs, cert);
1606 if (ret < 0)
1608 gnutls_assert ();
1609 return NULL;
1612 if (ret < 0)
1614 gnutls_assert ();
1615 _gnutls_gcert_deinit (local_certs);
1616 gnutls_free (local_certs);
1617 return NULL;
1620 return local_certs;
1623 /* converts the given raw key to gnutls_privkey* and allocates
1624 * space for it.
1626 static gnutls_privkey *
1627 alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key)
1629 gnutls_privkey *local_key;
1630 int ret = 0;
1632 if (key == NULL)
1633 return NULL;
1635 local_key = gnutls_malloc (sizeof (gnutls_privkey));
1636 if (local_key == NULL)
1638 gnutls_assert ();
1639 return NULL;
1642 if (_E_gnutls_openpgp_privkey_to_gkey == NULL)
1644 gnutls_assert ();
1645 return NULL;
1648 ret = _E_gnutls_openpgp_privkey_to_gkey (local_key, key);
1649 if (ret < 0)
1651 gnutls_assert ();
1652 return NULL;
1655 return local_key;
1659 void
1660 _gnutls_selected_certs_deinit (gnutls_session_t session)
1662 if (session->internals.selected_need_free != 0)
1664 int i;
1666 for (i = 0; i < session->internals.selected_cert_list_length; i++)
1668 _gnutls_gcert_deinit (&session->internals.selected_cert_list[i]);
1670 gnutls_free (session->internals.selected_cert_list);
1671 session->internals.selected_cert_list = NULL;
1672 session->internals.selected_cert_list_length = 0;
1674 _gnutls_gkey_deinit (session->internals.selected_key);
1675 if (session->internals.selected_key)
1677 gnutls_free (session->internals.selected_key);
1678 session->internals.selected_key = NULL;
1682 return;
1685 void
1686 _gnutls_selected_certs_set (gnutls_session_t session,
1687 gnutls_cert * certs, int ncerts,
1688 gnutls_privkey * key, int need_free)
1690 _gnutls_selected_certs_deinit (session);
1692 session->internals.selected_cert_list = certs;
1693 session->internals.selected_cert_list_length = ncerts;
1694 session->internals.selected_key = key;
1695 session->internals.selected_need_free = need_free;
1700 /* finds the most appropriate certificate in the cert list.
1701 * The 'appropriate' is defined by the user.
1703 * requested_algo holds the parameters required by the peer (RSA, DSA
1704 * or -1 for any).
1706 * Returns 0 on success and a negative value on error. The
1707 * selected certificate will be in session->internals.selected_*.
1711 _gnutls_server_select_cert (gnutls_session_t session,
1712 gnutls_pk_algorithm_t requested_algo)
1714 unsigned i;
1715 int idx, ret;
1716 gnutls_certificate_credentials_t cred;
1718 cred = (gnutls_certificate_credentials_t)
1719 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1720 if (cred == NULL)
1722 gnutls_assert ();
1723 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1726 /* If the callback which retrieves certificate has been set,
1727 * use it and leave.
1729 if (cred->server_get_cert_callback != NULL)
1730 return call_get_cert_callback (session, NULL, 0, NULL, 0);
1732 /* Otherwise... */
1734 ret = 0;
1735 idx = -1; /* default is use no certificate */
1738 for (i = 0; i < cred->ncerts; i++)
1740 /* find one compatible certificate
1742 if (requested_algo == GNUTLS_PK_ANY ||
1743 requested_algo == cred->cert_list[i][0].subject_pk_algorithm)
1745 /* if cert type matches
1747 if (session->security_parameters.cert_type ==
1748 cred->cert_list[i][0].cert_type)
1750 idx = i;
1751 break;
1756 /* store the certificate pointer for future use, in the handshake.
1757 * (This will allow not calling this callback again.)
1759 if (idx >= 0 && ret == 0)
1761 _gnutls_selected_certs_set (session,
1762 &cred->cert_list[idx][0],
1763 cred->cert_list_length[idx],
1764 &cred->pkey[idx], 0);
1766 else
1767 /* Certificate does not support REQUESTED_ALGO. */
1768 ret = GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1770 return ret;
1773 /* Frees the rsa_info_st structure.
1775 void
1776 _gnutls_free_rsa_info (rsa_info_st * rsa)
1778 _gnutls_free_datum (&rsa->modulus);
1779 _gnutls_free_datum (&rsa->exponent);