aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/tls
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/tls')
-rw-r--r--src/daemon/https/tls/Makefile.am73
-rw-r--r--src/daemon/https/tls/auth_anon.c178
-rw-r--r--src/daemon/https/tls/auth_anon.h48
-rw-r--r--src/daemon/https/tls/auth_cert.c1781
-rw-r--r--src/daemon/https/tls/auth_cert.h158
-rw-r--r--src/daemon/https/tls/auth_dh_common.c369
-rw-r--r--src/daemon/https/tls/auth_dh_common.h48
-rw-r--r--src/daemon/https/tls/auth_dhe.c276
-rw-r--r--src/daemon/https/tls/auth_rsa.c408
-rw-r--r--src/daemon/https/tls/auth_rsa_export.c325
-rw-r--r--src/daemon/https/tls/debug.c128
-rw-r--r--src/daemon/https/tls/debug.h30
-rw-r--r--src/daemon/https/tls/defines.h64
-rw-r--r--src/daemon/https/tls/ext_cert_type.c243
-rw-r--r--src/daemon/https/tls/ext_cert_type.h31
-rw-r--r--src/daemon/https/tls/ext_inner_application.c147
-rw-r--r--src/daemon/https/tls/ext_inner_application.h29
-rw-r--r--src/daemon/https/tls/ext_max_record.c196
-rw-r--r--src/daemon/https/tls/ext_max_record.h33
-rw-r--r--src/daemon/https/tls/ext_oprfi.c253
-rw-r--r--src/daemon/https/tls/ext_oprfi.h33
-rw-r--r--src/daemon/https/tls/ext_server_name.c330
-rw-r--r--src/daemon/https/tls/ext_server_name.h28
-rw-r--r--src/daemon/https/tls/gnutls.asn93
-rw-r--r--src/daemon/https/tls/gnutls.pc23
-rw-r--r--src/daemon/https/tls/gnutls_alert.c304
-rw-r--r--src/daemon/https/tls/gnutls_algorithms.c2225
-rw-r--r--src/daemon/https/tls/gnutls_algorithms.h141
-rw-r--r--src/daemon/https/tls/gnutls_anon_cred.c137
-rw-r--r--src/daemon/https/tls/gnutls_asn1_tab.c63
-rw-r--r--src/daemon/https/tls/gnutls_auth.c413
-rw-r--r--src/daemon/https/tls/gnutls_auth.h50
-rw-r--r--src/daemon/https/tls/gnutls_auth_int.h32
-rw-r--r--src/daemon/https/tls/gnutls_buffer.h31
-rw-r--r--src/daemon/https/tls/gnutls_buffers.c1241
-rw-r--r--src/daemon/https/tls/gnutls_buffers.h67
-rw-r--r--src/daemon/https/tls/gnutls_cert.c918
-rw-r--r--src/daemon/https/tls/gnutls_cert.h132
-rw-r--r--src/daemon/https/tls/gnutls_cipher.c584
-rw-r--r--src/daemon/https/tls/gnutls_cipher.h41
-rw-r--r--src/daemon/https/tls/gnutls_cipher_int.c133
-rw-r--r--src/daemon/https/tls/gnutls_cipher_int.h46
-rw-r--r--src/daemon/https/tls/gnutls_compress.c80
-rw-r--r--src/daemon/https/tls/gnutls_compress.h30
-rw-r--r--src/daemon/https/tls/gnutls_compress_int.c300
-rw-r--r--src/daemon/https/tls/gnutls_compress_int.h49
-rw-r--r--src/daemon/https/tls/gnutls_constate.c1039
-rw-r--r--src/daemon/https/tls/gnutls_constate.h40
-rw-r--r--src/daemon/https/tls/gnutls_datum.c114
-rw-r--r--src/daemon/https/tls/gnutls_datum.h40
-rw-r--r--src/daemon/https/tls/gnutls_db.c386
-rw-r--r--src/daemon/https/tls/gnutls_db.h37
-rw-r--r--src/daemon/https/tls/gnutls_dh.c162
-rw-r--r--src/daemon/https/tls/gnutls_dh.h38
-rw-r--r--src/daemon/https/tls/gnutls_dh_primes.c626
-rw-r--r--src/daemon/https/tls/gnutls_errors.c422
-rw-r--r--src/daemon/https/tls/gnutls_errors.h73
-rw-r--r--src/daemon/https/tls/gnutls_extensions.c318
-rw-r--r--src/daemon/https/tls/gnutls_extensions.h45
-rw-r--r--src/daemon/https/tls/gnutls_extra_hooks.c78
-rw-r--r--src/daemon/https/tls/gnutls_extra_hooks.h106
-rw-r--r--src/daemon/https/tls/gnutls_global.c375
-rw-r--r--src/daemon/https/tls/gnutls_global.h42
-rw-r--r--src/daemon/https/tls/gnutls_handshake.c3029
-rw-r--r--src/daemon/https/tls/gnutls_handshake.h60
-rw-r--r--src/daemon/https/tls/gnutls_hash_int.c446
-rw-r--r--src/daemon/https/tls/gnutls_hash_int.h72
-rw-r--r--src/daemon/https/tls/gnutls_int.h679
-rw-r--r--src/daemon/https/tls/gnutls_kx.c773
-rw-r--r--src/daemon/https/tls/gnutls_kx.h39
-rw-r--r--src/daemon/https/tls/gnutls_mem.c134
-rw-r--r--src/daemon/https/tls/gnutls_mem.h70
-rw-r--r--src/daemon/https/tls/gnutls_mpi.c285
-rw-r--r--src/daemon/https/tls/gnutls_mpi.h78
-rw-r--r--src/daemon/https/tls/gnutls_num.c192
-rw-r--r--src/daemon/https/tls/gnutls_num.h49
-rw-r--r--src/daemon/https/tls/gnutls_pk.c915
-rw-r--r--src/daemon/https/tls/gnutls_pk.h46
-rw-r--r--src/daemon/https/tls/gnutls_priority.c497
-rw-r--r--src/daemon/https/tls/gnutls_record.c1204
-rw-r--r--src/daemon/https/tls/gnutls_record.h32
-rw-r--r--src/daemon/https/tls/gnutls_rsa_export.c361
-rw-r--r--src/daemon/https/tls/gnutls_rsa_export.h27
-rw-r--r--src/daemon/https/tls/gnutls_session.c199
-rw-r--r--src/daemon/https/tls/gnutls_session.h23
-rw-r--r--src/daemon/https/tls/gnutls_session_pack.c1204
-rw-r--r--src/daemon/https/tls/gnutls_session_pack.h28
-rw-r--r--src/daemon/https/tls/gnutls_sig.c473
-rw-r--r--src/daemon/https/tls/gnutls_sig.h51
-rw-r--r--src/daemon/https/tls/gnutls_state.c1219
-rw-r--r--src/daemon/https/tls/gnutls_state.h72
-rw-r--r--src/daemon/https/tls/gnutls_str.c312
-rw-r--r--src/daemon/https/tls/gnutls_str.h67
-rw-r--r--src/daemon/https/tls/gnutls_supplemental.c207
-rw-r--r--src/daemon/https/tls/gnutls_supplemental.h31
-rw-r--r--src/daemon/https/tls/gnutls_ui.c627
-rw-r--r--src/daemon/https/tls/gnutls_v2_compat.c259
-rw-r--r--src/daemon/https/tls/gnutls_v2_compat.h26
-rw-r--r--src/daemon/https/tls/gnutls_x509.c1991
-rw-r--r--src/daemon/https/tls/gnutls_x509.h49
-rw-r--r--src/daemon/https/tls/gnutlsxx.cpp907
-rw-r--r--src/daemon/https/tls/io_debug.h79
-rw-r--r--src/daemon/https/tls/libgnutls-config104
-rw-r--r--src/daemon/https/tls/libgnutls.m4160
-rw-r--r--src/daemon/https/tls/libgnutls.vers27
-rw-r--r--src/daemon/https/tls/libgnutlsxx.vers30
-rw-r--r--src/daemon/https/tls/pkix.asn1241
-rw-r--r--src/daemon/https/tls/pkix_asn1_tab.c1130
-rw-r--r--src/daemon/https/tls/x509_b64.c599
-rw-r--r--src/daemon/https/tls/x509_b64.h45
110 files changed, 36431 insertions, 0 deletions
diff --git a/src/daemon/https/tls/Makefile.am b/src/daemon/https/tls/Makefile.am
new file mode 100644
index 00000000..309080ea
--- /dev/null
+++ b/src/daemon/https/tls/Makefile.am
@@ -0,0 +1,73 @@
1SUBDIRS = .
2
3AM_CPPFLAGS = \
4-I$(top_srcdir)/src/daemon/https/includes \
5-I$(top_srcdir)/src/daemon/https/lgl \
6-I$(top_srcdir)/src/daemon/https/x509 \
7-I$(top_srcdir)/src/daemon/https/tls \
8-I$(top_srcdir)/src/daemon/https/openpgp \
9-I$(top_srcdir)/src/daemon/https/opencdk \
10-I$(GCRYPT_CPPFLAGS)
11
12noinst_LTLIBRARIES = libtls.la
13
14libtls_la_LDFLAGS = \
15 -L$(GCRYPT_LIB_PATH)
16
17libtls_la_SOURCES = \
18auth_anon.c \
19auth_cert.c \
20auth_dh_common.c \
21auth_dhe.c \
22auth_rsa.c \
23auth_rsa_export.c \
24debug.c \
25ext_cert_type.c \
26ext_inner_application.c \
27ext_max_record.c \
28ext_oprfi.c \
29ext_server_name.c \
30gnutls_alert.c \
31gnutls_algorithms.c \
32gnutls_anon_cred.c \
33gnutls_asn1_tab.c \
34gnutls_auth.c \
35gnutls_buffers.c \
36gnutls_cert.c \
37gnutls_cipher.c \
38gnutls_cipher_int.c \
39gnutls_compress.c \
40gnutls_compress_int.c \
41gnutls_constate.c \
42gnutls_datum.c \
43gnutls_db.c \
44gnutls_dh.c \
45gnutls_dh_primes.c \
46gnutls_errors.c \
47gnutls_extensions.c \
48gnutls_extra_hooks.c \
49gnutls_global.c \
50gnutls_handshake.c \
51gnutls_hash_int.c \
52gnutls_kx.c \
53gnutls_mem.c \
54gnutls_mpi.c \
55gnutls_num.c \
56gnutls_pk.c \
57gnutls_priority.c \
58gnutls_record.c \
59gnutls_rsa_export.c \
60gnutls_session.c \
61gnutls_session_pack.c \
62gnutls_sig.c \
63gnutls_state.c \
64gnutls_str.c \
65gnutls_supplemental.c \
66gnutls_ui.c \
67gnutls_v2_compat.c \
68gnutls_x509.c \
69pkix_asn1_tab.c \
70x509_b64.c
71
72# gnutlsxx.cpp
73
diff --git a/src/daemon/https/tls/auth_anon.c b/src/daemon/https/tls/auth_anon.c
new file mode 100644
index 00000000..18cad200
--- /dev/null
+++ b/src/daemon/https/tls/auth_anon.c
@@ -0,0 +1,178 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains the Anonymous Diffie Hellman key exchange part of
26 * the anonymous authentication. The functions here are used in the
27 * handshake.
28 */
29
30#include <gnutls_int.h>
31
32#ifdef ENABLE_ANON
33
34#include "gnutls_auth_int.h"
35#include "gnutls_errors.h"
36#include "gnutls_dh.h"
37#include "auth_anon.h"
38#include "gnutls_num.h"
39#include "gnutls_mpi.h"
40#include <gnutls_state.h>
41#include <auth_dh_common.h>
42
43static int gen_anon_server_kx (gnutls_session_t, opaque **);
44static int proc_anon_client_kx (gnutls_session_t, opaque *, size_t);
45static int proc_anon_server_kx (gnutls_session_t, opaque *, size_t);
46
47const mod_auth_st anon_auth_struct = {
48 "ANON",
49 NULL,
50 NULL,
51 gen_anon_server_kx,
52 _gnutls_gen_dh_common_client_kx, /* this can be shared */
53 NULL,
54 NULL,
55
56 NULL,
57 NULL, /* certificate */
58 proc_anon_server_kx,
59 proc_anon_client_kx,
60 NULL,
61 NULL
62};
63
64static int
65gen_anon_server_kx (gnutls_session_t session, opaque ** data)
66{
67 mpi_t g, p;
68 const mpi_t *mpis;
69 int ret;
70 gnutls_dh_params_t dh_params;
71 gnutls_anon_server_credentials_t cred;
72
73 cred = (gnutls_anon_server_credentials_t)
74 _gnutls_get_cred (session->key, GNUTLS_CRD_ANON, NULL);
75 if (cred == NULL)
76 {
77 gnutls_assert ();
78 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
79 }
80
81 dh_params =
82 _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
83 mpis = _gnutls_dh_params_to_mpi (dh_params);
84 if (mpis == NULL)
85 {
86 gnutls_assert ();
87 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
88 }
89
90 p = mpis[0];
91 g = mpis[1];
92
93 if ((ret =
94 _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
95 sizeof (anon_auth_info_st), 1)) < 0)
96 {
97 gnutls_assert ();
98 return ret;
99 }
100
101 _gnutls_dh_set_group (session, g, p);
102
103 ret = _gnutls_dh_common_print_server_kx (session, g, p, data, 0);
104 if (ret < 0)
105 {
106 gnutls_assert ();
107 }
108
109 return ret;
110}
111
112
113static int
114proc_anon_client_kx (gnutls_session_t session, opaque * data,
115 size_t _data_size)
116{
117 gnutls_anon_server_credentials_t cred;
118 int bits;
119 int ret;
120 mpi_t p, g;
121 gnutls_dh_params_t dh_params;
122 const mpi_t *mpis;
123
124 bits = _gnutls_dh_get_allowed_prime_bits (session);
125
126 cred = (gnutls_anon_server_credentials_t)
127 _gnutls_get_cred (session->key, GNUTLS_CRD_ANON, NULL);
128 if (cred == NULL)
129 {
130 gnutls_assert ();
131 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
132 }
133
134 dh_params =
135 _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
136 mpis = _gnutls_dh_params_to_mpi (dh_params);
137 if (mpis == NULL)
138 {
139 gnutls_assert ();
140 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
141 }
142
143 p = mpis[0];
144 g = mpis[1];
145
146 ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p);
147
148 return ret;
149
150}
151
152int
153proc_anon_server_kx (gnutls_session_t session, opaque * data,
154 size_t _data_size)
155{
156
157 int ret;
158
159 /* set auth_info */
160 if ((ret =
161 _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
162 sizeof (anon_auth_info_st), 1)) < 0)
163 {
164 gnutls_assert ();
165 return ret;
166 }
167
168 ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 0);
169 if (ret < 0)
170 {
171 gnutls_assert ();
172 return ret;
173 }
174
175 return 0;
176}
177
178#endif /* ENABLE_ANON */
diff --git a/src/daemon/https/tls/auth_anon.h b/src/daemon/https/tls/auth_anon.h
new file mode 100644
index 00000000..b1705f85
--- /dev/null
+++ b/src/daemon/https/tls/auth_anon.h
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* this is not to be included by gnutls_anon.c */
26#include <gnutls_auth.h>
27#include <auth_dh_common.h>
28
29typedef struct gnutls_anon_server_credentials_st
30{
31 gnutls_dh_params_t dh_params;
32 /* this callback is used to retrieve the DH or RSA
33 * parameters.
34 */
35 gnutls_params_function *params_func;
36} anon_server_credentials_st;
37
38typedef struct gnutls_anon_client_credentials_st
39{
40 int dummy;
41} anon_client_credentials_st;
42
43typedef struct anon_auth_info_st
44{
45 dh_info_st dh;
46} *anon_auth_info_t;
47
48typedef struct anon_auth_info_st anon_auth_info_st;
diff --git a/src/daemon/https/tls/auth_cert.c b/src/daemon/https/tls/auth_cert.c
new file mode 100644
index 00000000..43dcb777
--- /dev/null
+++ b/src/daemon/https/tls/auth_cert.c
@@ -0,0 +1,1781 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
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.
27 */
28
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"
48
49static gnutls_cert *alloc_and_load_x509_certs (gnutls_x509_crt_t * certs,
50 unsigned);
51static gnutls_privkey *alloc_and_load_x509_key (gnutls_x509_privkey_t key);
52static gnutls_cert *alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert);
53static gnutls_privkey *alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t
54 key);
55
56
57/* Copies data from a internal certificate struct (gnutls_cert) to
58 * exported certificate struct (cert_auth_info_t)
59 */
60static int
61_gnutls_copy_certificate_auth_info (cert_auth_info_t info,
62 gnutls_cert * cert, int ncerts)
63{
64 /* Copy peer's information to auth_info_t
65 */
66 int ret, i, j;
67
68 if (ncerts == 0)
69 {
70 info->raw_certificate_list = NULL;
71 info->ncerts = 0;
72 return 0;
73 }
74
75 info->raw_certificate_list =
76 gnutls_calloc (1, sizeof (gnutls_datum_t) * ncerts);
77 if (info->raw_certificate_list == NULL)
78 {
79 gnutls_assert ();
80 return GNUTLS_E_MEMORY_ERROR;
81 }
82
83 for (i = 0; i < ncerts; i++)
84 {
85 if (cert->raw.size > 0)
86 {
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)
92 {
93 gnutls_assert ();
94 goto clear;
95 }
96 }
97 }
98 info->ncerts = ncerts;
99
100 return 0;
101
102clear:
103
104 for (j = 0; j < i; j++)
105 _gnutls_free_datum (&info->raw_certificate_list[j]);
106
107 gnutls_free (info->raw_certificate_list);
108 info->raw_certificate_list = NULL;
109
110 return ret;
111}
112
113
114
115
116/* returns 0 if the algo_to-check exists in the pk_algos list,
117 * -1 otherwise.
118 */
119inline 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)
123{
124 int i;
125 for (i = 0; i < pk_algos_length; i++)
126 {
127 if (algo_to_check == pk_algos[i])
128 {
129 return 0;
130 }
131 }
132 return -1;
133}
134
135
136/* Returns the issuer's Distinguished name in odn, of the certificate
137 * specified in cert.
138 */
139static int
140_gnutls_cert_get_issuer_dn (gnutls_cert * cert, gnutls_datum_t * odn)
141{
142 ASN1_TYPE dn;
143 int len, result;
144 int start, end;
145
146 if ((result = asn1_create_element
147 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS)
148 {
149 gnutls_assert ();
150 return _gnutls_asn2err (result);
151 }
152
153 result = asn1_der_decoding (&dn, cert->raw.data, cert->raw.size, NULL);
154 if (result != ASN1_SUCCESS)
155 {
156 /* couldn't decode DER */
157 gnutls_assert ();
158 asn1_delete_structure (&dn);
159 return _gnutls_asn2err (result);
160 }
161
162 result = asn1_der_decoding_startEnd (dn, cert->raw.data, cert->raw.size,
163 "tbsCertificate.issuer", &start, &end);
164
165 if (result != ASN1_SUCCESS)
166 {
167 /* couldn't decode DER */
168 gnutls_assert ();
169 asn1_delete_structure (&dn);
170 return _gnutls_asn2err (result);
171 }
172 asn1_delete_structure (&dn);
173
174 len = end - start + 1;
175
176 odn->size = len;
177 odn->data = &cert->raw.data[start];
178
179 return 0;
180}
181
182
183/* Locates the most appropriate x509 certificate using the
184 * given DN. If indx == -1 then no certificate was found.
185 *
186 * That is to guess which certificate to use, based on the
187 * CAs and sign algorithms supported by the peer server.
188 */
189static 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)
194{
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;
201
202 *indx = -1;
203
204 do
205 {
206
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;
211
212 for (i = 0; i < cred->ncerts; i++)
213 {
214 for (j = 0; j < cred->cert_list_length[i]; j++)
215 {
216 if ((result =
217 _gnutls_cert_get_issuer_dn (&cred->
218 cert_list[i][j], &odn)) < 0)
219 {
220 gnutls_assert ();
221 return result;
222 }
223
224 if (odn.size != size)
225 continue;
226
227 /* If the DN matches and
228 * the *_SIGN algorithm matches
229 * the cert is our cert!
230 */
231 cert_pk = cred->cert_list[i][0].subject_pk_algorithm;
232
233 if ((memcmp (odn.data, data, size) == 0) &&
234 (_gnutls_check_pk_algo_in_list
235 (pk_algos, pk_algos_length, cert_pk) == 0))
236 {
237 *indx = i;
238 break;
239 }
240 }
241 if (*indx != -1)
242 break;
243 }
244
245 if (*indx != -1)
246 break;
247
248 /* move to next record */
249 data += size;
250
251 }
252 while (1);
253
254 return 0;
255
256}
257
258/* Locates the most appropriate openpgp cert
259 */
260static 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)
264{
265 unsigned i, j;
266
267 *indx = -1;
268
269 for (i = 0; i < cred->ncerts; i++)
270 {
271 for (j = 0; j < cred->cert_list_length[i]; j++)
272 {
273
274 /* If the *_SIGN algorithm matches
275 * the cert is our cert!
276 */
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))
281 {
282 *indx = i;
283 break;
284 }
285 }
286 if (*indx != -1)
287 break;
288 }
289
290 return 0;
291}
292
293/* Returns the number of issuers in the server's
294 * certificate request packet.
295 */
296static int
297get_issuers_num (gnutls_session_t session, opaque * data, ssize_t data_size)
298{
299 int issuers_dn_len = 0, result;
300 unsigned size;
301
302 /* Count the number of the given issuers;
303 * This is used to allocate the issuers_dn without
304 * using realloc().
305 */
306
307 if (data_size == 0 || data == NULL)
308 return 0;
309
310 if (data_size > 0)
311 do
312 {
313 /* This works like DECR_LEN()
314 */
315 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
316 DECR_LENGTH_COM (data_size, 2, goto error);
317 size = _gnutls_read_uint16 (data);
318
319 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
320 DECR_LENGTH_COM (data_size, size, goto error);
321
322 data += 2;
323
324 if (size > 0)
325 {
326 issuers_dn_len++;
327 data += size;
328 }
329
330 if (data_size == 0)
331 break;
332
333 }
334 while (1);
335
336 return issuers_dn_len;
337
338error:
339 return result;
340}
341
342/* Returns the issuers in the server's certificate request
343 * packet.
344 */
345static int
346get_issuers (gnutls_session_t session,
347 gnutls_datum_t * issuers_dn, int issuers_len,
348 opaque * data, size_t data_size)
349{
350 int i;
351 unsigned size;
352
353 if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
354 return 0;
355
356 /* put the requested DNs to req_dn, only in case
357 * of X509 certificates.
358 */
359 if (issuers_len > 0)
360 {
361
362 for (i = 0; i < issuers_len; i++)
363 {
364 /* The checks here for the buffer boundaries
365 * are not needed since the buffer has been
366 * parsed above.
367 */
368 data_size -= 2;
369
370 size = _gnutls_read_uint16 (data);
371
372 data += 2;
373
374 issuers_dn[i].data = data;
375 issuers_dn[i].size = size;
376
377 data += size;
378 }
379 }
380
381 return 0;
382}
383
384/* Calls the client get callback.
385 */
386static int
387call_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)
391{
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;
399
400 cred = (gnutls_certificate_credentials_t)
401 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
402 if (cred == NULL)
403 {
404 gnutls_assert ();
405 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
406 }
407
408 memset (&st, 0, sizeof (st));
409
410 if (session->security_parameters.entity == GNUTLS_SERVER)
411 {
412 ret = cred->server_get_cert_callback (session, &st);
413 }
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);
420 }
421
422 if (ret < 0)
423 {
424 gnutls_assert ();
425 return GNUTLS_E_INTERNAL_ERROR;
426 }
427
428 if (st.ncerts == 0)
429 return 0; /* no certificate was selected */
430
431 if (type != st.type)
432 {
433 gnutls_assert ();
434 ret = GNUTLS_E_INVALID_REQUEST;
435 goto cleanup;
436 }
437
438 if (type == GNUTLS_CRT_X509)
439 {
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);
443
444 }
445 else
446 { /* PGP */
447 if (st.ncerts > 1)
448 {
449 gnutls_assert ();
450 ret = GNUTLS_E_INVALID_REQUEST;
451 goto cleanup;
452 }
453
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);
457
458 }
459
460 _gnutls_selected_certs_set (session, local_certs,
461 (local_certs != NULL) ? st.ncerts : 0,
462 local_key, 1);
463
464 ret = 0;
465
466cleanup:
467
468 if (st.type == GNUTLS_CRT_X509)
469 {
470 if (st.deinit_all)
471 {
472 for (i = 0; i < st.ncerts; i++)
473 {
474 gnutls_x509_crt_deinit (st.cert.x509[i]);
475 }
476 gnutls_free (st.cert.x509);
477 gnutls_x509_privkey_deinit (st.key.x509);
478 }
479 }
480 else
481 {
482 if (st.deinit_all)
483 {
484 if (_E_gnutls_openpgp_crt_deinit == NULL ||
485 _E_gnutls_openpgp_privkey_deinit == NULL)
486 {
487 gnutls_assert ();
488 return GNUTLS_E_INIT_LIBEXTRA;
489 }
490
491 _E_gnutls_openpgp_crt_deinit (st.cert.pgp);
492 _E_gnutls_openpgp_privkey_deinit (st.key.pgp);
493 }
494 }
495
496 return ret;
497}
498
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.
502 *
503 * 20020128: added ability to select a certificate depending on the SIGN
504 * algorithm (only in automatic mode).
505 */
506static 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)
510{
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;
518
519 cred = (gnutls_certificate_credentials_t)
520 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
521 if (cred == NULL)
522 {
523 gnutls_assert ();
524 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
525 }
526
527 if (cred->client_get_cert_callback != NULL)
528 {
529
530 /* use a callback to get certificate
531 */
532 if (session->security_parameters.cert_type != GNUTLS_CRT_X509)
533 issuers_dn_length = 0;
534 else
535 {
536 issuers_dn_length = get_issuers_num (session, data, data_size);
537 if (issuers_dn_length < 0)
538 {
539 gnutls_assert ();
540 return issuers_dn_length;
541 }
542
543 if (issuers_dn_length > 0)
544 {
545 issuers_dn =
546 gnutls_malloc (sizeof (gnutls_datum_t) * issuers_dn_length);
547 if (issuers_dn == NULL)
548 {
549 gnutls_assert ();
550 return GNUTLS_E_MEMORY_ERROR;
551 }
552
553 result =
554 get_issuers (session, issuers_dn, issuers_dn_length,
555 data, data_size);
556 if (result < 0)
557 {
558 gnutls_assert ();
559 goto cleanup;
560 }
561 }
562 }
563
564 result =
565 call_get_cert_callback (session, issuers_dn, issuers_dn_length,
566 pk_algos, pk_algos_length);
567 goto cleanup;
568
569 }
570 else
571 {
572 /* If we have no callbacks, try to guess.
573 */
574 result = 0;
575
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);
580
581 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP)
582 result = _find_openpgp_cert (cred, pk_algos, pk_algos_length, &indx);
583
584
585 if (result < 0)
586 {
587 gnutls_assert ();
588 return result;
589 }
590
591 if (indx >= 0)
592 {
593 _gnutls_selected_certs_set (session,
594 &cred->cert_list[indx][0],
595 cred->cert_list_length[indx],
596 &cred->pkey[indx], 0);
597 }
598 else
599 {
600 _gnutls_selected_certs_set (session, NULL, 0, NULL, 0);
601 }
602
603 result = 0;
604 }
605
606cleanup:
607 gnutls_free (issuers_dn);
608 return result;
609
610}
611
612/* Generate client certificate
613 */
614
615int
616_gnutls_gen_x509_crt (gnutls_session_t session, opaque ** data)
617{
618 int ret, i;
619 opaque *pdata;
620 gnutls_cert *apr_cert_list;
621 gnutls_privkey *apr_pkey;
622 int apr_cert_list_length;
623
624 /* find the appropriate certificate
625 */
626 if ((ret =
627 _gnutls_get_selected_cert (session, &apr_cert_list,
628 &apr_cert_list_length, &apr_pkey)) < 0)
629 {
630 gnutls_assert ();
631 return ret;
632 }
633
634 ret = 3;
635 for (i = 0; i < apr_cert_list_length; i++)
636 {
637 ret += apr_cert_list[i].raw.size + 3;
638 /* hold size
639 * for uint24 */
640 }
641
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
646 *
647 * ( the above is the whole handshake message, not
648 * the one produced here )
649 */
650
651 (*data) = gnutls_malloc (ret);
652 pdata = (*data);
653
654 if (pdata == NULL)
655 {
656 gnutls_assert ();
657 return GNUTLS_E_MEMORY_ERROR;
658 }
659 _gnutls_write_uint24 (ret - 3, pdata);
660 pdata += 3;
661 for (i = 0; i < apr_cert_list_length; i++)
662 {
663 _gnutls_write_datum24 (pdata, apr_cert_list[i].raw);
664 pdata += (3 + apr_cert_list[i].raw.size);
665 }
666
667 return ret;
668}
669
670enum PGPKeyDescriptorType
671{ PGP_KEY_FINGERPRINT, PGP_KEY };
672
673int
674_gnutls_gen_openpgp_certificate (gnutls_session_t session, opaque ** data)
675{
676 int ret;
677 opaque *pdata;
678 gnutls_cert *apr_cert_list;
679 gnutls_privkey *apr_pkey;
680 int apr_cert_list_length;
681
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)
686 {
687 gnutls_assert ();
688 return ret;
689 }
690
691 ret = 3 + 1 + 3;
692
693 if (apr_cert_list_length > 0)
694 ret += apr_cert_list[0].raw.size;
695
696 (*data) = gnutls_malloc (ret);
697 pdata = (*data);
698
699 if (pdata == NULL)
700 {
701 gnutls_assert ();
702 return GNUTLS_E_MEMORY_ERROR;
703 }
704
705 _gnutls_write_uint24 (ret - 3, pdata);
706 pdata += 3;
707
708 *pdata = PGP_KEY; /* whole key */
709 pdata++;
710
711 if (apr_cert_list_length > 0)
712 {
713 _gnutls_write_datum24 (pdata, apr_cert_list[0].raw);
714 pdata += (3 + apr_cert_list[0].raw.size);
715 }
716 else /* empty - no certificate */
717 _gnutls_write_uint24 (0, pdata);
718
719 return ret;
720}
721
722int
723_gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, opaque ** data)
724{
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;
731
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)
736 {
737 gnutls_assert ();
738 return ret;
739 }
740
741 packet_size = 3 + 1;
742
743 /* Only v4 fingerprints are sent
744 */
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);
749
750 (*data) = gnutls_malloc (packet_size);
751 pdata = (*data);
752
753 if (pdata == NULL)
754 {
755 gnutls_assert ();
756 return GNUTLS_E_MEMORY_ERROR;
757 }
758
759 _gnutls_write_uint24 (packet_size - 3, pdata);
760 pdata += 3;
761
762 *pdata = PGP_KEY_FINGERPRINT; /* key fingerprint */
763 pdata++;
764
765 *pdata = 20;
766 pdata++;
767
768 fpr_size = 20;
769
770 if (_E_gnutls_openpgp_fingerprint == NULL)
771 {
772 gnutls_assert ();
773 return GNUTLS_E_INIT_LIBEXTRA;
774 }
775
776 if ((ret =
777 _E_gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, pdata,
778 &fpr_size)) < 0)
779 {
780 gnutls_assert ();
781 return ret;
782 }
783
784 return packet_size;
785}
786
787
788
789int
790_gnutls_gen_cert_client_certificate (gnutls_session_t session, opaque ** data)
791{
792 switch (session->security_parameters.cert_type)
793 {
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);
799
800 case GNUTLS_CRT_X509:
801 return _gnutls_gen_x509_crt (session, data);
802
803 default:
804 gnutls_assert ();
805 return GNUTLS_E_INTERNAL_ERROR;
806 }
807}
808
809int
810_gnutls_gen_cert_server_certificate (gnutls_session_t session, opaque ** data)
811{
812 switch (session->security_parameters.cert_type)
813 {
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;
821 }
822}
823
824/* Process server certificate
825 */
826
827#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
828int
829_gnutls_proc_x509_server_certificate (gnutls_session_t session,
830 opaque * data, size_t data_size)
831{
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;
841
842 cred = (gnutls_certificate_credentials_t)
843 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
844 if (cred == NULL)
845 {
846 gnutls_assert ();
847 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
848 }
849
850
851 if ((ret =
852 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
853 sizeof (cert_auth_info_st), 1)) < 0)
854 {
855 gnutls_assert ();
856 return ret;
857 }
858
859 info = _gnutls_get_auth_info (session);
860
861 if (data == NULL || data_size == 0)
862 {
863 gnutls_assert ();
864 /* no certificate was sent */
865 return GNUTLS_E_NO_CERTIFICATE_FOUND;
866 }
867
868 DECR_LEN (dsize, 3);
869 size = _gnutls_read_uint24 (p);
870 p += 3;
871
872 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
873 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
874 */
875 if (size == 0 || size == 3)
876 {
877 gnutls_assert ();
878 /* no certificate was sent */
879 return GNUTLS_E_NO_CERTIFICATE_FOUND;
880 }
881
882 i = dsize;
883 while (i > 0)
884 {
885 DECR_LEN (dsize, 3);
886 len = _gnutls_read_uint24 (p);
887 p += 3;
888 DECR_LEN (dsize, len);
889 peer_certificate_list_size++;
890 p += len;
891 i -= len + 3;
892 }
893
894 if (peer_certificate_list_size == 0)
895 {
896 gnutls_assert ();
897 return GNUTLS_E_NO_CERTIFICATE_FOUND;
898 }
899
900 /* Ok we now allocate the memory to hold the
901 * certificate list
902 */
903
904 peer_certificate_list =
905 gnutls_malloc (sizeof (gnutls_cert) * (peer_certificate_list_size));
906
907 if (peer_certificate_list == NULL)
908 {
909 gnutls_assert ();
910 return GNUTLS_E_MEMORY_ERROR;
911 }
912 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
913 peer_certificate_list_size);
914
915 p = data + 3;
916
917 /* Now we start parsing the list (again).
918 * We don't use DECR_LEN since the list has
919 * been parsed before.
920 */
921
922 for (j = 0; j < peer_certificate_list_size; j++)
923 {
924 len = _gnutls_read_uint24 (p);
925 p += 3;
926
927 tmp.size = len;
928 tmp.data = p;
929
930 if ((ret =
931 _gnutls_x509_raw_cert_to_gcert (&peer_certificate_list
932 [j], &tmp,
933 CERT_ONLY_EXTENSIONS)) < 0)
934 {
935 gnutls_assert ();
936 goto cleanup;
937 }
938
939 p += len;
940 }
941
942
943 if ((ret =
944 _gnutls_copy_certificate_auth_info (info,
945 peer_certificate_list,
946 peer_certificate_list_size)) < 0)
947 {
948 gnutls_assert ();
949 goto cleanup;
950 }
951
952 if ((ret =
953 _gnutls_check_key_usage (&peer_certificate_list[0],
954 gnutls_kx_get (session))) < 0)
955 {
956 gnutls_assert ();
957 goto cleanup;
958 }
959
960 ret = 0;
961
962cleanup:
963 CLEAR_CERTS;
964 gnutls_free (peer_certificate_list);
965 return ret;
966
967}
968
969#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
970int
971_gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
972 opaque * data, size_t data_size)
973{
974 int size, ret, len;
975 opaque *p = data;
976 cert_auth_info_t info;
977 gnutls_certificate_credentials_t cred;
978 ssize_t dsize = data_size;
979 int i, x;
980 gnutls_cert *peer_certificate_list = NULL;
981 int peer_certificate_list_size = 0;
982 gnutls_datum_t tmp, akey = { NULL, 0 };
983
984 cred = (gnutls_certificate_credentials_t)
985 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
986 if (cred == NULL)
987 {
988 gnutls_assert ();
989 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
990 }
991
992 if ((ret =
993 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
994 sizeof (cert_auth_info_st), 1)) < 0)
995 {
996 gnutls_assert ();
997 return ret;
998 }
999
1000 info = _gnutls_get_auth_info (session);
1001
1002 if (data == NULL || data_size == 0)
1003 {
1004 gnutls_assert ();
1005 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1006 }
1007
1008 DECR_LEN (dsize, 3);
1009 size = _gnutls_read_uint24 (p);
1010 p += 3;
1011
1012 if (size == 0)
1013 {
1014 gnutls_assert ();
1015 /* no certificate was sent */
1016 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1017 }
1018 i = dsize;
1019
1020 /* Read PGPKeyDescriptor */
1021 DECR_LEN (dsize, 1);
1022 if (*p == PGP_KEY_FINGERPRINT)
1023 { /* the fingerprint */
1024 p++;
1025
1026 DECR_LEN (dsize, 1);
1027 len = (uint8_t) * p;
1028 p++;
1029
1030 if (len != 20)
1031 {
1032 gnutls_assert ();
1033 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED;
1034 }
1035
1036 DECR_LEN (dsize, 20);
1037
1038 /* request the actual key from our database, or
1039 * a key server or anything.
1040 */
1041 if (_E_gnutls_openpgp_request_key == NULL)
1042 {
1043 gnutls_assert ();
1044 return GNUTLS_E_INIT_LIBEXTRA;
1045 }
1046 if ((ret =
1047 _E_gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
1048 {
1049 gnutls_assert ();
1050 return ret;
1051 }
1052 tmp = akey;
1053 peer_certificate_list_size++;
1054
1055 }
1056 else if (*p == PGP_KEY)
1057 { /* the whole key */
1058
1059 p++;
1060
1061 /* Read the actual certificate */
1062 DECR_LEN (dsize, 3);
1063 len = _gnutls_read_uint24 (p);
1064 p += 3;
1065
1066 if (len == 0)
1067 {
1068 gnutls_assert ();
1069 /* no certificate was sent */
1070 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1071 }
1072
1073 DECR_LEN (dsize, len);
1074 peer_certificate_list_size++;
1075
1076 tmp.size = len;
1077 tmp.data = p;
1078
1079 }
1080 else
1081 {
1082 gnutls_assert ();
1083 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1084 }
1085
1086 /* ok we now have the peer's key in tmp datum
1087 */
1088
1089 if (peer_certificate_list_size == 0)
1090 {
1091 gnutls_assert ();
1092 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1093 }
1094
1095 peer_certificate_list =
1096 gnutls_alloca (sizeof (gnutls_cert) * (peer_certificate_list_size));
1097 if (peer_certificate_list == NULL)
1098 {
1099 gnutls_assert ();
1100 ret = GNUTLS_E_MEMORY_ERROR;
1101 goto cleanup;
1102 }
1103 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
1104 peer_certificate_list_size);
1105
1106 if (_E_gnutls_openpgp_raw_key_to_gcert == NULL)
1107 {
1108 gnutls_assert ();
1109 ret = GNUTLS_E_INIT_LIBEXTRA;
1110 goto cleanup;
1111 }
1112
1113 if ((ret =
1114 _E_gnutls_openpgp_raw_key_to_gcert (&peer_certificate_list[0],
1115 &tmp)) < 0)
1116 {
1117 gnutls_assert ();
1118 goto cleanup;
1119 }
1120
1121 if ((ret =
1122 _gnutls_copy_certificate_auth_info (info,
1123 peer_certificate_list,
1124 peer_certificate_list_size)) < 0)
1125 {
1126 gnutls_assert ();
1127 goto cleanup;
1128 }
1129
1130 if ((ret =
1131 _gnutls_check_key_usage (&peer_certificate_list[0],
1132 gnutls_kx_get (session))) < 0)
1133 {
1134 gnutls_assert ();
1135 goto cleanup;
1136 }
1137
1138 ret = 0;
1139
1140cleanup:
1141
1142 _gnutls_free_datum (&akey);
1143 CLEAR_CERTS;
1144 gnutls_afree (peer_certificate_list);
1145 return ret;
1146
1147}
1148
1149int
1150_gnutls_proc_cert_server_certificate (gnutls_session_t session,
1151 opaque * data, size_t data_size)
1152{
1153 switch (session->security_parameters.cert_type)
1154 {
1155 case GNUTLS_CRT_OPENPGP:
1156 return _gnutls_proc_openpgp_server_certificate (session,
1157 data, data_size);
1158 case GNUTLS_CRT_X509:
1159 return _gnutls_proc_x509_server_certificate (session, data, data_size);
1160 default:
1161 gnutls_assert ();
1162 return GNUTLS_E_INTERNAL_ERROR;
1163 }
1164}
1165
1166#define MAX_SIGN_ALGOS 2
1167typedef enum CertificateSigType
1168{ RSA_SIGN = 1, DSA_SIGN
1169} CertificateSigType;
1170
1171/* Checks if we support the given signature algorithm
1172 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1173 * if true;
1174 */
1175inline static int
1176_gnutls_check_supported_sign_algo (CertificateSigType algo)
1177{
1178 switch (algo)
1179 {
1180 case RSA_SIGN:
1181 return GNUTLS_PK_RSA;
1182 }
1183
1184 return -1;
1185}
1186
1187int
1188_gnutls_proc_cert_cert_req (gnutls_session_t session, opaque * data,
1189 size_t data_size)
1190{
1191 int size, ret;
1192 opaque *p;
1193 gnutls_certificate_credentials_t cred;
1194 cert_auth_info_t info;
1195 ssize_t dsize;
1196 int i, j;
1197 gnutls_pk_algorithm_t pk_algos[MAX_SIGN_ALGOS];
1198 int pk_algos_length;
1199 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1200
1201 cred = (gnutls_certificate_credentials_t)
1202 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1203 if (cred == NULL)
1204 {
1205 gnutls_assert ();
1206 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1207 }
1208
1209 if ((ret =
1210 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1211 sizeof (cert_auth_info_st), 0)) < 0)
1212 {
1213 gnutls_assert ();
1214 return ret;
1215 }
1216
1217 info = _gnutls_get_auth_info (session);
1218
1219 p = data;
1220 dsize = data_size;
1221
1222 DECR_LEN (dsize, 1);
1223 size = p[0];
1224 p++;
1225 /* check if the sign algorithm is supported.
1226 */
1227 pk_algos_length = j = 0;
1228 for (i = 0; i < size; i++, p++)
1229 {
1230 DECR_LEN (dsize, 1);
1231 if ((ret = _gnutls_check_supported_sign_algo (*p)) > 0)
1232 {
1233 if (j < MAX_SIGN_ALGOS)
1234 {
1235 pk_algos[j++] = ret;
1236 pk_algos_length++;
1237 }
1238 }
1239 }
1240
1241 if (pk_algos_length == 0)
1242 {
1243 gnutls_assert ();
1244 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1245 }
1246
1247 if (ver == GNUTLS_TLS1_2)
1248 {
1249 /* read supported hashes */
1250 int hash_num;
1251 DECR_LEN (dsize, 1);
1252
1253 hash_num = p[0] & 0xFF;
1254 p++;
1255
1256 DECR_LEN (dsize, hash_num);
1257 p += hash_num;
1258 }
1259
1260 /* read the certificate authorities */
1261 DECR_LEN (dsize, 2);
1262 size = _gnutls_read_uint16 (p);
1263 p += 2;
1264
1265 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP
1266 && size != 0)
1267 {
1268 gnutls_assert (); // size should be zero
1269 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1270 }
1271
1272 DECR_LEN (dsize, size);
1273
1274 /* now we ask the user to tell which one
1275 * he wants to use.
1276 */
1277 if ((ret =
1278 _select_client_cert (session, p, size, pk_algos, pk_algos_length)) < 0)
1279 {
1280 gnutls_assert ();
1281 return ret;
1282 }
1283
1284 /* We should reply with a certificate message,
1285 * even if we have no certificate to send.
1286 */
1287 session->key->certificate_requested = 1;
1288
1289 return 0;
1290}
1291
1292int
1293_gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data)
1294{
1295 int ret;
1296 gnutls_cert *apr_cert_list;
1297 gnutls_privkey *apr_pkey;
1298 int apr_cert_list_length, size;
1299 gnutls_datum_t signature;
1300
1301 *data = NULL;
1302
1303 /* find the appropriate certificate */
1304 if ((ret =
1305 _gnutls_get_selected_cert (session, &apr_cert_list,
1306 &apr_cert_list_length, &apr_pkey)) < 0)
1307 {
1308 gnutls_assert ();
1309 return ret;
1310 }
1311
1312 if (apr_cert_list_length > 0)
1313 {
1314 if ((ret =
1315 _gnutls_tls_sign_hdata (session,
1316 &apr_cert_list[0],
1317 apr_pkey, &signature)) < 0)
1318 {
1319 gnutls_assert ();
1320 return ret;
1321 }
1322 }
1323 else
1324 {
1325 return 0;
1326 }
1327
1328 *data = gnutls_malloc (signature.size + 2);
1329 if (*data == NULL)
1330 {
1331 _gnutls_free_datum (&signature);
1332 return GNUTLS_E_MEMORY_ERROR;
1333 }
1334 size = signature.size;
1335 _gnutls_write_uint16 (size, *data);
1336
1337 memcpy (&(*data)[2], signature.data, size);
1338
1339 _gnutls_free_datum (&signature);
1340
1341 return size + 2;
1342}
1343
1344int
1345_gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session,
1346 opaque * data, size_t data_size)
1347{
1348 int size, ret;
1349 ssize_t dsize = data_size;
1350 opaque *pdata = data;
1351 gnutls_datum_t sig;
1352 cert_auth_info_t info = _gnutls_get_auth_info (session);
1353 gnutls_cert peer_cert;
1354
1355 if (info == NULL || info->ncerts == 0)
1356 {
1357 gnutls_assert ();
1358 /* we need this in order to get peer's certificate */
1359 return GNUTLS_E_INTERNAL_ERROR;
1360 }
1361
1362 DECR_LEN (dsize, 2);
1363 size = _gnutls_read_uint16 (pdata);
1364 pdata += 2;
1365
1366 DECR_LEN (dsize, size);
1367
1368 sig.data = pdata;
1369 sig.size = size;
1370
1371 ret = _gnutls_raw_cert_to_gcert (&peer_cert,
1372 session->security_parameters.cert_type,
1373 &info->raw_certificate_list[0],
1374 CERT_NO_COPY);
1375
1376 if (ret < 0)
1377 {
1378 gnutls_assert ();
1379 return ret;
1380 }
1381
1382 if ((ret = _gnutls_verify_sig_hdata (session, &peer_cert, &sig)) < 0)
1383 {
1384 gnutls_assert ();
1385 _gnutls_gcert_deinit (&peer_cert);
1386 return ret;
1387 }
1388 _gnutls_gcert_deinit (&peer_cert);
1389
1390 return 0;
1391}
1392
1393#define CERTTYPE_SIZE 3
1394int
1395_gnutls_gen_cert_server_cert_req (gnutls_session_t session, opaque ** data)
1396{
1397 gnutls_certificate_credentials_t cred;
1398 int size;
1399 opaque *pdata;
1400 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1401
1402 /* Now we need to generate the RDN sequence. This is
1403 * already in the CERTIFICATE_CRED structure, to improve
1404 * performance.
1405 */
1406
1407 cred = (gnutls_certificate_credentials_t)
1408 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1409 if (cred == NULL)
1410 {
1411 gnutls_assert ();
1412 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1413 }
1414
1415 size = CERTTYPE_SIZE + 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1416 */
1417
1418 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1419 session->internals.ignore_rdn_sequence == 0)
1420 size += cred->x509_rdn_sequence.size;
1421
1422 if (ver == GNUTLS_TLS1_2)
1423 /* Need at least one byte to announce the number of supported hash
1424 functions (see below). */
1425 size += 1;
1426
1427 (*data) = gnutls_malloc (size);
1428 pdata = (*data);
1429
1430 if (pdata == NULL)
1431 {
1432 gnutls_assert ();
1433 return GNUTLS_E_MEMORY_ERROR;
1434 }
1435
1436 pdata[0] = CERTTYPE_SIZE - 1;
1437
1438 pdata[1] = RSA_SIGN;
1439 pdata[2] = DSA_SIGN; /* only these for now */
1440 pdata += CERTTYPE_SIZE;
1441
1442 if (ver == GNUTLS_TLS1_2)
1443 {
1444 /* Supported hashes (nothing for now -- FIXME). */
1445 *pdata = 0;
1446 pdata++;
1447 }
1448
1449 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1450 session->internals.ignore_rdn_sequence == 0)
1451 {
1452 _gnutls_write_datum16 (pdata, cred->x509_rdn_sequence);
1453 /* pdata += cred->x509_rdn_sequence.size + 2; */
1454 }
1455 else
1456 {
1457 _gnutls_write_uint16 (0, pdata);
1458 /* pdata+=2; */
1459 }
1460
1461 return size;
1462}
1463
1464
1465/* This function will return the appropriate certificate to use.
1466 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1467 * The return value is a negative value on error.
1468 *
1469 * It is normal to return 0 with no certificates in client side.
1470 *
1471 */
1472int
1473_gnutls_get_selected_cert (gnutls_session_t session,
1474 gnutls_cert ** apr_cert_list,
1475 int *apr_cert_list_length,
1476 gnutls_privkey ** apr_pkey)
1477{
1478 if (session->security_parameters.entity == GNUTLS_SERVER)
1479 {
1480
1481 /* select_client_cert() has been called before.
1482 */
1483
1484 *apr_cert_list = session->internals.selected_cert_list;
1485 *apr_pkey = session->internals.selected_key;
1486 *apr_cert_list_length = session->internals.selected_cert_list_length;
1487
1488 if (*apr_cert_list_length == 0 || *apr_cert_list == NULL)
1489 {
1490 gnutls_assert ();
1491 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1492 }
1493
1494 }
1495 else
1496 { /* CLIENT SIDE
1497 */
1498
1499 /* we have already decided which certificate
1500 * to send.
1501 */
1502 *apr_cert_list = session->internals.selected_cert_list;
1503 *apr_cert_list_length = session->internals.selected_cert_list_length;
1504 *apr_pkey = session->internals.selected_key;
1505
1506 }
1507
1508 return 0;
1509}
1510
1511/* converts the given x509 certificate to gnutls_cert* and allocates
1512 * space for them.
1513 */
1514static gnutls_cert *
1515alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, unsigned ncerts)
1516{
1517 gnutls_cert *local_certs;
1518 int ret = 0;
1519 unsigned i, j;
1520
1521 if (certs == NULL)
1522 return NULL;
1523
1524 local_certs = gnutls_malloc (sizeof (gnutls_cert) * ncerts);
1525 if (local_certs == NULL)
1526 {
1527 gnutls_assert ();
1528 return NULL;
1529 }
1530
1531 for (i = 0; i < ncerts; i++)
1532 {
1533 ret = _gnutls_x509_crt_to_gcert (&local_certs[i], certs[i], 0);
1534 if (ret < 0)
1535 break;
1536 }
1537
1538 if (ret < 0)
1539 {
1540 gnutls_assert ();
1541 for (j = 0; j < i; j++)
1542 {
1543 _gnutls_gcert_deinit (&local_certs[j]);
1544 }
1545 gnutls_free (local_certs);
1546 return NULL;
1547 }
1548
1549 return local_certs;
1550}
1551
1552/* converts the given x509 key to gnutls_privkey* and allocates
1553 * space for it.
1554 */
1555static gnutls_privkey *
1556alloc_and_load_x509_key (gnutls_x509_privkey_t key)
1557{
1558 gnutls_privkey *local_key;
1559 int ret = 0;
1560
1561 if (key == NULL)
1562 return NULL;
1563
1564 local_key = gnutls_malloc (sizeof (gnutls_privkey));
1565 if (local_key == NULL)
1566 {
1567 gnutls_assert ();
1568 return NULL;
1569 }
1570
1571 ret = _gnutls_x509_privkey_to_gkey (local_key, key);
1572 if (ret < 0)
1573 {
1574 gnutls_assert ();
1575 return NULL;
1576 }
1577
1578 return local_key;
1579}
1580
1581/* converts the given pgp certificate to gnutls_cert* and allocates
1582 * space for them.
1583 */
1584static gnutls_cert *
1585alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
1586{
1587 gnutls_cert *local_certs;
1588 int ret = 0;
1589
1590 if (cert == NULL)
1591 return NULL;
1592
1593 local_certs = gnutls_malloc (sizeof (gnutls_cert));
1594 if (local_certs == NULL)
1595 {
1596 gnutls_assert ();
1597 return NULL;
1598 }
1599
1600 if (_E_gnutls_openpgp_crt_to_gcert == NULL)
1601 {
1602 gnutls_assert ();
1603 return NULL;
1604 }
1605
1606 ret = _E_gnutls_openpgp_crt_to_gcert (local_certs, cert);
1607 if (ret < 0)
1608 {
1609 gnutls_assert ();
1610 return NULL;
1611 }
1612
1613 if (ret < 0)
1614 {
1615 gnutls_assert ();
1616 _gnutls_gcert_deinit (local_certs);
1617 gnutls_free (local_certs);
1618 return NULL;
1619 }
1620
1621 return local_certs;
1622}
1623
1624/* converts the given raw key to gnutls_privkey* and allocates
1625 * space for it.
1626 */
1627static gnutls_privkey *
1628alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key)
1629{
1630 gnutls_privkey *local_key;
1631 int ret = 0;
1632
1633 if (key == NULL)
1634 return NULL;
1635
1636 local_key = gnutls_malloc (sizeof (gnutls_privkey));
1637 if (local_key == NULL)
1638 {
1639 gnutls_assert ();
1640 return NULL;
1641 }
1642
1643 if (_E_gnutls_openpgp_privkey_to_gkey == NULL)
1644 {
1645 gnutls_assert ();
1646 return NULL;
1647 }
1648
1649 ret = _E_gnutls_openpgp_privkey_to_gkey (local_key, key);
1650 if (ret < 0)
1651 {
1652 gnutls_assert ();
1653 return NULL;
1654 }
1655
1656 return local_key;
1657}
1658
1659
1660void
1661_gnutls_selected_certs_deinit (gnutls_session_t session)
1662{
1663 if (session->internals.selected_need_free != 0)
1664 {
1665 int i;
1666
1667 for (i = 0; i < session->internals.selected_cert_list_length; i++)
1668 {
1669 _gnutls_gcert_deinit (&session->internals.selected_cert_list[i]);
1670 }
1671 gnutls_free (session->internals.selected_cert_list);
1672 session->internals.selected_cert_list = NULL;
1673 session->internals.selected_cert_list_length = 0;
1674
1675 _gnutls_gkey_deinit (session->internals.selected_key);
1676 if (session->internals.selected_key)
1677 {
1678 gnutls_free (session->internals.selected_key);
1679 session->internals.selected_key = NULL;
1680 }
1681 }
1682
1683 return;
1684}
1685
1686void
1687_gnutls_selected_certs_set (gnutls_session_t session,
1688 gnutls_cert * certs, int ncerts,
1689 gnutls_privkey * key, int need_free)
1690{
1691 _gnutls_selected_certs_deinit (session);
1692
1693 session->internals.selected_cert_list = certs;
1694 session->internals.selected_cert_list_length = ncerts;
1695 session->internals.selected_key = key;
1696 session->internals.selected_need_free = need_free;
1697
1698}
1699
1700
1701/* finds the most appropriate certificate in the cert list.
1702 * The 'appropriate' is defined by the user.
1703 *
1704 * requested_algo holds the parameters required by the peer (RSA, DSA
1705 * or -1 for any).
1706 *
1707 * Returns 0 on success and a negative value on error. The
1708 * selected certificate will be in session->internals.selected_*.
1709 *
1710 */
1711int
1712_gnutls_server_select_cert (gnutls_session_t session,
1713 gnutls_pk_algorithm_t requested_algo)
1714{
1715 unsigned i;
1716 int idx, ret;
1717 gnutls_certificate_credentials_t cred;
1718
1719 cred = (gnutls_certificate_credentials_t)
1720 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1721 if (cred == NULL)
1722 {
1723 gnutls_assert ();
1724 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1725 }
1726
1727 /* If the callback which retrieves certificate has been set,
1728 * use it and leave.
1729 */
1730 if (cred->server_get_cert_callback != NULL)
1731 return call_get_cert_callback (session, NULL, 0, NULL, 0);
1732
1733 /* Otherwise... */
1734
1735 ret = 0;
1736 idx = -1; /* default is use no certificate */
1737
1738
1739 for (i = 0; i < cred->ncerts; i++)
1740 {
1741 /* find one compatible certificate
1742 */
1743 if (requested_algo == GNUTLS_PK_ANY ||
1744 requested_algo == cred->cert_list[i][0].subject_pk_algorithm)
1745 {
1746 /* if cert type matches
1747 */
1748 if (session->security_parameters.cert_type ==
1749 cred->cert_list[i][0].cert_type)
1750 {
1751 idx = i;
1752 break;
1753 }
1754 }
1755 }
1756
1757 /* store the certificate pointer for future use, in the handshake.
1758 * (This will allow not calling this callback again.)
1759 */
1760 if (idx >= 0 && ret == 0)
1761 {
1762 _gnutls_selected_certs_set (session,
1763 &cred->cert_list[idx][0],
1764 cred->cert_list_length[idx],
1765 &cred->pkey[idx], 0);
1766 }
1767 else
1768 /* Certificate does not support REQUESTED_ALGO. */
1769 ret = GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1770
1771 return ret;
1772}
1773
1774/* Frees the rsa_info_st structure.
1775 */
1776void
1777_gnutls_free_rsa_info (rsa_info_st * rsa)
1778{
1779 _gnutls_free_datum (&rsa->modulus);
1780 _gnutls_free_datum (&rsa->exponent);
1781}
diff --git a/src/daemon/https/tls/auth_cert.h b/src/daemon/https/tls/auth_cert.h
new file mode 100644
index 00000000..86e0230f
--- /dev/null
+++ b/src/daemon/https/tls/auth_cert.h
@@ -0,0 +1,158 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef AUTH_CERT_H
26# define AUTH_CERT_H
27
28# include "gnutls_cert.h"
29# include "gnutls_auth.h"
30# include "auth_dh_common.h"
31# include "x509.h"
32# include "openpgp.h"
33
34/* This structure may be complex, but it's the only way to
35 * support a server that has multiple certificates
36 */
37typedef struct gnutls_certificate_credentials_st
38{
39 gnutls_dh_params_t dh_params;
40 gnutls_rsa_params_t rsa_params;
41 /* this callback is used to retrieve the DH or RSA
42 * parameters.
43 */
44 gnutls_params_function *params_func;
45
46 gnutls_cert **cert_list;
47 /* contains a list of a list of certificates.
48 * eg (X509): [0] certificate1, certificate11, certificate111
49 * (if more than one, one certificate certifies the one before)
50 * [1] certificate2, certificate22, ...
51 */
52 unsigned *cert_list_length;
53 /* contains the number of the certificates in a
54 * row (should be 1 for OpenPGP keys).
55 */
56 unsigned ncerts; /* contains the number of columns in cert_list.
57 * This is the same with the number of pkeys.
58 */
59
60 gnutls_privkey *pkey;
61 /* private keys. It contains ncerts private
62 * keys. pkey[i] corresponds to certificate in
63 * cert_list[i][0].
64 */
65
66 /* OpenPGP specific stuff */
67
68#ifndef KEYRING_HACK
69 gnutls_openpgp_keyring_t keyring;
70#else
71 gnutls_datum_t keyring;
72 int keyring_format;
73#endif
74
75 /* X509 specific stuff */
76
77 gnutls_x509_crt_t *x509_ca_list;
78 unsigned x509_ncas; /* number of CAs in the ca_list
79 */
80
81 gnutls_x509_crl_t *x509_crl_list;
82 unsigned x509_ncrls; /* number of CRLs in the crl_list
83 */
84
85 unsigned int verify_flags; /* flags to be used at
86 * certificate verification.
87 */
88 unsigned int verify_depth;
89 unsigned int verify_bits;
90
91 /* holds a sequence of the
92 * RDNs of the CAs above.
93 * This is better than
94 * generating on every handshake.
95 */
96 gnutls_datum_t x509_rdn_sequence;
97
98 gnutls_certificate_client_retrieve_function *client_get_cert_callback;
99 gnutls_certificate_server_retrieve_function *server_get_cert_callback;
100} certificate_credentials_st;
101
102typedef struct rsa_info_st
103{
104 gnutls_datum_t modulus;
105 gnutls_datum_t exponent;
106} rsa_info_st;
107
108typedef struct cert_auth_info_st
109{
110 int certificate_requested; /* if the peer requested certificate
111 * this is non zero;
112 */
113
114 /* These (dh/rsa) are just copies from the credentials_t structure.
115 * They must be freed.
116 */
117 dh_info_st dh;
118 rsa_info_st rsa_export;
119
120 gnutls_datum_t *raw_certificate_list; /* holds the raw certificate of the
121 * peer.
122 */
123 unsigned int ncerts; /* holds the size of the list above */
124} *cert_auth_info_t;
125
126typedef struct cert_auth_info_st cert_auth_info_st;
127
128void _gnutls_free_rsa_info (rsa_info_st * rsa);
129
130/* AUTH X509 functions */
131int _gnutls_gen_cert_server_certificate (gnutls_session_t, opaque **);
132int _gnutls_gen_cert_client_certificate (gnutls_session_t, opaque **);
133int _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t, opaque **);
134int _gnutls_gen_cert_server_cert_req (gnutls_session_t, opaque **);
135int _gnutls_proc_cert_cert_req (gnutls_session_t, opaque *, size_t);
136int _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t, opaque *, size_t);
137int _gnutls_proc_cert_server_certificate (gnutls_session_t, opaque *, size_t);
138int _gnutls_get_selected_cert (gnutls_session_t session,
139 gnutls_cert ** apr_cert_list,
140 int *apr_cert_list_length,
141 gnutls_privkey ** apr_pkey);
142
143int _gnutls_server_select_cert (struct gnutls_session_int *,
144 gnutls_pk_algorithm_t);
145void _gnutls_selected_certs_deinit (gnutls_session_t session);
146void _gnutls_selected_certs_set (gnutls_session_t session,
147 gnutls_cert * certs, int ncerts,
148 gnutls_privkey * key, int need_free);
149
150#define _gnutls_proc_cert_client_certificate _gnutls_proc_cert_server_certificate
151
152gnutls_rsa_params_t _gnutls_certificate_get_rsa_params (gnutls_rsa_params_t
153 rsa_params,
154 gnutls_params_function
155 * func,
156 gnutls_session_t);
157
158#endif
diff --git a/src/daemon/https/tls/auth_dh_common.c b/src/daemon/https/tls/auth_dh_common.c
new file mode 100644
index 00000000..f1b82bf9
--- /dev/null
+++ b/src/daemon/https/tls/auth_dh_common.c
@@ -0,0 +1,369 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains common stuff in Ephemeral Diffie Hellman (DHE) and
26 * Anonymous DH key exchange(DHA). These are used in the handshake procedure
27 * of the certificate and anoymous authentication.
28 */
29
30#include "gnutls_int.h"
31#include "gnutls_auth_int.h"
32#include "gnutls_errors.h"
33#include "gnutls_dh.h"
34#include "gnutls_num.h"
35#include "gnutls_sig.h"
36#include <gnutls_datum.h>
37#include <gnutls_x509.h>
38#include <gnutls_state.h>
39#include <auth_dh_common.h>
40#include <gnutls_algorithms.h>
41
42/* Frees the dh_info_st structure.
43 */
44void
45_gnutls_free_dh_info (dh_info_st * dh)
46{
47 dh->secret_bits = 0;
48 _gnutls_free_datum (&dh->prime);
49 _gnutls_free_datum (&dh->generator);
50 _gnutls_free_datum (&dh->public_key);
51}
52
53int
54_gnutls_proc_dh_common_client_kx (gnutls_session_t session,
55 opaque * data, size_t _data_size,
56 mpi_t g, mpi_t p)
57{
58 uint16_t n_Y;
59 size_t _n_Y;
60 int ret;
61 ssize_t data_size = _data_size;
62
63
64 DECR_LEN (data_size, 2);
65 n_Y = _gnutls_read_uint16 (&data[0]);
66 _n_Y = n_Y;
67
68 DECR_LEN (data_size, n_Y);
69 if (_gnutls_mpi_scan_nz (&session->key->client_Y, &data[2], &_n_Y))
70 {
71 gnutls_assert ();
72 return GNUTLS_E_MPI_SCAN_FAILED;
73 }
74
75 _gnutls_dh_set_peer_public (session, session->key->client_Y);
76
77 session->key->KEY =
78 gnutls_calc_dh_key (session->key->client_Y, session->key->dh_secret, p);
79
80 if (session->key->KEY == NULL)
81 {
82 gnutls_assert ();
83 return GNUTLS_E_MEMORY_ERROR;
84 }
85
86 _gnutls_mpi_release (&session->key->client_Y);
87 _gnutls_mpi_release (&session->key->dh_secret);
88
89
90 if (_gnutls_cipher_suite_get_kx_algo
91 (&session->security_parameters.current_cipher_suite)
92 != GNUTLS_KX_DHE_PSK)
93 {
94 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
95 }
96 /* In DHE_PSK the key is set differently
97 else
98 {
99 gnutls_datum_t tmp_dh_key;
100 ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY);
101 if (ret < 0)
102 {
103 gnutls_assert ();
104 return ret;
105 }
106
107 ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
108 _gnutls_free_datum (&tmp_dh_key);
109
110 }
111 */
112
113 _gnutls_mpi_release (&session->key->KEY);
114
115 if (ret < 0)
116 {
117 return ret;
118 }
119
120 return 0;
121}
122
123int
124_gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data)
125{
126 mpi_t x = NULL, X = NULL;
127 size_t n_X;
128 int ret;
129
130 *data = NULL;
131
132 X = gnutls_calc_dh_secret (&x, session->key->client_g,
133 session->key->client_p);
134 if (X == NULL || x == NULL)
135 {
136 gnutls_assert ();
137 ret = GNUTLS_E_MEMORY_ERROR;
138 goto error;
139 }
140
141 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
142
143 _gnutls_mpi_print (NULL, &n_X, X);
144 (*data) = gnutls_malloc (n_X + 2);
145 if (*data == NULL)
146 {
147 ret = GNUTLS_E_MEMORY_ERROR;
148 goto error;
149 }
150
151 _gnutls_mpi_print (&(*data)[2], &n_X, X);
152 _gnutls_mpi_release (&X);
153
154 _gnutls_write_uint16 (n_X, &(*data)[0]);
155
156 /* calculate the key after calculating the message */
157 session->key->KEY =
158 gnutls_calc_dh_key (session->key->client_Y, x, session->key->client_p);
159
160 _gnutls_mpi_release (&x);
161 if (session->key->KEY == NULL)
162 {
163 gnutls_assert ();
164 ret = GNUTLS_E_MEMORY_ERROR;
165 goto error;
166 }
167
168 /* THESE SHOULD BE DISCARDED */
169 _gnutls_mpi_release (&session->key->client_Y);
170 _gnutls_mpi_release (&session->key->client_p);
171 _gnutls_mpi_release (&session->key->client_g);
172
173 if (_gnutls_cipher_suite_get_kx_algo
174 (&session->security_parameters.current_cipher_suite)
175 != GNUTLS_KX_DHE_PSK)
176 {
177 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
178 }
179 /* In DHE_PSK the key is set differently
180 else
181 {
182 gnutls_datum_t tmp_dh_key;
183 ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY);
184 if (ret < 0)
185 {
186 gnutls_assert ();
187 goto error;
188 }
189
190 ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
191 _gnutls_free_datum (&tmp_dh_key);
192
193 }*/
194
195 _gnutls_mpi_release (&session->key->KEY);
196
197 if (ret < 0)
198 {
199 gnutls_assert ();
200 goto error;
201 }
202
203 return n_X + 2;
204
205error:
206 _gnutls_mpi_release (&x);
207 _gnutls_mpi_release (&X);
208 gnutls_free (*data);
209 *data = NULL;
210 return ret;
211}
212
213int
214_gnutls_proc_dh_common_server_kx (gnutls_session_t session,
215 opaque * data, size_t _data_size, int psk)
216{
217 uint16_t n_Y, n_g, n_p;
218 size_t _n_Y, _n_g, _n_p;
219 uint8_t *data_p;
220 uint8_t *data_g;
221 uint8_t *data_Y;
222 int i, bits, psk_size, ret;
223 ssize_t data_size = _data_size;
224
225 i = 0;
226
227 if (psk != 0)
228 {
229 DECR_LEN (data_size, 2);
230 psk_size = _gnutls_read_uint16 (&data[i]);
231 DECR_LEN (data_size, psk_size);
232 i += 2 + psk_size;
233 }
234
235 DECR_LEN (data_size, 2);
236 n_p = _gnutls_read_uint16 (&data[i]);
237 i += 2;
238
239 DECR_LEN (data_size, n_p);
240 data_p = &data[i];
241 i += n_p;
242
243 DECR_LEN (data_size, 2);
244 n_g = _gnutls_read_uint16 (&data[i]);
245 i += 2;
246
247 DECR_LEN (data_size, n_g);
248 data_g = &data[i];
249 i += n_g;
250
251 DECR_LEN (data_size, 2);
252 n_Y = _gnutls_read_uint16 (&data[i]);
253 i += 2;
254
255 DECR_LEN (data_size, n_Y);
256 data_Y = &data[i];
257 i += n_Y;
258
259 _n_Y = n_Y;
260 _n_g = n_g;
261 _n_p = n_p;
262
263 if (_gnutls_mpi_scan_nz (&session->key->client_Y, data_Y, &_n_Y) != 0)
264 {
265 gnutls_assert ();
266 return GNUTLS_E_MPI_SCAN_FAILED;
267 }
268
269 if (_gnutls_mpi_scan_nz (&session->key->client_g, data_g, &_n_g) != 0)
270 {
271 gnutls_assert ();
272 return GNUTLS_E_MPI_SCAN_FAILED;
273 }
274 if (_gnutls_mpi_scan_nz (&session->key->client_p, data_p, &_n_p) != 0)
275 {
276 gnutls_assert ();
277 return GNUTLS_E_MPI_SCAN_FAILED;
278 }
279
280 bits = _gnutls_dh_get_allowed_prime_bits (session);
281 if (bits < 0)
282 {
283 gnutls_assert ();
284 return bits;
285 }
286
287 if (_gnutls_mpi_get_nbits (session->key->client_p) < (size_t) bits)
288 {
289 /* the prime used by the peer is not acceptable
290 */
291 gnutls_assert ();
292 return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
293 }
294
295 _gnutls_dh_set_group (session, session->key->client_g,
296 session->key->client_p);
297 _gnutls_dh_set_peer_public (session, session->key->client_Y);
298
299 ret = n_Y + n_p + n_g + 6;
300 if (psk != 0)
301 ret += 2;
302
303 return ret;
304}
305
306/* If the psk flag is set, then an empty psk_identity_hint will
307 * be inserted */
308int
309_gnutls_dh_common_print_server_kx (gnutls_session_t session,
310 mpi_t g, mpi_t p, opaque ** data, int psk)
311{
312 mpi_t x, X;
313 size_t n_X, n_g, n_p;
314 int ret, data_size, pos;
315 uint8_t *pdata;
316
317 X = gnutls_calc_dh_secret (&x, g, p);
318 if (X == NULL || x == NULL)
319 {
320 gnutls_assert ();
321 return GNUTLS_E_MEMORY_ERROR;
322 }
323
324 session->key->dh_secret = x;
325 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
326
327 _gnutls_mpi_print (NULL, &n_g, g);
328 _gnutls_mpi_print (NULL, &n_p, p);
329 _gnutls_mpi_print (NULL, &n_X, X);
330
331 data_size = n_g + n_p + n_X + 6;
332 if (psk != 0)
333 data_size += 2;
334
335 (*data) = gnutls_malloc (data_size);
336 if (*data == NULL)
337 {
338 _gnutls_mpi_release (&X);
339 return GNUTLS_E_MEMORY_ERROR;
340 }
341
342 pos = 0;
343 pdata = *data;
344
345 if (psk != 0)
346 {
347 _gnutls_write_uint16 (0, &pdata[pos]);
348 pos += 2;
349 }
350
351 _gnutls_mpi_print (&pdata[pos + 2], &n_p, p);
352 _gnutls_write_uint16 (n_p, &pdata[pos]);
353
354 pos += n_p + 2;
355
356 _gnutls_mpi_print (&pdata[pos + 2], &n_g, g);
357 _gnutls_write_uint16 (n_g, &pdata[pos]);
358
359 pos += n_g + 2;
360
361 _gnutls_mpi_print (&pdata[pos + 2], &n_X, X);
362 _gnutls_mpi_release (&X);
363
364 _gnutls_write_uint16 (n_X, &pdata[pos]);
365
366 ret = data_size;
367
368 return ret;
369}
diff --git a/src/daemon/https/tls/auth_dh_common.h b/src/daemon/https/tls/auth_dh_common.h
new file mode 100644
index 00000000..be0ad066
--- /dev/null
+++ b/src/daemon/https/tls/auth_dh_common.h
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef AUTH_DH_COMMON
26# define AUTH_DH_COMMON
27
28typedef struct
29{
30 int secret_bits;
31
32 gnutls_datum_t prime;
33 gnutls_datum_t generator;
34 gnutls_datum_t public_key;
35} dh_info_st;
36
37void _gnutls_free_dh_info (dh_info_st * dh);
38int _gnutls_gen_dh_common_client_kx (gnutls_session_t, opaque **);
39int _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
40 opaque * data, size_t _data_size,
41 mpi_t p, mpi_t g);
42int _gnutls_dh_common_print_server_kx (gnutls_session_t, mpi_t g, mpi_t p,
43 opaque ** data, int psk);
44int _gnutls_proc_dh_common_server_kx (gnutls_session_t session,
45 opaque * data, size_t _data_size,
46 int psk);
47
48#endif
diff --git a/src/daemon/https/tls/auth_dhe.c b/src/daemon/https/tls/auth_dhe.c
new file mode 100644
index 00000000..0262bda3
--- /dev/null
+++ b/src/daemon/https/tls/auth_dhe.c
@@ -0,0 +1,276 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains everything for the Ephemeral Diffie Hellman (DHE)
26 * key exchange. This is used in the handshake procedure of the certificate
27 * authentication.
28 */
29
30#include "gnutls_int.h"
31#include "gnutls_auth_int.h"
32#include "gnutls_errors.h"
33#include "gnutls_dh.h"
34#include "gnutls_num.h"
35#include "gnutls_sig.h"
36#include <gnutls_datum.h>
37#include <auth_cert.h>
38#include <gnutls_x509.h>
39#include <gnutls_state.h>
40#include <auth_dh_common.h>
41
42static int gen_dhe_server_kx (gnutls_session_t, opaque **);
43static int proc_dhe_server_kx (gnutls_session_t, opaque *, size_t);
44static int proc_dhe_client_kx (gnutls_session_t, opaque *, size_t);
45
46const mod_auth_st dhe_rsa_auth_struct = {
47 "DHE_RSA",
48 _gnutls_gen_cert_server_certificate,
49 _gnutls_gen_cert_client_certificate,
50 gen_dhe_server_kx,
51 _gnutls_gen_dh_common_client_kx,
52 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
53 _gnutls_gen_cert_server_cert_req, /* server cert request */
54
55 _gnutls_proc_cert_server_certificate,
56 _gnutls_proc_cert_client_certificate,
57 proc_dhe_server_kx,
58 proc_dhe_client_kx,
59 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
60 _gnutls_proc_cert_cert_req /* proc server cert request */
61};
62
63const mod_auth_st dhe_dss_auth_struct = {
64 "DHE_DSS",
65 _gnutls_gen_cert_server_certificate,
66 _gnutls_gen_cert_client_certificate,
67 gen_dhe_server_kx,
68 _gnutls_gen_dh_common_client_kx,
69 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
70 _gnutls_gen_cert_server_cert_req, /* server cert request */
71
72 _gnutls_proc_cert_server_certificate,
73 _gnutls_proc_cert_client_certificate,
74 proc_dhe_server_kx,
75 proc_dhe_client_kx,
76 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
77 _gnutls_proc_cert_cert_req /* proc server cert request */
78};
79
80
81static int
82gen_dhe_server_kx (gnutls_session_t session, opaque ** data)
83{
84 mpi_t g, p;
85 const mpi_t *mpis;
86 int ret = 0, data_size;
87 int bits;
88 gnutls_cert *apr_cert_list;
89 gnutls_privkey *apr_pkey;
90 int apr_cert_list_length;
91 gnutls_datum_t signature, ddata;
92 gnutls_certificate_credentials_t cred;
93 gnutls_dh_params_t dh_params;
94
95 cred = (gnutls_certificate_credentials_t)
96 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
97 if (cred == NULL)
98 {
99 gnutls_assert ();
100 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
101 }
102
103 bits = _gnutls_dh_get_allowed_prime_bits (session);
104
105 /* find the appropriate certificate */
106 if ((ret =
107 _gnutls_get_selected_cert (session, &apr_cert_list,
108 &apr_cert_list_length, &apr_pkey)) < 0)
109 {
110 gnutls_assert ();
111 return ret;
112 }
113
114 dh_params =
115 _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
116 mpis = _gnutls_dh_params_to_mpi (dh_params);
117 if (mpis == NULL)
118 {
119 gnutls_assert ();
120 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
121 }
122
123 p = mpis[0];
124 g = mpis[1];
125
126 if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
127 sizeof (cert_auth_info_st), 0)) < 0)
128 {
129 gnutls_assert ();
130 return ret;
131 }
132
133 _gnutls_dh_set_group (session, g, p);
134
135 ret = _gnutls_dh_common_print_server_kx (session, g, p, data, 0);
136 if (ret < 0)
137 {
138 gnutls_assert ();
139 return ret;
140 }
141 data_size = ret;
142
143 /* Generate the signature. */
144
145 ddata.data = *data;
146 ddata.size = data_size;
147
148 if (apr_cert_list_length > 0)
149 {
150 if ((ret =
151 _gnutls_tls_sign_params (session, &apr_cert_list[0],
152 apr_pkey, &ddata, &signature)) < 0)
153 {
154 gnutls_assert ();
155 gnutls_free (*data);
156 return ret;
157 }
158 }
159 else
160 {
161 gnutls_assert ();
162 return data_size; /* do not put a signature - ILLEGAL! */
163 }
164
165 *data = gnutls_realloc_fast (*data, data_size + signature.size + 2);
166 if (*data == NULL)
167 {
168 _gnutls_free_datum (&signature);
169 gnutls_assert ();
170 return GNUTLS_E_MEMORY_ERROR;
171 }
172
173 _gnutls_write_datum16 (&(*data)[data_size], signature);
174 data_size += signature.size + 2;
175
176 _gnutls_free_datum (&signature);
177
178 return data_size;
179}
180
181static int
182proc_dhe_server_kx (gnutls_session_t session, opaque * data,
183 size_t _data_size)
184{
185 int sigsize;
186 gnutls_datum_t vparams, signature;
187 int ret;
188 cert_auth_info_t info = _gnutls_get_auth_info (session);
189 ssize_t data_size = _data_size;
190 gnutls_cert peer_cert;
191
192 if (info == NULL || info->ncerts == 0)
193 {
194 gnutls_assert ();
195 /* we need this in order to get peer's certificate */
196 return GNUTLS_E_INTERNAL_ERROR;
197 }
198
199 ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 0);
200 if (ret < 0)
201 {
202 gnutls_assert ();
203 return ret;
204 }
205
206 /* VERIFY SIGNATURE */
207
208 vparams.size = ret;
209 vparams.data = data;
210
211 DECR_LEN (data_size, 2);
212 sigsize = _gnutls_read_uint16 (&data[vparams.size]);
213
214 DECR_LEN (data_size, sigsize);
215 signature.data = &data[vparams.size + 2];
216 signature.size = sigsize;
217
218 if ((ret =
219 _gnutls_raw_cert_to_gcert (&peer_cert,
220 session->security_parameters.cert_type,
221 &info->raw_certificate_list[0],
222 CERT_NO_COPY)) < 0)
223 {
224 gnutls_assert ();
225 return ret;
226 }
227
228 ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature);
229
230 _gnutls_gcert_deinit (&peer_cert);
231 if (ret < 0)
232 {
233 gnutls_assert ();
234 return ret;
235 }
236
237 return ret;
238}
239
240
241
242static int
243proc_dhe_client_kx (gnutls_session_t session, opaque * data,
244 size_t _data_size)
245{
246 gnutls_certificate_credentials_t cred;
247 int ret;
248 mpi_t p, g;
249 const mpi_t *mpis;
250 gnutls_dh_params_t dh_params;
251
252 cred = (gnutls_certificate_credentials_t)
253 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
254 if (cred == NULL)
255 {
256 gnutls_assert ();
257 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
258 }
259
260 dh_params =
261 _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
262 mpis = _gnutls_dh_params_to_mpi (dh_params);
263 if (mpis == NULL)
264 {
265 gnutls_assert ();
266 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
267 }
268
269 p = mpis[0];
270 g = mpis[1];
271
272 ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p);
273
274 return ret;
275
276}
diff --git a/src/daemon/https/tls/auth_rsa.c b/src/daemon/https/tls/auth_rsa.c
new file mode 100644
index 00000000..4430009d
--- /dev/null
+++ b/src/daemon/https/tls/auth_rsa.c
@@ -0,0 +1,408 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains the RSA key exchange part of the certificate
26 * authentication.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_auth_int.h"
31#include "gnutls_errors.h"
32#include "gnutls_dh.h"
33#include "gnutls_num.h"
34#include "libtasn1.h"
35#include "gnutls_datum.h"
36#include "auth_cert.h"
37#include <gnutls_pk.h>
38#include <gnutls_algorithms.h>
39#include <gnutls_global.h>
40#include "debug.h"
41#include <gnutls_sig.h>
42#include <gnutls_x509.h>
43#include <gc.h>
44
45int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **);
46int _gnutls_proc_rsa_client_kx (gnutls_session_t, opaque *, size_t);
47
48const mod_auth_st rsa_auth_struct = {
49 "RSA",
50 _gnutls_gen_cert_server_certificate,
51 _gnutls_gen_cert_client_certificate,
52 NULL, /* gen server kx */
53 _gnutls_gen_rsa_client_kx,
54 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
55 _gnutls_gen_cert_server_cert_req, /* server cert request */
56
57 _gnutls_proc_cert_server_certificate,
58 _gnutls_proc_cert_client_certificate,
59 NULL, /* proc server kx */
60 _gnutls_proc_rsa_client_kx, /* proc client kx */
61 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
62 _gnutls_proc_cert_cert_req /* proc server cert request */
63};
64
65/* This function reads the RSA parameters from peer's certificate;
66 */
67int
68_gnutls_get_public_rsa_params (gnutls_session_t session,
69 mpi_t params[MAX_PUBLIC_PARAMS_SIZE],
70 int *params_len)
71{
72 int ret;
73 cert_auth_info_t info;
74 gnutls_cert peer_cert;
75 int i;
76
77 /* normal non export case */
78
79 info = _gnutls_get_auth_info (session);
80
81 if (info == NULL || info->ncerts == 0)
82 {
83 gnutls_assert ();
84 return GNUTLS_E_INTERNAL_ERROR;
85 }
86
87 ret =
88 _gnutls_raw_cert_to_gcert (&peer_cert,
89 session->security_parameters.cert_type,
90 &info->raw_certificate_list[0],
91 CERT_ONLY_PUBKEY | CERT_NO_COPY);
92
93 if (ret < 0)
94 {
95 gnutls_assert ();
96 return ret;
97 }
98
99
100 /* EXPORT case: */
101 if (_gnutls_cipher_suite_get_kx_algo
102 (&session->security_parameters.current_cipher_suite)
103 == GNUTLS_KX_RSA_EXPORT
104 && _gnutls_mpi_get_nbits (peer_cert.params[0]) > 512)
105 {
106
107 _gnutls_gcert_deinit (&peer_cert);
108
109 if (session->key->rsa[0] == NULL || session->key->rsa[1] == NULL)
110 {
111 gnutls_assert ();
112 return GNUTLS_E_INTERNAL_ERROR;
113 }
114
115 if (*params_len < 2)
116 {
117 gnutls_assert ();
118 return GNUTLS_E_INTERNAL_ERROR;
119 }
120 *params_len = 2;
121 for (i = 0; i < *params_len; i++)
122 {
123 params[i] = _gnutls_mpi_copy (session->key->rsa[i]);
124 }
125
126 return 0;
127 }
128
129 /* end of export case */
130
131 if (*params_len < peer_cert.params_size)
132 {
133 gnutls_assert ();
134 return GNUTLS_E_INTERNAL_ERROR;
135 }
136 *params_len = peer_cert.params_size;
137
138 for (i = 0; i < *params_len; i++)
139 {
140 params[i] = _gnutls_mpi_copy (peer_cert.params[i]);
141 }
142 _gnutls_gcert_deinit (&peer_cert);
143
144 return 0;
145}
146
147/* This function reads the RSA parameters from the private key
148 */
149int
150_gnutls_get_private_rsa_params (gnutls_session_t session,
151 mpi_t ** params, int *params_size)
152{
153 int bits;
154 gnutls_certificate_credentials_t cred;
155 gnutls_rsa_params_t rsa_params;
156
157 cred = (gnutls_certificate_credentials_t)
158 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
159 if (cred == NULL)
160 {
161 gnutls_assert ();
162 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
163 }
164
165 if (session->internals.selected_cert_list == NULL)
166 {
167 gnutls_assert ();
168 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
169 }
170
171 bits =
172 _gnutls_mpi_get_nbits (session->internals.selected_cert_list[0].
173 params[0]);
174
175 if (_gnutls_cipher_suite_get_kx_algo
176 (&session->security_parameters.current_cipher_suite)
177 == GNUTLS_KX_RSA_EXPORT && bits > 512)
178 {
179
180 rsa_params =
181 _gnutls_certificate_get_rsa_params (cred->rsa_params,
182 cred->params_func, session);
183 /* EXPORT case: */
184 if (rsa_params == NULL)
185 {
186 gnutls_assert ();
187 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
188 }
189
190 /* In the export case, we do use temporary RSA params
191 * of 512 bits size. The params in the certificate are
192 * used to sign this temporary stuff.
193 */
194 *params_size = RSA_PRIVATE_PARAMS;
195 *params = rsa_params->params;
196
197 return 0;
198 }
199
200 /* non export cipher suites. */
201
202 *params_size = session->internals.selected_key->params_size;
203 *params = session->internals.selected_key->params;
204
205 return 0;
206}
207
208int
209_gnutls_proc_rsa_client_kx (gnutls_session_t session, opaque * data,
210 size_t _data_size)
211{
212 gnutls_datum_t plaintext;
213 gnutls_datum_t ciphertext;
214 int ret, dsize;
215 mpi_t *params;
216 int params_len;
217 int randomize_key = 0;
218 ssize_t data_size = _data_size;
219
220 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
221 {
222 /* SSL 3.0
223 */
224 ciphertext.data = data;
225 ciphertext.size = data_size;
226 }
227 else
228 {
229 /* TLS 1.0
230 */
231 DECR_LEN (data_size, 2);
232 ciphertext.data = &data[2];
233 dsize = _gnutls_read_uint16 (data);
234
235 if (dsize != data_size)
236 {
237 gnutls_assert ();
238 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
239 }
240 ciphertext.size = dsize;
241 }
242
243 ret = _gnutls_get_private_rsa_params (session, &params, &params_len);
244 if (ret < 0)
245 {
246 gnutls_assert ();
247 return ret;
248 }
249
250 ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, params_len, 2); /* btype==2 */
251
252 if (ret < 0 || plaintext.size != TLS_MASTER_SIZE)
253 {
254 /* In case decryption fails then don't inform
255 * the peer. Just use a random key. (in order to avoid
256 * attack against pkcs-1 formating).
257 */
258 gnutls_assert ();
259 _gnutls_x509_log ("auth_rsa: Possible PKCS #1 format attack\n");
260 randomize_key = 1;
261 }
262 else
263 {
264 /* If the secret was properly formatted, then
265 * check the version number.
266 */
267 if (_gnutls_get_adv_version_major (session) != plaintext.data[0]
268 || _gnutls_get_adv_version_minor (session) != plaintext.data[1])
269 {
270 /* No error is returned here, if the version number check
271 * fails. We proceed normally.
272 * That is to defend against the attack described in the paper
273 * "Attacking RSA-based sessions in SSL/TLS" by Vlastimil Klima,
274 * Ondej Pokorny and Tomas Rosa.
275 */
276 gnutls_assert ();
277 _gnutls_x509_log
278 ("auth_rsa: Possible PKCS #1 version check format attack\n");
279 }
280 }
281
282 if (randomize_key != 0)
283 {
284 session->key->key.size = TLS_MASTER_SIZE;
285 session->key->key.data = gnutls_malloc (session->key->key.size);
286 if (session->key->key.data == NULL)
287 {
288 gnutls_assert ();
289 return GNUTLS_E_MEMORY_ERROR;
290 }
291
292 /* we do not need strong random numbers here.
293 */
294 if (gc_nonce (session->key->key.data, session->key->key.size) != GC_OK)
295 {
296 gnutls_assert ();
297 return GNUTLS_E_RANDOM_FAILED;
298 }
299
300 }
301 else
302 {
303 session->key->key.data = plaintext.data;
304 session->key->key.size = plaintext.size;
305 }
306
307 /* This is here to avoid the version check attack
308 * discussed above.
309 */
310 session->key->key.data[0] = _gnutls_get_adv_version_major (session);
311 session->key->key.data[1] = _gnutls_get_adv_version_minor (session);
312
313 return 0;
314}
315
316
317
318/* return RSA(random) using the peers public key
319 */
320int
321_gnutls_gen_rsa_client_kx (gnutls_session_t session, opaque ** data)
322{
323 cert_auth_info_t auth = session->key->auth_info;
324 gnutls_datum_t sdata; /* data to send */
325 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
326 int params_len = MAX_PUBLIC_PARAMS_SIZE;
327 int ret, i;
328 gnutls_protocol_t ver;
329
330 if (auth == NULL)
331 {
332 /* this shouldn't have happened. The proc_certificate
333 * function should have detected that.
334 */
335 gnutls_assert ();
336 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
337 }
338
339 session->key->key.size = TLS_MASTER_SIZE;
340 session->key->key.data = gnutls_secure_malloc (session->key->key.size);
341
342 if (session->key->key.data == NULL)
343 {
344 gnutls_assert ();
345 return GNUTLS_E_MEMORY_ERROR;
346 }
347
348 if (gc_pseudo_random (session->key->key.data,
349 session->key->key.size) != GC_OK)
350 {
351 gnutls_assert ();
352 return GNUTLS_E_RANDOM_FAILED;
353 }
354
355 ver = _gnutls_get_adv_version (session);
356
357 if (session->internals.rsa_pms_version[0] == 0)
358 {
359 session->key->key.data[0] = _gnutls_version_get_major (ver);
360 session->key->key.data[1] = _gnutls_version_get_minor (ver);
361 }
362 else
363 { /* use the version provided */
364 session->key->key.data[0] = session->internals.rsa_pms_version[0];
365 session->key->key.data[1] = session->internals.rsa_pms_version[1];
366 }
367
368 /* move RSA parameters to key (session).
369 */
370 if ((ret =
371 _gnutls_get_public_rsa_params (session, params, &params_len)) < 0)
372 {
373 gnutls_assert ();
374 return ret;
375 }
376
377 if ((ret =
378 _gnutls_pkcs1_rsa_encrypt (&sdata, &session->key->key,
379 params, params_len, 2)) < 0)
380 {
381 gnutls_assert ();
382 return ret;
383 }
384
385 for (i = 0; i < params_len; i++)
386 _gnutls_mpi_release (&params[i]);
387
388 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
389 {
390 /* SSL 3.0 */
391 *data = sdata.data;
392 return sdata.size;
393 }
394 else
395 { /* TLS 1 */
396 *data = gnutls_malloc (sdata.size + 2);
397 if (*data == NULL)
398 {
399 _gnutls_free_datum (&sdata);
400 return GNUTLS_E_MEMORY_ERROR;
401 }
402 _gnutls_write_datum16 (*data, sdata);
403 ret = sdata.size + 2;
404 _gnutls_free_datum (&sdata);
405 return ret;
406 }
407
408}
diff --git a/src/daemon/https/tls/auth_rsa_export.c b/src/daemon/https/tls/auth_rsa_export.c
new file mode 100644
index 00000000..3c84121d
--- /dev/null
+++ b/src/daemon/https/tls/auth_rsa_export.c
@@ -0,0 +1,325 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains the RSA key exchange part of the certificate
26 * authentication.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_auth_int.h"
31#include "gnutls_errors.h"
32#include "gnutls_dh.h"
33#include "gnutls_num.h"
34#include "libtasn1.h"
35#include "gnutls_datum.h"
36#include "auth_cert.h"
37#include <gnutls_pk.h>
38#include <gnutls_algorithms.h>
39#include <gnutls_global.h>
40#include "debug.h"
41#include <gnutls_sig.h>
42#include <gnutls_x509.h>
43#include <gnutls_rsa_export.h>
44#include <gnutls_state.h>
45
46int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **);
47int _gnutls_proc_rsa_client_kx (gnutls_session_t, opaque *, size_t);
48static int gen_rsa_export_server_kx (gnutls_session_t, opaque **);
49static int proc_rsa_export_server_kx (gnutls_session_t, opaque *, size_t);
50
51const mod_auth_st rsa_export_auth_struct = {
52 "RSA EXPORT",
53 _gnutls_gen_cert_server_certificate,
54 _gnutls_gen_cert_client_certificate,
55 gen_rsa_export_server_kx,
56 _gnutls_gen_rsa_client_kx,
57 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
58 _gnutls_gen_cert_server_cert_req, /* server cert request */
59
60 _gnutls_proc_cert_server_certificate,
61 _gnutls_proc_cert_client_certificate,
62 proc_rsa_export_server_kx,
63 _gnutls_proc_rsa_client_kx, /* proc client kx */
64 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
65 _gnutls_proc_cert_cert_req /* proc server cert request */
66};
67
68static int
69gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data)
70{
71 gnutls_rsa_params_t rsa_params;
72 const mpi_t *rsa_mpis;
73 size_t n_e, n_m;
74 uint8_t *data_e, *data_m;
75 int ret = 0, data_size;
76 gnutls_cert *apr_cert_list;
77 gnutls_privkey *apr_pkey;
78 int apr_cert_list_length;
79 gnutls_datum_t signature, ddata;
80 cert_auth_info_t info;
81 gnutls_certificate_credentials_t cred;
82
83 cred = (gnutls_certificate_credentials_t)
84 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
85 if (cred == NULL)
86 {
87 gnutls_assert ();
88 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
89 }
90
91 /* find the appropriate certificate */
92 if ((ret =
93 _gnutls_get_selected_cert (session, &apr_cert_list,
94 &apr_cert_list_length, &apr_pkey)) < 0)
95 {
96 gnutls_assert ();
97 return ret;
98 }
99
100 /* abort sending this message if we have a certificate
101 * of 512 bits or less.
102 */
103 if (apr_pkey && _gnutls_mpi_get_nbits (apr_pkey->params[0]) <= 512)
104 {
105 gnutls_assert ();
106 return GNUTLS_E_INT_RET_0;
107 }
108
109 rsa_params =
110 _gnutls_certificate_get_rsa_params (cred->rsa_params, cred->params_func,
111 session);
112 rsa_mpis = _gnutls_rsa_params_to_mpi (rsa_params);
113 if (rsa_mpis == NULL)
114 {
115 gnutls_assert ();
116 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
117 }
118
119 if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
120 sizeof (cert_auth_info_st), 0)) < 0)
121 {
122 gnutls_assert ();
123 return ret;
124 }
125
126 info = _gnutls_get_auth_info (session);
127 _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]);
128
129 _gnutls_mpi_print (NULL, &n_m, rsa_mpis[0]);
130 _gnutls_mpi_print (NULL, &n_e, rsa_mpis[1]);
131
132 (*data) = gnutls_malloc (n_e + n_m + 4);
133 if (*data == NULL)
134 {
135 return GNUTLS_E_MEMORY_ERROR;
136 }
137
138 data_m = &(*data)[0];
139 _gnutls_mpi_print (&data_m[2], &n_m, rsa_mpis[0]);
140
141 _gnutls_write_uint16 (n_m, data_m);
142
143 data_e = &data_m[2 + n_m];
144 _gnutls_mpi_print (&data_e[2], &n_e, rsa_mpis[1]);
145
146 _gnutls_write_uint16 (n_e, data_e);
147
148 data_size = n_m + n_e + 4;
149
150
151 /* Generate the signature. */
152
153 ddata.data = *data;
154 ddata.size = data_size;
155
156 if (apr_cert_list_length > 0)
157 {
158 if ((ret =
159 _gnutls_tls_sign_params (session, &apr_cert_list[0],
160 apr_pkey, &ddata, &signature)) < 0)
161 {
162 gnutls_assert ();
163 gnutls_free (*data);
164 *data = NULL;
165 return ret;
166 }
167 }
168 else
169 {
170 gnutls_assert ();
171 return data_size; /* do not put a signature - ILLEGAL! */
172 }
173
174 *data = gnutls_realloc_fast (*data, data_size + signature.size + 2);
175 if (*data == NULL)
176 {
177 _gnutls_free_datum (&signature);
178 gnutls_assert ();
179 return GNUTLS_E_MEMORY_ERROR;
180 }
181
182 _gnutls_write_datum16 (&((*data)[data_size]), signature);
183 data_size += signature.size + 2;
184
185 _gnutls_free_datum (&signature);
186
187 return data_size;
188}
189
190/* if the peer's certificate is of 512 bits or less, returns non zero.
191 */
192int
193_gnutls_peers_cert_less_512 (gnutls_session_t session)
194{
195 gnutls_cert peer_cert;
196 int ret;
197 cert_auth_info_t info = _gnutls_get_auth_info (session);
198
199 if (info == NULL || info->ncerts == 0)
200 {
201 gnutls_assert ();
202 /* we need this in order to get peer's certificate */
203 return 0;
204 }
205
206 if ((ret =
207 _gnutls_raw_cert_to_gcert (&peer_cert,
208 session->security_parameters.cert_type,
209 &info->raw_certificate_list[0],
210 CERT_NO_COPY)) < 0)
211 {
212 gnutls_assert ();
213 return 0;
214 }
215
216 if (peer_cert.subject_pk_algorithm != GNUTLS_PK_RSA)
217 {
218 gnutls_assert ();
219 _gnutls_gcert_deinit (&peer_cert);
220 return 0;
221 }
222
223 if (_gnutls_mpi_get_nbits (peer_cert.params[0]) <= 512)
224 {
225 _gnutls_gcert_deinit (&peer_cert);
226 return 1;
227 }
228
229 _gnutls_gcert_deinit (&peer_cert);
230
231 return 0;
232}
233
234static int
235proc_rsa_export_server_kx (gnutls_session_t session,
236 opaque * data, size_t _data_size)
237{
238 uint16_t n_m, n_e;
239 size_t _n_m, _n_e;
240 uint8_t *data_m;
241 uint8_t *data_e;
242 int i, sigsize;
243 gnutls_datum_t vparams, signature;
244 int ret;
245 ssize_t data_size = _data_size;
246 cert_auth_info_t info;
247 gnutls_cert peer_cert;
248
249 info = _gnutls_get_auth_info (session);
250 if (info == NULL || info->ncerts == 0)
251 {
252 gnutls_assert ();
253 /* we need this in order to get peer's certificate */
254 return GNUTLS_E_INTERNAL_ERROR;
255 }
256
257
258 i = 0;
259
260 DECR_LEN (data_size, 2);
261 n_m = _gnutls_read_uint16 (&data[i]);
262 i += 2;
263
264 DECR_LEN (data_size, n_m);
265 data_m = &data[i];
266 i += n_m;
267
268 DECR_LEN (data_size, 2);
269 n_e = _gnutls_read_uint16 (&data[i]);
270 i += 2;
271
272 DECR_LEN (data_size, n_e);
273 data_e = &data[i];
274 i += n_e;
275
276 _n_e = n_e;
277 _n_m = n_m;
278
279 if (_gnutls_mpi_scan_nz (&session->key->rsa[0], data_m, &_n_m) != 0)
280 {
281 gnutls_assert ();
282 return GNUTLS_E_MPI_SCAN_FAILED;
283 }
284
285 if (_gnutls_mpi_scan_nz (&session->key->rsa[1], data_e, &_n_e) != 0)
286 {
287 gnutls_assert ();
288 return GNUTLS_E_MPI_SCAN_FAILED;
289 }
290
291 _gnutls_rsa_export_set_pubkey (session, session->key->rsa[1],
292 session->key->rsa[0]);
293
294 /* VERIFY SIGNATURE */
295
296 vparams.size = n_m + n_e + 4;
297 vparams.data = data;
298
299 DECR_LEN (data_size, 2);
300 sigsize = _gnutls_read_uint16 (&data[vparams.size]);
301
302 DECR_LEN (data_size, sigsize);
303 signature.data = &data[vparams.size + 2];
304 signature.size = sigsize;
305
306 if ((ret =
307 _gnutls_raw_cert_to_gcert (&peer_cert,
308 session->security_parameters.cert_type,
309 &info->raw_certificate_list[0],
310 CERT_NO_COPY)) < 0)
311 {
312 gnutls_assert ();
313 return ret;
314 }
315
316 ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature);
317
318 _gnutls_gcert_deinit (&peer_cert);
319 if (ret < 0)
320 {
321 gnutls_assert ();
322 }
323
324 return ret;
325}
diff --git a/src/daemon/https/tls/debug.c b/src/daemon/https/tls/debug.c
new file mode 100644
index 00000000..2ea31577
--- /dev/null
+++ b/src/daemon/https/tls/debug.c
@@ -0,0 +1,128 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include "gnutls_int.h"
26#include "gnutls_errors.h"
27#include <stdio.h>
28#include <stdlib.h>
29#include <gcrypt.h>
30
31#ifdef DEBUG
32
33
34void
35_gnutls_print_state (gnutls_session_t session)
36{
37
38 _gnutls_debug_log ("GNUTLS State:\n");
39 _gnutls_debug_log ("Connection End: %d\n",
40 session->security_parameters.entity);
41 _gnutls_debug_log ("Cipher Algorithm: %d\n",
42 session->security_parameters.read_bulk_cipher_algorithm);
43 _gnutls_debug_log ("MAC algorithm: %d\n",
44 session->security_parameters.read_mac_algorithm);
45 _gnutls_debug_log ("Compression Algorithm: %d\n",
46 session->security_parameters.read_compression_algorithm);
47 _gnutls_debug_log ("\n");
48
49}
50
51#endif
52
53const char *
54_gnutls_packet2str (content_type_t packet)
55{
56 switch (packet)
57 {
58 case GNUTLS_CHANGE_CIPHER_SPEC:
59 return "Change Cipher Spec";
60 case GNUTLS_ALERT:
61 return "Alert";
62 case GNUTLS_HANDSHAKE:
63 return "Handshake";
64 case GNUTLS_APPLICATION_DATA:
65 return "Application Data";
66 case GNUTLS_INNER_APPLICATION:
67 return "Inner Application";
68
69 default:
70 return "Unknown Packet";
71 }
72}
73
74const char *
75_gnutls_handshake2str (gnutls_handshake_description_t handshake)
76{
77
78 switch (handshake)
79 {
80 case GNUTLS_HANDSHAKE_HELLO_REQUEST:
81 return "HELLO REQUEST";
82 break;
83 case GNUTLS_HANDSHAKE_CLIENT_HELLO:
84 return "CLIENT HELLO";
85 break;
86 case GNUTLS_HANDSHAKE_SERVER_HELLO:
87 return "SERVER HELLO";
88 break;
89 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
90 return "CERTIFICATE";
91 break;
92 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
93 return "SERVER KEY EXCHANGE";
94 break;
95 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
96 return "CERTIFICATE REQUEST";
97 break;
98 case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
99 return "SERVER HELLO DONE";
100 break;
101 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
102 return "CERTIFICATE VERIFY";
103 break;
104 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
105 return "CLIENT KEY EXCHANGE";
106 break;
107 case GNUTLS_HANDSHAKE_FINISHED:
108 return "FINISHED";
109 break;
110 case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
111 return "SUPPLEMENTAL";
112 break;
113 default:
114 return "Unknown Handshake packet";
115
116 }
117}
118
119void
120_gnutls_dump_mpi (const char *prefix, mpi_t a)
121{
122 opaque buf[1024];
123 size_t n = sizeof buf;
124
125 if (gcry_mpi_print (GCRYMPI_FMT_HEX, buf, n, &n, a))
126 strcpy (buf, "[can't print value]"); /* Flawfinder: ignore */
127 _gnutls_hard_log ("MPI: length: %d\n\t%s%s\n", (n - 1) / 2, prefix, buf);
128}
diff --git a/src/daemon/https/tls/debug.h b/src/daemon/https/tls/debug.h
new file mode 100644
index 00000000..169bc21d
--- /dev/null
+++ b/src/daemon/https/tls/debug.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifdef DEBUG
26void _gnutls_print_state (gnutls_session_t session);
27#endif
28const char *_gnutls_packet2str (content_type_t packet);
29const char *_gnutls_handshake2str (gnutls_handshake_description_t handshake);
30void _gnutls_dump_mpi (const char *prefix, mpi_t a);
diff --git a/src/daemon/https/tls/defines.h b/src/daemon/https/tls/defines.h
new file mode 100644
index 00000000..a53ce2e4
--- /dev/null
+++ b/src/daemon/https/tls/defines.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef DEFINES_H
26# define DEFINES_H
27
28#if HAVE_CONFIG_H
29# include <config.h>
30#endif
31
32#include <stddef.h>
33#include <string.h>
34#include <stdlib.h>
35#include <stdio.h>
36#include <ctype.h>
37#include <limits.h>
38#include <stdint.h>
39
40#ifdef NO_SSIZE_T
41# define HAVE_SSIZE_T
42typedef int ssize_t;
43#endif
44
45#include <sys/types.h>
46#include <unistd.h>
47#include <sys/stat.h>
48#include <sys/socket.h>
49#include <time.h>
50
51// TODO check if these should go into config.h
52#define SIZEOF_UNSIGNED_INT 4
53#define SIZEOF_UNSIGNED_LONG 8
54#define SIZEOF_UNSIGNED_LONG_INT SIZEOF_UNSIGNED_LONG
55
56/* some systems had problems with long long int, thus,
57 * it is not used.
58 */
59typedef struct
60{
61 unsigned char i[8];
62} uint64;
63
64#endif /* defines_h */
diff --git a/src/daemon/https/tls/ext_cert_type.c b/src/daemon/https/tls/ext_cert_type.c
new file mode 100644
index 00000000..f970e1fe
--- /dev/null
+++ b/src/daemon/https/tls/ext_cert_type.c
@@ -0,0 +1,243 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains the code the Certificate Type TLS extension.
26 * This extension is currently gnutls specific.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_errors.h"
31#include "gnutls_num.h"
32#include "ext_cert_type.h"
33#include <gnutls_state.h>
34#include <gnutls_num.h>
35
36inline static int _gnutls_num2cert_type (int num);
37inline static int _gnutls_cert_type2num (int record_size);
38
39/*
40 * In case of a server: if a CERT_TYPE extension type is received then it stores
41 * into the session security parameters the new value. The server may use gnutls_session_certificate_type_get(),
42 * to access it.
43 *
44 * In case of a client: If a cert_types have been specified then we send the extension.
45 *
46 */
47
48int
49_gnutls_cert_type_recv_params (gnutls_session_t session,
50 const opaque * data, size_t _data_size)
51{
52 int new_type = -1, ret, i;
53 ssize_t data_size = _data_size;
54
55 if (session->security_parameters.entity == GNUTLS_CLIENT)
56 {
57 if (data_size > 0)
58 {
59 if (data_size != 1)
60 {
61 gnutls_assert ();
62 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
63 }
64
65 new_type = _gnutls_num2cert_type (data[0]);
66
67 if (new_type < 0)
68 {
69 gnutls_assert ();
70 return new_type;
71 }
72
73 /* Check if we support this cert_type */
74 if ((ret =
75 _gnutls_session_cert_type_supported (session, new_type)) < 0)
76 {
77 gnutls_assert ();
78 return ret;
79 }
80
81 _gnutls_session_cert_type_set (session, new_type);
82 }
83 }
84 else
85 { /* SERVER SIDE - we must check if the sent cert type is the right one
86 */
87 if (data_size > 1)
88 {
89 uint8_t len;
90
91 len = data[0];
92 DECR_LEN (data_size, len);
93
94 for (i = 0; i < len; i++)
95 {
96 new_type = _gnutls_num2cert_type (data[i + 1]);
97
98 if (new_type < 0)
99 continue;
100
101 /* Check if we support this cert_type */
102 if ((ret =
103 _gnutls_session_cert_type_supported (session,
104 new_type)) < 0)
105 {
106 gnutls_assert ();
107 continue;
108 }
109 else
110 break;
111 /* new_type is ok */
112 }
113
114 if (new_type < 0)
115 {
116 gnutls_assert ();
117 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
118 }
119
120 if ((ret =
121 _gnutls_session_cert_type_supported (session, new_type)) < 0)
122 {
123 gnutls_assert ();
124 /* The peer has requested unsupported certificate
125 * types. Instead of failing, procceed normally.
126 * (the ciphersuite selection would fail, or a
127 * non certificate ciphersuite will be selected).
128 */
129 return 0;
130 }
131
132 _gnutls_session_cert_type_set (session, new_type);
133 }
134
135
136 }
137
138 return 0;
139}
140
141/* returns data_size or a negative number on failure
142 */
143int
144_gnutls_cert_type_send_params (gnutls_session_t session, opaque * data,
145 size_t data_size)
146{
147 unsigned len, i;
148
149 /* this function sends the client extension data (dnsname) */
150 if (session->security_parameters.entity == GNUTLS_CLIENT)
151 {
152
153 if (session->internals.priorities.cert_type.algorithms > 0)
154 {
155
156 len = session->internals.priorities.cert_type.algorithms;
157
158 if (len == 1 &&
159 session->internals.priorities.cert_type.priority[0] ==
160 GNUTLS_CRT_X509)
161 {
162 /* We don't use this extension if X.509 certificates
163 * are used.
164 */
165 return 0;
166 }
167
168 if (data_size < len + 1)
169 {
170 gnutls_assert ();
171 return GNUTLS_E_SHORT_MEMORY_BUFFER;
172 }
173
174 /* this is a vector!
175 */
176 data[0] = (uint8_t) len;
177
178 for (i = 0; i < len; i++)
179 {
180 data[i + 1] = _gnutls_cert_type2num (session->internals.
181 priorities.cert_type.
182 priority[i]);
183 }
184 return len + 1;
185 }
186
187 }
188 else
189 { /* server side */
190 if (session->security_parameters.cert_type != DEFAULT_CERT_TYPE)
191 {
192 len = 1;
193 if (data_size < len)
194 {
195 gnutls_assert ();
196 return GNUTLS_E_SHORT_MEMORY_BUFFER;
197 }
198
199 data[0] =
200 _gnutls_cert_type2num (session->security_parameters.cert_type);
201 return len;
202 }
203
204
205 }
206
207 return 0;
208}
209
210/* Maps numbers to record sizes according to the
211 * extensions draft.
212 */
213inline static int
214_gnutls_num2cert_type (int num)
215{
216 switch (num)
217 {
218 case 0:
219 return GNUTLS_CRT_X509;
220 case 1:
221 return GNUTLS_CRT_OPENPGP;
222 default:
223 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
224 }
225}
226
227/* Maps record size to numbers according to the
228 * extensions draft.
229 */
230inline static int
231_gnutls_cert_type2num (int cert_type)
232{
233 switch (cert_type)
234 {
235 case GNUTLS_CRT_X509:
236 return 0;
237 case GNUTLS_CRT_OPENPGP:
238 return 1;
239 default:
240 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
241 }
242
243}
diff --git a/src/daemon/https/tls/ext_cert_type.h b/src/daemon/https/tls/ext_cert_type.h
new file mode 100644
index 00000000..ea7cf219
--- /dev/null
+++ b/src/daemon/https/tls/ext_cert_type.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Maps record size to numbers according to the
26 * extensions draft.
27 */
28int _gnutls_cert_type_recv_params (gnutls_session_t session,
29 const opaque * data, size_t data_size);
30int _gnutls_cert_type_send_params (gnutls_session_t session, opaque * data,
31 size_t);
diff --git a/src/daemon/https/tls/ext_inner_application.c b/src/daemon/https/tls/ext_inner_application.c
new file mode 100644
index 00000000..b86b7151
--- /dev/null
+++ b/src/daemon/https/tls/ext_inner_application.c
@@ -0,0 +1,147 @@
1/*
2 * Copyright (C) 2005, 2006 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
21 * 02110-1301, USA
22 *
23 */
24
25#include "gnutls_int.h"
26#include "gnutls_auth_int.h"
27#include "gnutls_errors.h"
28#include "gnutls_num.h"
29#include "ext_inner_application.h"
30
31#define NO 0
32#define YES 1
33
34int
35_gnutls_inner_application_recv_params (gnutls_session_t session,
36 const opaque * data, size_t data_size)
37{
38 tls_ext_st *ext = &session->security_parameters.extensions;
39
40 if (data_size != 1)
41 {
42 gnutls_assert ();
43 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
44 }
45
46 ext->gnutls_ia_peer_enable = 1;
47 ext->gnutls_ia_peer_allowskip = 0;
48
49 switch ((unsigned char) *data)
50 {
51 case NO: /* Peer's ia_on_resume == no */
52 ext->gnutls_ia_peer_allowskip = 1;
53 break;
54
55 case YES:
56 break;
57
58 default:
59 gnutls_assert ();
60 }
61
62 return 0;
63}
64
65
66/* returns data_size or a negative number on failure
67 */
68int
69_gnutls_inner_application_send_params (gnutls_session_t session,
70 opaque * data, size_t data_size)
71{
72 tls_ext_st *ext = &session->security_parameters.extensions;
73
74 /* Set ext->gnutls_ia_enable depending on whether we have a TLS/IA
75 credential in the session. */
76
77 if (session->security_parameters.entity == GNUTLS_CLIENT)
78 {
79 gnutls_ia_client_credentials_t cred = (gnutls_ia_client_credentials_t)
80 _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
81
82 if (cred)
83 ext->gnutls_ia_enable = 1;
84 }
85 else
86 {
87 gnutls_ia_server_credentials_t cred = (gnutls_ia_server_credentials_t)
88 _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
89
90 if (cred)
91 ext->gnutls_ia_enable = 1;
92 }
93
94 /* If we don't want gnutls_ia locally, or we are a server and the
95 * client doesn't want it, don't advertise TLS/IA support at all, as
96 * required. */
97
98 if (!ext->gnutls_ia_enable)
99 return 0;
100
101 if (session->security_parameters.entity == GNUTLS_SERVER &&
102 !ext->gnutls_ia_peer_enable)
103 return 0;
104
105 /* We'll advertise. Check if there's room in the hello buffer. */
106
107 if (data_size < 1)
108 {
109 gnutls_assert ();
110 return GNUTLS_E_SHORT_MEMORY_BUFFER;
111 }
112
113 /* default: require new application phase */
114
115 *data = YES;
116
117 if (session->security_parameters.entity == GNUTLS_CLIENT)
118 {
119
120 /* Client: value follows local setting */
121
122 if (ext->gnutls_ia_allowskip)
123 *data = NO;
124 }
125 else
126 {
127
128 /* Server: value follows local setting and client's setting, but only
129 * if we are resuming.
130 *
131 * XXX Can server test for resumption at this stage?
132 *
133 * Ai! It seems that read_client_hello only calls parse_extensions if
134 * we're NOT resuming! That would make us automatically violate the IA
135 * draft; if we're resuming, we must first learn what the client wants
136 * -- IA or no IA -- and then prepare our response. Right now we'll
137 * always skip IA on resumption, because recv_ext isn't even called
138 * to record the peer's support for IA at all. Simon? */
139
140 if (ext->gnutls_ia_allowskip &&
141 ext->gnutls_ia_peer_allowskip &&
142 session->internals.resumed == RESUME_TRUE)
143 *data = NO;
144 }
145
146 return 1;
147}
diff --git a/src/daemon/https/tls/ext_inner_application.h b/src/daemon/https/tls/ext_inner_application.h
new file mode 100644
index 00000000..e75719e3
--- /dev/null
+++ b/src/daemon/https/tls/ext_inner_application.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2005 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_inner_application_recv_params (gnutls_session_t session,
26 const opaque * data,
27 size_t data_size);
28int _gnutls_inner_application_send_params (gnutls_session_t session,
29 opaque * data, size_t);
diff --git a/src/daemon/https/tls/ext_max_record.c b/src/daemon/https/tls/ext_max_record.c
new file mode 100644
index 00000000..d0787483
--- /dev/null
+++ b/src/daemon/https/tls/ext_max_record.c
@@ -0,0 +1,196 @@
1/*
2 * Copyright (C) 2001, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains the code for the Max Record Size TLS extension.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_errors.h"
30#include "gnutls_num.h"
31#include <ext_max_record.h>
32
33/*
34 * In case of a server: if a MAX_RECORD_SIZE extension type is received then it stores
35 * into the session the new value. The server may use gnutls_get_max_record_size(),
36 * in order to access it.
37 *
38 * In case of a client: If a different max record size (than the default) has
39 * been specified then it sends the extension.
40 *
41 */
42
43int
44_gnutls_max_record_recv_params (gnutls_session_t session,
45 const opaque * data, size_t _data_size)
46{
47 ssize_t new_size;
48 ssize_t data_size = _data_size;
49
50 if (session->security_parameters.entity == GNUTLS_SERVER)
51 {
52 if (data_size > 0)
53 {
54 DECR_LEN (data_size, 1);
55
56 new_size = _gnutls_mre_num2record (data[0]);
57
58 if (new_size < 0)
59 {
60 gnutls_assert ();
61 return new_size;
62 }
63
64 session->security_parameters.max_record_send_size = new_size;
65 session->security_parameters.max_record_recv_size = new_size;
66 }
67 }
68 else
69 { /* CLIENT SIDE - we must check if the sent record size is the right one
70 */
71 if (data_size > 0)
72 {
73
74 if (data_size != 1)
75 {
76 gnutls_assert ();
77 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
78 }
79
80 new_size = _gnutls_mre_num2record (data[0]);
81
82 if (new_size < 0
83 || new_size != session->internals.proposed_record_size)
84 {
85 gnutls_assert ();
86 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
87 }
88 else
89 {
90 session->security_parameters.max_record_recv_size =
91 session->internals.proposed_record_size;
92 }
93
94 }
95
96
97 }
98
99 return 0;
100}
101
102/* returns data_size or a negative number on failure
103 */
104int
105_gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
106 size_t data_size)
107{
108 uint16_t len;
109 /* this function sends the client extension data (dnsname) */
110 if (session->security_parameters.entity == GNUTLS_CLIENT)
111 {
112
113 if (session->internals.proposed_record_size != DEFAULT_MAX_RECORD_SIZE)
114 {
115 len = 1;
116 if (data_size < len)
117 {
118 gnutls_assert ();
119 return GNUTLS_E_SHORT_MEMORY_BUFFER;
120 }
121
122 data[0] =
123 (uint8_t) _gnutls_mre_record2num (session->internals.
124 proposed_record_size);
125 return len;
126 }
127
128 }
129 else
130 { /* server side */
131
132 if (session->security_parameters.max_record_recv_size !=
133 DEFAULT_MAX_RECORD_SIZE)
134 {
135 len = 1;
136 if (data_size < len)
137 {
138 gnutls_assert ();
139 return GNUTLS_E_SHORT_MEMORY_BUFFER;
140 }
141
142 data[0] =
143 (uint8_t) _gnutls_mre_record2num (session->
144 security_parameters.
145 max_record_recv_size);
146 return len;
147 }
148
149
150 }
151
152 return 0;
153}
154
155/* Maps numbers to record sizes according to the
156 * extensions draft.
157 */
158int
159_gnutls_mre_num2record (int num)
160{
161 switch (num)
162 {
163 case 1:
164 return 512;
165 case 2:
166 return 1024;
167 case 3:
168 return 2048;
169 case 4:
170 return 4096;
171 default:
172 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
173 }
174}
175
176/* Maps record size to numbers according to the
177 * extensions draft.
178 */
179int
180_gnutls_mre_record2num (uint16_t record_size)
181{
182 switch (record_size)
183 {
184 case 512:
185 return 1;
186 case 1024:
187 return 2;
188 case 2048:
189 return 3;
190 case 4096:
191 return 4;
192 default:
193 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
194 }
195
196}
diff --git a/src/daemon/https/tls/ext_max_record.h b/src/daemon/https/tls/ext_max_record.h
new file mode 100644
index 00000000..751bedc8
--- /dev/null
+++ b/src/daemon/https/tls/ext_max_record.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Maps record size to numbers according to the
26 * extensions draft.
27 */
28int _gnutls_mre_num2record (int num);
29int _gnutls_mre_record2num (uint16_t record_size);
30int _gnutls_max_record_recv_params (gnutls_session_t session,
31 const opaque * data, size_t data_size);
32int _gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
33 size_t);
diff --git a/src/daemon/https/tls/ext_oprfi.c b/src/daemon/https/tls/ext_oprfi.c
new file mode 100644
index 00000000..c862ad1c
--- /dev/null
+++ b/src/daemon/https/tls/ext_oprfi.c
@@ -0,0 +1,253 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Implementation of Opaque PRF Input:
26 * http://tools.ietf.org/id/draft-rescorla-tls-opaque-prf-input-00.txt
27 *
28 */
29
30#include <ext_oprfi.h>
31
32#include <gnutls_errors.h>
33#include <gnutls_num.h>
34
35int
36oprfi_recv_server (gnutls_session_t session,
37 const opaque * data, size_t _data_size)
38{
39 ssize_t data_size = _data_size;
40 uint16_t len;
41 int ret;
42
43 if (!session->security_parameters.extensions.oprfi_cb)
44 {
45 gnutls_assert ();
46 return 0;
47 }
48
49 DECR_LEN (data_size, 2);
50 len = _gnutls_read_uint16 (data);
51 data += 2;
52
53 if (len != data_size)
54 {
55 gnutls_assert ();
56 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
57 }
58
59 /* Store incoming data. */
60 session->security_parameters.extensions.oprfi_client_len = len;
61 session->security_parameters.extensions.oprfi_client = gnutls_malloc (len);
62 if (!session->security_parameters.extensions.oprfi_client)
63 {
64 gnutls_assert ();
65 return GNUTLS_E_MEMORY_ERROR;
66 }
67 memcpy (session->security_parameters.extensions.oprfi_client, data, len);
68
69 return 0;
70}
71
72int
73oprfi_recv_client (gnutls_session_t session,
74 const opaque * data, size_t _data_size)
75{
76 ssize_t data_size = _data_size;
77 uint16_t len;
78 int ret;
79
80 if (session->security_parameters.extensions.oprfi_client == NULL)
81 {
82 gnutls_assert ();
83 return 0;
84 }
85
86 DECR_LEN (data_size, 2);
87 len = _gnutls_read_uint16 (data);
88 data += 2;
89
90 if (len != data_size)
91 {
92 gnutls_assert ();
93 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
94 }
95
96 if (len != session->security_parameters.extensions.oprfi_client_len)
97 {
98 gnutls_assert ();
99 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
100 }
101
102 /* Store incoming data. */
103 session->security_parameters.extensions.oprfi_server_len = len;
104 session->security_parameters.extensions.oprfi_server = gnutls_malloc (len);
105 if (!session->security_parameters.extensions.oprfi_server)
106 {
107 gnutls_assert ();
108 return GNUTLS_E_MEMORY_ERROR;
109 }
110 memcpy (session->security_parameters.extensions.oprfi_server, data, len);
111
112 return 0;
113}
114
115int
116_gnutls_oprfi_recv_params (gnutls_session_t session,
117 const opaque * data, size_t data_size)
118{
119 if (session->security_parameters.entity == GNUTLS_CLIENT)
120 return oprfi_recv_client (session, data, data_size);
121 else
122 return oprfi_recv_server (session, data, data_size);
123}
124
125int
126oprfi_send_client (gnutls_session_t session, opaque * data, size_t _data_size)
127{
128 opaque *p = data;
129 ssize_t data_size = _data_size;
130 int oprf_size = session->security_parameters.extensions.oprfi_client_len;
131
132 if (oprf_size == 0)
133 return 0;
134
135 DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
136 _gnutls_write_uint16 (oprf_size, p);
137 p += 2;
138
139 DECR_LENGTH_RET (data_size, oprf_size, GNUTLS_E_SHORT_MEMORY_BUFFER);
140
141 memcpy (p, session->security_parameters.extensions.oprfi_client, oprf_size);
142
143 return 2 + oprf_size;
144}
145
146int
147oprfi_send_server (gnutls_session_t session, opaque * data, size_t _data_size)
148{
149 opaque *p = data;
150 int ret;
151 ssize_t data_size = _data_size;
152 size_t len;
153
154 if (!session->security_parameters.extensions.oprfi_client ||
155 !session->security_parameters.extensions.oprfi_cb)
156 return 0;
157
158 /* Allocate buffer for outgoing data. */
159 session->security_parameters.extensions.oprfi_server_len =
160 session->security_parameters.extensions.oprfi_client_len;
161 session->security_parameters.extensions.oprfi_server =
162 gnutls_malloc (session->security_parameters.extensions.oprfi_server_len);
163 if (!session->security_parameters.extensions.oprfi_server)
164 {
165 gnutls_assert ();
166 return GNUTLS_E_MEMORY_ERROR;
167 }
168
169 /* Get outgoing data. */
170 ret = session->security_parameters.extensions.oprfi_cb
171 (session, session->security_parameters.extensions.oprfi_userdata,
172 session->security_parameters.extensions.oprfi_client_len,
173 session->security_parameters.extensions.oprfi_client,
174 session->security_parameters.extensions.oprfi_server);
175 if (ret < 0)
176 {
177 gnutls_assert ();
178 gnutls_free (session->security_parameters.extensions.oprfi_server);
179 return ret;
180 }
181
182 DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
183 _gnutls_write_uint16 (session->security_parameters.
184 extensions.oprfi_server_len, p);
185 p += 2;
186
187 DECR_LENGTH_RET (data_size, session->security_parameters.
188 extensions.oprfi_server_len, GNUTLS_E_SHORT_MEMORY_BUFFER);
189
190 memcpy (p, session->security_parameters.extensions.oprfi_server,
191 session->security_parameters.extensions.oprfi_server_len);
192
193 return 2 + session->security_parameters.extensions.oprfi_server_len;
194}
195
196int
197_gnutls_oprfi_send_params (gnutls_session_t session,
198 opaque * data, size_t data_size)
199{
200 if (session->security_parameters.entity == GNUTLS_CLIENT)
201 return oprfi_send_client (session, data, data_size);
202 else
203 return oprfi_send_server (session, data, data_size);
204}
205
206/**
207 * gnutls_oprfi_enable_client:
208 * @session: is a #gnutls_session_t structure.
209 * @len: length of Opaque PRF data to use in client.
210 * @data: Opaque PRF data to use in client.
211 *
212 * Request that the client should attempt to negotiate the Opaque PRF
213 * Input TLS extension, using the given data as the client's Opaque
214 * PRF input.
215 *
216 * The data is copied into the session context after this call, so you
217 * may de-allocate it immediately after calling this function.
218 **/
219void
220gnutls_oprfi_enable_client (gnutls_session_t session,
221 size_t len, unsigned char *data)
222{
223 session->security_parameters.extensions.oprfi_client_len = len;
224 session->security_parameters.extensions.oprfi_client = data;
225}
226
227/**
228 * gnutls_oprfi_enable_server:
229 * @session: is a #gnutls_session_t structure.
230 * @cb: function pointer to Opaque PRF extension server callback.
231 * @userdata: hook passed to callback function for passing application state.
232 *
233 * Request that the server should attempt to accept the Opaque PRF
234 * Input TLS extension. If the client requests the extension, the
235 * provided callback @cb will be invoked. The callback must have the
236 * following prototype:
237 *
238 * int callback (gnutls_session_t session, void *userdata,
239 * size_t oprfi_len, const unsigned char *in_oprfi,
240 * unsigned char *out_oprfi);
241 *
242 * The callback can inspect the client-provided data in the input
243 * parameters, and specify its own opaque prf input data in the output
244 * variable. The function must return 0 on success, otherwise the
245 * handshake will be aborted.
246 **/
247void
248gnutls_oprfi_enable_server (gnutls_session_t session,
249 gnutls_oprfi_callback_func cb, void *userdata)
250{
251 session->security_parameters.extensions.oprfi_cb = cb;
252 session->security_parameters.extensions.oprfi_userdata = userdata;
253}
diff --git a/src/daemon/https/tls/ext_oprfi.h b/src/daemon/https/tls/ext_oprfi.h
new file mode 100644
index 00000000..7f75be9c
--- /dev/null
+++ b/src/daemon/https/tls/ext_oprfi.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26
27int _gnutls_oprfi_recv_params (gnutls_session_t state,
28 const opaque * data,
29 size_t data_size);
30
31int _gnutls_oprfi_send_params (gnutls_session_t state,
32 opaque * data,
33 size_t data_size);
diff --git a/src/daemon/https/tls/ext_server_name.c b/src/daemon/https/tls/ext_server_name.c
new file mode 100644
index 00000000..bc6b4759
--- /dev/null
+++ b/src/daemon/https/tls/ext_server_name.c
@@ -0,0 +1,330 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include "gnutls_int.h"
26#include "gnutls_auth_int.h"
27#include "gnutls_errors.h"
28#include "gnutls_num.h"
29#include <ext_server_name.h>
30
31/*
32 * In case of a server: if a NAME_DNS extension type is received then it stores
33 * into the session the value of NAME_DNS. The server may use gnutls_ext_get_server_name(),
34 * in order to access it.
35 *
36 * In case of a client: If a proper NAME_DNS extension type is found in the session then
37 * it sends the extension to the peer.
38 *
39 */
40
41int
42_gnutls_server_name_recv_params (gnutls_session_t session,
43 const opaque * data, size_t _data_size)
44{
45 int i;
46 const unsigned char *p;
47 uint16_t len, type;
48 ssize_t data_size = _data_size;
49 int server_names = 0;
50
51 if (session->security_parameters.entity == GNUTLS_SERVER)
52 {
53 DECR_LENGTH_RET (data_size, 2, 0);
54 len = _gnutls_read_uint16 (data);
55
56 if (len != data_size)
57 {
58 /* This is unexpected packet length, but
59 * just ignore it, for now.
60 */
61 gnutls_assert ();
62 return 0;
63 }
64
65 p = data + 2;
66
67 /* Count all server_names in the packet. */
68 while (data_size > 0)
69 {
70 DECR_LENGTH_RET (data_size, 1, 0);
71 p++;
72
73 DECR_LEN (data_size, 2);
74 len = _gnutls_read_uint16 (p);
75 p += 2;
76
77 DECR_LENGTH_RET (data_size, len, 0);
78 server_names++;
79
80 p += len;
81 }
82
83 session->security_parameters.extensions.server_names_size =
84 server_names;
85 if (server_names == 0)
86 return 0; /* no names found */
87
88 /* we cannot accept more server names.
89 */
90 if (server_names > MAX_SERVER_NAME_EXTENSIONS)
91 server_names = MAX_SERVER_NAME_EXTENSIONS;
92
93 p = data + 2;
94 for (i = 0; i < server_names; i++)
95 {
96 type = *p;
97 p++;
98
99 len = _gnutls_read_uint16 (p);
100 p += 2;
101
102 switch (type)
103 {
104 case 0: /* NAME_DNS */
105 if (len <= MAX_SERVER_NAME_SIZE)
106 {
107 memcpy (session->security_parameters.extensions.
108 server_names[i].name, p, len);
109 session->security_parameters.extensions.
110 server_names[i].name_length = len;
111 session->security_parameters.extensions.
112 server_names[i].type = GNUTLS_NAME_DNS;
113 break;
114 }
115 }
116
117 /* move to next record */
118 p += len;
119 }
120 }
121 return 0;
122}
123
124/* returns data_size or a negative number on failure
125 */
126int
127_gnutls_server_name_send_params (gnutls_session_t session,
128 opaque * data, size_t _data_size)
129{
130 uint16_t len;
131 opaque *p;
132 unsigned i;
133 ssize_t data_size = _data_size;
134 int total_size = 0;
135
136 /* this function sends the client extension data (dnsname)
137 */
138 if (session->security_parameters.entity == GNUTLS_CLIENT)
139 {
140
141 if (session->security_parameters.extensions.server_names_size == 0)
142 return 0;
143
144 /* uint16_t
145 */
146 total_size = 2;
147 for (i = 0;
148 i < session->security_parameters.extensions.server_names_size; i++)
149 {
150 /* count the total size
151 */
152 len =
153 session->security_parameters.extensions.server_names[i].
154 name_length;
155
156 /* uint8_t + uint16_t + size
157 */
158 total_size += 1 + 2 + len;
159 }
160
161 p = data;
162
163 /* UINT16: write total size of all names
164 */
165 DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
166 _gnutls_write_uint16 (total_size - 2, p);
167 p += 2;
168
169 for (i = 0;
170 i < session->security_parameters.extensions.server_names_size; i++)
171 {
172
173 switch (session->security_parameters.extensions.
174 server_names[i].type)
175 {
176 case GNUTLS_NAME_DNS:
177
178 len =
179 session->security_parameters.extensions.
180 server_names[i].name_length;
181 if (len == 0)
182 break;
183
184 /* UINT8: type of this extension
185 * UINT16: size of the first name
186 * LEN: the actual server name.
187 */
188 DECR_LENGTH_RET (data_size, len + 3,
189 GNUTLS_E_SHORT_MEMORY_BUFFER);
190
191 *p = 0; /* NAME_DNS type */
192 p++;
193
194 _gnutls_write_uint16 (len, p);
195 p += 2;
196
197 memcpy (p,
198 session->security_parameters.extensions.
199 server_names[0].name, len);
200 p += len;
201 break;
202 default:
203 gnutls_assert ();
204 return GNUTLS_E_INTERNAL_ERROR;
205 }
206 }
207 }
208
209 return total_size;
210}
211
212/**
213 * gnutls_server_name_get - Used to get the server name indicator send by a client
214 * @session: is a #gnutls_session_t structure.
215 * @data: will hold the data
216 * @data_length: will hold the data length. Must hold the maximum size of data.
217 * @type: will hold the server name indicator type
218 * @indx: is the index of the server_name
219 *
220 * This function will allow you to get the name indication (if any),
221 * a client has sent. The name indication may be any of the enumeration
222 * gnutls_server_name_type_t.
223 *
224 * If @type is GNUTLS_NAME_DNS, then this function is to be used by servers
225 * that support virtual hosting, and the data will be a null terminated UTF-8 string.
226 *
227 * If @data has not enough size to hold the server name GNUTLS_E_SHORT_MEMORY_BUFFER
228 * is returned, and @data_length will hold the required size.
229 *
230 * @index is used to retrieve more than one server names (if sent by the client).
231 * The first server name has an index of 0, the second 1 and so on. If no name with the given
232 * index exists GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
233 *
234 **/
235int
236gnutls_server_name_get (gnutls_session_t session, void *data,
237 size_t * data_length,
238 unsigned int *type, unsigned int indx)
239{
240 char *_data = data;
241
242 if (session->security_parameters.entity == GNUTLS_CLIENT)
243 {
244 gnutls_assert ();
245 return GNUTLS_E_INVALID_REQUEST;
246 }
247
248 if (indx + 1 > session->security_parameters.extensions.server_names_size)
249 {
250 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
251 }
252
253 *type = session->security_parameters.extensions.server_names[indx].type;
254
255 if (*data_length > /* greater since we need one extra byte for the null */
256 session->security_parameters.extensions.server_names[indx].name_length)
257 {
258 *data_length =
259 session->security_parameters.extensions.server_names[indx].
260 name_length;
261 memcpy (data,
262 session->security_parameters.extensions.server_names[indx].
263 name, *data_length);
264
265 if (*type == GNUTLS_NAME_DNS) /* null terminate */
266 _data[(*data_length)] = 0;
267
268 }
269 else
270 {
271 *data_length =
272 session->security_parameters.extensions.server_names[indx].
273 name_length;
274 return GNUTLS_E_SHORT_MEMORY_BUFFER;
275 }
276
277 return 0;
278}
279
280/**
281 * gnutls_server_name_set - Used to set a name indicator to be sent as an extension
282 * @session: is a #gnutls_session_t structure.
283 * @type: specifies the indicator type
284 * @name: is a string that contains the server name.
285 * @name_length: holds the length of name
286 *
287 * This function is to be used by clients that want to inform
288 * (via a TLS extension mechanism) the server of the name they
289 * connected to. This should be used by clients that connect
290 * to servers that do virtual hosting.
291 *
292 * The value of @name depends on the @ind type. In case of GNUTLS_NAME_DNS,
293 * an ASCII or UTF-8 null terminated string, without the trailing dot, is expected.
294 * IPv4 or IPv6 addresses are not permitted.
295 *
296 **/
297int
298gnutls_server_name_set (gnutls_session_t session,
299 gnutls_server_name_type_t type,
300 const void *name, size_t name_length)
301{
302 int server_names;
303
304 if (session->security_parameters.entity == GNUTLS_SERVER)
305 {
306 gnutls_assert ();
307 return GNUTLS_E_INVALID_REQUEST;
308 }
309
310 if (name_length > MAX_SERVER_NAME_SIZE)
311 return GNUTLS_E_SHORT_MEMORY_BUFFER;
312
313 server_names =
314 session->security_parameters.extensions.server_names_size + 1;
315
316 if (server_names > MAX_SERVER_NAME_EXTENSIONS)
317 server_names = MAX_SERVER_NAME_EXTENSIONS;
318
319 session->security_parameters.extensions.server_names[server_names -
320 1].type = type;
321 memcpy (session->security_parameters.extensions.
322 server_names[server_names - 1].name, name, name_length);
323 session->security_parameters.extensions.server_names[server_names -
324 1].name_length =
325 name_length;
326
327 session->security_parameters.extensions.server_names_size++;
328
329 return 0;
330}
diff --git a/src/daemon/https/tls/ext_server_name.h b/src/daemon/https/tls/ext_server_name.h
new file mode 100644
index 00000000..91e727a1
--- /dev/null
+++ b/src/daemon/https/tls/ext_server_name.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_server_name_recv_params (gnutls_session_t session,
26 const opaque * data, size_t data_size);
27int _gnutls_server_name_send_params (gnutls_session_t session,
28 opaque * data, size_t);
diff --git a/src/daemon/https/tls/gnutls.asn b/src/daemon/https/tls/gnutls.asn
new file mode 100644
index 00000000..0cb98414
--- /dev/null
+++ b/src/daemon/https/tls/gnutls.asn
@@ -0,0 +1,93 @@
1GNUTLS { }
2
3DEFINITIONS EXPLICIT TAGS ::=
4
5BEGIN
6
7-- This file contains parts of PKCS-1 structures and some stuff
8-- required for DSA keys.
9
10RSAPublicKey ::= SEQUENCE {
11 modulus INTEGER, -- n
12 publicExponent INTEGER -- e
13}
14
15--
16-- Representation of RSA private key with information for the
17-- CRT algorithm.
18--
19RSAPrivateKey ::= SEQUENCE {
20 version Version,
21 modulus INTEGER, -- (Usually large) n
22 publicExponent INTEGER, -- (Usually small) e
23 privateExponent INTEGER, -- (Usually large) d
24 prime1 INTEGER, -- (Usually large) p
25 prime2 INTEGER, -- (Usually large) q
26 exponent1 INTEGER, -- (Usually large) d mod (p-1)
27 exponent2 INTEGER, -- (Usually large) d mod (q-1)
28 coefficient INTEGER, -- (Usually large) (inverse of q) mod p
29 otherPrimeInfos OtherPrimeInfos OPTIONAL
30}
31
32Version ::= INTEGER { two-prime(0), multi(1) }
33-- (CONSTRAINED BY { version must be multi if otherPrimeInfos present }) --
34
35OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
36
37OtherPrimeInfo ::= SEQUENCE {
38 prime INTEGER, -- ri
39 exponent INTEGER, -- di
40 coefficient INTEGER -- ti
41}
42
43-- for signature calculation
44-- added by nmav
45
46AlgorithmIdentifier ::= SEQUENCE {
47 algorithm OBJECT IDENTIFIER,
48 parameters ANY DEFINED BY algorithm OPTIONAL
49}
50 -- contains a value of the type
51 -- registered for use with the
52 -- algorithm object identifier value
53
54DigestInfo ::= SEQUENCE {
55 digestAlgorithm DigestAlgorithmIdentifier,
56 digest Digest
57}
58
59DigestAlgorithmIdentifier ::= AlgorithmIdentifier
60
61Digest ::= OCTET STRING
62
63DSAPublicKey ::= INTEGER
64
65DSAParameters ::= SEQUENCE {
66 p INTEGER,
67 q INTEGER,
68 g INTEGER
69}
70
71DSASignatureValue ::= SEQUENCE {
72 r INTEGER,
73 s INTEGER
74}
75
76DSAPrivateKey ::= SEQUENCE {
77 version INTEGER, -- should be zero
78 p INTEGER,
79 q INTEGER,
80 g INTEGER,
81 Y INTEGER, -- public
82 priv INTEGER
83}
84
85-- from PKCS#3
86DHParameter ::= SEQUENCE {
87 prime INTEGER, -- p
88 base INTEGER, -- g
89 privateValueLength INTEGER OPTIONAL
90}
91
92
93END
diff --git a/src/daemon/https/tls/gnutls.pc b/src/daemon/https/tls/gnutls.pc
new file mode 100644
index 00000000..544428cb
--- /dev/null
+++ b/src/daemon/https/tls/gnutls.pc
@@ -0,0 +1,23 @@
1# Process this file with autoconf to produce a pkg-config metadata file.
2# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3# Author: Simon Josefsson
4#
5# This file is free software; as a special exception the author gives
6# unlimited permission to copy and/or distribute it, with or without
7# modifications, as long as this notice is preserved.
8#
9# This file is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
11# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13prefix=/home/lama/workbench/programming/c/gnunet/gnutls-2.2.3/build
14exec_prefix=${prefix}
15libdir=${exec_prefix}/lib
16includedir=${prefix}/include
17
18Name: GnuTLS
19Description: Transport Security Layer implementation for the GNU system
20Version: 2.2.3
21Libs: -L${libdir} -lgnutls
22Libs.private: -L${exec_prefix}/lib -lgnutls -L/usr/lib -ltasn1 -lgcrypt
23Cflags: -I${includedir}
diff --git a/src/daemon/https/tls/gnutls_alert.c b/src/daemon/https/tls/gnutls_alert.c
new file mode 100644
index 00000000..75f9dcd2
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_alert.c
@@ -0,0 +1,304 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_record.h>
28#include <debug.h>
29
30typedef struct
31{
32 gnutls_alert_description_t alert;
33 const char *desc;
34} gnutls_alert_entry;
35
36static const gnutls_alert_entry sup_alerts[] = {
37 {GNUTLS_A_CLOSE_NOTIFY, "Close notify"},
38 {GNUTLS_A_UNEXPECTED_MESSAGE, "Unexpected message"},
39 {GNUTLS_A_BAD_RECORD_MAC, "Bad record MAC"},
40 {GNUTLS_A_DECRYPTION_FAILED, "Decryption failed"},
41 {GNUTLS_A_RECORD_OVERFLOW, "Record overflow"},
42 {GNUTLS_A_DECOMPRESSION_FAILURE, "Decompression failed"},
43 {GNUTLS_A_HANDSHAKE_FAILURE, "Handshake failed"},
44 {GNUTLS_A_BAD_CERTIFICATE, "Certificate is bad"},
45 {GNUTLS_A_UNSUPPORTED_CERTIFICATE, "Certificate is not supported"},
46 {GNUTLS_A_CERTIFICATE_REVOKED, "Certificate was revoked"},
47 {GNUTLS_A_CERTIFICATE_EXPIRED, "Certificate is expired"},
48 {GNUTLS_A_CERTIFICATE_UNKNOWN, "Unknown certificate"},
49 {GNUTLS_A_ILLEGAL_PARAMETER, "Illegal parameter"},
50 {GNUTLS_A_UNKNOWN_CA, "CA is unknown"},
51 {GNUTLS_A_ACCESS_DENIED, "Access was denied"},
52 {GNUTLS_A_DECODE_ERROR, "Decode error"},
53 {GNUTLS_A_DECRYPT_ERROR, "Decrypt error"},
54 {GNUTLS_A_EXPORT_RESTRICTION, "Export restriction"},
55 {GNUTLS_A_PROTOCOL_VERSION, "Error in protocol version"},
56 {GNUTLS_A_INSUFFICIENT_SECURITY, "Insufficient security"},
57 {GNUTLS_A_USER_CANCELED, "User canceled"},
58 {GNUTLS_A_INTERNAL_ERROR, "Internal error"},
59 {GNUTLS_A_NO_RENEGOTIATION, "No renegotiation is allowed"},
60 {GNUTLS_A_CERTIFICATE_UNOBTAINABLE,
61 "Could not retrieve the specified certificate"},
62 {GNUTLS_A_UNSUPPORTED_EXTENSION, "An unsupported extension was sent"},
63 {GNUTLS_A_UNRECOGNIZED_NAME,
64 "The server name sent was not recognized"},
65 {GNUTLS_A_UNKNOWN_PSK_IDENTITY,
66 "The SRP/PSK username is missing or not known"},
67 {GNUTLS_A_INNER_APPLICATION_FAILURE,
68 "Inner application negotiation failed"},
69 {GNUTLS_A_INNER_APPLICATION_VERIFICATION,
70 "Inner application verification failed"},
71 {0, NULL}
72};
73
74#define GNUTLS_ALERT_LOOP(b) \
75 const gnutls_alert_entry *p; \
76 for(p = sup_alerts; p->desc != NULL; p++) { b ; }
77
78#define GNUTLS_ALERT_ID_LOOP(a) \
79 GNUTLS_ALERT_LOOP( if(p->alert == alert) { a; break; })
80
81
82/**
83 * gnutls_alert_get_name - Returns a string describing the alert number given
84 * @alert: is an alert number #gnutls_session_t structure.
85 *
86 * This function will return a string that describes the given alert
87 * number or NULL. See gnutls_alert_get().
88 *
89 **/
90const char *
91gnutls_alert_get_name (gnutls_alert_description_t alert)
92{
93 const char *ret = NULL;
94
95 GNUTLS_ALERT_ID_LOOP (ret = p->desc);
96
97 return ret;
98}
99
100/**
101 * gnutls_alert_send - This function sends an alert message to the peer
102 * @session: is a #gnutls_session_t structure.
103 * @level: is the level of the alert
104 * @desc: is the alert description
105 *
106 * This function will send an alert to the peer in order to inform
107 * him of something important (eg. his Certificate could not be verified).
108 * If the alert level is Fatal then the peer is expected to close the
109 * connection, otherwise he may ignore the alert and continue.
110 *
111 * The error code of the underlying record send function will be returned,
112 * so you may also receive GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN as well.
113 *
114 * Returns 0 on success.
115 *
116 **/
117int
118gnutls_alert_send (gnutls_session_t session, gnutls_alert_level_t level,
119 gnutls_alert_description_t desc)
120{
121 uint8_t data[2];
122 int ret;
123 const char *name;
124
125 data[0] = (uint8_t) level;
126 data[1] = (uint8_t) desc;
127
128 name = gnutls_alert_get_name ((int) data[1]);
129 if (name == NULL)
130 name = "(unknown)";
131 _gnutls_record_log ("REC: Sending Alert[%d|%d] - %s\n", data[0],
132 data[1], name);
133
134 if ((ret = _gnutls_send_int (session, GNUTLS_ALERT, -1, data, 2)) >= 0)
135 return 0;
136 else
137 return ret;
138}
139
140/**
141 * gnutls_error_to_alert - This function returns an alert code based on the given error code
142 * @err: is a negative integer
143 * @level: the alert level will be stored there
144 *
145 * Returns an alert depending on the error code returned by a gnutls
146 * function. All alerts sent by this function should be considered fatal.
147 * The only exception is when err == GNUTLS_E_REHANDSHAKE, where a warning
148 * alert should be sent to the peer indicating that no renegotiation will
149 * be performed.
150 *
151 * If there is no mapping to a valid alert the alert to indicate internal error
152 * is returned.
153 *
154 **/
155int
156gnutls_error_to_alert (int err, int *level)
157{
158 int ret, _level = -1;
159
160 switch (err)
161 { /* send appropriate alert */
162 case GNUTLS_E_DECRYPTION_FAILED:
163 /* GNUTLS_A_DECRYPTION_FAILED is not sent, because
164 * it is not defined in SSL3. Note that we must
165 * not distinguish Decryption failures from mac
166 * check failures, due to the possibility of some
167 * attacks.
168 */
169 ret = GNUTLS_A_BAD_RECORD_MAC;
170 _level = GNUTLS_AL_FATAL;
171 break;
172 case GNUTLS_E_DECOMPRESSION_FAILED:
173 ret = GNUTLS_A_DECOMPRESSION_FAILURE;
174 _level = GNUTLS_AL_FATAL;
175 break;
176 case GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER:
177 case GNUTLS_E_ILLEGAL_SRP_USERNAME:
178 ret = GNUTLS_A_ILLEGAL_PARAMETER;
179 _level = GNUTLS_AL_FATAL;
180 break;
181 case GNUTLS_E_ASN1_ELEMENT_NOT_FOUND:
182 case GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND:
183 case GNUTLS_E_ASN1_DER_ERROR:
184 case GNUTLS_E_ASN1_VALUE_NOT_FOUND:
185 case GNUTLS_E_ASN1_GENERIC_ERROR:
186 case GNUTLS_E_ASN1_VALUE_NOT_VALID:
187 case GNUTLS_E_ASN1_TAG_ERROR:
188 case GNUTLS_E_ASN1_TAG_IMPLICIT:
189 case GNUTLS_E_ASN1_TYPE_ANY_ERROR:
190 case GNUTLS_E_ASN1_SYNTAX_ERROR:
191 case GNUTLS_E_ASN1_DER_OVERFLOW:
192 ret = GNUTLS_A_BAD_CERTIFICATE;
193 _level = GNUTLS_AL_FATAL;
194 break;
195 case GNUTLS_E_UNKNOWN_CIPHER_SUITE:
196 case GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM:
197 case GNUTLS_E_INSUFFICIENT_CREDENTIALS:
198 case GNUTLS_E_NO_CIPHER_SUITES:
199 case GNUTLS_E_NO_COMPRESSION_ALGORITHMS:
200 ret = GNUTLS_A_HANDSHAKE_FAILURE;
201 _level = GNUTLS_AL_FATAL;
202 break;
203 case GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION:
204 ret = GNUTLS_A_UNSUPPORTED_EXTENSION;
205 _level = GNUTLS_AL_FATAL;
206 break;
207 case GNUTLS_E_UNEXPECTED_PACKET:
208 case GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET:
209 ret = GNUTLS_A_UNEXPECTED_MESSAGE;
210 _level = GNUTLS_AL_FATAL;
211 break;
212 case GNUTLS_E_REHANDSHAKE:
213 ret = GNUTLS_A_NO_RENEGOTIATION;
214 _level = GNUTLS_AL_WARNING;
215 break;
216 case GNUTLS_E_UNSUPPORTED_VERSION_PACKET:
217 ret = GNUTLS_A_PROTOCOL_VERSION;
218 _level = GNUTLS_AL_FATAL;
219 break;
220 case GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE:
221 ret = GNUTLS_A_UNSUPPORTED_CERTIFICATE;
222 _level = GNUTLS_AL_FATAL;
223 break;
224 case GNUTLS_E_UNEXPECTED_PACKET_LENGTH:
225 ret = GNUTLS_A_RECORD_OVERFLOW;
226 _level = GNUTLS_AL_FATAL;
227 break;
228 case GNUTLS_E_INTERNAL_ERROR:
229 case GNUTLS_E_NO_TEMPORARY_DH_PARAMS:
230 case GNUTLS_E_NO_TEMPORARY_RSA_PARAMS:
231 ret = GNUTLS_A_INTERNAL_ERROR;
232 _level = GNUTLS_AL_FATAL;
233 break;
234 case GNUTLS_E_OPENPGP_GETKEY_FAILED:
235 ret = GNUTLS_A_CERTIFICATE_UNOBTAINABLE;
236 _level = GNUTLS_AL_FATAL;
237 break;
238 case GNUTLS_E_DH_PRIME_UNACCEPTABLE:
239 case GNUTLS_E_NO_CERTIFICATE_FOUND:
240 ret = GNUTLS_A_INSUFFICIENT_SECURITY;
241 _level = GNUTLS_AL_FATAL;
242 break;
243 default:
244 ret = GNUTLS_A_INTERNAL_ERROR;
245 _level = GNUTLS_AL_FATAL;
246 break;
247 }
248
249 if (level != NULL)
250 *level = _level;
251
252 return ret;
253}
254
255
256/**
257 * gnutls_alert_send_appropriate - This function sends an alert to the peer depending on the error code
258 * @session: is a #gnutls_session_t structure.
259 * @err: is an integer
260 *
261 * Sends an alert to the peer depending on the error code returned by a gnutls
262 * function. This function will call gnutls_error_to_alert() to determine
263 * the appropriate alert to send.
264 *
265 * This function may also return GNUTLS_E_AGAIN, or GNUTLS_E_INTERRUPTED.
266 *
267 * If the return value is GNUTLS_E_INVALID_REQUEST, then no alert has
268 * been sent to the peer.
269 *
270 * Returns zero on success.
271 */
272int
273gnutls_alert_send_appropriate (gnutls_session_t session, int err)
274{
275 int alert;
276 int level;
277
278 alert = gnutls_error_to_alert (err, &level);
279 if (alert < 0)
280 {
281 return alert;
282 }
283
284 return gnutls_alert_send (session, level, alert);
285}
286
287/**
288 * gnutls_alert_get - Returns the last alert number received.
289 * @session: is a #gnutls_session_t structure.
290 *
291 * This function will return the last alert number received. This
292 * function should be called if GNUTLS_E_WARNING_ALERT_RECEIVED or
293 * GNUTLS_E_FATAL_ALERT_RECEIVED has been returned by a gnutls
294 * function. The peer may send alerts if he thinks some things were
295 * not right. Check gnutls.h for the available alert descriptions.
296 *
297 * If no alert has been received the returned value is undefined.
298 *
299 **/
300gnutls_alert_description_t
301gnutls_alert_get (gnutls_session_t session)
302{
303 return session->internals.last_alert;
304}
diff --git a/src/daemon/https/tls/gnutls_algorithms.c b/src/daemon/https/tls/gnutls_algorithms.c
new file mode 100644
index 00000000..82bf9bf6
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_algorithms.c
@@ -0,0 +1,2225 @@
1/*
2 * Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include "gnutls_int.h"
26#include "gnutls_algorithms.h"
27#include "gnutls_errors.h"
28#include "gnutls_cert.h"
29/* x509 */
30#include "common.h"
31
32/* Cred type mappings to KX algorithms
33 * FIXME: The mappings are not 1-1. Some KX such as SRP_RSA require
34 * more than one credentials type.
35 */
36typedef struct
37{
38 gnutls_kx_algorithm_t algorithm;
39 gnutls_credentials_type_t client_type;
40 gnutls_credentials_type_t server_type; /* The type of credentials a server
41 * needs to set */
42} gnutls_cred_map;
43
44static const gnutls_cred_map cred_mappings[] = {
45 {GNUTLS_KX_ANON_DH,
46 GNUTLS_CRD_ANON,
47 GNUTLS_CRD_ANON},
48 {GNUTLS_KX_RSA,
49 GNUTLS_CRD_CERTIFICATE,
50 GNUTLS_CRD_CERTIFICATE},
51 {GNUTLS_KX_RSA_EXPORT,
52 GNUTLS_CRD_CERTIFICATE,
53 GNUTLS_CRD_CERTIFICATE},
54 {GNUTLS_KX_DHE_DSS,
55 GNUTLS_CRD_CERTIFICATE,
56 GNUTLS_CRD_CERTIFICATE},
57 {GNUTLS_KX_DHE_RSA,
58 GNUTLS_CRD_CERTIFICATE,
59 GNUTLS_CRD_CERTIFICATE},
60 {GNUTLS_KX_PSK,
61 GNUTLS_CRD_PSK,
62 GNUTLS_CRD_PSK},
63 {GNUTLS_KX_DHE_PSK,
64 GNUTLS_CRD_PSK,
65 GNUTLS_CRD_PSK},
66 {GNUTLS_KX_SRP,
67 GNUTLS_CRD_SRP,
68 GNUTLS_CRD_SRP},
69 {GNUTLS_KX_SRP_RSA,
70 GNUTLS_CRD_SRP,
71 GNUTLS_CRD_CERTIFICATE},
72 {GNUTLS_KX_SRP_DSS,
73 GNUTLS_CRD_SRP,
74 GNUTLS_CRD_CERTIFICATE},
75 {0,
76 0,
77 0}
78};
79
80#define GNUTLS_KX_MAP_LOOP(b) \
81 const gnutls_cred_map *p; \
82 for(p = cred_mappings; p->algorithm != 0; p++) { b ; }
83
84#define GNUTLS_KX_MAP_ALG_LOOP_SERVER(a) \
85 GNUTLS_KX_MAP_LOOP( if(p->server_type == type) { a; break; })
86
87#define GNUTLS_KX_MAP_ALG_LOOP_CLIENT(a) \
88 GNUTLS_KX_MAP_LOOP( if(p->client_type == type) { a; break; })
89
90/* KX mappings to PK algorithms */
91typedef struct
92{
93 gnutls_kx_algorithm_t kx_algorithm;
94 gnutls_pk_algorithm_t pk_algorithm;
95 enum encipher_type encipher_type; /* CIPHER_ENCRYPT if this algorithm is to be used
96 * for encryption, CIPHER_SIGN if signature only,
97 * CIPHER_IGN if this does not apply at all.
98 *
99 * This is useful to certificate cipher suites, which check
100 * against the certificate key usage bits.
101 */
102} gnutls_pk_map;
103
104/* This table maps the Key exchange algorithms to
105 * the certificate algorithms. Eg. if we have
106 * RSA algorithm in the certificate then we can
107 * use GNUTLS_KX_RSA or GNUTLS_KX_DHE_RSA.
108 */
109static const gnutls_pk_map pk_mappings[] = {
110 {GNUTLS_KX_RSA,
111 GNUTLS_PK_RSA,
112 CIPHER_ENCRYPT},
113 {GNUTLS_KX_RSA_EXPORT,
114 GNUTLS_PK_RSA,
115 CIPHER_SIGN},
116 {GNUTLS_KX_DHE_RSA,
117 GNUTLS_PK_RSA,
118 CIPHER_SIGN},
119 {GNUTLS_KX_SRP_RSA,
120 GNUTLS_PK_RSA,
121 CIPHER_SIGN},
122 {0,
123 0,
124 0}
125};
126
127#define GNUTLS_PK_MAP_LOOP(b) \
128 const gnutls_pk_map *p; \
129 for(p = pk_mappings; p->kx_algorithm != 0; p++) { b }
130
131#define GNUTLS_PK_MAP_ALG_LOOP(a) \
132 GNUTLS_PK_MAP_LOOP( if(p->kx_algorithm == kx_algorithm) { a; break; })
133
134/* TLS Versions */
135
136typedef struct
137{
138 const char *name;
139 gnutls_protocol_t id; /* gnutls internal version number */
140 int major; /* defined by the protocol */
141 int minor; /* defined by the protocol */
142 int supported; /* 0 not supported, > 0 is supported */
143} gnutls_version_entry;
144
145static const gnutls_version_entry sup_versions[] = {
146 {"SSL3.0",
147 GNUTLS_SSL3,
148 3,
149 0,
150 1},
151 {"TLS1.0",
152 GNUTLS_TLS1,
153 3,
154 1,
155 1},
156 {"TLS1.1",
157 GNUTLS_TLS1_1,
158 3,
159 2,
160 1},
161 {"TLS1.2",
162 GNUTLS_TLS1_2,
163 3,
164 3,
165 1},
166 {0,
167 0,
168 0,
169 0,
170 0}
171};
172
173/* Keep the contents of this struct the same as the previous one. */
174static const gnutls_protocol_t supported_protocols[] = { GNUTLS_SSL3,
175 GNUTLS_TLS1,
176 GNUTLS_TLS1_1,
177 GNUTLS_TLS1_2,
178 0
179};
180
181#define GNUTLS_VERSION_LOOP(b) \
182 const gnutls_version_entry *p; \
183 for(p = sup_versions; p->name != NULL; p++) { b ; }
184
185#define GNUTLS_VERSION_ALG_LOOP(a) \
186 GNUTLS_VERSION_LOOP( if(p->id == version) { a; break; })
187
188struct gnutls_cipher_entry
189{
190 const char *name;
191 gnutls_cipher_algorithm_t id;
192 uint16_t blocksize;
193 uint16_t keysize;
194 cipher_type_t block;
195 uint16_t iv;
196 int export_flag; /* 0 non export */
197};
198typedef struct gnutls_cipher_entry gnutls_cipher_entry;
199
200/* Note that all algorithms are in CBC or STREAM modes.
201 * Do not add any algorithms in other modes (avoid modified algorithms).
202 * View first: "The order of encryption and authentication for
203 * protecting communications" by Hugo Krawczyk - CRYPTO 2001
204 */
205static const gnutls_cipher_entry algorithms[] = {
206 {"AES-256-CBC",
207 GNUTLS_CIPHER_AES_256_CBC,
208 16,
209 32,
210 CIPHER_BLOCK,
211 16,
212 0},
213 {"AES-128-CBC",
214 GNUTLS_CIPHER_AES_128_CBC,
215 16,
216 16,
217 CIPHER_BLOCK,
218 16,
219 0},
220 {"3DES-CBC",
221 GNUTLS_CIPHER_3DES_CBC,
222 8,
223 24,
224 CIPHER_BLOCK,
225 8,
226 0},
227 {"DES-CBC",
228 GNUTLS_CIPHER_DES_CBC,
229 8,
230 8,
231 CIPHER_BLOCK,
232 8,
233 0},
234 {"ARCFOUR-128",
235 GNUTLS_CIPHER_ARCFOUR_128,
236 1,
237 16,
238 CIPHER_STREAM,
239 0,
240 0},
241 {"ARCFOUR-40",
242 GNUTLS_CIPHER_ARCFOUR_40,
243 1,
244 5,
245 CIPHER_STREAM,
246 0,
247 1},
248 {"RC2-40",
249 GNUTLS_CIPHER_RC2_40_CBC,
250 8,
251 5,
252 CIPHER_BLOCK,
253 8,
254 1},
255#ifdef ENABLE_CAMELLIA
256 {"CAMELLIA-256-CBC", GNUTLS_CIPHER_CAMELLIA_256_CBC, 16, 32, CIPHER_BLOCK,
257 16, 0},
258 {"CAMELLIA-128-CBC", GNUTLS_CIPHER_CAMELLIA_128_CBC, 16, 16, CIPHER_BLOCK,
259 16, 0},
260#endif
261 {"NULL",
262 GNUTLS_CIPHER_NULL,
263 1,
264 0,
265 CIPHER_STREAM,
266 0,
267 0},
268 {0,
269 0,
270 0,
271 0,
272 0,
273 0,
274 0}
275};
276
277/* Keep the contents of this struct the same as the previous one. */
278static const gnutls_cipher_algorithm_t supported_ciphers[] =
279 { GNUTLS_CIPHER_AES_256_CBC,
280 GNUTLS_CIPHER_AES_128_CBC,
281 GNUTLS_CIPHER_3DES_CBC,
282 GNUTLS_CIPHER_DES_CBC,
283 GNUTLS_CIPHER_ARCFOUR_128,
284 GNUTLS_CIPHER_ARCFOUR_40,
285 GNUTLS_CIPHER_RC2_40_CBC,
286#ifdef ENABLE_CAMELLIA
287 GNUTLS_CIPHER_CAMELLIA_256_CBC,
288 GNUTLS_CIPHER_CAMELLIA_128_CBC,
289#endif
290 GNUTLS_CIPHER_NULL,
291 0
292};
293
294#define GNUTLS_LOOP(b) \
295 const gnutls_cipher_entry *p; \
296 for(p = algorithms; p->name != NULL; p++) { b ; }
297
298#define GNUTLS_ALG_LOOP(a) \
299 GNUTLS_LOOP( if(p->id == algorithm) { a; break; } )
300
301struct gnutls_hash_entry
302{
303 const char *name;
304 const char *oid;
305 gnutls_mac_algorithm_t id;
306 size_t key_size; /* in case of mac */
307};
308typedef struct gnutls_hash_entry gnutls_hash_entry;
309
310static const gnutls_hash_entry hash_algorithms[] = {
311 {"SHA1",
312 HASH_OID_SHA1,
313 GNUTLS_MAC_SHA1,
314 20},
315 {"MD5",
316 HASH_OID_MD5,
317 GNUTLS_MAC_MD5,
318 16},
319 {"SHA256",
320 HASH_OID_SHA256,
321 GNUTLS_MAC_SHA256,
322 32},
323 {"NULL",
324 NULL,
325 GNUTLS_MAC_NULL,
326 0},
327 {0,
328 0,
329 0,
330 0}
331};
332
333/* Keep the contents of this struct the same as the previous one. */
334static const gnutls_mac_algorithm_t supported_macs[] = { GNUTLS_MAC_SHA1,
335 GNUTLS_MAC_MD5,
336 GNUTLS_MAC_SHA256,
337 GNUTLS_MAC_NULL,
338 0
339};
340
341#define GNUTLS_HASH_LOOP(b) \
342 const gnutls_hash_entry *p; \
343 for(p = hash_algorithms; p->name != NULL; p++) { b ; }
344
345#define GNUTLS_HASH_ALG_LOOP(a) \
346 GNUTLS_HASH_LOOP( if(p->id == algorithm) { a; break; } )
347
348/* Compression Section */
349#define GNUTLS_COMPRESSION_ENTRY(name, id, wb, ml, cl) \
350 { #name, name, id, wb, ml, cl}
351
352#define MAX_COMP_METHODS 5
353const int _gnutls_comp_algorithms_size = MAX_COMP_METHODS;
354
355/* the compression entry is defined in gnutls_algorithms.h */
356
357gnutls_compression_entry _gnutls_compression_algorithms[MAX_COMP_METHODS] =
358 { GNUTLS_COMPRESSION_ENTRY (GNUTLS_COMP_NULL, 0x00, 0, 0, 0),
359#ifdef HAVE_LIBZ
360 /* draft-ietf-tls-compression-02 */
361 GNUTLS_COMPRESSION_ENTRY (GNUTLS_COMP_DEFLATE, 0x01, 15, 8, 3),
362#endif
363 {0,
364 0,
365 0,
366 0,
367 0,
368 0}
369};
370
371static const gnutls_compression_method_t supported_compressions[] = {
372#ifdef HAVE_LIBZ
373 GNUTLS_COMP_DEFLATE,
374#endif
375 GNUTLS_COMP_NULL,
376 0
377};
378
379#define GNUTLS_COMPRESSION_LOOP(b) \
380 const gnutls_compression_entry *p; \
381 for(p = _gnutls_compression_algorithms; p->name != NULL; p++) { b ; }
382#define GNUTLS_COMPRESSION_ALG_LOOP(a) \
383 GNUTLS_COMPRESSION_LOOP( if(p->id == algorithm) { a; break; } )
384#define GNUTLS_COMPRESSION_ALG_LOOP_NUM(a) \
385 GNUTLS_COMPRESSION_LOOP( if(p->num == num) { a; break; } )
386
387/* Key Exchange Section */
388extern mod_auth_st rsa_auth_struct;
389extern mod_auth_st rsa_export_auth_struct;
390extern mod_auth_st dhe_rsa_auth_struct;
391extern mod_auth_st dhe_dss_auth_struct;
392extern mod_auth_st anon_auth_struct;
393extern mod_auth_st srp_auth_struct;
394extern mod_auth_st psk_auth_struct;
395extern mod_auth_st dhe_psk_auth_struct;
396extern mod_auth_st srp_rsa_auth_struct;
397extern mod_auth_st srp_dss_auth_struct;
398
399struct gnutls_kx_algo_entry
400{
401 const char *name;
402 gnutls_kx_algorithm_t algorithm;
403 mod_auth_st *auth_struct;
404 int needs_dh_params;
405 int needs_rsa_params;
406};
407typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry;
408
409static const gnutls_kx_algo_entry _gnutls_kx_algorithms[] = {
410#ifdef ENABLE_ANON
411 {"ANON-DH", GNUTLS_KX_ANON_DH, &anon_auth_struct, 1, 0},
412#endif
413 {"RSA",
414 GNUTLS_KX_RSA,
415 &rsa_auth_struct,
416 0,
417 0},
418 {"RSA-EXPORT",
419 GNUTLS_KX_RSA_EXPORT,
420 &rsa_export_auth_struct,
421 0,
422 1 /* needs RSA params */ },
423 {"DHE-RSA",
424 GNUTLS_KX_DHE_RSA,
425 &dhe_rsa_auth_struct,
426 1,
427 0},
428 {"DHE-DSS",
429 GNUTLS_KX_DHE_DSS,
430 &dhe_dss_auth_struct,
431 1,
432 0},
433
434#ifdef ENABLE_SRP
435 {"SRP-DSS", GNUTLS_KX_SRP_DSS, &srp_dss_auth_struct, 0, 0},
436 {"SRP-RSA", GNUTLS_KX_SRP_RSA, &srp_rsa_auth_struct, 0, 0},
437 {"SRP", GNUTLS_KX_SRP, &srp_auth_struct, 0, 0},
438#endif
439#ifdef ENABLE_PSK
440 {"PSK", GNUTLS_KX_PSK, &psk_auth_struct, 0, 0},
441 {"DHE-PSK", GNUTLS_KX_DHE_PSK, &dhe_psk_auth_struct,
442 1 /* needs DHE params */ , 0},
443#endif
444 {0,
445 0,
446 0,
447 0,
448 0}
449};
450
451/* Keep the contents of this struct the same as the previous one. */
452static const gnutls_kx_algorithm_t supported_kxs[] = {
453#ifdef ENABLE_ANON
454 GNUTLS_KX_ANON_DH,
455#endif
456 GNUTLS_KX_RSA,
457 GNUTLS_KX_RSA_EXPORT,
458 GNUTLS_KX_DHE_RSA,
459 GNUTLS_KX_DHE_DSS,
460#ifdef ENABLE_SRP
461 GNUTLS_KX_SRP_DSS,
462 GNUTLS_KX_SRP_RSA,
463 GNUTLS_KX_SRP,
464#endif
465#ifdef ENABLE_PSK
466 GNUTLS_KX_PSK,
467 GNUTLS_KX_DHE_PSK,
468#endif
469 0
470};
471
472#define GNUTLS_KX_LOOP(b) \
473 const gnutls_kx_algo_entry *p; \
474 for(p = _gnutls_kx_algorithms; p->name != NULL; p++) { b ; }
475
476#define GNUTLS_KX_ALG_LOOP(a) \
477 GNUTLS_KX_LOOP( if(p->algorithm == algorithm) { a; break; } )
478
479/* Cipher SUITES */
480#define GNUTLS_CIPHER_SUITE_ENTRY( name, block_algorithm, kx_algorithm, mac_algorithm, version ) \
481 { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, version }
482
483typedef struct
484{
485 const char *name;
486 cipher_suite_st id;
487 gnutls_cipher_algorithm_t block_algorithm;
488 gnutls_kx_algorithm_t kx_algorithm;
489 gnutls_mac_algorithm_t mac_algorithm;
490 gnutls_protocol_t version; /* this cipher suite is supported
491 * from 'version' and above;
492 */
493} gnutls_cipher_suite_entry;
494
495/* RSA with NULL cipher and MD5 MAC
496 * for test purposes.
497 */
498#define GNUTLS_RSA_NULL_MD5 { 0x00, 0x01 }
499
500/* ANONymous cipher suites.
501 */
502
503#define GNUTLS_ANON_DH_3DES_EDE_CBC_SHA1 { 0x00, 0x1B }
504#define GNUTLS_ANON_DH_ARCFOUR_MD5 { 0x00, 0x18 }
505
506/* rfc3268: */
507#define GNUTLS_ANON_DH_AES_128_CBC_SHA1 { 0x00, 0x34 }
508#define GNUTLS_ANON_DH_AES_256_CBC_SHA1 { 0x00, 0x3A }
509
510/* rfc4132 */
511#define GNUTLS_ANON_DH_CAMELLIA_128_CBC_SHA1 { 0x00,0x46 }
512#define GNUTLS_ANON_DH_CAMELLIA_256_CBC_SHA1 { 0x00,0x89 }
513
514/* PSK (not in TLS 1.0)
515 * draft-ietf-tls-psk:
516 */
517#define GNUTLS_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8A }
518#define GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8B }
519#define GNUTLS_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x8C }
520#define GNUTLS_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x8D }
521
522#define GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8E }
523#define GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8F }
524#define GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x90 }
525#define GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x91 }
526
527/* SRP (rfc5054)
528 */
529#define GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1 { 0xC0, 0x1A }
530#define GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA1 { 0xC0, 0x1B }
531#define GNUTLS_SRP_SHA_DSS_3DES_EDE_CBC_SHA1 { 0xC0, 0x1C }
532
533#define GNUTLS_SRP_SHA_AES_128_CBC_SHA1 { 0xC0, 0x1D }
534#define GNUTLS_SRP_SHA_RSA_AES_128_CBC_SHA1 { 0xC0, 0x1E }
535#define GNUTLS_SRP_SHA_DSS_AES_128_CBC_SHA1 { 0xC0, 0x1F }
536
537#define GNUTLS_SRP_SHA_AES_256_CBC_SHA1 { 0xC0, 0x20 }
538#define GNUTLS_SRP_SHA_RSA_AES_256_CBC_SHA1 { 0xC0, 0x21 }
539#define GNUTLS_SRP_SHA_DSS_AES_256_CBC_SHA1 { 0xC0, 0x22 }
540
541/* RSA
542 */
543#define GNUTLS_RSA_ARCFOUR_SHA1 { 0x00, 0x05 }
544#define GNUTLS_RSA_ARCFOUR_MD5 { 0x00, 0x04 }
545#define GNUTLS_RSA_3DES_EDE_CBC_SHA1 { 0x00, 0x0A }
546
547#define GNUTLS_RSA_EXPORT_ARCFOUR_40_MD5 { 0x00, 0x03 }
548
549/* rfc3268:
550 */
551#define GNUTLS_RSA_AES_128_CBC_SHA1 { 0x00, 0x2F }
552#define GNUTLS_RSA_AES_256_CBC_SHA1 { 0x00, 0x35 }
553
554/* rfc4132 */
555#define GNUTLS_RSA_CAMELLIA_128_CBC_SHA1 { 0x00,0x41 }
556#define GNUTLS_RSA_CAMELLIA_256_CBC_SHA1 { 0x00,0x84 }
557
558/* DHE DSS
559 */
560
561#define GNUTLS_DHE_DSS_3DES_EDE_CBC_SHA1 { 0x00, 0x13 }
562
563/* draft-ietf-tls-56-bit-ciphersuites-01:
564 */
565#define GNUTLS_DHE_DSS_ARCFOUR_SHA1 { 0x00, 0x66 }
566
567/* rfc3268:
568 */
569#define GNUTLS_DHE_DSS_AES_256_CBC_SHA1 { 0x00, 0x38 }
570#define GNUTLS_DHE_DSS_AES_128_CBC_SHA1 { 0x00, 0x32 }
571
572/* rfc4132 */
573#define GNUTLS_DHE_DSS_CAMELLIA_128_CBC_SHA1 { 0x00,0x44 }
574#define GNUTLS_DHE_DSS_CAMELLIA_256_CBC_SHA1 { 0x00,0x87 }
575
576/* DHE RSA
577 */
578#define GNUTLS_DHE_RSA_3DES_EDE_CBC_SHA1 { 0x00, 0x16 }
579
580/* rfc3268:
581 */
582#define GNUTLS_DHE_RSA_AES_128_CBC_SHA1 { 0x00, 0x33 }
583#define GNUTLS_DHE_RSA_AES_256_CBC_SHA1 { 0x00, 0x39 }
584
585/* rfc4132 */
586#define GNUTLS_DHE_RSA_CAMELLIA_128_CBC_SHA1 { 0x00,0x45 }
587#define GNUTLS_DHE_RSA_CAMELLIA_256_CBC_SHA1 { 0x00,0x88 }
588
589#define CIPHER_SUITES_COUNT sizeof(cs_algorithms)/sizeof(gnutls_cipher_suite_entry)-1
590
591static const gnutls_cipher_suite_entry cs_algorithms[] = {
592 /* ANON_DH */
593 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_ARCFOUR_MD5,
594 GNUTLS_CIPHER_ARCFOUR_128,
595 GNUTLS_KX_ANON_DH, GNUTLS_MAC_MD5,
596 GNUTLS_SSL3),
597 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_3DES_EDE_CBC_SHA1,
598 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_ANON_DH,
599 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
600 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_128_CBC_SHA1,
601 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ANON_DH,
602 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
603 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_256_CBC_SHA1,
604 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ANON_DH,
605 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
606#ifdef ENABLE_CAMELLIA
607 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_CAMELLIA_128_CBC_SHA1,
608 GNUTLS_CIPHER_CAMELLIA_128_CBC,
609 GNUTLS_KX_ANON_DH,
610 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
611 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_CAMELLIA_256_CBC_SHA1,
612 GNUTLS_CIPHER_CAMELLIA_256_CBC,
613 GNUTLS_KX_ANON_DH,
614 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
615#endif
616
617 /* PSK */
618 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_ARCFOUR_SHA1,
619 GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_PSK,
620 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
621 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1,
622 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_PSK,
623 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
624 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_128_CBC_SHA1,
625 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_PSK,
626 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
627 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_256_CBC_SHA1,
628 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_PSK,
629 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
630
631 /* DHE-PSK */
632 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1,
633 GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_DHE_PSK,
634 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
635 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1,
636 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_PSK,
637 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
638 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1,
639 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_PSK,
640 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
641 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1,
642 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_PSK,
643 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
644
645 /* SRP */
646 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1,
647 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP,
648 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
649 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_AES_128_CBC_SHA1,
650 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP,
651 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
652 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_AES_256_CBC_SHA1,
653 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP,
654 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
655
656 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_3DES_EDE_CBC_SHA1,
657 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_DSS,
658 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
659
660 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA1,
661 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_RSA,
662 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
663
664 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_AES_128_CBC_SHA1,
665 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP_DSS,
666 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
667
668 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_AES_128_CBC_SHA1,
669 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP_RSA,
670 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
671
672 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_AES_256_CBC_SHA1,
673 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP_DSS,
674 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
675
676 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_AES_256_CBC_SHA1,
677 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP_RSA,
678 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
679
680 /* DHE_DSS */
681 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_ARCFOUR_SHA1,
682 GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_KX_DHE_DSS,
683 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
684 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_3DES_EDE_CBC_SHA1,
685 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_DSS,
686 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
687 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_128_CBC_SHA1,
688 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_DSS,
689 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
690 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_256_CBC_SHA1,
691 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_DSS,
692 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
693#ifdef ENABLE_CAMELLIA
694 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_CAMELLIA_128_CBC_SHA1,
695 GNUTLS_CIPHER_CAMELLIA_128_CBC,
696 GNUTLS_KX_DHE_DSS,
697 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
698 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_CAMELLIA_256_CBC_SHA1,
699 GNUTLS_CIPHER_CAMELLIA_256_CBC,
700 GNUTLS_KX_DHE_DSS,
701 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
702#endif
703 /* DHE_RSA */
704 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_3DES_EDE_CBC_SHA1,
705 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_RSA,
706 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
707 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_128_CBC_SHA1,
708 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_RSA,
709 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
710 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_256_CBC_SHA1,
711 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_RSA,
712 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
713#ifdef ENABLE_CAMELLIA
714 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_CAMELLIA_128_CBC_SHA1,
715 GNUTLS_CIPHER_CAMELLIA_128_CBC,
716 GNUTLS_KX_DHE_RSA,
717 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
718 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_CAMELLIA_256_CBC_SHA1,
719 GNUTLS_CIPHER_CAMELLIA_256_CBC,
720 GNUTLS_KX_DHE_RSA,
721 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
722#endif
723 /* RSA */
724 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_NULL_MD5,
725 GNUTLS_CIPHER_NULL,
726 GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3),
727
728 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_EXPORT_ARCFOUR_40_MD5,
729 GNUTLS_CIPHER_ARCFOUR_40,
730 GNUTLS_KX_RSA_EXPORT, GNUTLS_MAC_MD5,
731 GNUTLS_SSL3),
732
733 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_SHA1,
734 GNUTLS_CIPHER_ARCFOUR_128,
735 GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3),
736 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_MD5,
737 GNUTLS_CIPHER_ARCFOUR_128,
738 GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3),
739 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_3DES_EDE_CBC_SHA1,
740 GNUTLS_CIPHER_3DES_CBC,
741 GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3),
742 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_128_CBC_SHA1,
743 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_RSA,
744 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
745 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_256_CBC_SHA1,
746 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_RSA,
747 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
748#ifdef ENABLE_CAMELLIA
749 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_CAMELLIA_128_CBC_SHA1,
750 GNUTLS_CIPHER_CAMELLIA_128_CBC, GNUTLS_KX_RSA,
751 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
752 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_CAMELLIA_256_CBC_SHA1,
753 GNUTLS_CIPHER_CAMELLIA_256_CBC, GNUTLS_KX_RSA,
754 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
755#endif
756 {0,
757 {
758 {0,
759 0}},
760 0,
761 0,
762 0,
763 0}
764};
765
766#define GNUTLS_CIPHER_SUITE_LOOP(b) \
767 const gnutls_cipher_suite_entry *p; \
768 for(p = cs_algorithms; p->name != NULL; p++) { b ; }
769
770#define GNUTLS_CIPHER_SUITE_ALG_LOOP(a) \
771 GNUTLS_CIPHER_SUITE_LOOP( if( (p->id.suite[0] == suite->suite[0]) && (p->id.suite[1] == suite->suite[1])) { a; break; } )
772
773/* Generic Functions */
774
775int
776_gnutls_mac_priority (gnutls_session_t session,
777 gnutls_mac_algorithm_t algorithm)
778{ /* actually returns the priority */
779 unsigned int i;
780 for (i = 0; i < session->internals.priorities.mac.algorithms; i++)
781 {
782 if (session->internals.priorities.mac.priority[i] == algorithm)
783 return i;
784 }
785 return -1;
786}
787
788/**
789 * gnutls_mac_get_name - Returns a string with the name of the specified mac algorithm
790 * @algorithm: is a MAC algorithm
791 *
792 * Returns: a string that contains the name of the specified MAC
793 * algorithm, or %NULL.
794 **/
795const char *
796gnutls_mac_get_name (gnutls_mac_algorithm_t algorithm)
797{
798 const char *ret = NULL;
799
800 /* avoid prefix */
801 GNUTLS_HASH_ALG_LOOP (ret = p->name);
802
803 return ret;
804}
805
806/**
807 * gnutls_mac_get_id - Returns the gnutls id of the specified in string algorithm
808 * @algorithm: is a MAC algorithm name
809 *
810 * Returns: an %gnutls_mac_algorithm_tid of the specified in a string
811 * MAC algorithm, or %GNUTLS_MAC_UNKNOWN on failures. The names are
812 * compared in a case insensitive way.
813 **/
814gnutls_mac_algorithm_t
815gnutls_mac_get_id (const char *name)
816{
817 gnutls_mac_algorithm_t ret = GNUTLS_MAC_UNKNOWN;
818
819 GNUTLS_HASH_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id)
820 ;
821
822 return ret;
823}
824
825/**
826 * gnutls_mac_get_key_size - Returns the length of the MAC's key size
827 * @algorithm: is an encryption algorithm
828 *
829 * Returns: length (in bytes) of the given MAC key size, or 0 if the
830 * given MAC algorithm is invalid.
831 *
832 **/
833size_t
834gnutls_mac_get_key_size (gnutls_mac_algorithm_t algorithm)
835{
836 size_t ret = 0;
837
838 /* avoid prefix */
839 GNUTLS_HASH_ALG_LOOP (ret = p->key_size);
840
841 return ret;
842}
843
844/**
845 * gnutls_mac_list:
846 *
847 * Get a list of hash algorithms for use as MACs. Note that not
848 * necessarily all MACs are supported in TLS cipher suites. For
849 * example, MD2 is not supported as a cipher suite, but is supported
850 * for other purposes (e.g., X.509 signature verification or similar).
851 *
852 * Returns: Return a zero-terminated list of %gnutls_mac_algorithm_t
853 * integers indicating the available MACs.
854 **/
855const gnutls_mac_algorithm_t *
856gnutls_mac_list (void)
857{
858 return supported_macs;
859}
860
861const char *
862_gnutls_x509_mac_to_oid (gnutls_mac_algorithm_t algorithm)
863{
864 const char *ret = NULL;
865
866 /* avoid prefix */
867 GNUTLS_HASH_ALG_LOOP (ret = p->oid);
868
869 return ret;
870}
871
872gnutls_mac_algorithm_t
873_gnutls_x509_oid2mac_algorithm (const char *oid)
874{
875 gnutls_mac_algorithm_t ret = 0;
876
877 GNUTLS_HASH_LOOP (if (p->oid && strcmp (oid, p->oid) == 0)
878 {
879 ret = p->id; break;}
880 )
881 ;
882
883 if (ret == 0)
884 return GNUTLS_MAC_UNKNOWN;
885 return ret;
886}
887
888int
889_gnutls_mac_is_ok (gnutls_mac_algorithm_t algorithm)
890{
891 ssize_t ret = -1;
892 GNUTLS_HASH_ALG_LOOP (ret = p->id);
893 if (ret >= 0)
894 ret = 0;
895 else
896 ret = 1;
897 return ret;
898}
899
900/* Compression Functions */
901int
902_gnutls_compression_priority (gnutls_session_t session,
903 gnutls_compression_method_t algorithm)
904{ /* actually returns the priority */
905 unsigned int i;
906 for (i = 0; i < session->internals.priorities.compression.algorithms; i++)
907 {
908 if (session->internals.priorities.compression.priority[i] == algorithm)
909 return i;
910 }
911 return -1;
912}
913
914/**
915 * gnutls_compression_get_name - Returns a string with the name of the specified compression algorithm
916 * @algorithm: is a Compression algorithm
917 *
918 * Returns: a pointer to a string that contains the name of the
919 * specified compression algorithm, or %NULL.
920 **/
921const char *
922gnutls_compression_get_name (gnutls_compression_method_t algorithm)
923{
924 const char *ret = NULL;
925
926 /* avoid prefix */
927 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->name + sizeof ("GNUTLS_COMP_") - 1);
928
929 return ret;
930}
931
932/**
933 * gnutls_compression_get_id - Returns the gnutls id of the specified in string algorithm
934 * @algorithm: is a compression method name
935 *
936 * The names are compared in a case insensitive way.
937 *
938 * Returns: an id of the specified in a string compression method, or
939 * %GNUTLS_COMP_UNKNOWN on error.
940 *
941 **/
942gnutls_compression_method_t
943gnutls_compression_get_id (const char *name)
944{
945 gnutls_compression_method_t ret = GNUTLS_COMP_UNKNOWN;
946
947 GNUTLS_COMPRESSION_LOOP (if
948 (strcasecmp
949 (p->name + sizeof ("GNUTLS_COMP_") - 1,
950 name) == 0) ret = p->id)
951 ;
952
953 return ret;
954}
955
956/**
957 * gnutls_compression_list:
958 *
959 * Get a list of compression methods. Note that to be able to use LZO
960 * compression, you must link to libgnutls-extra and call
961 * gnutls_global_init_extra().
962 *
963 * Returns: a zero-terminated list of %gnutls_compression_method_t
964 * integers indicating the available compression methods.
965 **/
966const gnutls_compression_method_t *
967gnutls_compression_list (void)
968{
969 return supported_compressions;
970}
971
972/* return the tls number of the specified algorithm */
973int
974_gnutls_compression_get_num (gnutls_compression_method_t algorithm)
975{
976 int ret = -1;
977
978 /* avoid prefix */
979 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->num);
980
981 return ret;
982}
983
984int
985_gnutls_compression_get_wbits (gnutls_compression_method_t algorithm)
986{
987 int ret = -1;
988 /* avoid prefix */
989 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->window_bits);
990 return ret;
991}
992
993int
994_gnutls_compression_get_mem_level (gnutls_compression_method_t algorithm)
995{
996 int ret = -1;
997 /* avoid prefix */
998 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->mem_level);
999 return ret;
1000}
1001
1002int
1003_gnutls_compression_get_comp_level (gnutls_compression_method_t algorithm)
1004{
1005 int ret = -1;
1006 /* avoid prefix */
1007 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->comp_level);
1008 return ret;
1009}
1010
1011/* returns the gnutls internal ID of the TLS compression
1012 * method num
1013 */
1014gnutls_compression_method_t
1015_gnutls_compression_get_id (int num)
1016{
1017 gnutls_compression_method_t ret = -1;
1018
1019 /* avoid prefix */
1020 GNUTLS_COMPRESSION_ALG_LOOP_NUM (ret = p->id);
1021
1022 return ret;
1023}
1024
1025int
1026_gnutls_compression_is_ok (gnutls_compression_method_t algorithm)
1027{
1028 ssize_t ret = -1;
1029 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->id);
1030 if (ret >= 0)
1031 ret = 0;
1032 else
1033 ret = 1;
1034 return ret;
1035}
1036
1037/* CIPHER functions */
1038int
1039_gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm)
1040{
1041 size_t ret = 0;
1042 GNUTLS_ALG_LOOP (ret = p->blocksize);
1043 return ret;
1044
1045}
1046
1047/* returns the priority */
1048int
1049_gnutls_cipher_priority (gnutls_session_t session,
1050 gnutls_cipher_algorithm_t algorithm)
1051{
1052 unsigned int i;
1053 for (i = 0; i < session->internals.priorities.cipher.algorithms; i++)
1054 {
1055 if (session->internals.priorities.cipher.priority[i] == algorithm)
1056 return i;
1057 }
1058 return -1;
1059}
1060
1061int
1062_gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm)
1063{
1064 size_t ret = 0;
1065
1066 GNUTLS_ALG_LOOP (ret = p->block);
1067 return ret;
1068
1069}
1070
1071/**
1072 * gnutls_cipher_get_key_size - Returns the length of the cipher's key size
1073 * @algorithm: is an encryption algorithm
1074 *
1075 * Returns: length (in bytes) of the given cipher's key size, o 0 if
1076 * the given cipher is invalid.
1077 **/
1078size_t
1079gnutls_cipher_get_key_size (gnutls_cipher_algorithm_t algorithm)
1080{ /* In bytes */
1081 size_t ret = 0;
1082 GNUTLS_ALG_LOOP (ret = p->keysize);
1083 return ret;
1084
1085}
1086
1087int
1088_gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm)
1089{ /* In bytes */
1090 size_t ret = 0;
1091 GNUTLS_ALG_LOOP (ret = p->iv);
1092 return ret;
1093
1094}
1095
1096int
1097_gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm)
1098{ /* In bytes */
1099 size_t ret = 0;
1100 GNUTLS_ALG_LOOP (ret = p->export_flag);
1101 return ret;
1102
1103}
1104
1105/**
1106 * gnutls_cipher_get_name - Returns a string with the name of the specified cipher algorithm
1107 * @algorithm: is an encryption algorithm
1108 *
1109 * Returns: a pointer to a string that contains the name of the
1110 * specified cipher, or %NULL.
1111 **/
1112const char *
1113gnutls_cipher_get_name (gnutls_cipher_algorithm_t algorithm)
1114{
1115 const char *ret = NULL;
1116
1117 /* avoid prefix */
1118 GNUTLS_ALG_LOOP (ret = p->name);
1119
1120 return ret;
1121}
1122
1123/**
1124 * gnutls_cipher_get_id - Returns the gnutls id of the specified in string algorithm
1125 * @algorithm: is a MAC algorithm name
1126 *
1127 * The names are compared in a case insensitive way.
1128 *
1129 * Returns: an id of the specified cipher, or %GNUTLS_CIPHER_UNKNOWN
1130 * on error.
1131 *
1132 **/
1133gnutls_cipher_algorithm_t
1134gnutls_cipher_get_id (const char *name)
1135{
1136 gnutls_cipher_algorithm_t ret = GNUTLS_CIPHER_UNKNOWN;
1137
1138 GNUTLS_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id)
1139 ;
1140
1141 return ret;
1142}
1143
1144/**
1145 * gnutls_cipher_list:
1146 *
1147 * Get a list of supported cipher algorithms. Note that not
1148 * necessarily all ciphers are supported as TLS cipher suites. For
1149 * example, DES is not supported as a cipher suite, but is supported
1150 * for other purposes (e.g., PKCS#8 or similar).
1151 *
1152 * Returns: a zero-terminated list of %gnutls_cipher_algorithm_t
1153 * integers indicating the available ciphers.
1154 *
1155 **/
1156const gnutls_cipher_algorithm_t *
1157gnutls_cipher_list (void)
1158{
1159 return supported_ciphers;
1160}
1161
1162int
1163_gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm)
1164{
1165 ssize_t ret = -1;
1166 GNUTLS_ALG_LOOP (ret = p->id);
1167 if (ret >= 0)
1168 ret = 0;
1169 else
1170 ret = 1;
1171 return ret;
1172}
1173
1174/* Key EXCHANGE functions */
1175mod_auth_st *
1176_gnutls_kx_auth_struct (gnutls_kx_algorithm_t algorithm)
1177{
1178 mod_auth_st *ret = NULL;
1179 GNUTLS_KX_ALG_LOOP (ret = p->auth_struct);
1180 return ret;
1181
1182}
1183
1184int
1185_gnutls_kx_priority (gnutls_session_t session,
1186 gnutls_kx_algorithm_t algorithm)
1187{
1188 unsigned int i;
1189 for (i = 0; i < session->internals.priorities.kx.algorithms; i++)
1190 {
1191 if (session->internals.priorities.kx.priority[i] == algorithm)
1192 return i;
1193 }
1194 return -1;
1195}
1196
1197/**
1198 * gnutls_kx_get_name - Returns a string with the name of the specified key exchange algorithm
1199 * @algorithm: is a key exchange algorithm
1200 *
1201 * Returns: a pointer to a string that contains the name of the
1202 * specified key exchange algorithm, or %NULL.
1203 **/
1204const char *
1205gnutls_kx_get_name (gnutls_kx_algorithm_t algorithm)
1206{
1207 const char *ret = NULL;
1208
1209 /* avoid prefix */
1210 GNUTLS_KX_ALG_LOOP (ret = p->name);
1211
1212 return ret;
1213}
1214
1215/**
1216 * gnutls_kx_get_id - Returns the gnutls id of the specified in string algorithm
1217 * @algorithm: is a KX name
1218 *
1219 * The names are compared in a case insensitive way.
1220 *
1221 * Returns: an id of the specified KX algorithm, or
1222 * %GNUTLS_KX_UNKNOWN on error.
1223 **/
1224gnutls_kx_algorithm_t
1225gnutls_kx_get_id (const char *name)
1226{
1227 gnutls_cipher_algorithm_t ret = GNUTLS_KX_UNKNOWN;
1228
1229 GNUTLS_KX_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->algorithm)
1230 ;
1231
1232 return ret;
1233}
1234
1235/**
1236 * gnutls_kx_list:
1237 *
1238 * Get a list of supported key exchange algorithms.
1239 *
1240 * Returns: a zero-terminated list of %gnutls_kx_algorithm_t integers
1241 * indicating the available key exchange algorithms.
1242 **/
1243const gnutls_kx_algorithm_t *
1244gnutls_kx_list (void)
1245{
1246 return supported_kxs;
1247}
1248
1249int
1250_gnutls_kx_is_ok (gnutls_kx_algorithm_t algorithm)
1251{
1252 ssize_t ret = -1;
1253 GNUTLS_KX_ALG_LOOP (ret = p->algorithm);
1254 if (ret >= 0)
1255 ret = 0;
1256 else
1257 ret = 1;
1258 return ret;
1259}
1260
1261int
1262_gnutls_kx_needs_rsa_params (gnutls_kx_algorithm_t algorithm)
1263{
1264 ssize_t ret = 0;
1265 GNUTLS_KX_ALG_LOOP (ret = p->needs_rsa_params);
1266 return ret;
1267}
1268
1269int
1270_gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm)
1271{
1272 ssize_t ret = 0;
1273 GNUTLS_KX_ALG_LOOP (ret = p->needs_dh_params);
1274 return ret;
1275}
1276
1277/* Version */
1278int
1279_gnutls_version_priority (gnutls_session_t session, gnutls_protocol_t version)
1280{ /* actually returns the priority */
1281 unsigned int i;
1282
1283 if (session->internals.priorities.protocol.priority == NULL)
1284 {
1285 gnutls_assert ();
1286 return -1;
1287 }
1288
1289 for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
1290 {
1291 if (session->internals.priorities.protocol.priority[i] == version)
1292 return i;
1293 }
1294 return -1;
1295}
1296
1297gnutls_protocol_t
1298_gnutls_version_lowest (gnutls_session_t session)
1299{ /* returns the lowest version supported */
1300 unsigned int i, min = 0xff;
1301
1302 if (session->internals.priorities.protocol.priority == NULL)
1303 {
1304 return GNUTLS_VERSION_UNKNOWN;
1305 }
1306 else
1307 for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
1308 {
1309 if (session->internals.priorities.protocol.priority[i] < min)
1310 min = session->internals.priorities.protocol.priority[i];
1311 }
1312
1313 if (min == 0xff)
1314 return GNUTLS_VERSION_UNKNOWN; /* unknown version */
1315
1316 return min;
1317}
1318
1319gnutls_protocol_t
1320_gnutls_version_max (gnutls_session_t session)
1321{ /* returns the maximum version supported */
1322 unsigned int i, max = 0x00;
1323
1324 if (session->internals.priorities.protocol.priority == NULL)
1325 {
1326 return GNUTLS_VERSION_UNKNOWN;
1327 }
1328 else
1329 for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
1330 {
1331 if (session->internals.priorities.protocol.priority[i] > max)
1332 max = session->internals.priorities.protocol.priority[i];
1333 }
1334
1335 if (max == 0x00)
1336 return GNUTLS_VERSION_UNKNOWN; /* unknown version */
1337
1338 return max;
1339}
1340
1341/**
1342 * gnutls_protocol_get_name - Returns a string with the name of the specified SSL/TLS version
1343 * @version: is a (gnutls) version number
1344 *
1345 * Returns: a string that contains the name of the specified TLS
1346 * version (e.g., "TLS 1.0"), or %NULL.
1347 **/
1348const char *
1349gnutls_protocol_get_name (gnutls_protocol_t version)
1350{
1351 const char *ret = NULL;
1352
1353 /* avoid prefix */
1354 GNUTLS_VERSION_ALG_LOOP (ret = p->name);
1355 return ret;
1356}
1357
1358/**
1359 * gnutls_protocol_get_id - Returns the gnutls id of the specified in string protocol
1360 * @algorithm: is a protocol name
1361 *
1362 * The names are compared in a case insensitive way.
1363 *
1364 * Returns: an id of the specified protocol, or
1365 * %GNUTLS_VERSION_UNKNOWN on error.
1366 **/
1367gnutls_protocol_t
1368gnutls_protocol_get_id (const char *name)
1369{
1370 gnutls_protocol_t ret = GNUTLS_VERSION_UNKNOWN;
1371
1372 GNUTLS_VERSION_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id)
1373 ;
1374
1375 return ret;
1376}
1377
1378/**
1379 * gnutls_protocol_list:
1380 *
1381 * Get a list of supported protocols, e.g. SSL 3.0, TLS 1.0 etc.
1382 *
1383 * Returns: a zero-terminated list of %gnutls_protocol_t integers
1384 * indicating the available protocols.
1385 *
1386 **/
1387const gnutls_protocol_t *
1388gnutls_protocol_list (void)
1389{
1390 return supported_protocols;
1391}
1392
1393int
1394_gnutls_version_get_minor (gnutls_protocol_t version)
1395{
1396 int ret = -1;
1397
1398 GNUTLS_VERSION_ALG_LOOP (ret = p->minor);
1399 return ret;
1400}
1401
1402gnutls_protocol_t
1403_gnutls_version_get (int major, int minor)
1404{
1405 int ret = -1;
1406
1407 GNUTLS_VERSION_LOOP (if ((p->major == major) && (p->minor == minor))
1408 ret = p->id)
1409 ;
1410 return ret;
1411}
1412
1413int
1414_gnutls_version_get_major (gnutls_protocol_t version)
1415{
1416 int ret = -1;
1417
1418 GNUTLS_VERSION_ALG_LOOP (ret = p->major);
1419 return ret;
1420}
1421
1422/* Version Functions */
1423
1424int
1425_gnutls_version_is_supported (gnutls_session_t session,
1426 const gnutls_protocol_t version)
1427{
1428 int ret = 0;
1429
1430 GNUTLS_VERSION_ALG_LOOP (ret = p->supported);
1431 if (ret == 0)
1432 return 0;
1433
1434 if (_gnutls_version_priority (session, version) < 0)
1435 return 0; /* disabled by the user */
1436 else
1437 return 1;
1438}
1439
1440/* Type to KX mappings */
1441gnutls_kx_algorithm_t
1442_gnutls_map_kx_get_kx (gnutls_credentials_type_t type, int server)
1443{
1444 gnutls_kx_algorithm_t ret = -1;
1445
1446 if (server)
1447 {
1448 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
1449 }
1450 else
1451 {
1452 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
1453 }
1454 return ret;
1455}
1456
1457gnutls_credentials_type_t
1458_gnutls_map_kx_get_cred (gnutls_kx_algorithm_t algorithm, int server)
1459{
1460 gnutls_credentials_type_t ret = -1;
1461 if (server)
1462 {
1463 GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret = p->server_type)
1464 ;
1465 }
1466 else
1467 {
1468 GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret = p->client_type)
1469 ;
1470 }
1471
1472 return ret;
1473}
1474
1475/* Cipher Suite's functions */
1476gnutls_cipher_algorithm_t
1477_gnutls_cipher_suite_get_cipher_algo (const cipher_suite_st * suite)
1478{
1479 int ret = 0;
1480 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->block_algorithm);
1481 return ret;
1482}
1483
1484gnutls_protocol_t
1485_gnutls_cipher_suite_get_version (const cipher_suite_st * suite)
1486{
1487 int ret = 0;
1488 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->version);
1489 return ret;
1490}
1491
1492gnutls_kx_algorithm_t
1493_gnutls_cipher_suite_get_kx_algo (const cipher_suite_st * suite)
1494{
1495 int ret = 0;
1496
1497 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->kx_algorithm);
1498 return ret;
1499
1500}
1501
1502gnutls_mac_algorithm_t
1503_gnutls_cipher_suite_get_mac_algo (const cipher_suite_st * suite)
1504{ /* In bytes */
1505 int ret = 0;
1506 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->mac_algorithm);
1507 return ret;
1508
1509}
1510
1511const char *
1512_gnutls_cipher_suite_get_name (cipher_suite_st * suite)
1513{
1514 const char *ret = NULL;
1515
1516 /* avoid prefix */
1517 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->name + sizeof ("GNUTLS_") - 1);
1518
1519 return ret;
1520}
1521
1522/**
1523 * gnutls_cipher_suite_get_name - Returns a string with the name of the specified cipher suite
1524 * @kx_algorithm: is a Key exchange algorithm
1525 * @cipher_algorithm: is a cipher algorithm
1526 * @mac_algorithm: is a MAC algorithm
1527 *
1528 * Note that the full cipher suite name must be prepended by TLS or
1529 * SSL depending of the protocol in use.
1530 *
1531 * Returns: a string that contains the name of a TLS cipher suite,
1532 * specified by the given algorithms, or %NULL.
1533 **/
1534const char *
1535gnutls_cipher_suite_get_name (gnutls_kx_algorithm_t kx_algorithm,
1536 gnutls_cipher_algorithm_t cipher_algorithm,
1537 gnutls_mac_algorithm_t mac_algorithm)
1538{
1539 const char *ret = NULL;
1540
1541 /* avoid prefix */
1542 GNUTLS_CIPHER_SUITE_LOOP (if (kx_algorithm == p->kx_algorithm &&
1543 cipher_algorithm == p->block_algorithm &&
1544 mac_algorithm == p->mac_algorithm)
1545 ret = p->name + sizeof ("GNUTLS_") - 1)
1546 ;
1547
1548 return ret;
1549}
1550
1551/**
1552 * gnutls_cipher_suite_info:
1553 * @idx: index of cipher suite to get information about, starts on 0.
1554 * @cs_id: output buffer with room for 2 bytes, indicating cipher suite value
1555 * @kx: output variable indicating key exchange algorithm, or %NULL.
1556 * @cipher: output variable indicating cipher, or %NULL.
1557 * @mac: output variable indicating MAC algorithm, or %NULL.
1558 * @version: output variable indicating TLS protocol version, or %NULL.
1559 *
1560 * Get information about supported cipher suites. Use the function
1561 * iteratively to get information about all supported cipher suites.
1562 * Call with idx=0 to get information about first cipher suite, then
1563 * idx=1 and so on until the function returns NULL.
1564 *
1565 * Returns: the name of @idx cipher suite, and set the information
1566 * about the cipher suite in the output variables. If @idx is out of
1567 * bounds, %NULL is returned.
1568 **/
1569const char *
1570gnutls_cipher_suite_info (size_t idx,
1571 char *cs_id,
1572 gnutls_kx_algorithm_t * kx,
1573 gnutls_cipher_algorithm_t * cipher,
1574 gnutls_mac_algorithm_t * mac,
1575 gnutls_protocol_t * version)
1576{
1577 if (idx >= CIPHER_SUITES_COUNT)
1578 return NULL;
1579
1580 if (cs_id)
1581 memcpy (cs_id, cs_algorithms[idx].id.suite, 2);
1582 if (kx)
1583 *kx = cs_algorithms[idx].kx_algorithm;
1584 if (cipher)
1585 *cipher = cs_algorithms[idx].block_algorithm;
1586 if (mac)
1587 *mac = cs_algorithms[idx].mac_algorithm;
1588 if (version)
1589 *version = cs_algorithms[idx].version;
1590
1591 return cs_algorithms[idx].name + sizeof ("GNU") - 1;
1592}
1593
1594static inline int
1595_gnutls_cipher_suite_is_ok (cipher_suite_st * suite)
1596{
1597 size_t ret;
1598 const char *name = NULL;
1599
1600 GNUTLS_CIPHER_SUITE_ALG_LOOP (name = p->name);
1601 if (name != NULL)
1602 ret = 0;
1603 else
1604 ret = 1;
1605 return ret;
1606
1607}
1608
1609#define SWAP(x, y) memcpy(tmp,x,size); \
1610 memcpy(x,y,size); \
1611 memcpy(y,tmp,size);
1612
1613#define MAX_ELEM_SIZE 4
1614static inline int
1615_gnutls_partition (gnutls_session_t session,
1616 void *_base,
1617 size_t nmemb,
1618 size_t size,
1619 int (*compar) (gnutls_session_t,
1620 const void *, const void *))
1621{
1622 uint8_t *base = _base;
1623 uint8_t tmp[MAX_ELEM_SIZE];
1624 uint8_t ptmp[MAX_ELEM_SIZE];
1625 unsigned int pivot;
1626 unsigned int i, j;
1627 unsigned int full;
1628
1629 i = pivot = 0;
1630 j = full = (nmemb - 1) * size;
1631
1632 memcpy (ptmp, &base[0], size); /* set pivot item */
1633
1634 while (i < j)
1635 {
1636 while ((compar (session, &base[i], ptmp) <= 0) && (i < full))
1637 {
1638 i += size;
1639 }
1640 while ((compar (session, &base[j], ptmp) >= 0) && (j > 0))
1641 j -= size;
1642
1643 if (i < j)
1644 {
1645 SWAP (&base[j], &base[i]);
1646 }
1647 }
1648
1649 if (j > pivot)
1650 {
1651 SWAP (&base[pivot], &base[j]);
1652 pivot = j;
1653 }
1654 else if (i < pivot)
1655 {
1656 SWAP (&base[pivot], &base[i]);
1657 pivot = i;
1658 }
1659 return pivot / size;
1660}
1661
1662static void
1663_gnutls_qsort (gnutls_session_t session,
1664 void *_base,
1665 size_t nmemb,
1666 size_t size,
1667 int (*compar) (gnutls_session_t, const void *, const void *))
1668{
1669 unsigned int pivot;
1670 char *base = _base;
1671 size_t snmemb = nmemb;
1672
1673#ifdef DEBUG
1674 if (size > MAX_ELEM_SIZE)
1675 {
1676 gnutls_assert ();
1677 _gnutls_debug_log ("QSORT BUG\n");
1678 exit (1);
1679 }
1680#endif
1681
1682 if (snmemb <= 1)
1683 return;
1684 pivot = _gnutls_partition (session, _base, nmemb, size, compar);
1685
1686 _gnutls_qsort (session, base, pivot < nmemb ? pivot + 1
1687 : pivot, size, compar);
1688 _gnutls_qsort (session, &base[(pivot + 1) * size], nmemb - pivot - 1, size,
1689 compar);
1690}
1691
1692/* a compare function for KX algorithms (using priorities).
1693 * For use with qsort
1694 */
1695static int
1696_gnutls_compare_algo (gnutls_session_t session,
1697 const void *i_A1, const void *i_A2)
1698{
1699 gnutls_kx_algorithm_t kA1 =
1700 _gnutls_cipher_suite_get_kx_algo ((const cipher_suite_st *) i_A1);
1701 gnutls_kx_algorithm_t kA2 =
1702 _gnutls_cipher_suite_get_kx_algo ((const cipher_suite_st *) i_A2);
1703 gnutls_cipher_algorithm_t cA1 =
1704 _gnutls_cipher_suite_get_cipher_algo ((const cipher_suite_st *) i_A1);
1705 gnutls_cipher_algorithm_t cA2 =
1706 _gnutls_cipher_suite_get_cipher_algo ((const cipher_suite_st *) i_A2);
1707 gnutls_mac_algorithm_t mA1 =
1708 _gnutls_cipher_suite_get_mac_algo ((const cipher_suite_st *) i_A1);
1709 gnutls_mac_algorithm_t mA2 =
1710 _gnutls_cipher_suite_get_mac_algo ((const cipher_suite_st *) i_A2);
1711
1712 int p1 = (_gnutls_kx_priority (session, kA1) + 1) * 64;
1713 int p2 = (_gnutls_kx_priority (session, kA2) + 1) * 64;
1714 p1 += (_gnutls_cipher_priority (session, cA1) + 1) * 8;
1715 p2 += (_gnutls_cipher_priority (session, cA2) + 1) * 8;
1716 p1 += _gnutls_mac_priority (session, mA1);
1717 p2 += _gnutls_mac_priority (session, mA2);
1718
1719 if (p1 > p2)
1720 {
1721 return 1;
1722 }
1723 else
1724 {
1725 if (p1 == p2)
1726 {
1727 return 0;
1728 }
1729 return -1;
1730 }
1731}
1732
1733#ifdef SORT_DEBUG
1734static void
1735_gnutls_bsort (gnutls_session_t session, void *_base, size_t nmemb,
1736 size_t size, int (*compar) (gnutls_session_t, const void *,
1737 const void *))
1738{
1739 unsigned int i, j;
1740 int full = nmemb * size;
1741 char *base = _base;
1742 char tmp[MAX_ELEM_SIZE];
1743
1744 for (i = 0; i < full; i += size)
1745 {
1746 for (j = 0; j < full; j += size)
1747 {
1748 if (compar (session, &base[i], &base[j]) < 0)
1749 {
1750 SWAP (&base[j], &base[i]);
1751 }
1752 }
1753 }
1754
1755}
1756#endif
1757
1758int
1759_gnutls_supported_ciphersuites_sorted (gnutls_session_t session,
1760 cipher_suite_st ** ciphers)
1761{
1762
1763#ifdef SORT_DEBUG
1764 unsigned int i;
1765#endif
1766 int count;
1767
1768 count = _gnutls_supported_ciphersuites (session, ciphers);
1769 if (count <= 0)
1770 {
1771 gnutls_assert ();
1772 return count;
1773 }
1774#ifdef SORT_DEBUG
1775 _gnutls_debug_log ("Unsorted: \n");
1776 for (i = 0; i < count; i++)
1777 _gnutls_debug_log ("\t%d: %s\n", i,
1778 _gnutls_cipher_suite_get_name ((*ciphers)[i]));
1779#endif
1780
1781 _gnutls_qsort (session, *ciphers, count, sizeof (cipher_suite_st),
1782 _gnutls_compare_algo);
1783
1784#ifdef SORT_DEBUG
1785 _gnutls_debug_log ("Sorted: \n");
1786 for (i = 0; i < count; i++)
1787 _gnutls_debug_log ("\t%d: %s\n", i,
1788 _gnutls_cipher_suite_get_name ((*ciphers)[i]));
1789#endif
1790
1791 return count;
1792}
1793
1794int
1795_gnutls_supported_ciphersuites (gnutls_session_t session,
1796 cipher_suite_st ** _ciphers)
1797{
1798
1799 unsigned int i, ret_count, j;
1800 unsigned int count = CIPHER_SUITES_COUNT;
1801 cipher_suite_st *tmp_ciphers;
1802 cipher_suite_st *ciphers;
1803 gnutls_protocol_t version;
1804
1805 if (count == 0)
1806 {
1807 return 0;
1808 }
1809
1810 tmp_ciphers = gnutls_alloca (count * sizeof (cipher_suite_st));
1811 if (tmp_ciphers == NULL)
1812 return GNUTLS_E_MEMORY_ERROR;
1813
1814 ciphers = gnutls_malloc (count * sizeof (cipher_suite_st));
1815 if (ciphers == NULL)
1816 {
1817 gnutls_afree (tmp_ciphers);
1818 return GNUTLS_E_MEMORY_ERROR;
1819 }
1820
1821 version = gnutls_protocol_get_version (session);
1822
1823 for (i = 0; i < count; i++)
1824 {
1825 memcpy (&tmp_ciphers[i], &cs_algorithms[i].id,
1826 sizeof (cipher_suite_st));
1827 }
1828
1829 for (i = j = 0; i < count; i++)
1830 {
1831 /* remove private cipher suites, if requested.
1832 */
1833 if (tmp_ciphers[i].suite[0] == 0xFF && session->internals.enable_private
1834 == 0)
1835 continue;
1836
1837 /* remove cipher suites which do not support the
1838 * protocol version used.
1839 */
1840 if (_gnutls_cipher_suite_get_version (&tmp_ciphers[i]) > version)
1841 continue;
1842
1843 if (_gnutls_kx_priority (session,
1844 _gnutls_cipher_suite_get_kx_algo (&tmp_ciphers
1845 [i])) < 0)
1846 continue;
1847 if (_gnutls_mac_priority (session,
1848 _gnutls_cipher_suite_get_mac_algo
1849 (&tmp_ciphers[i])) < 0)
1850 continue;
1851 if (_gnutls_cipher_priority (session,
1852 _gnutls_cipher_suite_get_cipher_algo
1853 (&tmp_ciphers[i])) < 0)
1854 continue;
1855
1856 memcpy (&ciphers[j], &tmp_ciphers[i], sizeof (cipher_suite_st));
1857 j++;
1858 }
1859
1860 ret_count = j;
1861
1862#if 0 /* expensive */
1863 if (ret_count > 0 && ret_count != count)
1864 {
1865 ciphers =
1866 gnutls_realloc_fast (ciphers, ret_count * sizeof (cipher_suite_st));
1867 }
1868 else
1869 {
1870 if (ret_count != count)
1871 {
1872 gnutls_free (ciphers);
1873 ciphers = NULL;
1874 }
1875 }
1876#endif
1877
1878 gnutls_afree (tmp_ciphers);
1879
1880 /* This function can no longer return 0 cipher suites.
1881 * It returns an error code instead.
1882 */
1883 if (ret_count == 0)
1884 {
1885 gnutls_assert ();
1886 gnutls_free (ciphers);
1887 return GNUTLS_E_NO_CIPHER_SUITES;
1888 }
1889 *_ciphers = ciphers;
1890 return ret_count;
1891}
1892
1893/* For compression */
1894
1895#define MIN_PRIVATE_COMP_ALGO 0xEF
1896
1897/* returns the TLS numbers of the compression methods we support
1898 */
1899#define SUPPORTED_COMPRESSION_METHODS session->internals.priorities.compression.algorithms
1900int
1901_gnutls_supported_compression_methods (gnutls_session_t session,
1902 uint8_t ** comp)
1903{
1904 unsigned int i, j;
1905
1906 *comp = gnutls_malloc (sizeof (uint8_t) * SUPPORTED_COMPRESSION_METHODS);
1907 if (*comp == NULL)
1908 return GNUTLS_E_MEMORY_ERROR;
1909
1910 for (i = j = 0; i < SUPPORTED_COMPRESSION_METHODS; i++)
1911 {
1912 int tmp = _gnutls_compression_get_num (session->internals.priorities.
1913 compression.priority[i]);
1914
1915 /* remove private compression algorithms, if requested.
1916 */
1917 if (tmp == -1 || (tmp >= MIN_PRIVATE_COMP_ALGO
1918 && session->internals.enable_private == 0))
1919 {
1920 gnutls_assert ();
1921 continue;
1922 }
1923
1924 (*comp)[j] = (uint8_t) tmp;
1925 j++;
1926 }
1927
1928 if (j == 0)
1929 {
1930 gnutls_assert ();
1931 gnutls_free (*comp);
1932 *comp = NULL;
1933 return GNUTLS_E_NO_COMPRESSION_ALGORITHMS;
1934 }
1935 return j;
1936}
1937
1938/**
1939 * gnutls_certificate_type_get_name - Returns a string with the name of the specified certificate type
1940 * @type: is a certificate type
1941 *
1942 * Returns: a string (or %NULL) that contains the name of the
1943 * specified certificate type.
1944 **/
1945const char *
1946gnutls_certificate_type_get_name (gnutls_certificate_type_t type)
1947{
1948 const char *ret = NULL;
1949
1950 if (type == GNUTLS_CRT_X509)
1951 ret = "X.509";
1952 if (type == GNUTLS_CRT_OPENPGP)
1953 ret = "OPENPGP";
1954
1955 return ret;
1956}
1957
1958/**
1959 * gnutls_certificate_type_get_id - Returns the gnutls id of the specified in string type
1960 * @name: is a certificate type name
1961 *
1962 * The names are compared in a case insensitive way.
1963 *
1964 * Returns: an id of the specified in a string certificate type, or
1965 * %GNUTLS_CRT_UNKNOWN on error.
1966 **/
1967gnutls_certificate_type_t
1968gnutls_certificate_type_get_id (const char *name)
1969{
1970 gnutls_certificate_type_t ret = GNUTLS_CRT_UNKNOWN;
1971
1972 if (strcasecmp (name, "X.509") == 0 || strcasecmp (name, "X509") == 0)
1973 return GNUTLS_CRT_X509;
1974 if (strcasecmp (name, "OPENPGP") == 0)
1975 return GNUTLS_CRT_OPENPGP;
1976
1977 return ret;
1978}
1979
1980static const gnutls_certificate_type_t supported_certificate_types[] =
1981 { GNUTLS_CRT_X509,
1982 GNUTLS_CRT_OPENPGP,
1983 0
1984};
1985
1986/**
1987 * gnutls_certificate_type_list:
1988 *
1989 * Get a list of certificate types. Note that to be able to use
1990 * OpenPGP certificates, you must link to libgnutls-extra and call
1991 * gnutls_global_init_extra().
1992 *
1993 * Returns: a zero-terminated list of %gnutls_certificate_type_t
1994 * integers indicating the available certificate types.
1995 *
1996 **/
1997const gnutls_certificate_type_t *
1998gnutls_certificate_type_list (void)
1999{
2000 return supported_certificate_types;
2001}
2002
2003/* returns the gnutls_pk_algorithm_t which is compatible with
2004 * the given gnutls_kx_algorithm_t.
2005 */
2006gnutls_pk_algorithm_t
2007_gnutls_map_pk_get_pk (gnutls_kx_algorithm_t kx_algorithm)
2008{
2009 gnutls_pk_algorithm_t ret = -1;
2010
2011 GNUTLS_PK_MAP_ALG_LOOP (ret = p->pk_algorithm) return ret;
2012}
2013
2014/* Returns the encipher type for the given key exchange algorithm.
2015 * That one of CIPHER_ENCRYPT, CIPHER_SIGN, CIPHER_IGN.
2016 *
2017 * ex. GNUTLS_KX_RSA requires a certificate able to encrypt... so returns CIPHER_ENCRYPT.
2018 */
2019enum encipher_type
2020_gnutls_kx_encipher_type (gnutls_kx_algorithm_t kx_algorithm)
2021{
2022 int ret = CIPHER_IGN;
2023 GNUTLS_PK_MAP_ALG_LOOP (ret = p->encipher_type) return ret;
2024
2025}
2026
2027/* signature algorithms;
2028 */
2029struct gnutls_sign_entry
2030{
2031 const char *name;
2032 const char *oid;
2033 gnutls_sign_algorithm_t id;
2034 gnutls_pk_algorithm_t pk;
2035 gnutls_mac_algorithm_t mac;
2036};
2037typedef struct gnutls_sign_entry gnutls_sign_entry;
2038
2039static const gnutls_sign_entry sign_algorithms[] = {
2040 {"RSA-SHA",
2041 SIG_RSA_SHA1_OID,
2042 GNUTLS_SIGN_RSA_SHA1,
2043 GNUTLS_PK_RSA,
2044 GNUTLS_MAC_SHA1},
2045 {"RSA-SHA256",
2046 SIG_RSA_SHA256_OID,
2047 GNUTLS_SIGN_RSA_SHA256,
2048 GNUTLS_PK_RSA,
2049 GNUTLS_MAC_SHA256},
2050 {"RSA-MD5",
2051 SIG_RSA_MD5_OID,
2052 GNUTLS_SIGN_RSA_MD5,
2053 GNUTLS_PK_RSA,
2054 GNUTLS_MAC_MD5},
2055 {"GOST R 34.10-2001",
2056 SIG_GOST_R3410_2001_OID,
2057 0,
2058 0,
2059 0},
2060 {"GOST R 34.10-94",
2061 SIG_GOST_R3410_94_OID,
2062 0,
2063 0,
2064 0},
2065 {0,
2066 0,
2067 0,
2068 0,
2069 0}
2070};
2071
2072#define GNUTLS_SIGN_LOOP(b) \
2073 do { \
2074 const gnutls_sign_entry *p; \
2075 for(p = sign_algorithms; p->name != NULL; p++) { b ; } \
2076 } while (0)
2077
2078#define GNUTLS_SIGN_ALG_LOOP(a) \
2079 GNUTLS_SIGN_LOOP( if(p->id && p->id == sign) { a; break; } )
2080
2081/**
2082 * gnutls_sign_algorithm_get_name - Returns a string with the name of the specified sign algorithm
2083 * @algorithm: is a sign algorithm
2084 *
2085 * Returns: a string that contains the name of the specified sign
2086 * algorithm, or %NULL.
2087 **/
2088const char *
2089gnutls_sign_algorithm_get_name (gnutls_sign_algorithm_t sign)
2090{
2091 const char *ret = NULL;
2092
2093 /* avoid prefix */
2094 GNUTLS_SIGN_ALG_LOOP (ret = p->name);
2095
2096 return ret;
2097}
2098
2099gnutls_sign_algorithm_t
2100_gnutls_x509_oid2sign_algorithm (const char *oid)
2101{
2102 gnutls_sign_algorithm_t ret = 0;
2103
2104 GNUTLS_SIGN_LOOP (if (strcmp (oid, p->oid) == 0)
2105 {
2106 ret = p->id; break;}
2107 );
2108
2109 if (ret == 0)
2110 {
2111 _gnutls_x509_log ("Unknown SIGN OID: '%s'\n", oid);
2112 return GNUTLS_SIGN_UNKNOWN;
2113 }
2114 return ret;
2115}
2116
2117gnutls_sign_algorithm_t
2118_gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk, gnutls_mac_algorithm_t mac)
2119{
2120 gnutls_sign_algorithm_t ret = 0;
2121
2122 GNUTLS_SIGN_LOOP (if (pk == p->pk && mac == p->mac)
2123 {
2124 ret = p->id; break;}
2125 );
2126
2127 if (ret == 0)
2128 return GNUTLS_SIGN_UNKNOWN;
2129 return ret;
2130}
2131
2132const char *
2133_gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t pk,
2134 gnutls_mac_algorithm_t mac)
2135{
2136 gnutls_sign_algorithm_t sign;
2137 const char *ret = NULL;
2138
2139 sign = _gnutls_x509_pk_to_sign (pk, mac);
2140 if (sign == GNUTLS_SIGN_UNKNOWN)
2141 return NULL;
2142
2143 GNUTLS_SIGN_ALG_LOOP (ret = p->oid);
2144 return ret;
2145}
2146
2147/* pk algorithms;
2148 */
2149struct gnutls_pk_entry
2150{
2151 const char *name;
2152 const char *oid;
2153 gnutls_pk_algorithm_t id;
2154};
2155typedef struct gnutls_pk_entry gnutls_pk_entry;
2156
2157static const gnutls_pk_entry pk_algorithms[] = {
2158 {"RSA",
2159 PK_PKIX1_RSA_OID,
2160 GNUTLS_PK_RSA},
2161 {"GOST R 34.10-2001",
2162 PK_GOST_R3410_2001_OID,
2163 0},
2164 {"GOST R 34.10-94",
2165 PK_GOST_R3410_94_OID,
2166 0},
2167 {0,
2168 0,
2169 0}
2170};
2171
2172/**
2173 * gnutls_pk_algorithm_get_name - Returns a string with the name of the specified public key algorithm
2174 * @algorithm: is a pk algorithm
2175 *
2176 * Returns: a string that contains the name of the specified public
2177 * key algorithm, or %NULL.
2178 **/
2179const char *
2180gnutls_pk_algorithm_get_name (gnutls_pk_algorithm_t algorithm)
2181{
2182 const char *ret = NULL;
2183 const gnutls_pk_entry *p;
2184
2185 for (p = pk_algorithms; p->name != NULL; p++)
2186 if (p->id && p->id == algorithm)
2187 {
2188 ret = p->name;
2189 break;
2190 }
2191
2192 return ret;
2193}
2194
2195gnutls_pk_algorithm_t
2196_gnutls_x509_oid2pk_algorithm (const char *oid)
2197{
2198 gnutls_pk_algorithm_t ret = GNUTLS_PK_UNKNOWN;
2199 const gnutls_pk_entry *p;
2200
2201 for (p = pk_algorithms; p->name != NULL; p++)
2202 if (strcmp (p->oid, oid) == 0)
2203 {
2204 ret = p->id;
2205 break;
2206 }
2207
2208 return ret;
2209}
2210
2211const char *
2212_gnutls_x509_pk_to_oid (gnutls_pk_algorithm_t algorithm)
2213{
2214 const char *ret = NULL;
2215 const gnutls_pk_entry *p;
2216
2217 for (p = pk_algorithms; p->name != NULL; p++)
2218 if (p->id == algorithm)
2219 {
2220 ret = p->oid;
2221 break;
2222 }
2223
2224 return ret;
2225}
diff --git a/src/daemon/https/tls/gnutls_algorithms.h b/src/daemon/https/tls/gnutls_algorithms.h
new file mode 100644
index 00000000..fd23ef0a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_algorithms.h
@@ -0,0 +1,141 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef ALGORITHMS_H
26# define ALGORITHMS_H
27
28#include "gnutls_auth.h"
29
30/* Functions for version handling. */
31gnutls_protocol_t _gnutls_version_lowest (gnutls_session_t session);
32gnutls_protocol_t _gnutls_version_max (gnutls_session_t session);
33int _gnutls_version_priority (gnutls_session_t session,
34 gnutls_protocol_t version);
35int _gnutls_version_is_supported (gnutls_session_t session,
36 const gnutls_protocol_t version);
37int _gnutls_version_get_major (gnutls_protocol_t ver);
38int _gnutls_version_get_minor (gnutls_protocol_t ver);
39gnutls_protocol_t _gnutls_version_get (int major, int minor);
40
41/* Functions for MACs. */
42int _gnutls_mac_is_ok (gnutls_mac_algorithm_t algorithm);
43gnutls_mac_algorithm_t _gnutls_x509_oid2mac_algorithm (const char *oid);
44const char *_gnutls_x509_mac_to_oid (gnutls_mac_algorithm_t mac);
45
46/* Functions for cipher suites. */
47int _gnutls_supported_ciphersuites (gnutls_session_t session,
48 cipher_suite_st ** ciphers);
49int _gnutls_supported_ciphersuites_sorted (gnutls_session_t session,
50 cipher_suite_st ** ciphers);
51int _gnutls_supported_compression_methods (gnutls_session_t session,
52 uint8_t ** comp);
53const char *_gnutls_cipher_suite_get_name (cipher_suite_st * algorithm);
54gnutls_cipher_algorithm_t _gnutls_cipher_suite_get_cipher_algo (const
55 cipher_suite_st
56 * algorithm);
57gnutls_kx_algorithm_t _gnutls_cipher_suite_get_kx_algo (const cipher_suite_st
58 * algorithm);
59gnutls_mac_algorithm_t _gnutls_cipher_suite_get_mac_algo (const
60 cipher_suite_st *
61 algorithm);
62gnutls_protocol_t _gnutls_cipher_suite_get_version (const cipher_suite_st *
63 algorithm);
64cipher_suite_st _gnutls_cipher_suite_get_suite_name (cipher_suite_st *
65 algorithm);
66
67/* Functions for ciphers. */
68int _gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm);
69int _gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm);
70int _gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm);
71int _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm);
72int _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm);
73
74/* Functions for key exchange. */
75int _gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm);
76int _gnutls_kx_needs_rsa_params (gnutls_kx_algorithm_t algorithm);
77mod_auth_st *_gnutls_kx_auth_struct (gnutls_kx_algorithm_t algorithm);
78int _gnutls_kx_is_ok (gnutls_kx_algorithm_t algorithm);
79
80/* Functions for compression. */
81int _gnutls_compression_is_ok (gnutls_compression_method_t algorithm);
82int _gnutls_compression_get_num (gnutls_compression_method_t algorithm);
83gnutls_compression_method_t _gnutls_compression_get_id (int num);
84int _gnutls_compression_get_mem_level (gnutls_compression_method_t algorithm);
85int _gnutls_compression_get_comp_level (gnutls_compression_method_t
86 algorithm);
87int _gnutls_compression_get_wbits (gnutls_compression_method_t algorithm);
88
89/* Type to KX mappings. */
90gnutls_kx_algorithm_t _gnutls_map_kx_get_kx (gnutls_credentials_type_t type,
91 int server);
92gnutls_credentials_type_t _gnutls_map_kx_get_cred (gnutls_kx_algorithm_t
93 algorithm, int server);
94
95/* KX to PK mapping. */
96gnutls_pk_algorithm_t _gnutls_map_pk_get_pk (gnutls_kx_algorithm_t
97 kx_algorithm);
98gnutls_pk_algorithm_t _gnutls_x509_oid2pk_algorithm (const char *oid);
99const char *_gnutls_x509_pk_to_oid (gnutls_pk_algorithm_t pk);
100
101enum encipher_type
102{ CIPHER_ENCRYPT = 0, CIPHER_SIGN = 1, CIPHER_IGN };
103
104enum encipher_type _gnutls_kx_encipher_type (gnutls_kx_algorithm_t algorithm);
105
106struct gnutls_compression_entry
107{
108 const char *name;
109 gnutls_compression_method_t id;
110 int num; /* the number reserved in TLS for the specific compression method */
111
112 /* used in zlib compressor */
113 int window_bits;
114 int mem_level;
115 int comp_level;
116};
117typedef struct gnutls_compression_entry gnutls_compression_entry;
118
119/* Functions for sign algorithms. */
120gnutls_sign_algorithm_t _gnutls_x509_oid2sign_algorithm (const char *oid);
121gnutls_sign_algorithm_t _gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk,
122 gnutls_mac_algorithm_t mac);
123const char *_gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t,
124 gnutls_mac_algorithm_t mac);
125
126int _gnutls_mac_priority (gnutls_session_t session,
127 gnutls_mac_algorithm_t algorithm);
128int _gnutls_cipher_priority (gnutls_session_t session,
129 gnutls_cipher_algorithm_t algorithm);
130int _gnutls_kx_priority (gnutls_session_t session,
131 gnutls_kx_algorithm_t algorithm);
132int _gnutls_compression_priority (gnutls_session_t session,
133 gnutls_compression_method_t algorithm);
134
135gnutls_mac_algorithm_t gnutls_mac_get_id (const char* name);
136gnutls_cipher_algorithm_t gnutls_cipher_get_id (const char* name);
137gnutls_kx_algorithm_t gnutls_kx_get_id (const char* name);
138gnutls_protocol_t gnutls_protocol_get_id (const char* name);
139gnutls_certificate_type_t gnutls_certificate_type_get_id (const char* name);
140
141#endif
diff --git a/src/daemon/https/tls/gnutls_anon_cred.c b/src/daemon/https/tls/gnutls_anon_cred.c
new file mode 100644
index 00000000..919315ef
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_anon_cred.c
@@ -0,0 +1,137 @@
1/*
2 * Copyright (C) 2001, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include "gnutls_int.h"
26
27#ifdef ENABLE_ANON
28
29#include "gnutls_errors.h"
30#include "auth_anon.h"
31#include "gnutls_auth_int.h"
32#include "gnutls_dh.h"
33#include "gnutls_num.h"
34#include "gnutls_mpi.h"
35
36static const int anon_dummy;
37
38/**
39 * gnutls_anon_free_server_credentials - Used to free an allocated gnutls_anon_server_credentials_t structure
40 * @sc: is an #gnutls_anon_server_credentials_t structure.
41 *
42 * This structure is complex enough to manipulate directly thus this
43 * helper function is provided in order to free (deallocate) it.
44 **/
45void
46gnutls_anon_free_server_credentials (gnutls_anon_server_credentials_t sc)
47{
48
49 gnutls_free (sc);
50}
51
52/**
53 * gnutls_anon_allocate_server_credentials - Used to allocate an gnutls_anon_server_credentials_t structure
54 * @sc: is a pointer to an #gnutls_anon_server_credentials_t structure.
55 *
56 * This structure is complex enough to manipulate directly thus this
57 * helper function is provided in order to allocate it.
58 *
59 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
60 **/
61int
62gnutls_anon_allocate_server_credentials (gnutls_anon_server_credentials_t *
63 sc)
64{
65
66 *sc = gnutls_calloc (1, sizeof (anon_server_credentials_st));
67
68 return 0;
69}
70
71
72/**
73 * gnutls_anon_free_client_credentials - Used to free an allocated gnutls_anon_client_credentials_t structure
74 * @sc: is an #gnutls_anon_client_credentials_t structure.
75 *
76 * This structure is complex enough to manipulate directly thus this
77 * helper function is provided in order to free (deallocate) it.
78 **/
79void
80gnutls_anon_free_client_credentials (gnutls_anon_client_credentials_t sc)
81{
82}
83
84/**
85 * gnutls_anon_allocate_client_credentials - Used to allocate a credentials structure
86 * @sc: is a pointer to an #gnutls_anon_client_credentials_t structure.
87 *
88 * This structure is complex enough to manipulate directly thus
89 * this helper function is provided in order to allocate it.
90 *
91 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
92 **/
93int
94gnutls_anon_allocate_client_credentials (gnutls_anon_client_credentials_t *
95 sc)
96{
97 /* anon_dummy is only there for *sc not to be null.
98 * it is not used at all;
99 */
100 *sc = (void *) &anon_dummy;
101
102 return 0;
103}
104
105/**
106 * gnutls_anon_set_server_dh_params - This function will set the DH parameters for a server to use
107 * @res: is a gnutls_anon_server_credentials_t structure
108 * @dh_params: is a structure that holds diffie hellman parameters.
109 *
110 * This function will set the diffie hellman parameters for an
111 * anonymous server to use. These parameters will be used in
112 * Anonymous Diffie Hellman cipher suites.
113 **/
114void
115gnutls_anon_set_server_dh_params (gnutls_anon_server_credentials_t res,
116 gnutls_dh_params_t dh_params)
117{
118 res->dh_params = dh_params;
119}
120
121/**
122 * gnutls_anon_set_server_params_function - This function will set the DH parameters callback
123 * @res: is a gnutls_certificate_credentials_t structure
124 * @func: is the function to be called
125 *
126 * This function will set a callback in order for the server to get
127 * the diffie hellman parameters for anonymous authentication. The
128 * callback should return zero on success.
129 **/
130void
131gnutls_anon_set_server_params_function (gnutls_anon_server_credentials_t res,
132 gnutls_params_function * func)
133{
134 res->params_func = func;
135}
136
137#endif
diff --git a/src/daemon/https/tls/gnutls_asn1_tab.c b/src/daemon/https/tls/gnutls_asn1_tab.c
new file mode 100644
index 00000000..cabea4e1
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_asn1_tab.c
@@ -0,0 +1,63 @@
1#if HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <libtasn1.h>
6
7extern const ASN1_ARRAY_TYPE gnutls_asn1_tab[] = {
8 {"GNUTLS", 536872976, 0},
9 {0, 1073741836, 0},
10 {"RSAPublicKey", 1610612741, 0},
11 {"modulus", 1073741827, 0},
12 {"publicExponent", 3, 0},
13 {"RSAPrivateKey", 1610612741, 0},
14 {"version", 1073741826, "Version"},
15 {"modulus", 1073741827, 0},
16 {"publicExponent", 1073741827, 0},
17 {"privateExponent", 1073741827, 0},
18 {"prime1", 1073741827, 0},
19 {"prime2", 1073741827, 0},
20 {"exponent1", 1073741827, 0},
21 {"exponent2", 1073741827, 0},
22 {"coefficient", 1073741827, 0},
23 {"otherPrimeInfos", 16386, "OtherPrimeInfos"},
24 {"Version", 1610874883, 0},
25 {"two-prime", 1073741825, "0"},
26 {"multi", 1, "1"},
27 {"OtherPrimeInfos", 1612709899, 0},
28 {"MAX", 1074266122, "1"},
29 {0, 2, "OtherPrimeInfo"},
30 {"OtherPrimeInfo", 1610612741, 0},
31 {"prime", 1073741827, 0},
32 {"exponent", 1073741827, 0},
33 {"coefficient", 3, 0},
34 {"AlgorithmIdentifier", 1610612741, 0},
35 {"algorithm", 1073741836, 0},
36 {"parameters", 541081613, 0},
37 {"algorithm", 1, 0},
38 {"DigestInfo", 1610612741, 0},
39 {"digestAlgorithm", 1073741826, "DigestAlgorithmIdentifier"},
40 {"digest", 2, "Digest"},
41 {"DigestAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
42 {"Digest", 1073741831, 0},
43 {"DSAPublicKey", 1073741827, 0},
44 {"DSAParameters", 1610612741, 0},
45 {"p", 1073741827, 0},
46 {"q", 1073741827, 0},
47 {"g", 3, 0},
48 {"DSASignatureValue", 1610612741, 0},
49 {"r", 1073741827, 0},
50 {"s", 3, 0},
51 {"DSAPrivateKey", 1610612741, 0},
52 {"version", 1073741827, 0},
53 {"p", 1073741827, 0},
54 {"q", 1073741827, 0},
55 {"g", 1073741827, 0},
56 {"Y", 1073741827, 0},
57 {"priv", 3, 0},
58 {"DHParameter", 536870917, 0},
59 {"prime", 1073741827, 0},
60 {"base", 1073741827, 0},
61 {"privateValueLength", 16387, 0},
62 {0, 0, 0}
63};
diff --git a/src/daemon/https/tls/gnutls_auth.c b/src/daemon/https/tls/gnutls_auth.c
new file mode 100644
index 00000000..89640402
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_auth.c
@@ -0,0 +1,413 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include "gnutls_int.h"
26#include "gnutls_errors.h"
27#include "gnutls_auth.h"
28#include "gnutls_auth_int.h"
29#include "gnutls_algorithms.h"
30#include "auth_cert.h"
31#include <gnutls_datum.h>
32
33#include "auth_anon.h"
34/* The functions here are used in order for authentication algorithms
35 * to be able to retrieve the needed credentials eg public and private
36 * key etc.
37 */
38
39/**
40 * gnutls_credentials_clear - Clears all the credentials previously set
41 * @session: is a #gnutls_session_t structure.
42 *
43 * Clears all the credentials previously set in this session.
44 *
45 **/
46void
47gnutls_credentials_clear (gnutls_session_t session)
48{
49 if (session->key && session->key->cred)
50 { /* beginning of the list */
51 auth_cred_st *ccred, *ncred;
52 ccred = session->key->cred;
53 while (ccred != NULL)
54 {
55 ncred = ccred->next;
56 gnutls_free (ccred);
57 ccred = ncred;
58 }
59 session->key->cred = NULL;
60 }
61}
62
63/*
64 * This creates a linked list of the form:
65 * { algorithm, credentials, pointer to next }
66 */
67/**
68 * gnutls_credentials_set - Sets the needed credentials for the specified authentication algorithm.
69 * @session: is a #gnutls_session_t structure.
70 * @type: is the type of the credentials
71 * @cred: is a pointer to a structure.
72 *
73 * Sets the needed credentials for the specified type.
74 * Eg username, password - or public and private keys etc.
75 * The (void* cred) parameter is a structure that depends on the
76 * specified type and on the current session (client or server).
77 * [ In order to minimize memory usage, and share credentials between
78 * several threads gnutls keeps a pointer to cred, and not the whole cred
79 * structure. Thus you will have to keep the structure allocated until
80 * you call gnutls_deinit(). ]
81 *
82 * For GNUTLS_CRD_ANON cred should be gnutls_anon_client_credentials_t in case of a client.
83 * In case of a server it should be gnutls_anon_server_credentials_t.
84 *
85 * For GNUTLS_CRD_SRP cred should be gnutls_srp_client_credentials_t
86 * in case of a client, and gnutls_srp_server_credentials_t, in case
87 * of a server.
88 *
89 * For GNUTLS_CRD_CERTIFICATE cred should be gnutls_certificate_credentials_t.
90 *
91 **/
92int
93gnutls_credentials_set (gnutls_session_t session,
94 gnutls_credentials_type_t type, void *cred)
95{
96 auth_cred_st *ccred = NULL, *pcred = NULL;
97 int exists = 0;
98
99 if (session->key->cred == NULL)
100 { /* beginning of the list */
101
102 session->key->cred = gnutls_malloc (sizeof (auth_cred_st));
103 if (session->key->cred == NULL)
104 return GNUTLS_E_MEMORY_ERROR;
105
106 /* copy credentials locally */
107 session->key->cred->credentials = cred;
108
109 session->key->cred->next = NULL;
110 session->key->cred->algorithm = type;
111 }
112 else
113 {
114 ccred = session->key->cred;
115 while (ccred != NULL)
116 {
117 if (ccred->algorithm == type)
118 {
119 exists = 1;
120 break;
121 }
122 pcred = ccred;
123 ccred = ccred->next;
124 }
125 /* After this, pcred is not null.
126 */
127
128 if (exists == 0)
129 { /* new entry */
130 pcred->next = gnutls_malloc (sizeof (auth_cred_st));
131 if (pcred->next == NULL)
132 return GNUTLS_E_MEMORY_ERROR;
133
134 ccred = pcred->next;
135
136 /* copy credentials locally */
137 ccred->credentials = cred;
138
139 ccred->next = NULL;
140 ccred->algorithm = type;
141 }
142 else
143 { /* modify existing entry */
144 gnutls_free (ccred->credentials);
145 ccred->credentials = cred;
146 }
147 }
148
149 return 0;
150}
151
152/**
153 * gnutls_auth_get_type - Returns the type of credentials for the current authentication schema.
154 * @session: is a #gnutls_session_t structure.
155 *
156 * Returns type of credentials for the current authentication schema.
157 * The returned information is to be used to distinguish the function used
158 * to access authentication data.
159 *
160 * Eg. for CERTIFICATE ciphersuites (key exchange algorithms: KX_RSA, KX_DHE_RSA),
161 * the same function are to be used to access the authentication data.
162 **/
163gnutls_credentials_type_t
164gnutls_auth_get_type (gnutls_session_t session)
165{
166/* This is not the credentials we must set, but the authentication data
167 * we get by the peer, so it should be reversed.
168 */
169 int server = session->security_parameters.entity == GNUTLS_SERVER ? 0 : 1;
170
171 return
172 _gnutls_map_kx_get_cred (_gnutls_cipher_suite_get_kx_algo
173 (&session->security_parameters.
174 current_cipher_suite), server);
175}
176
177/**
178 * gnutls_auth_server_get_type - Returns the type of credentials for the server authentication schema.
179 * @session: is a #gnutls_session_t structure.
180 *
181 * Returns the type of credentials that were used for server authentication.
182 * The returned information is to be used to distinguish the function used
183 * to access authentication data.
184 *
185 **/
186gnutls_credentials_type_t
187gnutls_auth_server_get_type (gnutls_session_t session)
188{
189 return
190 _gnutls_map_kx_get_cred (_gnutls_cipher_suite_get_kx_algo
191 (&session->security_parameters.
192 current_cipher_suite), 1);
193}
194
195/**
196 * gnutls_auth_client_get_type - Returns the type of credentials for the client authentication schema.
197 * @session: is a #gnutls_session_t structure.
198 *
199 * Returns the type of credentials that were used for client authentication.
200 * The returned information is to be used to distinguish the function used
201 * to access authentication data.
202 *
203 **/
204gnutls_credentials_type_t
205gnutls_auth_client_get_type (gnutls_session_t session)
206{
207 return
208 _gnutls_map_kx_get_cred (_gnutls_cipher_suite_get_kx_algo
209 (&session->security_parameters.
210 current_cipher_suite), 0);
211}
212
213
214/*
215 * This returns a pointer to the linked list. Don't
216 * free that!!!
217 */
218const void *
219_gnutls_get_kx_cred (gnutls_session_t session,
220 gnutls_kx_algorithm_t algo, int *err)
221{
222 int server = session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
223
224 return _gnutls_get_cred (session->key,
225 _gnutls_map_kx_get_cred (algo, server), err);
226}
227
228const void *
229_gnutls_get_cred (gnutls_key_st key, gnutls_credentials_type_t type, int *err)
230{
231 const void *retval = NULL;
232 int _err = -1;
233 auth_cred_st *ccred;
234
235 if (key == NULL)
236 goto out;
237
238 ccred = key->cred;
239 while (ccred != NULL)
240 {
241 if (ccred->algorithm == type)
242 {
243 break;
244 }
245 ccred = ccred->next;
246 }
247 if (ccred == NULL)
248 goto out;
249
250 _err = 0;
251 retval = ccred->credentials;
252
253out:
254 if (err != NULL)
255 *err = _err;
256 return retval;
257}
258
259/*-
260 * _gnutls_get_auth_info - Returns a pointer to authentication information.
261 * @session: is a #gnutls_session_t structure.
262 *
263 * This function must be called after a succesful gnutls_handshake().
264 * Returns a pointer to authentication information. That information
265 * is data obtained by the handshake protocol, the key exchange algorithm,
266 * and the TLS extensions messages.
267 *
268 * In case of GNUTLS_CRD_ANON returns a type of &anon_(server/client)_auth_info_t;
269 * In case of GNUTLS_CRD_CERTIFICATE returns a type of &cert_auth_info_t;
270 * In case of GNUTLS_CRD_SRP returns a type of &srp_(server/client)_auth_info_t;
271 -*/
272void *
273_gnutls_get_auth_info (gnutls_session_t session)
274{
275 return session->key->auth_info;
276}
277
278/*-
279 * _gnutls_free_auth_info - Frees the auth info structure
280 * @session: is a #gnutls_session_t structure.
281 *
282 * This function frees the auth info structure and sets it to
283 * null. It must be called since some structures contain malloced
284 * elements.
285 -*/
286void
287_gnutls_free_auth_info (gnutls_session_t session)
288{
289 dh_info_st *dh_info;
290 rsa_info_st *rsa_info;
291
292 if (session == NULL || session->key == NULL)
293 {
294 gnutls_assert ();
295 return;
296 }
297
298 switch (session->key->auth_info_type)
299 {
300 case GNUTLS_CRD_SRP:
301 break;
302 case GNUTLS_CRD_ANON:
303 {
304 anon_auth_info_t info = _gnutls_get_auth_info (session);
305
306 if (info == NULL)
307 break;
308
309 dh_info = &info->dh;
310 _gnutls_free_dh_info (dh_info);
311 }
312 break;
313 case GNUTLS_CRD_CERTIFICATE:
314 {
315 unsigned int i;
316 cert_auth_info_t info = _gnutls_get_auth_info (session);
317
318 if (info == NULL)
319 break;
320
321 dh_info = &info->dh;
322 rsa_info = &info->rsa_export;
323 for (i = 0; i < info->ncerts; i++)
324 {
325 _gnutls_free_datum (&info->raw_certificate_list[i]);
326 }
327
328 gnutls_free (info->raw_certificate_list);
329 info->raw_certificate_list = NULL;
330 info->ncerts = 0;
331
332 _gnutls_free_dh_info (dh_info);
333 _gnutls_free_rsa_info (rsa_info);
334 }
335
336
337 break;
338 default:
339 return;
340
341 }
342
343 gnutls_free (session->key->auth_info);
344 session->key->auth_info = NULL;
345 session->key->auth_info_size = 0;
346 session->key->auth_info_type = 0;
347
348}
349
350/* This function will set the auth info structure in the key
351 * structure.
352 * If allow change is !=0 then this will allow changing the auth
353 * info structure to a different type.
354 */
355int
356_gnutls_auth_info_set (gnutls_session_t session,
357 gnutls_credentials_type_t type, int size,
358 int allow_change)
359{
360 if (session->key->auth_info == NULL)
361 {
362 session->key->auth_info = gnutls_calloc (1, size);
363 if (session->key->auth_info == NULL)
364 {
365 gnutls_assert ();
366 return GNUTLS_E_MEMORY_ERROR;
367 }
368 session->key->auth_info_type = type;
369 session->key->auth_info_size = size;
370 }
371 else
372 {
373 if (allow_change == 0)
374 {
375 /* If the credentials for the current authentication scheme,
376 * are not the one we want to set, then it's an error.
377 * This may happen if a rehandshake is performed an the
378 * ciphersuite which is negotiated has different authentication
379 * schema.
380 */
381 if (gnutls_auth_get_type (session) != session->key->auth_info_type)
382 {
383 gnutls_assert ();
384 return GNUTLS_E_INVALID_REQUEST;
385 }
386 }
387 else
388 {
389 /* The new behaviour: Here we reallocate the auth info structure
390 * in order to be able to negotiate different authentication
391 * types. Ie. perform an auth_anon and then authenticate again using a
392 * certificate (in order to prevent revealing the certificate's contents,
393 * to passive eavesdropers.
394 */
395 if (gnutls_auth_get_type (session) != session->key->auth_info_type)
396 {
397
398 _gnutls_free_auth_info (session);
399
400 session->key->auth_info = calloc (1, size);
401 if (session->key->auth_info == NULL)
402 {
403 gnutls_assert ();
404 return GNUTLS_E_MEMORY_ERROR;
405 }
406
407 session->key->auth_info_type = type;
408 session->key->auth_info_size = size;
409 }
410 }
411 }
412 return 0;
413}
diff --git a/src/daemon/https/tls/gnutls_auth.h b/src/daemon/https/tls/gnutls_auth.h
new file mode 100644
index 00000000..07d81352
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_auth.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_AUTH_H
26# define GNUTLS_AUTH_H
27
28typedef struct mod_auth_st_int
29{
30 const char *name; /* null terminated */
31 int (*gnutls_generate_server_certificate) (gnutls_session_t, opaque **);
32 int (*gnutls_generate_client_certificate) (gnutls_session_t, opaque **);
33 int (*gnutls_generate_server_kx) (gnutls_session_t, opaque **);
34 int (*gnutls_generate_client_kx) (gnutls_session_t, opaque **); /* used in SRP */
35 int (*gnutls_generate_client_cert_vrfy) (gnutls_session_t, opaque **);
36 int (*gnutls_generate_server_certificate_request) (gnutls_session_t,
37 opaque **);
38
39 int (*gnutls_process_server_certificate) (gnutls_session_t, opaque *,
40 size_t);
41 int (*gnutls_process_client_certificate) (gnutls_session_t, opaque *,
42 size_t);
43 int (*gnutls_process_server_kx) (gnutls_session_t, opaque *, size_t);
44 int (*gnutls_process_client_kx) (gnutls_session_t, opaque *, size_t);
45 int (*gnutls_process_client_cert_vrfy) (gnutls_session_t, opaque *, size_t);
46 int (*gnutls_process_server_certificate_request) (gnutls_session_t,
47 opaque *, size_t);
48} mod_auth_st;
49
50#endif
diff --git a/src/daemon/https/tls/gnutls_auth_int.h b/src/daemon/https/tls/gnutls_auth_int.h
new file mode 100644
index 00000000..85fe53a1
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_auth_int.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25const void *_gnutls_get_cred (gnutls_key_st key,
26 gnutls_credentials_type_t kx, int *err);
27const void *_gnutls_get_kx_cred (gnutls_session_t session,
28 gnutls_kx_algorithm_t algo, int *err);
29void *_gnutls_get_auth_info (gnutls_session_t session);
30int _gnutls_auth_info_set (gnutls_session_t session,
31 gnutls_credentials_type_t type, int size,
32 int allow_change);
diff --git a/src/daemon/https/tls/gnutls_buffer.h b/src/daemon/https/tls/gnutls_buffer.h
new file mode 100644
index 00000000..5c552a7a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_buffer.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_str.h>
26
27typedef gnutls_string gnutls_buffer;
28
29#define _gnutls_buffer_init(buf) _gnutls_string_init(buf, gnutls_malloc, gnutls_realloc, gnutls_free);
30#define _gnutls_buffer_clear _gnutls_string_clear
31#define _gnutls_buffer_append _gnutls_string_append_data
diff --git a/src/daemon/https/tls/gnutls_buffers.c b/src/daemon/https/tls/gnutls_buffers.c
new file mode 100644
index 00000000..5a272dca
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_buffers.c
@@ -0,0 +1,1241 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This is the only file that uses the berkeley sockets API.
26 *
27 * Also holds all the buffering code used in gnutls.
28 * The buffering code works as:
29 *
30 * RECORD LAYER:
31 * 1. uses a buffer to hold data (application/handshake),
32 * we got but they were not requested, yet.
33 * (see gnutls_record_buffer_put(), gnutls_record_buffer_get_size() etc.)
34 *
35 * 2. uses a buffer to hold data that were incomplete (ie the read/write
36 * was interrupted)
37 * (see _gnutls_io_read_buffered(), _gnutls_io_write_buffered() etc.)
38 *
39 * HANDSHAKE LAYER:
40 * 1. Uses a buffer to hold data that was not sent or received
41 * complete. (E.g. sent 10 bytes of a handshake packet that is 20 bytes
42 * long).
43 * (see _gnutls_handshake_send_int(), _gnutls_handshake_recv_int())
44 *
45 * 2. Uses buffer to hold the last received handshake message.
46 * (see _gnutls_handshake_buffer_put() etc.)
47 *
48 */
49
50#include <gnutls_int.h>
51#include <gnutls_errors.h>
52#include <gnutls_num.h>
53#include <gnutls_record.h>
54#include <gnutls_buffers.h>
55
56#include <errno.h>
57
58#ifdef _WIN32
59# include <winsock2.h>
60#endif
61
62#ifndef EAGAIN
63# define EAGAIN EWOULDBLOCK
64#endif
65
66#ifdef IO_DEBUG
67# include <io_debug.h>
68#endif
69
70/**
71 * gnutls_transport_set_errno:
72 * @session: is a #gnutls_session_t structure.
73 * @err: error value to store in session-specific errno variable.
74 *
75 * Store @err in the session-specific errno variable. Useful values
76 * for @err is EAGAIN and EINTR, other values are treated will be
77 * treated as real errors in the push/pull function.
78 *
79 * This function is useful in replacement push/pull functions set by
80 * gnutls_transport_set_push_function and
81 * gnutls_transport_set_pullpush_function under Windows, where the
82 * replacement push/pull may not have access to the same @errno
83 * variable that is used by GnuTLS (e.g., the application is linked to
84 * msvcr71.dll and gnutls is linked to msvcrt.dll).
85 *
86 * If you don't have the @session variable easily accessible from the
87 * push/pull function, and don't worry about thread conflicts, you can
88 * also use gnutls_transport_set_global_errno().
89 **/
90void gnutls_transport_set_errno(gnutls_session_t session,
91 int err)
92{
93 session->internals.errnum = err;
94}
95
96/**
97 * gnutls_transport_set_global_errno:
98 * @err: error value to store in global errno variable.
99 *
100 * Store @err in the global errno variable. Useful values for @err is
101 * EAGAIN and EINTR, other values are treated will be treated as real
102 * errors in the push/pull function.
103 *
104 * This function is useful in replacement push/pull functions set by
105 * gnutls_transport_set_push_function and
106 * gnutls_transport_set_pullpush_function under Windows, where the
107 * replacement push/pull may not have access to the same @errno
108 * variable that is used by GnuTLS (e.g., the application is linked to
109 * msvcr71.dll and gnutls is linked to msvcrt.dll).
110 *
111 * Whether this function is thread safe or not depends on whether the
112 * global variable errno is thread safe, some system libraries make it
113 * a thread-local variable. When feasible, using the guaranteed
114 * thread-safe gnutls_transport_set_errno() may be better.
115 **/
116void gnutls_transport_set_global_errno(int err)
117{
118 errno = err;
119}
120
121/* Buffers received packets of type APPLICATION DATA and
122 * HANDSHAKE DATA.
123 */
124int _gnutls_record_buffer_put(content_type_t type,
125 gnutls_session_t session,
126 opaque * data,
127 size_t length)
128{
129 gnutls_buffer *buf;
130
131 if (length == 0)
132 return 0;
133
134 switch (type)
135 {
136 case GNUTLS_APPLICATION_DATA:
137 buf = &session->internals.application_data_buffer;
138 _gnutls_buffers_log ("BUF[REC]: Inserted %d bytes of Data(%d)\n",
139 length, type);
140 break;
141
142 case GNUTLS_HANDSHAKE:
143 buf = &session->internals.handshake_data_buffer;
144 _gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data(%d)\n",
145 length, type);
146 break;
147
148 case GNUTLS_INNER_APPLICATION:
149 buf = &session->internals.ia_data_buffer;
150 _gnutls_buffers_log ("BUF[IA]: Inserted %d bytes of Data(%d)\n", length,
151 type);
152 break;
153
154 default:
155 gnutls_assert ()
156 ;
157 return GNUTLS_E_INVALID_REQUEST;
158 }
159
160 if (_gnutls_buffer_append (buf, data, length) < 0)
161 {
162 gnutls_assert ();
163 return GNUTLS_E_MEMORY_ERROR;
164 }
165
166 return 0;
167}
168
169int _gnutls_record_buffer_get_size(content_type_t type,
170 gnutls_session_t session)
171{
172 switch (type)
173 {
174 case GNUTLS_APPLICATION_DATA:
175 return session->internals.application_data_buffer.length;
176
177 case GNUTLS_HANDSHAKE:
178 return session->internals.handshake_data_buffer.length;
179
180 case GNUTLS_INNER_APPLICATION:
181 return session->internals.ia_data_buffer.length;
182
183 default:
184 return GNUTLS_E_INVALID_REQUEST;
185 }
186}
187
188/**
189 * gnutls_record_check_pending - checks if there are any data to receive in gnutls buffers.
190 * @session: is a #gnutls_session_t structure.
191 *
192 * This function checks if there are any data to receive
193 * in the gnutls buffers. Returns the size of that data or 0.
194 * Notice that you may also use select() to check for data in
195 * a TCP connection, instead of this function.
196 * (gnutls leaves some data in the tcp buffer in order for select
197 * to work).
198 **/
199size_t gnutls_record_check_pending(gnutls_session_t session)
200{
201 return _gnutls_record_buffer_get_size(GNUTLS_APPLICATION_DATA, session);
202}
203
204int _gnutls_record_buffer_get(content_type_t type,
205 gnutls_session_t session,
206 opaque * data,
207 size_t length)
208{
209 if (length == 0 || data == NULL)
210 {
211 gnutls_assert ();
212 return GNUTLS_E_INVALID_REQUEST;
213 }
214
215 switch (type)
216 {
217 case GNUTLS_APPLICATION_DATA:
218
219 if (length > session->internals.application_data_buffer.length)
220 {
221 length = session->internals.application_data_buffer.length;
222 }
223
224 _gnutls_buffers_log ("BUFFER[REC][AD]: Read %d bytes of Data(%d)\n",
225 length, type);
226
227 session->internals.application_data_buffer.length -= length;
228 memcpy(data, session->internals.application_data_buffer.data, length);
229
230 /* overwrite buffer */
231 memmove(session->internals.application_data_buffer.data,
232 &session->internals.application_data_buffer.data[length],
233 session->internals.application_data_buffer.length);
234
235 /* we do no longer realloc the application_data_buffer.data,
236 * since it serves no practical reason. It also decreases
237 * performance.
238 */
239 break;
240
241 case GNUTLS_HANDSHAKE:
242 if (length > session->internals.handshake_data_buffer.length)
243 {
244 length = session->internals.handshake_data_buffer.length;
245 }
246
247 _gnutls_buffers_log ("BUF[REC][HD]: Read %d bytes of Data(%d)\n",
248 length, type);
249
250 session->internals.handshake_data_buffer.length -= length;
251 memcpy(data, session->internals.handshake_data_buffer.data, length);
252
253 /* overwrite buffer */
254 memmove(session->internals.handshake_data_buffer.data,
255 &session->internals.handshake_data_buffer.data[length],
256 session->internals.handshake_data_buffer.length);
257
258 break;
259
260 case GNUTLS_INNER_APPLICATION:
261 if (length > session->internals.ia_data_buffer.length)
262 length = session->internals.ia_data_buffer.length;
263
264 _gnutls_buffers_log ("BUF[REC][IA]: Read %d bytes of Data(%d)\n",
265 length, type);
266
267 session->internals.ia_data_buffer.length -= length;
268 memcpy(data, session->internals.ia_data_buffer.data, length);
269
270 /* overwrite buffer */
271 memmove(session->internals.ia_data_buffer.data,
272 &session->internals.ia_data_buffer.data[length],
273 session->internals.ia_data_buffer.length);
274
275 break;
276
277 default:
278 gnutls_assert ()
279 ;
280 return GNUTLS_E_INVALID_REQUEST;
281 }
282
283 return length;
284}
285
286/* This function is like read. But it does not return -1 on error.
287 * It does return gnutls_errno instead.
288 *
289 * Flags are only used if the default recv() function is being used.
290 */
291static ssize_t _gnutls_read(gnutls_session_t session,
292 void *iptr,
293 size_t sizeOfPtr,
294 int flags)
295{
296 size_t left;
297 ssize_t i = 0;
298 char *ptr = iptr;
299 unsigned j, x, sum = 0;
300 gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;
301
302 session->internals.direction = 0;
303
304 left = sizeOfPtr;
305 while (left > 0)
306 {
307
308 session->internals.errnum = 0;
309
310 if (session->internals._gnutls_pull_func == NULL)
311 {
312 i = recv(GNUTLS_POINTER_TO_INT (fd), &ptr[sizeOfPtr - left], left,
313 flags);
314#if HAVE_WINSOCK
315 if (i < 0)
316 {
317 int tmperr = WSAGetLastError ();
318 switch (tmperr)
319 {
320 case WSAEWOULDBLOCK:
321 session->internals.errnum = EAGAIN;
322 break;
323
324 case WSAEINTR:
325 session->internals.errnum = EINTR;
326 break;
327
328 default:
329 session->internals.errnum = EIO;
330 break;
331 }
332 WSASetLastError (tmperr);
333 }
334#endif
335 }
336 else
337 i = session->internals._gnutls_pull_func(fd, &ptr[sizeOfPtr -
338 left], left);
339
340 if (i < 0)
341 {
342 int err = session->internals.errnum ? session->internals.errnum
343 : errno;
344
345 _gnutls_read_log ("READ: %d returned from %d, errno=%d gerrno=%d\n",
346 i, fd, errno, session->internals.errnum);
347
348 if (err == EAGAIN || err == EINTR)
349 {
350 if (sizeOfPtr - left > 0)
351 {
352
353 _gnutls_read_log ("READ: returning %d bytes from %d\n",
354 sizeOfPtr - left, fd);
355
356 goto finish;
357 }
358 gnutls_assert ();
359
360 if (err == EAGAIN)
361 return GNUTLS_E_AGAIN;
362 return GNUTLS_E_INTERRUPTED;
363 }
364 else
365 {
366 gnutls_assert ();
367 return GNUTLS_E_PULL_ERROR;
368 }
369 }
370 else
371 {
372
373 _gnutls_read_log ("READ: Got %d bytes from %d\n", i, fd);
374
375 if (i == 0)
376 break; /* EOF */
377 }
378
379 left -= i;
380
381 }
382
383 finish:
384
385 if (_gnutls_log_level >= 7)
386 {
387 char line[128];
388 char tmp[16];
389
390 _gnutls_read_log ("READ: read %d bytes from %d\n", (sizeOfPtr - left),
391 fd);
392
393 for (x = 0; x < ((sizeOfPtr - left) / 16) + 1; x++)
394 {
395 line[0] = 0;
396
397 sprintf(tmp, "%.4x - ", x);
398 _gnutls_str_cat(line, sizeof (line), tmp);
399
400 for (j = 0; j < 16; j++)
401 {
402 if (sum < (sizeOfPtr - left))
403 {
404 sprintf(tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
405 _gnutls_str_cat(line, sizeof (line), tmp);
406 }
407 }
408 _gnutls_read_log ("%s\n", line);
409 }
410 }
411
412 return (sizeOfPtr - left);
413}
414
415#define RCVLOWAT session->internals.lowat
416
417/* This function is only used with berkeley style sockets.
418 * Clears the peeked data (read with MSG_PEEK).
419 */
420int _gnutls_io_clear_peeked_data(gnutls_session_t session)
421{
422 char *peekdata;
423 int ret, sum;
424
425 if (session->internals.have_peeked_data == 0 || RCVLOWAT == 0)
426 return 0;
427
428 peekdata = gnutls_alloca (RCVLOWAT);
429 if (peekdata == NULL)
430 {
431 gnutls_assert ();
432 return GNUTLS_E_MEMORY_ERROR;
433 }
434
435 /* this was already read by using MSG_PEEK - so it shouldn't fail */
436 sum = 0;
437 do
438 { /* we need this to finish now */
439 ret = _gnutls_read(session, peekdata, RCVLOWAT - sum, 0);
440 if (ret > 0)
441 sum += ret;
442 } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || sum
443 < RCVLOWAT);
444
445 gnutls_afree (peekdata);
446
447 if (ret < 0)
448 {
449 gnutls_assert ();
450 return ret;
451 }
452
453 session->internals.have_peeked_data = 0;
454
455 return 0;
456}
457
458void _gnutls_io_clear_read_buffer(gnutls_session_t session)
459{
460 session->internals.record_recv_buffer.length = 0;
461}
462
463/* This function is like recv(with MSG_PEEK). But it does not return -1 on error.
464 * It does return gnutls_errno instead.
465 * This function reads data from the socket and keeps them in a buffer, of up to
466 * MAX_RECV_SIZE.
467 *
468 * This is not a general purpose function. It returns EXACTLY the data requested,
469 * which are stored in a local (in the session) buffer. A pointer (iptr) to this buffer is returned.
470 *
471 */
472ssize_t _gnutls_io_read_buffered(gnutls_session_t session,
473 opaque ** iptr,
474 size_t sizeOfPtr,
475 content_type_t recv_type)
476{
477 ssize_t ret = 0, ret2 = 0;
478 size_t min;
479 int buf_pos;
480 opaque *buf;
481 int recvlowat;
482 int recvdata, alloc_size;
483
484 *iptr = session->internals.record_recv_buffer.data;
485
486 if (sizeOfPtr > MAX_RECV_SIZE || sizeOfPtr == 0)
487 {
488 gnutls_assert (); /* internal error */
489 return GNUTLS_E_INVALID_REQUEST;
490 }
491
492 /* If an external pull function is used, then do not leave
493 * any data into the kernel buffer.
494 */
495 if (session->internals._gnutls_pull_func != NULL)
496 {
497 recvlowat = 0;
498 }
499 else
500 {
501 /* leave peeked data to the kernel space only if application data
502 * is received and we don't have any peeked
503 * data in gnutls session.
504 */
505 if (recv_type != GNUTLS_APPLICATION_DATA
506 && session->internals.have_peeked_data == 0)
507 recvlowat = 0;
508 else
509 recvlowat = RCVLOWAT;
510 }
511
512 /* calculate the actual size, ie. get the minimum of the
513 * buffered data and the requested data.
514 */
515 min = MIN(session->internals.record_recv_buffer.length, sizeOfPtr);
516 if (min > 0)
517 {
518 /* if we have enough buffered data
519 * then just return them.
520 */
521 if (min == sizeOfPtr)
522 {
523 return min;
524 }
525 }
526
527 /* min is over zero. recvdata is the data we must
528 * receive in order to return the requested data.
529 */
530 recvdata = sizeOfPtr - min;
531
532 /* Check if the previously read data plus the new data to
533 * receive are longer than the maximum receive buffer size.
534 */
535 if ((session->internals.record_recv_buffer.length + recvdata) > MAX_RECV_SIZE)
536 {
537 gnutls_assert (); /* internal error */
538 return GNUTLS_E_INVALID_REQUEST;
539 }
540
541 /* Allocate the data required to store the new packet.
542 */
543 alloc_size = recvdata + session->internals.record_recv_buffer.length;
544 session->internals.record_recv_buffer.data
545 = gnutls_realloc_fast(session->internals.record_recv_buffer.data,
546 alloc_size);
547 if (session->internals.record_recv_buffer.data == NULL)
548 {
549 gnutls_assert ();
550 return GNUTLS_E_MEMORY_ERROR;
551 }
552
553 buf_pos = session->internals.record_recv_buffer.length;
554 buf = session->internals.record_recv_buffer.data;
555 *iptr = buf;
556
557 /* READ DATA - but leave RCVLOWAT bytes in the kernel buffer. */
558 if (recvdata - recvlowat > 0)
559 {
560 ret = _gnutls_read(session, &buf[buf_pos], recvdata - recvlowat, 0);
561
562 /* return immediately if we got an interrupt or eagain
563 * error.
564 */
565 if (ret < 0 && gnutls_error_is_fatal(ret) == 0)
566 {
567 return ret;
568 }
569 }
570
571 /* copy fresh data to our buffer.
572 */
573 if (ret > 0)
574 {
575 _gnutls_read_log ("RB: Have %d bytes into buffer. Adding %d bytes.\n",
576 session->internals.record_recv_buffer.length, ret);
577 _gnutls_read_log ("RB: Requested %d bytes\n", sizeOfPtr);
578 session->internals.record_recv_buffer.length += ret;
579 }
580
581 buf_pos = session->internals.record_recv_buffer.length;
582
583 /* This is a hack placed in order for select to work. Just leave recvlowat data,
584 * into the kernel buffer (using a read with MSG_PEEK), thus making
585 * select think, that the socket is ready for reading.
586 * MSG_PEEK is only used with berkeley style sockets.
587 */
588 if (ret == (recvdata - recvlowat) && recvlowat > 0)
589 {
590 ret2 = _gnutls_read(session, &buf[buf_pos], recvlowat, MSG_PEEK);
591
592 if (ret2 < 0 && gnutls_error_is_fatal(ret2) == 0)
593 {
594 return ret2;
595 }
596
597 if (ret2 > 0)
598 {
599 _gnutls_read_log ("RB-PEEK: Read %d bytes in PEEK MODE.\n", ret2);
600 _gnutls_read_log
601 ("RB-PEEK: Have %d bytes into buffer. Adding %d bytes.\nRB: Requested %d bytes\n",
602 session->internals.record_recv_buffer.length, ret2, sizeOfPtr);
603 session->internals.have_peeked_data = 1;
604 session->internals.record_recv_buffer.length += ret2;
605
606 }
607 }
608
609 if (ret < 0 || ret2 < 0)
610 {
611 gnutls_assert ();
612 /* that's because they are initialized to 0 */
613 return MIN(ret, ret2);
614 }
615
616 ret += ret2;
617
618 if (ret > 0 && ret < recvlowat)
619 {
620 gnutls_assert ();
621 return GNUTLS_E_AGAIN;
622 }
623
624 if (ret == 0)
625 { /* EOF */
626 gnutls_assert ();
627 return 0;
628 }
629
630 ret = session->internals.record_recv_buffer.length;
631
632 if ((ret > 0) && ((size_t) ret < sizeOfPtr))
633 {
634 /* Short Read */
635 gnutls_assert ();
636 return GNUTLS_E_AGAIN;
637 }
638 else
639 {
640 return ret;
641 }
642}
643
644/* These two functions are used to insert data to the send buffer of the handshake or
645 * record protocol. The send buffer is kept if a send is interrupted and we need to keep
646 * the data left to sent, in order to send them later.
647 */
648
649#define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y))
650
651inline static int _gnutls_buffer_insert(gnutls_buffer * buffer,
652 const opaque * _data,
653 size_t data_size)
654{
655
656 if ((MEMSUB (_data, buffer->data) >= 0) && (MEMSUB (_data, buffer->data) < (ssize_t) buffer->length))
657 {
658 /* the given _data is part of the buffer.
659 */
660 if (data_size > buffer->length)
661 {
662 gnutls_assert ();
663 /* this shouldn't have happened */
664 return GNUTLS_E_INTERNAL_ERROR;
665 }
666
667 if (_data == buffer->data)
668 { /* then don't even memmove */
669 buffer->length = data_size;
670 return 0;
671 }
672
673 memmove(buffer->data, _data, data_size);
674 buffer->length = data_size;
675
676 return 0;
677
678 }
679
680 if (_gnutls_buffer_append (buffer, _data, data_size) < 0)
681 {
682 gnutls_assert ();
683 return GNUTLS_E_MEMORY_ERROR;
684 }
685
686 return 0;
687}
688
689inline static int _gnutls_buffer_get(gnutls_buffer * buffer,
690 const opaque ** ptr,
691 size_t * ptr_size)
692{
693 *ptr_size = buffer->length;
694 *ptr = buffer->data;
695
696 return 0;
697}
698
699/* This function is like write. But it does not return -1 on error.
700 * It does return gnutls_errno instead.
701 *
702 * In case of E_AGAIN and E_INTERRUPTED errors, you must call gnutls_write_flush(),
703 * until it returns ok (0).
704 *
705 * We need to push exactly the data in n, since we cannot send less
706 * data. In TLS the peer must receive the whole packet in order
707 * to decrypt and verify the integrity.
708 *
709 */
710ssize_t _gnutls_io_write_buffered(gnutls_session_t session,
711 const void *iptr,
712 size_t n)
713{
714 size_t left;
715 unsigned j, x, sum = 0;
716 ssize_t retval, i;
717 const opaque *ptr;
718 int ret;
719 gnutls_transport_ptr_t fd = session->internals.transport_send_ptr;
720
721 /* to know where the procedure was interrupted.
722 */
723 session->internals.direction = 1;
724
725 ptr = iptr;
726
727 /* In case the previous write was interrupted, check if the
728 * iptr != NULL and we have data in the buffer.
729 * If this is true then return an error.
730 */
731 if (session->internals.record_send_buffer.length > 0 && iptr != NULL)
732 {
733 gnutls_assert ();
734 return GNUTLS_E_INVALID_REQUEST;
735 }
736
737 /* If data in the buffer exist
738 */
739 if (iptr == NULL)
740 {
741 /* checking is handled above */
742 ret
743 = _gnutls_buffer_get(&session->internals.record_send_buffer, &ptr, &n);
744 if (ret < 0)
745 {
746 gnutls_assert ();
747 return ret;
748 }
749
750 _gnutls_write_log ("WRITE: Restoring old write. (%d bytes to send)\n",
751 n);
752 }
753
754 _gnutls_write_log ("WRITE: Will write %d bytes to %d.\n", n, fd);
755
756 i = 0;
757 left = n;
758 while (left > 0)
759 {
760
761 session->internals.errnum = 0;
762
763 if (session->internals._gnutls_push_func == NULL)
764 {
765 i = send(GNUTLS_POINTER_TO_INT (fd), &ptr[n - left], left, 0);
766#if HAVE_WINSOCK
767 if (i < 0)
768 {
769 int tmperr = WSAGetLastError ();
770 switch (tmperr)
771 {
772 case WSAEWOULDBLOCK:
773 session->internals.errnum = EAGAIN;
774 break;
775
776 case WSAEINTR:
777 session->internals.errnum = EINTR;
778 break;
779
780 default:
781 session->internals.errnum = EIO;
782 break;
783 }
784 WSASetLastError (tmperr);
785 }
786#endif
787 }
788 else
789 i = session->internals._gnutls_push_func(fd, &ptr[n - left], left);
790
791 if (i == -1)
792 {
793 int err = session->internals.errnum ? session->internals.errnum
794 : errno;
795
796 if (err == EAGAIN || err == EINTR)
797 {
798 session->internals.record_send_buffer_prev_size += n - left;
799
800 retval = _gnutls_buffer_insert(&session->internals.
801 record_send_buffer, &ptr[n - left], left);
802 if (retval < 0)
803 {
804 gnutls_assert ();
805 return retval;
806 }
807
808 _gnutls_write_log
809 ("WRITE: Interrupted. Stored %d bytes to buffer. Already sent %d bytes.\n",
810 left, n - left);
811
812 if (err == EAGAIN)
813 return GNUTLS_E_AGAIN;
814 return GNUTLS_E_INTERRUPTED;
815 }
816 else
817 {
818 gnutls_assert ();
819 return GNUTLS_E_PUSH_ERROR;
820 }
821 }
822 left -= i;
823
824 if (_gnutls_log_level >= 7)
825 {
826 char line[128];
827 char tmp[16];
828
829 _gnutls_write_log
830 ("WRITE: wrote %d bytes to %d. Left %d bytes. Total %d bytes.\n",
831 i, fd, left, n);
832 for (x = 0; x < (unsigned) ((i) / 16) + 1; x++)
833 {
834 line[0] = 0;
835
836 if (sum > n - left)
837 break;
838
839 sprintf(tmp, "%.4x - ", x);
840 _gnutls_str_cat(line, sizeof (line), tmp);
841
842 for (j = 0; j < 16; j++)
843 {
844 if (sum < n - left)
845 {
846 sprintf(tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
847 _gnutls_str_cat(line, sizeof (line), tmp);
848 }
849 else
850 break;
851 }
852 _gnutls_write_log ("%s\n", line);
853 }
854 }
855 }
856
857 retval = n + session->internals.record_send_buffer_prev_size;
858
859 session->internals.record_send_buffer.length = 0;
860 session->internals.record_send_buffer_prev_size = 0;
861
862 return retval;
863
864}
865
866/* This function writes the data that are left in the
867 * TLS write buffer (ie. because the previous write was
868 * interrupted.
869 */
870ssize_t _gnutls_io_write_flush(gnutls_session_t session)
871{
872 ssize_t ret;
873
874 if (session->internals.record_send_buffer.length == 0)
875 return 0; /* done */
876
877 ret = _gnutls_io_write_buffered(session, NULL, 0);
878 _gnutls_write_log ("WRITE FLUSH: %d [buffer: %d]\n", ret,
879 session->internals.record_send_buffer.length);
880
881 return ret;
882}
883
884/* This function writes the data that are left in the
885 * Handshake write buffer (ie. because the previous write was
886 * interrupted.
887 */
888ssize_t _gnutls_handshake_io_write_flush(gnutls_session_t session)
889{
890 ssize_t ret;
891 ret = _gnutls_handshake_io_send_int(session, 0, 0, NULL, 0);
892 if (ret < 0)
893 {
894 gnutls_assert ();
895 return ret;
896 }
897
898 _gnutls_write_log ("HANDSHAKE_FLUSH: written[1] %d bytes\n", ret);
899
900 if (session->internals.handshake_send_buffer.length == 0)
901 {
902 ret = session->internals.handshake_send_buffer_prev_size; /* done */
903 session->internals.handshake_send_buffer_prev_size = 0;
904 }
905
906 return ret;
907}
908
909/* This is a send function for the gnutls handshake
910 * protocol. Just makes sure that all data have been sent.
911 */
912ssize_t _gnutls_handshake_io_send_int(gnutls_session_t session,
913 content_type_t type,
914 gnutls_handshake_description_t htype,
915 const void *iptr,
916 size_t n)
917{
918 size_t left;
919 ssize_t ret = 0;
920 const opaque *ptr;
921 ssize_t retval = 0;
922
923 ptr = iptr;
924
925 if (session->internals.handshake_send_buffer.length > 0 && ptr == NULL && n
926 == 0)
927 {
928 /* resuming previously interrupted write
929 */
930 gnutls_assert ();
931 ret = _gnutls_buffer_get(&session->internals.handshake_send_buffer, &ptr,
932 &n);
933 if (ret < 0)
934 {
935 gnutls_assert ();
936 return retval;
937 }
938
939 type = session->internals.handshake_send_buffer_type;
940 htype = session->internals.handshake_send_buffer_htype;
941
942 }
943 else if (session->internals.handshake_send_buffer.length > 0)
944 {
945 gnutls_assert ();
946 return GNUTLS_E_INTERNAL_ERROR;
947 }
948#ifdef WRITE_DEBUG
949 else
950 {
951 size_t sum = 0, x, j;
952
953 _gnutls_write_log ("HWRITE: will write %d bytes to %d.\n", n,
954 gnutls_transport_get_ptr (session));
955 for (x = 0; x < ((n) / 16) + 1; x++)
956 {
957 if (sum> n)
958 break;
959
960 _gnutls_write_log ("%.4x - ", x);
961 for (j = 0; j < 16; j++)
962 {
963 if (sum < n)
964 {
965 _gnutls_write_log ("%.2x ", ((unsigned char *) ptr)[sum++]);
966 }
967 else
968 break;
969 }
970 _gnutls_write_log ("\n");
971 }
972 _gnutls_write_log ("\n");
973 }
974#endif
975
976 if (n == 0)
977 { /* if we have no data to send */
978 gnutls_assert ();
979 return 0;
980 }
981 else if (ptr == NULL)
982 {
983 gnutls_assert ();
984 return GNUTLS_E_INTERNAL_ERROR;
985 }
986
987 left = n;
988 while (left > 0)
989 {
990 ret = _gnutls_send_int(session, type, htype, &ptr[n - left], left);
991
992 if (ret <= 0)
993 {
994 if (ret == 0)
995 {
996 gnutls_assert ();
997 ret = GNUTLS_E_INTERNAL_ERROR;
998 }
999
1000 if (left > 0
1001 && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN))
1002 {
1003 gnutls_assert ();
1004
1005 retval = _gnutls_buffer_insert(&session->internals.
1006 handshake_send_buffer, &ptr[n - left], left);
1007 if (retval < 0)
1008 {
1009 gnutls_assert ();
1010 return retval;
1011 }
1012
1013 session->internals.handshake_send_buffer_prev_size += n - left;
1014
1015 session->internals.handshake_send_buffer_type = type;
1016 session->internals.handshake_send_buffer_htype = htype;
1017
1018 }
1019 else
1020 {
1021 session->internals.handshake_send_buffer_prev_size = 0;
1022 session->internals.handshake_send_buffer.length = 0;
1023 }
1024
1025 gnutls_assert ();
1026 return ret;
1027 }
1028 left -= ret;
1029 }
1030
1031 retval = n + session->internals.handshake_send_buffer_prev_size;
1032
1033 session->internals.handshake_send_buffer.length = 0;
1034 session->internals.handshake_send_buffer_prev_size = 0;
1035
1036 return retval;
1037
1038}
1039
1040/* This is a receive function for the gnutls handshake
1041 * protocol. Makes sure that we have received all data.
1042 */
1043ssize_t _gnutls_handshake_io_recv_int(gnutls_session_t session,
1044 content_type_t type,
1045 gnutls_handshake_description_t htype,
1046 void *iptr,
1047 size_t sizeOfPtr)
1048{
1049 size_t left;
1050 ssize_t i;
1051 opaque *ptr;
1052 size_t dsize;
1053
1054 ptr = iptr;
1055 left = sizeOfPtr;
1056
1057 if (sizeOfPtr == 0 || iptr == NULL)
1058 {
1059 gnutls_assert ();
1060 return GNUTLS_E_INVALID_REQUEST;
1061 }
1062
1063 if (session->internals.handshake_recv_buffer.length > 0)
1064 {
1065 /* if we have already received some data */
1066 if (sizeOfPtr <= session->internals.handshake_recv_buffer.length)
1067 {
1068 /* if requested less data then return it.
1069 */
1070 gnutls_assert ();
1071 memcpy(iptr, session->internals.handshake_recv_buffer.data, sizeOfPtr);
1072
1073 session->internals.handshake_recv_buffer.length -= sizeOfPtr;
1074
1075 memmove(session->internals.handshake_recv_buffer.data,
1076 &session->internals.handshake_recv_buffer.
1077 data[sizeOfPtr],
1078 session->internals.handshake_recv_buffer.length);
1079
1080 return sizeOfPtr;
1081 }
1082 gnutls_assert ();
1083 memcpy(iptr, session->internals.handshake_recv_buffer.data,
1084 session->internals.handshake_recv_buffer.length);
1085
1086 htype = session->internals.handshake_recv_buffer_htype;
1087 type = session->internals.handshake_recv_buffer_type;
1088
1089 left -= session->internals.handshake_recv_buffer.length;
1090
1091 session->internals.handshake_recv_buffer.length = 0;
1092 }
1093
1094 while (left > 0)
1095 {
1096 dsize = sizeOfPtr - left;
1097 i = _gnutls_recv_int(session, type, htype, &ptr[dsize], left);
1098 if (i < 0)
1099 {
1100
1101 if (dsize > 0 && (i == GNUTLS_E_INTERRUPTED || i == GNUTLS_E_AGAIN))
1102 {
1103 gnutls_assert ();
1104
1105 session->internals.handshake_recv_buffer.data
1106 = gnutls_realloc_fast(session->internals.
1107 handshake_recv_buffer.data, dsize);
1108 if (session->internals.handshake_recv_buffer.data == NULL)
1109 {
1110 gnutls_assert ();
1111 return GNUTLS_E_MEMORY_ERROR;
1112 }
1113
1114 memcpy(session->internals.handshake_recv_buffer.data, iptr, dsize);
1115
1116 session->internals.handshake_recv_buffer_htype = htype;
1117 session->internals.handshake_recv_buffer_type = type;
1118
1119 session->internals.handshake_recv_buffer.length = dsize;
1120 }
1121 else
1122 session->internals.handshake_recv_buffer.length = 0;
1123
1124 gnutls_assert ();
1125
1126 return i;
1127 }
1128 else
1129 {
1130 if (i == 0)
1131 break; /* EOF */
1132 }
1133
1134 left -= i;
1135
1136 }
1137
1138 session->internals.handshake_recv_buffer.length = 0;
1139
1140 return sizeOfPtr - left;
1141}
1142
1143/* Buffer for handshake packets. Keeps the packets in order
1144 * for finished messages to use them. Used in HMAC calculation
1145 * and finished messages.
1146 */
1147int _gnutls_handshake_buffer_put(gnutls_session_t session,
1148 opaque * data,
1149 size_t length)
1150{
1151
1152 if (length == 0)
1153 return 0;
1154
1155 if ((session->internals.max_handshake_data_buffer_size > 0) && ((length
1156 + session->
1157 internals.
1158 handshake_hash_buffer.
1159 length) > session->
1160 internals.
1161 max_handshake_data_buffer_size))
1162 {
1163 gnutls_assert ();
1164 return GNUTLS_E_MEMORY_ERROR;
1165 }
1166
1167 _gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data\n", length);
1168
1169 if (_gnutls_buffer_append (&session->internals.handshake_hash_buffer, data,
1170 length) < 0)
1171 {
1172 gnutls_assert ();
1173 return GNUTLS_E_MEMORY_ERROR;
1174 }
1175
1176 return 0;
1177}
1178
1179int _gnutls_handshake_buffer_get_size(gnutls_session_t session)
1180{
1181
1182 return session->internals.handshake_hash_buffer.length;
1183}
1184
1185/* this function does not touch the buffer
1186 * and returns data from it (peek mode!)
1187 */
1188int _gnutls_handshake_buffer_peek(gnutls_session_t session,
1189 opaque * data,
1190 size_t length)
1191{
1192 if (length > session->internals.handshake_hash_buffer.length)
1193 {
1194 length = session->internals.handshake_hash_buffer.length;
1195 }
1196
1197 _gnutls_buffers_log ("BUF[HSK]: Peeked %d bytes of Data\n", length);
1198
1199 memcpy(data, session->internals.handshake_hash_buffer.data, length);
1200 return length;
1201}
1202
1203/* this function does not touch the buffer
1204 * and returns data from it (peek mode!)
1205 */
1206int _gnutls_handshake_buffer_get_ptr(gnutls_session_t session,
1207 opaque ** data_ptr,
1208 size_t * length)
1209{
1210 if (length != NULL)
1211 *length = session->internals.handshake_hash_buffer.length;
1212
1213 _gnutls_buffers_log ("BUF[HSK]: Peeked %d bytes of Data\n", *length);
1214
1215 if (data_ptr != NULL)
1216 *data_ptr = session->internals.handshake_hash_buffer.data;
1217
1218 return 0;
1219}
1220
1221/* Does not free the buffer
1222 */
1223int _gnutls_handshake_buffer_empty(gnutls_session_t session)
1224{
1225
1226 _gnutls_buffers_log ("BUF[HSK]: Emptied buffer\n");
1227
1228 session->internals.handshake_hash_buffer.length = 0;
1229
1230 return 0;
1231}
1232
1233int _gnutls_handshake_buffer_clear(gnutls_session_t session)
1234{
1235
1236 _gnutls_buffers_log ("BUF[HSK]: Cleared Data from buffer\n");
1237
1238 _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
1239
1240 return 0;
1241}
diff --git a/src/daemon/https/tls/gnutls_buffers.h b/src/daemon/https/tls/gnutls_buffers.h
new file mode 100644
index 00000000..aaafde0d
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_buffers.h
@@ -0,0 +1,67 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_record_buffer_put (content_type_t type,
26 gnutls_session_t session, opaque * data,
27 size_t length);
28int _gnutls_record_buffer_get_size (content_type_t type,
29 gnutls_session_t session);
30int _gnutls_record_buffer_get (content_type_t type,
31 gnutls_session_t session, opaque * data,
32 size_t length);
33ssize_t _gnutls_io_read_buffered (gnutls_session_t, opaque ** iptr,
34 size_t n, content_type_t);
35void _gnutls_io_clear_read_buffer (gnutls_session_t);
36int _gnutls_io_clear_peeked_data (gnutls_session_t session);
37
38ssize_t _gnutls_io_write_buffered (gnutls_session_t, const void *iptr,
39 size_t n);
40ssize_t _gnutls_io_write_buffered2 (gnutls_session_t, const void *iptr,
41 size_t n, const void *iptr2, size_t n2);
42
43int _gnutls_handshake_buffer_get_size (gnutls_session_t session);
44int _gnutls_handshake_buffer_peek (gnutls_session_t session, opaque * data,
45 size_t length);
46int _gnutls_handshake_buffer_put (gnutls_session_t session, opaque * data,
47 size_t length);
48int _gnutls_handshake_buffer_clear (gnutls_session_t session);
49int _gnutls_handshake_buffer_empty (gnutls_session_t session);
50int _gnutls_handshake_buffer_get_ptr (gnutls_session_t session,
51 opaque ** data_ptr, size_t * length);
52
53#define _gnutls_handshake_io_buffer_clear( session) \
54 _gnutls_buffer_clear( &session->internals.handshake_send_buffer); \
55 _gnutls_buffer_clear( &session->internals.handshake_recv_buffer); \
56 session->internals.handshake_send_buffer_prev_size = 0
57
58ssize_t _gnutls_handshake_io_recv_int (gnutls_session_t, content_type_t,
59 gnutls_handshake_description_t, void *,
60 size_t);
61ssize_t _gnutls_handshake_io_send_int (gnutls_session_t, content_type_t,
62 gnutls_handshake_description_t,
63 const void *, size_t);
64ssize_t _gnutls_io_write_flush (gnutls_session_t session);
65ssize_t _gnutls_handshake_io_write_flush (gnutls_session_t session);
66
67size_t gnutls_record_check_pending (gnutls_session_t session);
diff --git a/src/daemon/https/tls/gnutls_cert.c b/src/daemon/https/tls/gnutls_cert.c
new file mode 100644
index 00000000..0160d644
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cert.c
@@ -0,0 +1,918 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Some of the stuff needed for Certificate authentication is contained
26 * in this file.
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_errors.h>
31#include <auth_cert.h>
32#include <gnutls_cert.h>
33#include <libtasn1.h>
34#include <gnutls_datum.h>
35#include <gnutls_mpi.h>
36#include <gnutls_global.h>
37#include <gnutls_algorithms.h>
38#include <gnutls_dh.h>
39#include <gnutls_str.h>
40#include <gnutls_state.h>
41#include <gnutls_auth_int.h>
42#include <gnutls_x509.h>
43#include <gnutls_extra_hooks.h>
44/* x509 */
45#include "x509.h"
46#include "mpi.h"
47
48/**
49 * gnutls_certificate_free_keys - Used to free all the keys from a gnutls_certificate_credentials_t structure
50 * @sc: is an #gnutls_certificate_credentials_t structure.
51 *
52 * This function will delete all the keys and the certificates associated
53 * with the given credentials. This function must not be called when a
54 * TLS negotiation that uses the credentials is in progress.
55 *
56 **/
57void
58gnutls_certificate_free_keys (gnutls_certificate_credentials_t sc)
59{
60 unsigned i, j;
61
62 for (i = 0; i < sc->ncerts; i++)
63 {
64 for (j = 0; j < sc->cert_list_length[i]; j++)
65 {
66 _gnutls_gcert_deinit (&sc->cert_list[i][j]);
67 }
68 gnutls_free (sc->cert_list[i]);
69 }
70
71 gnutls_free (sc->cert_list_length);
72 sc->cert_list_length = NULL;
73
74 gnutls_free (sc->cert_list);
75 sc->cert_list = NULL;
76
77 for (i = 0; i < sc->ncerts; i++)
78 {
79 _gnutls_gkey_deinit (&sc->pkey[i]);
80 }
81
82 gnutls_free (sc->pkey);
83 sc->pkey = NULL;
84
85 sc->ncerts = 0;
86
87}
88
89/**
90 * gnutls_certificate_free_cas - Used to free all the CAs from a gnutls_certificate_credentials_t structure
91 * @sc: is an #gnutls_certificate_credentials_t structure.
92 *
93 * This function will delete all the CAs associated
94 * with the given credentials. Servers that do not use
95 * gnutls_certificate_verify_peers2() may call this to
96 * save some memory.
97 *
98 **/
99void
100gnutls_certificate_free_cas (gnutls_certificate_credentials_t sc)
101{
102 unsigned j;
103
104 for (j = 0; j < sc->x509_ncas; j++)
105 {
106 gnutls_x509_crt_deinit (sc->x509_ca_list[j]);
107 }
108
109 sc->x509_ncas = 0;
110
111 gnutls_free (sc->x509_ca_list);
112 sc->x509_ca_list = NULL;
113
114}
115
116/**
117 * gnutls_certificate_free_ca_names - Used to free all the CA names from a gnutls_certificate_credentials_t structure
118 * @sc: is an #gnutls_certificate_credentials_t structure.
119 *
120 * This function will delete all the CA name in the
121 * given credentials. Clients may call this to save some memory
122 * since in client side the CA names are not used.
123 *
124 * CA names are used by servers to advertize the CAs they
125 * support to clients.
126 *
127 **/
128void
129gnutls_certificate_free_ca_names (gnutls_certificate_credentials_t sc)
130{
131 _gnutls_free_datum (&sc->x509_rdn_sequence);
132}
133
134/*-
135 * _gnutls_certificate_get_rsa_params - Returns the RSA parameters pointer
136 * @rsa_params: holds the RSA parameters or NULL.
137 * @func: function to retrieve the parameters or NULL.
138 * @session: The session.
139 *
140 * This function will return the rsa parameters pointer.
141 *
142 -*/
143gnutls_rsa_params_t
144_gnutls_certificate_get_rsa_params (gnutls_rsa_params_t rsa_params,
145 gnutls_params_function * func,
146 gnutls_session_t session)
147{
148 gnutls_params_st params;
149 int ret;
150
151 if (session->internals.params.rsa_params)
152 {
153 return session->internals.params.rsa_params;
154 }
155
156 if (rsa_params)
157 {
158 session->internals.params.rsa_params = rsa_params;
159 }
160 else if (func)
161 {
162 ret = func (session, GNUTLS_PARAMS_RSA_EXPORT, &params);
163 if (ret == 0 && params.type == GNUTLS_PARAMS_RSA_EXPORT)
164 {
165 session->internals.params.rsa_params = params.params.rsa_export;
166 session->internals.params.free_rsa_params = params.deinit;
167 }
168 }
169
170 return session->internals.params.rsa_params;
171}
172
173
174/**
175 * gnutls_certificate_free_credentials - Used to free an allocated gnutls_certificate_credentials_t structure
176 * @sc: is an #gnutls_certificate_credentials_t structure.
177 *
178 * This structure is complex enough to manipulate directly thus
179 * this helper function is provided in order to free (deallocate) it.
180 *
181 * This function does not free any temporary parameters associated
182 * with this structure (ie RSA and DH parameters are not freed by
183 * this function).
184 **/
185void
186gnutls_certificate_free_credentials (gnutls_certificate_credentials_t sc)
187{
188 gnutls_certificate_free_keys (sc);
189 gnutls_certificate_free_cas (sc);
190 gnutls_certificate_free_ca_names (sc);
191#ifdef ENABLE_PKI
192 gnutls_certificate_free_crls (sc);
193#endif
194
195#ifndef KEYRING_HACK
196 if (_E_gnutls_openpgp_keyring_deinit)
197 _E_gnutls_openpgp_keyring_deinit (sc->keyring);
198#else
199 _gnutls_free_datum (&sc->keyring);
200#endif
201
202 gnutls_free (sc);
203}
204
205
206/**
207 * gnutls_certificate_allocate_credentials - Used to allocate a gnutls_certificate_credentials_t structure
208 * @res: is a pointer to an #gnutls_certificate_credentials_t structure.
209 *
210 * This structure is complex enough to manipulate directly thus this
211 * helper function is provided in order to allocate it.
212 *
213 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
214 **/
215int
216gnutls_certificate_allocate_credentials (gnutls_certificate_credentials_t *
217 res)
218{
219 *res = gnutls_calloc (1, sizeof (certificate_credentials_st));
220
221 if (*res == NULL)
222 return GNUTLS_E_MEMORY_ERROR;
223
224 (*res)->verify_bits = DEFAULT_VERIFY_BITS;
225 (*res)->verify_depth = DEFAULT_VERIFY_DEPTH;
226
227 return 0;
228}
229
230
231/* returns the KX algorithms that are supported by a
232 * certificate. (Eg a certificate with RSA params, supports
233 * GNUTLS_KX_RSA algorithm).
234 * This function also uses the KeyUsage field of the certificate
235 * extensions in order to disable unneded algorithms.
236 */
237int
238_gnutls_selected_cert_supported_kx (gnutls_session_t session,
239 gnutls_kx_algorithm_t ** alg,
240 int *alg_size)
241{
242 gnutls_kx_algorithm_t kx;
243 gnutls_pk_algorithm_t pk;
244 gnutls_kx_algorithm_t kxlist[MAX_ALGOS];
245 gnutls_cert *cert;
246 int i;
247
248 if (session->internals.selected_cert_list_length == 0)
249 {
250 *alg_size = 0;
251 *alg = NULL;
252 return 0;
253 }
254
255 cert = &session->internals.selected_cert_list[0];
256 i = 0;
257
258 for (kx = 0; kx < MAX_ALGOS; kx++)
259 {
260 pk = _gnutls_map_pk_get_pk (kx);
261 if (pk == cert->subject_pk_algorithm)
262 {
263 /* then check key usage */
264 if (_gnutls_check_key_usage (cert, kx) == 0)
265 {
266 kxlist[i] = kx;
267 i++;
268 }
269 }
270 }
271
272 if (i == 0)
273 {
274 gnutls_assert ();
275 return GNUTLS_E_INVALID_REQUEST;
276 }
277
278 *alg = gnutls_calloc (1, sizeof (gnutls_kx_algorithm_t) * i);
279 if (*alg == NULL)
280 return GNUTLS_E_MEMORY_ERROR;
281
282 *alg_size = i;
283
284 memcpy (*alg, kxlist, i * sizeof (gnutls_kx_algorithm_t));
285
286 return 0;
287}
288
289
290/**
291 * gnutls_certificate_server_set_request - Used to set whether to request a client certificate
292 * @session: is an #gnutls_session_t structure.
293 * @req: is one of GNUTLS_CERT_REQUEST, GNUTLS_CERT_REQUIRE
294 *
295 * This function specifies if we (in case of a server) are going
296 * to send a certificate request message to the client. If @req
297 * is GNUTLS_CERT_REQUIRE then the server will return an error if
298 * the peer does not provide a certificate. If you do not
299 * call this function then the client will not be asked to
300 * send a certificate.
301 **/
302void
303gnutls_certificate_server_set_request (gnutls_session_t session,
304 gnutls_certificate_request_t req)
305{
306 session->internals.send_cert_req = req;
307}
308
309/**
310 * gnutls_certificate_client_set_retrieve_function - Used to set a callback to retrieve the certificate
311 * @cred: is a #gnutls_certificate_credentials_t structure.
312 * @func: is the callback function
313 *
314 * This function sets a callback to be called in order to retrieve the certificate
315 * to be used in the handshake.
316 * The callback's function prototype is:
317 * int (*callback)(gnutls_session_t, const gnutls_datum_t* req_ca_dn, int nreqs,
318 * const gnutls_pk_algorithm_t* pk_algos, int pk_algos_length, gnutls_retr_st* st);
319 *
320 * @req_ca_cert is only used in X.509 certificates.
321 * Contains a list with the CA names that the server considers trusted.
322 * Normally we should send a certificate that is signed
323 * by one of these CAs. These names are DER encoded. To get a more
324 * meaningful value use the function gnutls_x509_rdn_get().
325 *
326 * @pk_algos contains a list with server's acceptable signature algorithms.
327 * The certificate returned should support the server's given algorithms.
328 *
329 * @st should contain the certificates and private keys.
330 *
331 * If the callback function is provided then gnutls will call it, in the
332 * handshake, after the certificate request message has been received.
333 *
334 * The callback function should set the certificate list to be sent, and
335 * return 0 on success. If no certificate was selected then the number of certificates
336 * should be set to zero. The value (-1) indicates error and the handshake
337 * will be terminated.
338 **/
339void gnutls_certificate_client_set_retrieve_function
340 (gnutls_certificate_credentials_t cred,
341 gnutls_certificate_client_retrieve_function * func)
342{
343 cred->client_get_cert_callback = func;
344}
345
346/**
347 * gnutls_certificate_server_set_retrieve_function - Used to set a callback to retrieve the certificate
348 * @cred: is a #gnutls_certificate_credentials_t structure.
349 * @func: is the callback function
350 *
351 * This function sets a callback to be called in order to retrieve the certificate
352 * to be used in the handshake.
353 * The callback's function prototype is:
354 * int (*callback)(gnutls_session_t, gnutls_retr_st* st);
355 *
356 * @st should contain the certificates and private keys.
357 *
358 * If the callback function is provided then gnutls will call it, in the
359 * handshake, after the certificate request message has been received.
360 *
361 * The callback function should set the certificate list to be sent, and
362 * return 0 on success. The value (-1) indicates error and the handshake
363 * will be terminated.
364 **/
365void gnutls_certificate_server_set_retrieve_function
366 (gnutls_certificate_credentials_t cred,
367 gnutls_certificate_server_retrieve_function * func)
368{
369 cred->server_get_cert_callback = func;
370}
371
372/*-
373 * _gnutls_x509_extract_certificate_activation_time - This function returns the peer's certificate activation time
374 * @cert: should contain an X.509 DER encoded certificate
375 *
376 * This function will return the certificate's activation time in UNIX time
377 * (ie seconds since 00:00:00 UTC January 1, 1970).
378 *
379 * Returns a (time_t) -1 in case of an error.
380 *
381 -*/
382static time_t
383_gnutls_x509_get_raw_crt_activation_time (const gnutls_datum_t * cert)
384{
385 gnutls_x509_crt_t xcert;
386 time_t result;
387
388 result = gnutls_x509_crt_init (&xcert);
389 if (result < 0)
390 return (time_t) - 1;
391
392 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
393 if (result < 0)
394 {
395 gnutls_x509_crt_deinit (xcert);
396 return (time_t) - 1;
397 }
398
399 result = gnutls_x509_crt_get_activation_time (xcert);
400
401 gnutls_x509_crt_deinit (xcert);
402
403 return result;
404}
405
406/*-
407 * gnutls_x509_extract_certificate_expiration_time - This function returns the certificate's expiration time
408 * @cert: should contain an X.509 DER encoded certificate
409 *
410 * This function will return the certificate's expiration time in UNIX
411 * time (ie seconds since 00:00:00 UTC January 1, 1970). Returns a
412 *
413 * (time_t) -1 in case of an error.
414 *
415 -*/
416static time_t
417_gnutls_x509_get_raw_crt_expiration_time (const gnutls_datum_t * cert)
418{
419 gnutls_x509_crt_t xcert;
420 time_t result;
421
422 result = gnutls_x509_crt_init (&xcert);
423 if (result < 0)
424 return (time_t) - 1;
425
426 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
427 if (result < 0)
428 {
429 gnutls_x509_crt_deinit (xcert);
430 return (time_t) - 1;
431 }
432
433 result = gnutls_x509_crt_get_expiration_time (xcert);
434
435 gnutls_x509_crt_deinit (xcert);
436
437 return result;
438}
439
440/*-
441 * _gnutls_openpgp_crt_verify_peers - This function returns the peer's certificate status
442 * @session: is a gnutls session
443 *
444 * This function will try to verify the peer's certificate and return its status (TRUSTED, INVALID etc.).
445 * Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
446 *
447 -*/
448int
449_gnutls_openpgp_crt_verify_peers (gnutls_session_t session,
450 unsigned int *status)
451{
452 cert_auth_info_t info;
453 gnutls_certificate_credentials_t cred;
454 int peer_certificate_list_size, ret;
455
456 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
457
458 info = _gnutls_get_auth_info (session);
459 if (info == NULL)
460 return GNUTLS_E_INVALID_REQUEST;
461
462 cred = (gnutls_certificate_credentials_t)
463 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
464 if (cred == NULL)
465 {
466 gnutls_assert ();
467 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
468 }
469
470 if (info->raw_certificate_list == NULL || info->ncerts == 0)
471 {
472 gnutls_assert ();
473 return GNUTLS_E_NO_CERTIFICATE_FOUND;
474 }
475
476 /* generate a list of gnutls_certs based on the auth info
477 * raw certs.
478 */
479 peer_certificate_list_size = info->ncerts;
480
481 if (peer_certificate_list_size != 1)
482 {
483 gnutls_assert ();
484 return GNUTLS_E_INTERNAL_ERROR;
485 }
486
487 /* Verify certificate
488 */
489 if (_E_gnutls_openpgp_verify_key == NULL)
490 {
491 gnutls_assert ();
492 return GNUTLS_E_INIT_LIBEXTRA;
493 }
494 ret =
495 _E_gnutls_openpgp_verify_key (cred, &info->raw_certificate_list[0],
496 peer_certificate_list_size, status);
497
498 if (ret < 0)
499 {
500 gnutls_assert ();
501 return ret;
502 }
503
504 return 0;
505}
506
507
508/**
509 * gnutls_certificate_verify_peers2 - This function returns the peer's certificate verification status
510 * @session: is a gnutls session
511 * @status: is the output of the verification
512 *
513 * This function will try to verify the peer's certificate and return
514 * its status (trusted, invalid etc.). The value of @status should
515 * be one or more of the gnutls_certificate_status_t enumerated
516 * elements bitwise or'd. To avoid denial of service attacks some
517 * default upper limits regarding the certificate key size and chain
518 * size are set. To override them use
519 * gnutls_certificate_set_verify_limits().
520 *
521 * Note that you must also check the peer's name in order to check if
522 * the verified certificate belongs to the actual peer.
523 *
524 * This is the same as gnutls_x509_crt_list_verify() and uses the
525 * loaded CAs in the credentials as trusted CAs.
526 *
527 * Note that some commonly used X.509 Certificate Authorities are
528 * still using Version 1 certificates. If you want to accept them,
529 * you need to call gnutls_certificate_set_verify_flags() with, e.g.,
530 * %GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT parameter.
531 *
532 * Returns: a negative error code on error and zero on success.
533 **/
534int
535gnutls_certificate_verify_peers2 (gnutls_session_t session,
536 unsigned int *status)
537{
538 cert_auth_info_t info;
539
540 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
541
542 info = _gnutls_get_auth_info (session);
543 if (info == NULL)
544 {
545 return GNUTLS_E_NO_CERTIFICATE_FOUND;
546 }
547
548 if (info->raw_certificate_list == NULL || info->ncerts == 0)
549 return GNUTLS_E_NO_CERTIFICATE_FOUND;
550
551 switch (gnutls_certificate_type_get (session))
552 {
553 case GNUTLS_CRT_X509:
554 return _gnutls_x509_cert_verify_peers (session, status);
555 case GNUTLS_CRT_OPENPGP:
556 return _gnutls_openpgp_crt_verify_peers (session, status);
557 default:
558 return GNUTLS_E_INVALID_REQUEST;
559 }
560}
561
562/**
563 * gnutls_certificate_verify_peers - This function returns the peer's certificate verification status
564 * @session: is a gnutls session
565 *
566 * This function will try to verify the peer's certificate and return
567 * its status (trusted, invalid etc.). However you must also check
568 * the peer's name in order to check if the verified certificate
569 * belongs to the actual peer.
570 *
571 * The return value should be one or more of the
572 * gnutls_certificate_status_t enumerated elements bitwise or'd, or a
573 * negative value on error.
574 *
575 * This is the same as gnutls_x509_crt_list_verify().
576 *
577 * Deprecated: Use gnutls_certificate_verify_peers2() instead.
578 **/
579int
580gnutls_certificate_verify_peers (gnutls_session_t session)
581{
582 unsigned int status;
583 int ret;
584
585 ret = gnutls_certificate_verify_peers2 (session, &status);
586
587 if (ret < 0)
588 {
589 gnutls_assert ();
590 return ret;
591 }
592
593 return status;
594}
595
596/**
597 * gnutls_certificate_expiration_time_peers - This function returns the peer's certificate expiration time
598 * @session: is a gnutls session
599 *
600 * This function will return the peer's certificate expiration time.
601 *
602 * Returns: (time_t)-1 on error.
603 **/
604time_t
605gnutls_certificate_expiration_time_peers (gnutls_session_t session)
606{
607 cert_auth_info_t info;
608
609 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
610
611 info = _gnutls_get_auth_info (session);
612 if (info == NULL)
613 {
614 return (time_t) - 1;
615 }
616
617 if (info->raw_certificate_list == NULL || info->ncerts == 0)
618 {
619 gnutls_assert ();
620 return (time_t) - 1;
621 }
622
623 switch (gnutls_certificate_type_get (session))
624 {
625 case GNUTLS_CRT_X509:
626 return _gnutls_x509_get_raw_crt_expiration_time (&info->
627 raw_certificate_list
628 [0]);
629 case GNUTLS_CRT_OPENPGP:
630 if (_E_gnutls_openpgp_get_raw_key_expiration_time == NULL)
631 return (time_t) - 1;
632 return _E_gnutls_openpgp_get_raw_key_expiration_time (&info->
633 raw_certificate_list
634 [0]);
635 default:
636 return (time_t) - 1;
637 }
638}
639
640/**
641 * gnutls_certificate_activation_time_peers - This function returns the peer's certificate activation time
642 * @session: is a gnutls session
643 *
644 * This function will return the peer's certificate activation time.
645 * This is the creation time for openpgp keys.
646 *
647 * Returns: (time_t)-1 on error.
648 **/
649time_t
650gnutls_certificate_activation_time_peers (gnutls_session_t session)
651{
652 cert_auth_info_t info;
653
654 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
655
656 info = _gnutls_get_auth_info (session);
657 if (info == NULL)
658 {
659 return (time_t) - 1;
660 }
661
662 if (info->raw_certificate_list == NULL || info->ncerts == 0)
663 {
664 gnutls_assert ();
665 return (time_t) - 1;
666 }
667
668 switch (gnutls_certificate_type_get (session))
669 {
670 case GNUTLS_CRT_X509:
671 return _gnutls_x509_get_raw_crt_activation_time (&info->
672 raw_certificate_list
673 [0]);
674 case GNUTLS_CRT_OPENPGP:
675 if (_E_gnutls_openpgp_get_raw_key_creation_time == NULL)
676 return (time_t) - 1;
677 return _E_gnutls_openpgp_get_raw_key_creation_time (&info->
678 raw_certificate_list
679 [0]);
680 default:
681 return (time_t) - 1;
682 }
683}
684
685int
686_gnutls_raw_cert_to_gcert (gnutls_cert * gcert,
687 gnutls_certificate_type_t type,
688 const gnutls_datum_t * raw_cert,
689 int flags /* OR of ConvFlags */ )
690{
691 switch (type)
692 {
693 case GNUTLS_CRT_X509:
694 return _gnutls_x509_raw_cert_to_gcert (gcert, raw_cert, flags);
695 case GNUTLS_CRT_OPENPGP:
696 if (_E_gnutls_openpgp_raw_key_to_gcert == NULL)
697 {
698 gnutls_assert ();
699 return GNUTLS_E_INIT_LIBEXTRA;
700 }
701 return _E_gnutls_openpgp_raw_key_to_gcert (gcert, raw_cert);
702 default:
703 gnutls_assert ();
704 return GNUTLS_E_INTERNAL_ERROR;
705 }
706}
707
708int
709_gnutls_raw_privkey_to_gkey (gnutls_privkey * key,
710 gnutls_certificate_type_t type,
711 const gnutls_datum_t * raw_key,
712 int key_enc /* DER or PEM */ )
713{
714 switch (type)
715 {
716 case GNUTLS_CRT_X509:
717 return _gnutls_x509_raw_privkey_to_gkey (key, raw_key, key_enc);
718 case GNUTLS_CRT_OPENPGP:
719 if (_E_gnutls_openpgp_raw_privkey_to_gkey == NULL)
720 {
721 gnutls_assert ();
722 return GNUTLS_E_INIT_LIBEXTRA;
723 }
724 return _E_gnutls_openpgp_raw_privkey_to_gkey (key, raw_key,
725 (gnutls_openpgp_crt_fmt_t)
726 key_enc);
727 default:
728 gnutls_assert ();
729 return GNUTLS_E_INTERNAL_ERROR;
730 }
731}
732
733
734/* This function will convert a der certificate to a format
735 * (structure) that gnutls can understand and use. Actually the
736 * important thing on this function is that it extracts the
737 * certificate's (public key) parameters.
738 *
739 * The noext flag is used to complete the handshake even if the
740 * extensions found in the certificate are unsupported and critical.
741 * The critical extensions will be catched by the verification functions.
742 */
743int
744_gnutls_x509_raw_cert_to_gcert (gnutls_cert * gcert,
745 const gnutls_datum_t * derCert,
746 int flags /* OR of ConvFlags */ )
747{
748 int ret;
749 gnutls_x509_crt_t cert;
750
751 ret = gnutls_x509_crt_init (&cert);
752 if (ret < 0)
753 {
754 gnutls_assert ();
755 return ret;
756 }
757
758 ret = gnutls_x509_crt_import (cert, derCert, GNUTLS_X509_FMT_DER);
759 if (ret < 0)
760 {
761 gnutls_assert ();
762 gnutls_x509_crt_deinit (cert);
763 return ret;
764 }
765
766 ret = _gnutls_x509_crt_to_gcert (gcert, cert, flags);
767 gnutls_x509_crt_deinit (cert);
768
769 return ret;
770}
771
772/* Like above but it accepts a parsed certificate instead.
773 */
774int
775_gnutls_x509_crt_to_gcert (gnutls_cert * gcert,
776 gnutls_x509_crt_t cert, unsigned int flags)
777{
778 int ret = 0;
779
780 memset (gcert, 0, sizeof (gnutls_cert));
781 gcert->cert_type = GNUTLS_CRT_X509;
782
783 if (!(flags & CERT_NO_COPY))
784 {
785#define SMALL_DER 512
786 opaque *der;
787 size_t der_size = SMALL_DER;
788
789 /* initially allocate a bogus size, just in case the certificate
790 * fits in it. That way we minimize the DER encodings performed.
791 */
792 der = gnutls_malloc (SMALL_DER);
793 if (der == NULL)
794 {
795 gnutls_assert ();
796 return GNUTLS_E_MEMORY_ERROR;
797 }
798
799 ret =
800 gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_DER, der, &der_size);
801 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
802 {
803 gnutls_assert ();
804 gnutls_free (der);
805 return ret;
806 }
807
808 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
809 {
810 der = gnutls_realloc (der, der_size);
811 if (der == NULL)
812 {
813 gnutls_assert ();
814 return GNUTLS_E_MEMORY_ERROR;
815 }
816
817 ret =
818 gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_DER, der,
819 &der_size);
820 if (ret < 0)
821 {
822 gnutls_assert ();
823 gnutls_free (der);
824 return ret;
825 }
826 }
827
828 gcert->raw.data = der;
829 gcert->raw.size = der_size;
830 }
831 else
832 /* now we have 0 or a bitwise or of things to decode */
833 flags ^= CERT_NO_COPY;
834
835
836 if (flags & CERT_ONLY_EXTENSIONS || flags == 0)
837 {
838 gnutls_x509_crt_get_key_usage (cert, &gcert->key_usage, NULL);
839 gcert->version = gnutls_x509_crt_get_version (cert);
840 }
841 gcert->subject_pk_algorithm = gnutls_x509_crt_get_pk_algorithm (cert, NULL);
842
843 if (flags & CERT_ONLY_PUBKEY || flags == 0)
844 {
845 gcert->params_size = MAX_PUBLIC_PARAMS_SIZE;
846 ret =
847 _gnutls_x509_crt_get_mpis (cert, gcert->params, &gcert->params_size);
848 if (ret < 0)
849 {
850 gnutls_assert ();
851 return ret;
852 }
853 }
854
855 return 0;
856
857}
858
859void
860_gnutls_gcert_deinit (gnutls_cert * cert)
861{
862 int i;
863
864 if (cert == NULL)
865 return;
866
867 for (i = 0; i < cert->params_size; i++)
868 {
869 _gnutls_mpi_release (&cert->params[i]);
870 }
871
872 _gnutls_free_datum (&cert->raw);
873}
874
875/**
876 * gnutls_sign_callback_set:
877 * @session: is a gnutls session
878 * @sign_func: function pointer to application's sign callback.
879 * @userdata: void pointer that will be passed to sign callback.
880 *
881 * Set the callback function. The function must have this prototype:
882 *
883 * typedef int (*gnutls_sign_func) (gnutls_session_t session,
884 * void *userdata,
885 * gnutls_certificate_type_t cert_type,
886 * const gnutls_datum_t * cert,
887 * const gnutls_datum_t * hash,
888 * gnutls_datum_t * signature);
889 *
890 * The @userdata parameter is passed to the @sign_func verbatim, and
891 * can be used to store application-specific data needed in the
892 * callback function. See also gnutls_sign_callback_get().
893 **/
894void
895gnutls_sign_callback_set (gnutls_session_t session,
896 gnutls_sign_func sign_func, void *userdata)
897{
898 session->internals.sign_func = sign_func;
899 session->internals.sign_func_userdata = userdata;
900}
901
902/**
903 * gnutls_sign_callback_get:
904 * @session: is a gnutls session
905 * @userdata: if non-%NULL, will be set to abstract callback pointer.
906 *
907 * Retrieve the callback function, and its userdata pointer.
908 *
909 * Returns: The function pointer set by gnutls_sign_callback_set(), or
910 * if not set, %NULL.
911 **/
912gnutls_sign_func
913gnutls_sign_callback_get (gnutls_session_t session, void **userdata)
914{
915 if (userdata)
916 *userdata = session->internals.sign_func_userdata;
917 return session->internals.sign_func;
918}
diff --git a/src/daemon/https/tls/gnutls_cert.h b/src/daemon/https/tls/gnutls_cert.h
new file mode 100644
index 00000000..09df10eb
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cert.h
@@ -0,0 +1,132 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_CERT_H
26# define GNUTLS_CERT_H
27
28#include <gnutls_pk.h>
29#include <libtasn1.h>
30#include "x509.h"
31
32#define MAX_PUBLIC_PARAMS_SIZE 4 /* ok for RSA and DSA */
33
34/* parameters should not be larger than this limit */
35#define DSA_PUBLIC_PARAMS 4
36#define RSA_PUBLIC_PARAMS 2
37
38/* For key Usage, test as:
39 * if (st.key_usage & KEY_DIGITAL_SIGNATURE) ...
40 */
41#define KEY_DIGITAL_SIGNATURE 128
42#define KEY_NON_REPUDIATION 64
43#define KEY_KEY_ENCIPHERMENT 32
44#define KEY_DATA_ENCIPHERMENT 16
45#define KEY_KEY_AGREEMENT 8
46#define KEY_KEY_CERT_SIGN 4
47#define KEY_CRL_SIGN 2
48#define KEY_ENCIPHER_ONLY 1
49#define KEY_DECIPHER_ONLY 32768
50
51typedef struct gnutls_cert
52{
53 mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; /* the size of params depends on the public
54 * key algorithm
55 * RSA: [0] is modulus
56 * [1] is public exponent
57 * DSA: [0] is p
58 * [1] is q
59 * [2] is g
60 * [3] is public key
61 */
62 int params_size; /* holds the size of MPI params */
63
64 gnutls_pk_algorithm_t subject_pk_algorithm;
65
66 unsigned int key_usage; /* bits from KEY_*
67 */
68
69 unsigned int version;
70 /* holds the type (PGP, X509)
71 */
72 gnutls_certificate_type_t cert_type;
73
74 gnutls_datum_t raw;
75
76} gnutls_cert;
77
78typedef struct gnutls_privkey_int
79{
80 mpi_t params[MAX_PRIV_PARAMS_SIZE]; /* the size of params depends on the public
81 * key algorithm
82 */
83 /*
84 * RSA: [0] is modulus
85 * [1] is public exponent
86 * [2] is private exponent
87 * [3] is prime1 (p)
88 * [4] is prime2 (q)
89 * [5] is coefficient (u == inverse of p mod q)
90 * DSA: [0] is p
91 * [1] is q
92 * [2] is g
93 * [3] is y (public key)
94 * [4] is x (private key)
95 */
96 int params_size; /* holds the number of params */
97
98 gnutls_pk_algorithm_t pk_algorithm;
99} gnutls_privkey;
100
101struct gnutls_session_int; /* because gnutls_session_t is not defined when this file is included */
102
103typedef enum ConvFlags
104{
105 CERT_NO_COPY = 2,
106 CERT_ONLY_PUBKEY = 4,
107 CERT_ONLY_EXTENSIONS = 16
108} ConvFlags;
109
110int _gnutls_x509_raw_cert_to_gcert (gnutls_cert * gcert,
111 const gnutls_datum_t * derCert,
112 int flags);
113int _gnutls_x509_crt_to_gcert (gnutls_cert * gcert, gnutls_x509_crt_t cert,
114 unsigned int flags);
115
116void _gnutls_gkey_deinit (gnutls_privkey * key);
117void _gnutls_gcert_deinit (gnutls_cert * cert);
118
119int _gnutls_selected_cert_supported_kx (struct gnutls_session_int *session,
120 gnutls_kx_algorithm_t ** alg,
121 int *alg_size);
122
123int _gnutls_raw_cert_to_gcert (gnutls_cert * gcert,
124 gnutls_certificate_type_t type,
125 const gnutls_datum_t * raw_cert,
126 int flags /* OR of ConvFlags */ );
127int _gnutls_raw_privkey_to_gkey (gnutls_privkey * key,
128 gnutls_certificate_type_t type,
129 const gnutls_datum_t * raw_key,
130 int key_enc /* DER or PEM */ );
131
132#endif
diff --git a/src/daemon/https/tls/gnutls_cipher.c b/src/daemon/https/tls/gnutls_cipher.c
new file mode 100644
index 00000000..8245b1c0
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cipher.c
@@ -0,0 +1,584 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Some high level functions to be used in the record encryption are
26 * included here.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_errors.h"
31#include "gnutls_compress.h"
32#include "gnutls_cipher.h"
33#include "gnutls_algorithms.h"
34#include "gnutls_hash_int.h"
35#include "gnutls_cipher_int.h"
36#include "debug.h"
37#include "gnutls_num.h"
38#include "gnutls_datum.h"
39#include "gnutls_kx.h"
40#include "gnutls_record.h"
41#include "gnutls_constate.h"
42#include <gc.h>
43
44inline static int
45is_write_comp_null (gnutls_session_t session)
46{
47 if (session->security_parameters.write_compression_algorithm ==
48 GNUTLS_COMP_NULL)
49 return 0;
50
51 return 1;
52}
53
54inline static int
55is_read_comp_null (gnutls_session_t session)
56{
57 if (session->security_parameters.read_compression_algorithm ==
58 GNUTLS_COMP_NULL)
59 return 0;
60
61 return 1;
62}
63
64
65/* returns ciphertext which contains the headers too. This also
66 * calculates the size in the header field.
67 *
68 * If random pad != 0 then the random pad data will be appended.
69 */
70int
71_gnutls_encrypt (gnutls_session_t session, const opaque * headers,
72 size_t headers_size, const opaque * data,
73 size_t data_size, opaque * ciphertext,
74 size_t ciphertext_size, content_type_t type, int random_pad)
75{
76 gnutls_datum_t plain;
77 gnutls_datum_t comp;
78 int ret;
79 int free_comp = 1;
80
81 plain.data = (opaque *) data;
82 plain.size = data_size;
83
84 if (plain.size == 0 || is_write_comp_null (session) == 0)
85 {
86 comp = plain;
87 free_comp = 0;
88 }
89 else
90 {
91 /* Here comp is allocated and must be
92 * freed.
93 */
94 ret = _gnutls_m_plaintext2compressed (session, &comp, &plain);
95 if (ret < 0)
96 {
97 gnutls_assert ();
98 return ret;
99 }
100 }
101
102 ret = _gnutls_compressed2ciphertext (session, &ciphertext[headers_size],
103 ciphertext_size - headers_size,
104 comp, type, random_pad);
105
106 if (free_comp)
107 _gnutls_free_datum (&comp);
108
109 if (ret < 0)
110 {
111 gnutls_assert ();
112 return ret;
113 }
114
115
116 /* copy the headers */
117 memcpy (ciphertext, headers, headers_size);
118 _gnutls_write_uint16 (ret, &ciphertext[3]);
119
120 return ret + headers_size;
121}
122
123/* Decrypts the given data.
124 * Returns the decrypted data length.
125 */
126int
127_gnutls_decrypt (gnutls_session_t session, opaque * ciphertext,
128 size_t ciphertext_size, uint8_t * data,
129 size_t max_data_size, content_type_t type)
130{
131 gnutls_datum_t gtxt;
132 gnutls_datum_t gcipher;
133 int ret;
134
135 if (ciphertext_size == 0)
136 return 0;
137
138 gcipher.size = ciphertext_size;
139 gcipher.data = ciphertext;
140
141 ret =
142 _gnutls_ciphertext2compressed (session, data, max_data_size,
143 gcipher, type);
144 if (ret < 0)
145 {
146 return ret;
147 }
148
149 if (ret == 0 || is_read_comp_null (session) == 0)
150 {
151 /* ret == ret */
152
153 }
154 else
155 {
156 gnutls_datum_t gcomp;
157
158 /* compression has this malloc overhead.
159 */
160
161 gcomp.data = data;
162 gcomp.size = ret;
163 ret = _gnutls_m_compressed2plaintext (session, &gtxt, &gcomp);
164 if (ret < 0)
165 {
166 return ret;
167 }
168
169 if (gtxt.size > MAX_RECORD_RECV_SIZE)
170 {
171 gnutls_assert ();
172 _gnutls_free_datum (&gtxt);
173 /* This shouldn't have happen and
174 * is a TLS fatal error.
175 */
176 return GNUTLS_E_DECOMPRESSION_FAILED;
177 }
178
179 /* This check is not really needed */
180 if (max_data_size < MAX_RECORD_RECV_SIZE)
181 {
182 gnutls_assert ();
183 _gnutls_free_datum (&gtxt);
184 return GNUTLS_E_INTERNAL_ERROR;
185 }
186
187 memcpy (data, gtxt.data, gtxt.size);
188 ret = gtxt.size;
189
190 _gnutls_free_datum (&gtxt);
191 }
192
193 return ret;
194}
195
196inline static mac_hd_t
197mac_init (gnutls_mac_algorithm_t mac, opaque * secret, int secret_size,
198 int ver)
199{
200 mac_hd_t td;
201
202 if (mac == GNUTLS_MAC_NULL)
203 return GNUTLS_MAC_FAILED;
204
205 if (ver == GNUTLS_SSL3)
206 { /* SSL 3.0 */
207 td = _gnutls_mac_init_ssl3 (mac, secret, secret_size);
208 }
209 else
210 { /* TLS 1.x */
211 td = _gnutls_hmac_init (mac, secret, secret_size);
212 }
213
214 return td;
215}
216
217inline static void
218mac_deinit (mac_hd_t td, opaque * res, int ver)
219{
220 if (ver == GNUTLS_SSL3)
221 { /* SSL 3.0 */
222 _gnutls_mac_deinit_ssl3 (td, res);
223 }
224 else
225 {
226 _gnutls_hmac_deinit (td, res);
227 }
228}
229
230inline static int
231calc_enc_length (gnutls_session_t session, int data_size,
232 int hash_size, uint8_t * pad, int random_pad,
233 cipher_type_t block_algo, uint16_t blocksize)
234{
235 uint8_t rnd;
236 int length;
237
238 *pad = 0;
239
240 switch (block_algo)
241 {
242 case CIPHER_STREAM:
243 length = data_size + hash_size;
244
245 break;
246 case CIPHER_BLOCK:
247 if (gc_nonce (&rnd, 1) != GC_OK)
248 {
249 gnutls_assert ();
250 return GNUTLS_E_RANDOM_FAILED;
251 }
252
253 /* make rnd a multiple of blocksize */
254 if (session->security_parameters.version == GNUTLS_SSL3 ||
255 random_pad == 0)
256 {
257 rnd = 0;
258 }
259 else
260 {
261 rnd = (rnd / blocksize) * blocksize;
262 /* added to avoid the case of pad calculated 0
263 * seen below for pad calculation.
264 */
265 if (rnd > blocksize)
266 rnd -= blocksize;
267 }
268
269 length = data_size + hash_size;
270
271 *pad = (uint8_t) (blocksize - (length % blocksize)) + rnd;
272
273 length += *pad;
274 if (session->security_parameters.version >= GNUTLS_TLS1_1)
275 length += blocksize; /* for the IV */
276
277 break;
278 default:
279 gnutls_assert ();
280 return GNUTLS_E_INTERNAL_ERROR;
281 }
282
283 return length;
284}
285
286/* This is the actual encryption
287 * Encrypts the given compressed datum, and puts the result to cipher_data,
288 * which has cipher_size size.
289 * return the actual encrypted data length.
290 */
291int
292_gnutls_compressed2ciphertext (gnutls_session_t session,
293 opaque * cipher_data, int cipher_size,
294 gnutls_datum_t compressed,
295 content_type_t _type, int random_pad)
296{
297 uint8_t MAC[MAX_HASH_SIZE];
298 uint16_t c_length;
299 uint8_t pad;
300 int length, ret;
301 mac_hd_t td;
302 uint8_t type = _type;
303 uint8_t major, minor;
304 int hash_size =
305 _gnutls_hash_get_algo_len (session->security_parameters.
306 write_mac_algorithm);
307 gnutls_protocol_t ver;
308 int blocksize =
309 _gnutls_cipher_get_block_size (session->security_parameters.
310 write_bulk_cipher_algorithm);
311 cipher_type_t block_algo =
312 _gnutls_cipher_is_block (session->security_parameters.
313 write_bulk_cipher_algorithm);
314 opaque *data_ptr;
315
316
317 ver = gnutls_protocol_get_version (session);
318 minor = _gnutls_version_get_minor (ver);
319 major = _gnutls_version_get_major (ver);
320
321
322 /* Initialize MAC */
323 td = mac_init (session->security_parameters.write_mac_algorithm,
324 session->connection_state.write_mac_secret.data,
325 session->connection_state.write_mac_secret.size, ver);
326
327 if (td == GNUTLS_MAC_FAILED
328 && session->security_parameters.write_mac_algorithm != GNUTLS_MAC_NULL)
329 {
330 gnutls_assert ();
331 return GNUTLS_E_INTERNAL_ERROR;
332 }
333
334 c_length = _gnutls_conv_uint16 (compressed.size);
335
336 if (td != GNUTLS_MAC_FAILED)
337 { /* actually when the algorithm in not the NULL one */
338 _gnutls_hmac (td,
339 UINT64DATA (session->connection_state.
340 write_sequence_number), 8);
341
342 _gnutls_hmac (td, &type, 1);
343 if (ver >= GNUTLS_TLS1)
344 { /* TLS 1.0 or higher */
345 _gnutls_hmac (td, &major, 1);
346 _gnutls_hmac (td, &minor, 1);
347 }
348 _gnutls_hmac (td, &c_length, 2);
349 _gnutls_hmac (td, compressed.data, compressed.size);
350 mac_deinit (td, MAC, ver);
351 }
352
353
354 /* Calculate the encrypted length (padding etc.)
355 */
356 length =
357 calc_enc_length (session, compressed.size, hash_size, &pad,
358 random_pad, block_algo, blocksize);
359 if (length < 0)
360 {
361 gnutls_assert ();
362 return length;
363 }
364
365 /* copy the encrypted data to cipher_data.
366 */
367 if (cipher_size < length)
368 {
369 gnutls_assert ();
370 return GNUTLS_E_MEMORY_ERROR;
371 }
372
373 data_ptr = cipher_data;
374 if (block_algo == CIPHER_BLOCK &&
375 session->security_parameters.version >= GNUTLS_TLS1_1)
376 {
377 /* copy the random IV.
378 */
379 if (gc_nonce (data_ptr, blocksize) != GC_OK)
380 {
381 gnutls_assert ();
382 return GNUTLS_E_RANDOM_FAILED;
383 }
384 data_ptr += blocksize;
385 }
386
387 memcpy (data_ptr, compressed.data, compressed.size);
388 data_ptr += compressed.size;
389
390 if (hash_size > 0)
391 {
392 memcpy (data_ptr, MAC, hash_size);
393 data_ptr += hash_size;
394 }
395 if (block_algo == CIPHER_BLOCK && pad > 0)
396 {
397 memset (data_ptr, pad - 1, pad);
398 }
399
400
401 /* Actual encryption (inplace).
402 */
403 ret = _gnutls_cipher_encrypt (session->connection_state.
404 write_cipher_state, cipher_data, length);
405 if (ret < 0)
406 {
407 gnutls_assert ();
408 return ret;
409 }
410
411 return length;
412}
413
414/* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size.
415 * Returns the actual compressed packet size.
416 */
417int
418_gnutls_ciphertext2compressed (gnutls_session_t session,
419 opaque * compress_data,
420 int compress_size,
421 gnutls_datum_t ciphertext, uint8_t type)
422{
423 uint8_t MAC[MAX_HASH_SIZE];
424 uint16_t c_length;
425 uint8_t pad;
426 int length;
427 mac_hd_t td;
428 uint16_t blocksize;
429 int ret, i, pad_failed = 0;
430 uint8_t major, minor;
431 gnutls_protocol_t ver;
432 int hash_size =
433 _gnutls_hash_get_algo_len (session->security_parameters.
434 read_mac_algorithm);
435
436 ver = gnutls_protocol_get_version (session);
437 minor = _gnutls_version_get_minor (ver);
438 major = _gnutls_version_get_major (ver);
439
440 blocksize = _gnutls_cipher_get_block_size (session->security_parameters.
441 read_bulk_cipher_algorithm);
442
443 /* initialize MAC
444 */
445 td = mac_init (session->security_parameters.read_mac_algorithm,
446 session->connection_state.read_mac_secret.data,
447 session->connection_state.read_mac_secret.size, ver);
448
449 if (td == GNUTLS_MAC_FAILED
450 && session->security_parameters.read_mac_algorithm != GNUTLS_MAC_NULL)
451 {
452 gnutls_assert ();
453 return GNUTLS_E_INTERNAL_ERROR;
454 }
455
456
457 /* actual decryption (inplace)
458 */
459 switch (_gnutls_cipher_is_block
460 (session->security_parameters.read_bulk_cipher_algorithm))
461 {
462 case CIPHER_STREAM:
463 if ((ret = _gnutls_cipher_decrypt (session->connection_state.
464 read_cipher_state,
465 ciphertext.data,
466 ciphertext.size)) < 0)
467 {
468 gnutls_assert ();
469 return ret;
470 }
471
472 length = ciphertext.size - hash_size;
473
474 break;
475 case CIPHER_BLOCK:
476 if ((ciphertext.size < blocksize) || (ciphertext.size % blocksize != 0))
477 {
478 gnutls_assert ();
479 return GNUTLS_E_DECRYPTION_FAILED;
480 }
481
482 if ((ret = _gnutls_cipher_decrypt (session->connection_state.
483 read_cipher_state,
484 ciphertext.data,
485 ciphertext.size)) < 0)
486 {
487 gnutls_assert ();
488 return ret;
489 }
490
491 /* ignore the IV in TLS 1.1.
492 */
493 if (session->security_parameters.version >= GNUTLS_TLS1_1)
494 {
495 ciphertext.size -= blocksize;
496 ciphertext.data += blocksize;
497
498 if (ciphertext.size == 0)
499 {
500 gnutls_assert ();
501 return GNUTLS_E_DECRYPTION_FAILED;
502 }
503 }
504
505 pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */
506
507 length = ciphertext.size - hash_size - pad;
508
509 if (pad > ciphertext.size - hash_size)
510 {
511 gnutls_assert ();
512 /* We do not fail here. We check below for the
513 * the pad_failed. If zero means success.
514 */
515 pad_failed = GNUTLS_E_DECRYPTION_FAILED;
516 }
517
518 /* Check the pading bytes (TLS 1.x)
519 */
520 if (ver >= GNUTLS_TLS1 && pad_failed == 0)
521 for (i = 2; i < pad; i++)
522 {
523 if (ciphertext.data[ciphertext.size - i] !=
524 ciphertext.data[ciphertext.size - 1])
525 pad_failed = GNUTLS_E_DECRYPTION_FAILED;
526 }
527 break;
528 default:
529 gnutls_assert ();
530 return GNUTLS_E_INTERNAL_ERROR;
531 }
532
533 if (length < 0)
534 length = 0;
535 c_length = _gnutls_conv_uint16 ((uint16_t) length);
536
537 /* Pass the type, version, length and compressed through
538 * MAC.
539 */
540 if (td != GNUTLS_MAC_FAILED)
541 {
542 _gnutls_hmac (td,
543 UINT64DATA (session->connection_state.
544 read_sequence_number), 8);
545
546 _gnutls_hmac (td, &type, 1);
547 if (ver >= GNUTLS_TLS1)
548 { /* TLS 1.x */
549 _gnutls_hmac (td, &major, 1);
550 _gnutls_hmac (td, &minor, 1);
551 }
552 _gnutls_hmac (td, &c_length, 2);
553
554 if (length > 0)
555 _gnutls_hmac (td, ciphertext.data, length);
556
557 mac_deinit (td, MAC, ver);
558 }
559
560 /* This one was introduced to avoid a timing attack against the TLS
561 * 1.0 protocol.
562 */
563 if (pad_failed != 0)
564 return pad_failed;
565
566 /* HMAC was not the same.
567 */
568 if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0)
569 {
570 gnutls_assert ();
571 return GNUTLS_E_DECRYPTION_FAILED;
572 }
573
574 /* copy the decrypted stuff to compress_data.
575 */
576 if (compress_size < length)
577 {
578 gnutls_assert ();
579 return GNUTLS_E_DECOMPRESSION_FAILED;
580 }
581 memcpy (compress_data, ciphertext.data, length);
582
583 return length;
584}
diff --git a/src/daemon/https/tls/gnutls_cipher.h b/src/daemon/https/tls/gnutls_cipher.h
new file mode 100644
index 00000000..0279e859
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cipher.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_encrypt (gnutls_session_t session, const opaque * headers,
26 size_t headers_size, const opaque * data,
27 size_t data_size, opaque * ciphertext,
28 size_t ciphertext_size, content_type_t type,
29 int random_pad);
30
31int _gnutls_decrypt (gnutls_session_t session, opaque * ciphertext,
32 size_t ciphertext_size, uint8_t * data, size_t data_size,
33 content_type_t type);
34int _gnutls_compressed2ciphertext (gnutls_session_t session,
35 opaque * cipher_data, int cipher_size,
36 gnutls_datum_t compressed,
37 content_type_t _type, int random_pad);
38int _gnutls_ciphertext2compressed (gnutls_session_t session,
39 opaque * compress_data,
40 int compress_size,
41 gnutls_datum_t ciphertext, uint8_t type);
diff --git a/src/daemon/https/tls/gnutls_cipher_int.c b/src/daemon/https/tls/gnutls_cipher_int.c
new file mode 100644
index 00000000..c9200e5b
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cipher_int.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright (C) 2000, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_cipher_int.h>
28#include <gnutls_datum.h>
29
30cipher_hd_t
31_gnutls_cipher_init (gnutls_cipher_algorithm_t cipher,
32 const gnutls_datum_t * key, const gnutls_datum_t * iv)
33{
34 cipher_hd_t ret = NULL;
35 int err = GC_INVALID_CIPHER; /* doesn't matter */
36
37 switch (cipher)
38 {
39 case GNUTLS_CIPHER_AES_128_CBC:
40 err = gc_cipher_open (GC_AES128, GC_CBC, &ret);
41 break;
42
43 case GNUTLS_CIPHER_AES_256_CBC:
44 err = gc_cipher_open (GC_AES256, GC_CBC, &ret);
45 break;
46
47 case GNUTLS_CIPHER_3DES_CBC:
48 err = gc_cipher_open (GC_3DES, GC_CBC, &ret);
49 break;
50
51 case GNUTLS_CIPHER_DES_CBC:
52 err = gc_cipher_open (GC_DES, GC_CBC, &ret);
53 break;
54
55 case GNUTLS_CIPHER_ARCFOUR_128:
56 err = gc_cipher_open (GC_ARCFOUR128, GC_STREAM, &ret);
57 break;
58
59 case GNUTLS_CIPHER_ARCFOUR_40:
60 err = gc_cipher_open (GC_ARCFOUR40, GC_STREAM, &ret);
61 break;
62
63 case GNUTLS_CIPHER_RC2_40_CBC:
64 err = gc_cipher_open (GC_ARCTWO40, GC_CBC, &ret);
65 break;
66
67#ifdef ENABLE_CAMELLIA
68 case GNUTLS_CIPHER_CAMELLIA_128_CBC:
69 err = gc_cipher_open (GC_CAMELLIA128, GC_CBC, &ret);
70 break;
71
72 case GNUTLS_CIPHER_CAMELLIA_256_CBC:
73 err = gc_cipher_open (GC_CAMELLIA256, GC_CBC, &ret);
74 break;
75#endif
76
77 default:
78 return NULL;
79 }
80
81 if (err == 0)
82 {
83 gc_cipher_setkey (ret, key->size, key->data);
84 if (iv->data != NULL && iv->size > 0)
85 gc_cipher_setiv (ret, iv->size, iv->data);
86 }
87 else if (cipher != GNUTLS_CIPHER_NULL)
88 {
89 gnutls_assert ();
90 _gnutls_x509_log ("Crypto cipher[%d] error: %d\n", cipher, err);
91 /* FIXME: gc_strerror */
92 }
93
94 return ret;
95}
96
97int
98_gnutls_cipher_encrypt (cipher_hd_t handle, void *text, int textlen)
99{
100 if (handle != GNUTLS_CIPHER_FAILED)
101 {
102 if (gc_cipher_encrypt_inline (handle, textlen, text) != 0)
103 {
104 gnutls_assert ();
105 return GNUTLS_E_INTERNAL_ERROR;
106 }
107 }
108 return 0;
109}
110
111int
112_gnutls_cipher_decrypt (cipher_hd_t handle, void *ciphertext,
113 int ciphertextlen)
114{
115 if (handle != GNUTLS_CIPHER_FAILED)
116 {
117 if (gc_cipher_decrypt_inline (handle, ciphertextlen, ciphertext) != 0)
118 {
119 gnutls_assert ();
120 return GNUTLS_E_INTERNAL_ERROR;
121 }
122 }
123 return 0;
124}
125
126void
127_gnutls_cipher_deinit (cipher_hd_t handle)
128{
129 if (handle != GNUTLS_CIPHER_FAILED)
130 {
131 gc_cipher_close (handle);
132 }
133}
diff --git a/src/daemon/https/tls/gnutls_cipher_int.h b/src/daemon/https/tls/gnutls_cipher_int.h
new file mode 100644
index 00000000..78ed487f
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cipher_int.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_CIPHER_INT
26# define GNUTLS_CIPHER_INT
27
28#define cipher_hd_t gc_cipher_handle
29#define GNUTLS_CIPHER_FAILED NULL
30
31// TODO gc_cipher_handle -> void * x3
32void * _gnutls_cipher_init(gnutls_cipher_algorithm_t cipher,
33 const gnutls_datum_t * key,
34 const gnutls_datum_t * iv);
35
36int _gnutls_cipher_encrypt(void * handle,
37 void *text,
38 int textlen);
39
40int _gnutls_cipher_decrypt(void * handle,
41 void *ciphertext,
42 int ciphertextlen);
43
44void _gnutls_cipher_deinit(void * handle);
45
46#endif /* GNUTLS_CIPHER_INT */
diff --git a/src/daemon/https/tls/gnutls_compress.c b/src/daemon/https/tls/gnutls_compress.c
new file mode 100644
index 00000000..e6561ad6
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_compress.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) 2000, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains the functions which convert the TLS plaintext
26 * packet to TLS compressed packet.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_compress.h"
31#include "gnutls_errors.h"
32#include "gnutls_compress_int.h"
33
34/* These functions allocate the return value internally
35 */
36int
37_gnutls_m_plaintext2compressed (gnutls_session_t session,
38 gnutls_datum_t * compressed,
39 const gnutls_datum_t * plaintext)
40{
41 int size;
42 opaque *data;
43
44 size =
45 _gnutls_compress (session->connection_state.write_compression_state,
46 plaintext->data, plaintext->size, &data,
47 MAX_RECORD_SEND_SIZE + EXTRA_COMP_SIZE);
48 if (size < 0)
49 {
50 gnutls_assert ();
51 return GNUTLS_E_COMPRESSION_FAILED;
52 }
53 compressed->data = data;
54 compressed->size = size;
55
56 return 0;
57}
58
59int
60_gnutls_m_compressed2plaintext (gnutls_session_t session,
61 gnutls_datum_t * plain,
62 const gnutls_datum_t * compressed)
63{
64 int size;
65 opaque *data;
66
67 size =
68 _gnutls_decompress (session->connection_state.
69 read_compression_state, compressed->data,
70 compressed->size, &data, MAX_RECORD_RECV_SIZE);
71 if (size < 0)
72 {
73 gnutls_assert ();
74 return GNUTLS_E_DECOMPRESSION_FAILED;
75 }
76 plain->data = data;
77 plain->size = size;
78
79 return 0;
80}
diff --git a/src/daemon/https/tls/gnutls_compress.h b/src/daemon/https/tls/gnutls_compress.h
new file mode 100644
index 00000000..44666321
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_compress.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_m_plaintext2compressed (gnutls_session_t session,
26 gnutls_datum_t * compressed,
27 const gnutls_datum_t *plaintext);
28int _gnutls_m_compressed2plaintext (gnutls_session_t session,
29 gnutls_datum_t * plain,
30 const gnutls_datum_t* compressed);
diff --git a/src/daemon/https/tls/gnutls_compress_int.c b/src/daemon/https/tls/gnutls_compress_int.c
new file mode 100644
index 00000000..eedfd63d
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_compress_int.c
@@ -0,0 +1,300 @@
1/*
2 * Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_compress.h>
27#include <gnutls_algorithms.h>
28#include "gnutls_errors.h"
29
30/* The flag d is the direction (compress, decompress). Non zero is
31 * decompress.
32 */
33comp_hd_t
34_gnutls_comp_init (gnutls_compression_method_t method, int d)
35{
36 comp_hd_t ret;
37 int err;
38
39 ret = gnutls_malloc (sizeof (struct comp_hd_t_STRUCT));
40 if (ret == NULL)
41 {
42 gnutls_assert ();
43 return NULL;
44 }
45
46 ret->algo = method;
47 ret->handle = NULL;
48
49 switch (method)
50 {
51#ifdef HAVE_LIBZ
52 case GNUTLS_COMP_DEFLATE:
53 {
54 int window_bits, mem_level;
55 int comp_level;
56 z_stream *zhandle;
57
58 window_bits = _gnutls_compression_get_wbits (method);
59 mem_level = _gnutls_compression_get_mem_level (method);
60 comp_level = _gnutls_compression_get_comp_level (method);
61
62 ret->handle = gnutls_malloc (sizeof (z_stream));
63 if (ret->handle == NULL)
64 {
65 gnutls_assert ();
66 goto cleanup_ret;
67 }
68
69 zhandle = ret->handle;
70
71 zhandle->zalloc = (alloc_func) 0;
72 zhandle->zfree = (free_func) 0;
73 zhandle->opaque = (voidpf) 0;
74
75 if (d)
76 err = inflateInit2 (zhandle, window_bits);
77 else
78 {
79 err = deflateInit2 (zhandle,
80 comp_level, Z_DEFLATED,
81 window_bits, mem_level, Z_DEFAULT_STRATEGY);
82 }
83 if (err != Z_OK)
84 {
85 gnutls_assert ();
86 gnutls_free (ret->handle);
87 goto cleanup_ret;
88 }
89 break;
90 }
91#endif
92 case GNUTLS_COMP_NULL:
93 break;
94 }
95 return ret;
96
97cleanup_ret:
98 gnutls_free (ret);
99 return NULL;
100}
101
102/* The flag d is the direction (compress, decompress). Non zero is
103 * decompress.
104 */
105void
106_gnutls_comp_deinit (comp_hd_t handle, int d)
107{
108 int err;
109
110 if (handle != NULL)
111 {
112 switch (handle->algo)
113 {
114#ifdef HAVE_LIBZ
115 case GNUTLS_COMP_DEFLATE:
116 if (d)
117 err = inflateEnd (handle->handle);
118 else
119 err = deflateEnd (handle->handle);
120 break;
121#endif
122 default:
123 break;
124 }
125 gnutls_free (handle->handle);
126 gnutls_free (handle);
127
128 }
129}
130
131/* These functions are memory consuming
132 */
133
134int
135_gnutls_compress (comp_hd_t handle, const opaque * plain,
136 size_t plain_size, opaque ** compressed,
137 size_t max_comp_size)
138{
139 int compressed_size = GNUTLS_E_COMPRESSION_FAILED;
140 int err;
141
142 /* NULL compression is not handled here
143 */
144 if (handle == NULL)
145 {
146 gnutls_assert ();
147 return GNUTLS_E_INTERNAL_ERROR;
148 }
149
150 switch (handle->algo)
151 {
152
153#ifdef HAVE_LIBZ
154 case GNUTLS_COMP_DEFLATE:
155 {
156 uLongf size;
157 z_stream *zhandle;
158
159 size = (plain_size + plain_size) + 10;
160 *compressed = gnutls_malloc (size);
161 if (*compressed == NULL)
162 {
163 gnutls_assert ();
164 return GNUTLS_E_MEMORY_ERROR;
165 }
166
167 zhandle = handle->handle;
168
169 zhandle->next_in = (Bytef *) plain;
170 zhandle->avail_in = plain_size;
171 zhandle->next_out = (Bytef *) * compressed;
172 zhandle->avail_out = size;
173
174 err = deflate (zhandle, Z_SYNC_FLUSH);
175
176 if (err != Z_OK || zhandle->avail_in != 0)
177 {
178 gnutls_assert ();
179 gnutls_free (*compressed);
180 *compressed = NULL;
181 return GNUTLS_E_COMPRESSION_FAILED;
182 }
183
184 compressed_size = size - zhandle->avail_out;
185 break;
186 }
187#endif
188 default:
189 gnutls_assert ();
190 return GNUTLS_E_INTERNAL_ERROR;
191 } /* switch */
192
193#ifdef COMPRESSION_DEBUG
194 _gnutls_debug_log ("Compression ratio: %f\n",
195 (float) ((float) compressed_size / (float) plain_size));
196#endif
197
198 if ((size_t) compressed_size > max_comp_size)
199 {
200 gnutls_free (*compressed);
201 *compressed = NULL;
202 return GNUTLS_E_COMPRESSION_FAILED;
203 }
204
205 return compressed_size;
206}
207
208
209
210int
211_gnutls_decompress (comp_hd_t handle, opaque * compressed,
212 size_t compressed_size, opaque ** plain,
213 size_t max_record_size)
214{
215 int plain_size = GNUTLS_E_DECOMPRESSION_FAILED, err;
216 int cur_pos;
217
218 if (compressed_size > max_record_size + EXTRA_COMP_SIZE)
219 {
220 gnutls_assert ();
221 return GNUTLS_E_DECOMPRESSION_FAILED;
222 }
223
224 /* NULL compression is not handled here
225 */
226
227 if (handle == NULL)
228 {
229 gnutls_assert ();
230 return GNUTLS_E_INTERNAL_ERROR;
231 }
232
233 switch (handle->algo)
234 {
235#ifdef HAVE_LIBZ
236 case GNUTLS_COMP_DEFLATE:
237 {
238 uLongf out_size;
239 z_stream *zhandle;
240
241 *plain = NULL;
242 out_size = compressed_size + compressed_size;
243 plain_size = 0;
244
245 zhandle = handle->handle;
246
247 zhandle->next_in = (Bytef *) compressed;
248 zhandle->avail_in = compressed_size;
249
250 cur_pos = 0;
251
252 do
253 {
254 out_size += 512;
255 *plain = gnutls_realloc_fast (*plain, out_size);
256 if (*plain == NULL)
257 {
258 gnutls_assert ();
259 return GNUTLS_E_MEMORY_ERROR;
260 }
261
262 zhandle->next_out = (Bytef *) (*plain + cur_pos);
263 zhandle->avail_out = out_size - cur_pos;
264
265 err = inflate (zhandle, Z_SYNC_FLUSH);
266
267 cur_pos = out_size - zhandle->avail_out;
268
269 }
270 while ((err == Z_BUF_ERROR && zhandle->avail_out == 0
271 && out_size < max_record_size)
272 || (err == Z_OK && zhandle->avail_in != 0));
273
274 if (err != Z_OK)
275 {
276 gnutls_assert ();
277 gnutls_free (*plain);
278 *plain = NULL;
279 return GNUTLS_E_DECOMPRESSION_FAILED;
280 }
281
282 plain_size = out_size - zhandle->avail_out;
283 break;
284 }
285#endif
286 default:
287 gnutls_assert ();
288 return GNUTLS_E_INTERNAL_ERROR;
289 } /* switch */
290
291 if ((size_t) plain_size > max_record_size)
292 {
293 gnutls_assert ();
294 gnutls_free (*plain);
295 *plain = NULL;
296 return GNUTLS_E_DECOMPRESSION_FAILED;
297 }
298
299 return plain_size;
300}
diff --git a/src/daemon/https/tls/gnutls_compress_int.h b/src/daemon/https/tls/gnutls_compress_int.h
new file mode 100644
index 00000000..4479fb4d
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_compress_int.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_COMP_INT
26# define GNUTLS_COMP_INT
27
28#ifdef HAVE_LIBZ
29# include <zlib.h>
30#endif
31
32#define GNUTLS_COMP_FAILED NULL
33
34typedef struct comp_hd_t_STRUCT
35{
36 void *handle;
37 gnutls_compression_method_t algo;
38} *comp_hd_t;
39
40comp_hd_t _gnutls_comp_init (gnutls_compression_method_t, int d);
41void _gnutls_comp_deinit (comp_hd_t handle, int d);
42
43int _gnutls_decompress (comp_hd_t handle, opaque * compressed,
44 size_t compressed_size, opaque ** plain,
45 size_t max_record_size);
46int _gnutls_compress (comp_hd_t, const opaque * plain, size_t plain_size,
47 opaque ** compressed, size_t max_comp_size);
48
49#endif
diff --git a/src/daemon/https/tls/gnutls_constate.c b/src/daemon/https/tls/gnutls_constate.c
new file mode 100644
index 00000000..c2323c46
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_constate.c
@@ -0,0 +1,1039 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Functions that are supposed to run after the handshake procedure is
26 * finished. These functions activate the established security parameters.
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_constate.h>
31#include <gnutls_errors.h>
32#include <gnutls_kx.h>
33#include <gnutls_algorithms.h>
34#include <gnutls_num.h>
35#include <gnutls_datum.h>
36#include <gnutls_state.h>
37
38static const char keyexp[] = "key expansion";
39static const int keyexp_length = sizeof (keyexp) - 1;
40
41static const char ivblock[] = "IV block";
42static const int ivblock_length = sizeof (ivblock) - 1;
43
44static const char cliwrite[] = "client write key";
45static const int cliwrite_length = sizeof (cliwrite) - 1;
46
47static const char servwrite[] = "server write key";
48static const int servwrite_length = sizeof (servwrite) - 1;
49
50#define EXPORT_FINAL_KEY_SIZE 16
51
52/* This function is to be called after handshake, when master_secret,
53 * client_random and server_random have been initialized.
54 * This function creates the keys and stores them into pending session.
55 * (session->cipher_specs)
56 */
57int
58_gnutls_set_keys (gnutls_session_t session, int hash_size, int IV_size,
59 int key_size, int export_flag)
60{
61
62/* FIXME: This function is too long
63 */
64 opaque *key_block;
65 opaque rnd[2 * TLS_RANDOM_SIZE];
66 opaque rrnd[2 * TLS_RANDOM_SIZE];
67 int pos, ret;
68 int block_size;
69 char buf[65];
70
71 if (session->cipher_specs.generated_keys != 0)
72 {
73 /* keys have already been generated.
74 * reset generated_keys and exit normally.
75 */
76 session->cipher_specs.generated_keys = 0;
77 return 0;
78 }
79
80 block_size = 2 * hash_size + 2 * key_size;
81 if (export_flag == 0)
82 block_size += 2 * IV_size;
83
84 key_block = gnutls_secure_malloc (block_size);
85 if (key_block == NULL)
86 {
87 gnutls_assert ();
88 return GNUTLS_E_MEMORY_ERROR;
89 }
90
91 memcpy (rnd, session->security_parameters.server_random, TLS_RANDOM_SIZE);
92 memcpy (&rnd[TLS_RANDOM_SIZE],
93 session->security_parameters.client_random, TLS_RANDOM_SIZE);
94
95 memcpy (rrnd, session->security_parameters.client_random, TLS_RANDOM_SIZE);
96 memcpy (&rrnd[TLS_RANDOM_SIZE],
97 session->security_parameters.server_random, TLS_RANDOM_SIZE);
98
99 if (session->security_parameters.version == GNUTLS_SSL3)
100 { /* SSL 3 */
101 ret =
102 _gnutls_ssl3_generate_random (session->
103 security_parameters.
104 master_secret,
105 TLS_MASTER_SIZE, rnd,
106 2 * TLS_RANDOM_SIZE,
107 block_size, key_block);
108 }
109 else
110 { /* TLS 1.0 */
111 ret =
112 _gnutls_PRF (session, session->security_parameters.master_secret,
113 TLS_MASTER_SIZE, keyexp, keyexp_length,
114 rnd, 2 * TLS_RANDOM_SIZE, block_size, key_block);
115 }
116
117 if (ret < 0)
118 {
119 gnutls_assert ();
120 gnutls_free (key_block);
121 return ret;
122 }
123
124 _gnutls_hard_log ("INT: KEY BLOCK[%d]: %s\n", block_size,
125 _gnutls_bin2hex (key_block, block_size, buf,
126 sizeof (buf)));
127
128 pos = 0;
129 if (hash_size > 0)
130 {
131 if (_gnutls_sset_datum
132 (&session->cipher_specs.client_write_mac_secret,
133 &key_block[pos], hash_size) < 0)
134 {
135 gnutls_free (key_block);
136 return GNUTLS_E_MEMORY_ERROR;
137 }
138 pos += hash_size;
139
140 if (_gnutls_sset_datum
141 (&session->cipher_specs.server_write_mac_secret,
142 &key_block[pos], hash_size) < 0)
143 {
144 gnutls_free (key_block);
145 return GNUTLS_E_MEMORY_ERROR;
146 }
147 pos += hash_size;
148 }
149
150 if (key_size > 0)
151 {
152 opaque *client_write_key, *server_write_key;
153 int client_write_key_size, server_write_key_size;
154 int free_keys = 0;
155
156 if (export_flag == 0)
157 {
158 client_write_key = &key_block[pos];
159 client_write_key_size = key_size;
160
161 pos += key_size;
162
163 server_write_key = &key_block[pos];
164 server_write_key_size = key_size;
165
166 pos += key_size;
167
168 }
169 else
170 { /* export */
171 free_keys = 1;
172
173 client_write_key = gnutls_secure_malloc (EXPORT_FINAL_KEY_SIZE);
174 if (client_write_key == NULL)
175 {
176 gnutls_assert ();
177 gnutls_free (key_block);
178 return GNUTLS_E_MEMORY_ERROR;
179 }
180
181 server_write_key = gnutls_secure_malloc (EXPORT_FINAL_KEY_SIZE);
182 if (server_write_key == NULL)
183 {
184 gnutls_assert ();
185 gnutls_free (key_block);
186 gnutls_free (client_write_key);
187 return GNUTLS_E_MEMORY_ERROR;
188 }
189
190 /* generate the final keys */
191
192 if (session->security_parameters.version == GNUTLS_SSL3)
193 { /* SSL 3 */
194 ret =
195 _gnutls_ssl3_hash_md5 (&key_block[pos],
196 key_size, rrnd,
197 2 * TLS_RANDOM_SIZE,
198 EXPORT_FINAL_KEY_SIZE,
199 client_write_key);
200
201 }
202 else
203 { /* TLS 1.0 */
204 ret =
205 _gnutls_PRF (session, &key_block[pos], key_size,
206 cliwrite, cliwrite_length,
207 rrnd,
208 2 * TLS_RANDOM_SIZE,
209 EXPORT_FINAL_KEY_SIZE, client_write_key);
210 }
211
212 if (ret < 0)
213 {
214 gnutls_assert ();
215 gnutls_free (key_block);
216 gnutls_free (server_write_key);
217 gnutls_free (client_write_key);
218 return ret;
219 }
220
221 client_write_key_size = EXPORT_FINAL_KEY_SIZE;
222 pos += key_size;
223
224 if (session->security_parameters.version == GNUTLS_SSL3)
225 { /* SSL 3 */
226 ret =
227 _gnutls_ssl3_hash_md5 (&key_block[pos], key_size,
228 rnd, 2 * TLS_RANDOM_SIZE,
229 EXPORT_FINAL_KEY_SIZE,
230 server_write_key);
231 }
232 else
233 { /* TLS 1.0 */
234 ret =
235 _gnutls_PRF (session, &key_block[pos], key_size,
236 servwrite, servwrite_length,
237 rrnd, 2 * TLS_RANDOM_SIZE,
238 EXPORT_FINAL_KEY_SIZE, server_write_key);
239 }
240
241 if (ret < 0)
242 {
243 gnutls_assert ();
244 gnutls_free (key_block);
245 gnutls_free (server_write_key);
246 gnutls_free (client_write_key);
247 return ret;
248 }
249
250 server_write_key_size = EXPORT_FINAL_KEY_SIZE;
251 pos += key_size;
252 }
253
254 if (_gnutls_sset_datum
255 (&session->cipher_specs.client_write_key,
256 client_write_key, client_write_key_size) < 0)
257 {
258 gnutls_free (key_block);
259 gnutls_free (server_write_key);
260 gnutls_free (client_write_key);
261 return GNUTLS_E_MEMORY_ERROR;
262 }
263 _gnutls_hard_log ("INT: CLIENT WRITE KEY [%d]: %s\n",
264 client_write_key_size,
265 _gnutls_bin2hex (client_write_key,
266 client_write_key_size, buf,
267 sizeof (buf)));
268
269 if (_gnutls_sset_datum
270 (&session->cipher_specs.server_write_key,
271 server_write_key, server_write_key_size) < 0)
272 {
273 gnutls_free (key_block);
274 gnutls_free (server_write_key);
275 gnutls_free (client_write_key);
276 return GNUTLS_E_MEMORY_ERROR;
277 }
278
279 _gnutls_hard_log ("INT: SERVER WRITE KEY [%d]: %s\n",
280 server_write_key_size,
281 _gnutls_bin2hex (server_write_key,
282 server_write_key_size, buf,
283 sizeof (buf)));
284
285 if (free_keys != 0)
286 {
287 gnutls_free (server_write_key);
288 gnutls_free (client_write_key);
289 }
290 }
291
292
293 /* IV generation in export and non export ciphers.
294 */
295 if (IV_size > 0 && export_flag == 0)
296 {
297 if (_gnutls_sset_datum
298 (&session->cipher_specs.client_write_IV, &key_block[pos],
299 IV_size) < 0)
300 {
301 gnutls_free (key_block);
302 return GNUTLS_E_MEMORY_ERROR;
303 }
304 pos += IV_size;
305
306 if (_gnutls_sset_datum
307 (&session->cipher_specs.server_write_IV, &key_block[pos],
308 IV_size) < 0)
309 {
310 gnutls_free (key_block);
311 return GNUTLS_E_MEMORY_ERROR;
312 }
313 pos += IV_size;
314
315 }
316 else if (IV_size > 0 && export_flag != 0)
317 {
318 opaque *iv_block = gnutls_alloca (IV_size * 2);
319 if (iv_block == NULL)
320 {
321 gnutls_assert ();
322 gnutls_free (key_block);
323 return GNUTLS_E_MEMORY_ERROR;
324 }
325
326 if (session->security_parameters.version == GNUTLS_SSL3)
327 { /* SSL 3 */
328 ret = _gnutls_ssl3_hash_md5 ("", 0,
329 rrnd, TLS_RANDOM_SIZE * 2,
330 IV_size, iv_block);
331
332 if (ret < 0)
333 {
334 gnutls_assert ();
335 gnutls_free (key_block);
336 gnutls_afree (iv_block);
337 return ret;
338 }
339
340 ret = _gnutls_ssl3_hash_md5 ("", 0, rnd,
341 TLS_RANDOM_SIZE * 2,
342 IV_size, &iv_block[IV_size]);
343
344 }
345 else
346 { /* TLS 1.0 */
347 ret = _gnutls_PRF (session, "", 0,
348 ivblock, ivblock_length, rrnd,
349 2 * TLS_RANDOM_SIZE, IV_size * 2, iv_block);
350 }
351
352 if (ret < 0)
353 {
354 gnutls_assert ();
355 gnutls_afree (iv_block);
356 gnutls_free (key_block);
357 return ret;
358 }
359
360 if (_gnutls_sset_datum
361 (&session->cipher_specs.client_write_IV, iv_block, IV_size) < 0)
362 {
363 gnutls_afree (iv_block);
364 gnutls_free (key_block);
365 return GNUTLS_E_MEMORY_ERROR;
366 }
367
368 if (_gnutls_sset_datum
369 (&session->cipher_specs.server_write_IV,
370 &iv_block[IV_size], IV_size) < 0)
371 {
372 gnutls_afree (iv_block);
373 gnutls_free (key_block);
374 return GNUTLS_E_MEMORY_ERROR;
375 }
376
377 gnutls_afree (iv_block);
378 }
379
380 gnutls_free (key_block);
381
382 session->cipher_specs.generated_keys = 1;
383
384 return 0;
385}
386
387int
388_gnutls_set_read_keys (gnutls_session_t session)
389{
390 int hash_size;
391 int IV_size;
392 int key_size, export_flag;
393 gnutls_cipher_algorithm_t algo;
394 gnutls_mac_algorithm_t mac_algo;
395
396 mac_algo = session->security_parameters.read_mac_algorithm;
397 algo = session->security_parameters.read_bulk_cipher_algorithm;
398
399 hash_size = _gnutls_hash_get_algo_len (mac_algo);
400 IV_size = _gnutls_cipher_get_iv_size (algo);
401 key_size = gnutls_cipher_get_key_size (algo);
402 export_flag = _gnutls_cipher_get_export_flag (algo);
403
404 return _gnutls_set_keys (session, hash_size, IV_size, key_size,
405 export_flag);
406}
407
408int
409_gnutls_set_write_keys (gnutls_session_t session)
410{
411 int hash_size;
412 int IV_size;
413 int key_size, export_flag;
414 gnutls_cipher_algorithm_t algo;
415 gnutls_mac_algorithm_t mac_algo;
416
417 mac_algo = session->security_parameters.write_mac_algorithm;
418 algo = session->security_parameters.write_bulk_cipher_algorithm;
419
420 hash_size = _gnutls_hash_get_algo_len (mac_algo);
421 IV_size = _gnutls_cipher_get_iv_size (algo);
422 key_size = gnutls_cipher_get_key_size (algo);
423 export_flag = _gnutls_cipher_get_export_flag (algo);
424
425 return _gnutls_set_keys (session, hash_size, IV_size, key_size,
426 export_flag);
427}
428
429#define CPY_COMMON dst->entity = src->entity; \
430 dst->kx_algorithm = src->kx_algorithm; \
431 memcpy( &dst->current_cipher_suite, &src->current_cipher_suite, sizeof(cipher_suite_st)); \
432 memcpy( dst->master_secret, src->master_secret, TLS_MASTER_SIZE); \
433 memcpy( dst->client_random, src->client_random, TLS_RANDOM_SIZE); \
434 memcpy( dst->server_random, src->server_random, TLS_RANDOM_SIZE); \
435 memcpy( dst->session_id, src->session_id, TLS_MAX_SESSION_ID_SIZE); \
436 dst->session_id_size = src->session_id_size; \
437 dst->cert_type = src->cert_type; \
438 dst->timestamp = src->timestamp; \
439 dst->max_record_recv_size = src->max_record_recv_size; \
440 dst->max_record_send_size = src->max_record_send_size; \
441 dst->version = src->version; \
442 memcpy( &dst->extensions, &src->extensions, sizeof(tls_ext_st)); \
443 memcpy( &dst->inner_secret, &src->inner_secret, TLS_MASTER_SIZE);
444
445static void
446_gnutls_cpy_read_security_parameters (security_parameters_st *
447 dst, security_parameters_st * src)
448{
449 CPY_COMMON;
450
451 dst->read_bulk_cipher_algorithm = src->read_bulk_cipher_algorithm;
452 dst->read_mac_algorithm = src->read_mac_algorithm;
453 dst->read_compression_algorithm = src->read_compression_algorithm;
454}
455
456static void
457_gnutls_cpy_write_security_parameters (security_parameters_st *
458 dst, security_parameters_st * src)
459{
460 CPY_COMMON;
461
462 dst->write_bulk_cipher_algorithm = src->write_bulk_cipher_algorithm;
463 dst->write_mac_algorithm = src->write_mac_algorithm;
464 dst->write_compression_algorithm = src->write_compression_algorithm;
465}
466
467/* Sets the current connection session to conform with the
468 * Security parameters(pending session), and initializes encryption.
469 * Actually it initializes and starts encryption ( so it needs
470 * secrets and random numbers to have been negotiated)
471 * This is to be called after sending the Change Cipher Spec packet.
472 */
473int
474_gnutls_connection_state_init (gnutls_session_t session)
475{
476 int ret;
477
478/* Setup the master secret
479 */
480 if ((ret = _gnutls_generate_master (session, 0), 0) < 0)
481 {
482 gnutls_assert ();
483 return ret;
484 }
485
486
487 return 0;
488}
489
490
491/* Initializes the read connection session
492 * (read encrypted data)
493 */
494int
495_gnutls_read_connection_state_init (gnutls_session_t session)
496{
497 int mac_size;
498 int rc;
499
500 _gnutls_uint64zero (session->connection_state.read_sequence_number);
501
502/* Update internals from CipherSuite selected.
503 * If we are resuming just copy the connection session
504 */
505 if (session->internals.resumed == RESUME_FALSE)
506 {
507 rc = _gnutls_set_read_cipher (session,
508 _gnutls_cipher_suite_get_cipher_algo
509 (&session->security_parameters.
510 current_cipher_suite));
511 if (rc < 0)
512 return rc;
513 rc = _gnutls_set_read_mac (session,
514 _gnutls_cipher_suite_get_mac_algo
515 (&session->security_parameters.
516 current_cipher_suite));
517 if (rc < 0)
518 return rc;
519
520 rc = _gnutls_set_kx (session,
521 _gnutls_cipher_suite_get_kx_algo
522 (&session->security_parameters.
523 current_cipher_suite));
524 if (rc < 0)
525 return rc;
526
527 rc = _gnutls_set_read_compression (session,
528 session->internals.
529 compression_method);
530 if (rc < 0)
531 return rc;
532 }
533 else
534 { /* RESUME_TRUE */
535 _gnutls_cpy_read_security_parameters (&session->
536 security_parameters,
537 &session->
538 internals.
539 resumed_security_parameters);
540 }
541
542
543 rc = _gnutls_set_read_keys (session);
544 if (rc < 0)
545 return rc;
546
547 _gnutls_handshake_log ("HSK[%x]: Cipher Suite: %s\n",
548 session, _gnutls_cipher_suite_get_name (&session->
549 security_parameters.
550 current_cipher_suite));
551
552 if (_gnutls_compression_is_ok
553 (session->security_parameters.read_compression_algorithm) != 0)
554 {
555 gnutls_assert ();
556 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
557 }
558
559 if (_gnutls_mac_is_ok
560 (session->security_parameters.read_mac_algorithm) != 0)
561 {
562 gnutls_assert ();
563 return GNUTLS_E_INTERNAL_ERROR;
564 }
565
566 /* Free all the previous keys/ sessions etc.
567 */
568 if (session->connection_state.read_mac_secret.data != NULL)
569 _gnutls_free_datum (&session->connection_state.read_mac_secret);
570
571 if (session->connection_state.read_cipher_state != NULL)
572 _gnutls_cipher_deinit (session->connection_state.read_cipher_state);
573
574 if (session->connection_state.read_compression_state != NULL)
575 _gnutls_comp_deinit (session->connection_state.read_compression_state, 1);
576
577
578 mac_size =
579 _gnutls_hash_get_algo_len (session->security_parameters.
580 read_mac_algorithm);
581
582 _gnutls_handshake_log
583 ("HSK[%x]: Initializing internal [read] cipher sessions\n", session);
584
585 switch (session->security_parameters.entity)
586 {
587 case GNUTLS_SERVER:
588 /* initialize cipher session
589 */
590 session->connection_state.read_cipher_state =
591 _gnutls_cipher_init (session->security_parameters.
592 read_bulk_cipher_algorithm,
593 &session->cipher_specs.
594 client_write_key,
595 &session->cipher_specs.client_write_IV);
596 if (session->connection_state.read_cipher_state ==
597 GNUTLS_CIPHER_FAILED
598 && session->security_parameters.
599 read_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
600 {
601 gnutls_assert ();
602 return GNUTLS_E_INTERNAL_ERROR;
603 }
604
605 /* copy mac secrets from cipherspecs, to connection
606 * session.
607 */
608 if (mac_size > 0)
609 {
610 if (_gnutls_sset_datum (&session->connection_state.
611 read_mac_secret,
612 session->cipher_specs.
613 client_write_mac_secret.data,
614 session->cipher_specs.
615 client_write_mac_secret.size) < 0)
616 {
617 gnutls_assert ();
618 return GNUTLS_E_MEMORY_ERROR;
619 }
620
621 }
622
623 break;
624
625 case GNUTLS_CLIENT:
626 session->connection_state.read_cipher_state =
627 _gnutls_cipher_init (session->security_parameters.
628 read_bulk_cipher_algorithm,
629 &session->cipher_specs.
630 server_write_key,
631 &session->cipher_specs.server_write_IV);
632
633 if (session->connection_state.read_cipher_state ==
634 GNUTLS_CIPHER_FAILED
635 && session->security_parameters.
636 read_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
637 {
638 gnutls_assert ();
639 return GNUTLS_E_INTERNAL_ERROR;
640 }
641
642
643 /* copy mac secret to connection session
644 */
645 if (mac_size > 0)
646 {
647 if (_gnutls_sset_datum (&session->connection_state.
648 read_mac_secret,
649 session->cipher_specs.
650 server_write_mac_secret.data,
651 session->cipher_specs.
652 server_write_mac_secret.size) < 0)
653 {
654 gnutls_assert ();
655 return GNUTLS_E_MEMORY_ERROR;
656 }
657 }
658
659 break;
660
661 default: /* this check is useless */
662 gnutls_assert ();
663 return GNUTLS_E_INTERNAL_ERROR;
664 }
665
666 session->connection_state.read_compression_state =
667 _gnutls_comp_init (session->security_parameters.
668 read_compression_algorithm, 1);
669
670 if (session->connection_state.read_compression_state == GNUTLS_COMP_FAILED)
671 {
672 gnutls_assert ();
673 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
674 }
675
676 return 0;
677}
678
679
680
681/* Initializes the write connection session
682 * (write encrypted data)
683 */
684int
685_gnutls_write_connection_state_init (gnutls_session_t session)
686{
687 int mac_size;
688 int rc;
689
690 _gnutls_uint64zero (session->connection_state.write_sequence_number);
691
692/* Update internals from CipherSuite selected.
693 * If we are resuming just copy the connection session
694 */
695 if (session->internals.resumed == RESUME_FALSE)
696 {
697 rc = _gnutls_set_write_cipher (session,
698 _gnutls_cipher_suite_get_cipher_algo
699 (&session->security_parameters.
700 current_cipher_suite));
701 if (rc < 0)
702 return rc;
703 rc = _gnutls_set_write_mac (session,
704 _gnutls_cipher_suite_get_mac_algo
705 (&session->security_parameters.
706 current_cipher_suite));
707 if (rc < 0)
708 return rc;
709
710 rc = _gnutls_set_kx (session,
711 _gnutls_cipher_suite_get_kx_algo
712 (&session->security_parameters.
713 current_cipher_suite));
714 if (rc < 0)
715 return rc;
716
717 rc = _gnutls_set_write_compression (session,
718 session->internals.
719 compression_method);
720 if (rc < 0)
721 return rc;
722 }
723 else
724 { /* RESUME_TRUE */
725 _gnutls_cpy_write_security_parameters (&session->
726 security_parameters,
727 &session->
728 internals.
729 resumed_security_parameters);
730 }
731
732 rc = _gnutls_set_write_keys (session);
733 if (rc < 0)
734 return rc;
735
736 _gnutls_handshake_log ("HSK[%x]: Cipher Suite: %s\n", session,
737 _gnutls_cipher_suite_get_name (&session->
738 security_parameters.
739 current_cipher_suite));
740
741 if (_gnutls_compression_is_ok
742 (session->security_parameters.write_compression_algorithm) != 0)
743 {
744 gnutls_assert ();
745 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
746 }
747
748 if (_gnutls_mac_is_ok
749 (session->security_parameters.write_mac_algorithm) != 0)
750 {
751 gnutls_assert ();
752 return GNUTLS_E_INTERNAL_ERROR;
753 }
754
755
756
757 /* Free all the previous keys/ sessions etc.
758 */
759 if (session->connection_state.write_mac_secret.data != NULL)
760 _gnutls_free_datum (&session->connection_state.write_mac_secret);
761
762 if (session->connection_state.write_cipher_state != NULL)
763 _gnutls_cipher_deinit (session->connection_state.write_cipher_state);
764
765 if (session->connection_state.write_compression_state != NULL)
766 _gnutls_comp_deinit (session->connection_state.
767 write_compression_state, 0);
768
769 mac_size =
770 _gnutls_hash_get_algo_len (session->security_parameters.
771 write_mac_algorithm);
772
773 _gnutls_handshake_log
774 ("HSK[%x]: Initializing internal [write] cipher sessions\n", session);
775
776 switch (session->security_parameters.entity)
777 {
778 case GNUTLS_SERVER:
779 /* initialize cipher session
780 */
781 session->connection_state.write_cipher_state =
782 _gnutls_cipher_init (session->security_parameters.
783 write_bulk_cipher_algorithm,
784 &session->cipher_specs.
785 server_write_key,
786 &session->cipher_specs.server_write_IV);
787
788 if (session->connection_state.write_cipher_state ==
789 GNUTLS_CIPHER_FAILED
790 && session->security_parameters.
791 write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
792 {
793 gnutls_assert ();
794 return GNUTLS_E_INTERNAL_ERROR;
795 }
796
797
798 /* copy mac secrets from cipherspecs, to connection
799 * session.
800 */
801 if (mac_size > 0)
802 {
803 if (_gnutls_sset_datum (&session->connection_state.
804 write_mac_secret,
805 session->cipher_specs.
806 server_write_mac_secret.data,
807 session->cipher_specs.
808 server_write_mac_secret.size) < 0)
809 {
810 gnutls_assert ();
811 return GNUTLS_E_MEMORY_ERROR;
812 }
813
814 }
815
816
817 break;
818
819 case GNUTLS_CLIENT:
820 session->connection_state.write_cipher_state =
821 _gnutls_cipher_init (session->security_parameters.
822 write_bulk_cipher_algorithm,
823 &session->cipher_specs.
824 client_write_key,
825 &session->cipher_specs.client_write_IV);
826
827 if (session->connection_state.write_cipher_state ==
828 GNUTLS_CIPHER_FAILED
829 && session->security_parameters.
830 write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
831 {
832 gnutls_assert ();
833 return GNUTLS_E_INTERNAL_ERROR;
834 }
835
836 /* copy mac secret to connection session
837 */
838 if (mac_size > 0)
839 {
840 if (_gnutls_sset_datum (&session->connection_state.
841 write_mac_secret,
842 session->cipher_specs.
843 client_write_mac_secret.data,
844 session->cipher_specs.
845 client_write_mac_secret.size) < 0)
846 {
847 gnutls_assert ();
848 return GNUTLS_E_MEMORY_ERROR;
849 }
850 }
851
852 break;
853
854 default:
855 gnutls_assert ();
856 return GNUTLS_E_INTERNAL_ERROR;
857 }
858
859
860 session->connection_state.write_compression_state =
861 _gnutls_comp_init (session->security_parameters.
862 write_compression_algorithm, 0);
863
864 if (session->connection_state.write_compression_state == GNUTLS_COMP_FAILED)
865 {
866 gnutls_assert ();
867 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
868 }
869
870 return 0;
871}
872
873/* Sets the specified cipher into the pending session
874 */
875int
876_gnutls_set_read_cipher (gnutls_session_t session,
877 gnutls_cipher_algorithm_t algo)
878{
879
880 if (_gnutls_cipher_is_ok (algo) == 0)
881 {
882 if (_gnutls_cipher_priority (session, algo) < 0)
883 {
884 gnutls_assert ();
885 return GNUTLS_E_UNWANTED_ALGORITHM;
886 }
887
888 session->security_parameters.read_bulk_cipher_algorithm = algo;
889
890 }
891 else
892 {
893 gnutls_assert ();
894 return GNUTLS_E_INTERNAL_ERROR;
895 }
896
897 return 0;
898
899}
900
901int
902_gnutls_set_write_cipher (gnutls_session_t session,
903 gnutls_cipher_algorithm_t algo)
904{
905
906 if (_gnutls_cipher_is_ok (algo) == 0)
907 {
908 if (_gnutls_cipher_priority (session, algo) < 0)
909 {
910 gnutls_assert ();
911 return GNUTLS_E_UNWANTED_ALGORITHM;
912 }
913
914 session->security_parameters.write_bulk_cipher_algorithm = algo;
915
916 }
917 else
918 {
919 gnutls_assert ();
920 return GNUTLS_E_INTERNAL_ERROR;
921 }
922
923 return 0;
924
925}
926
927
928/* Sets the specified algorithm into pending compression session
929 */
930int
931_gnutls_set_read_compression (gnutls_session_t session,
932 gnutls_compression_method_t algo)
933{
934
935 if (_gnutls_compression_is_ok (algo) == 0)
936 {
937 session->security_parameters.read_compression_algorithm = algo;
938 }
939 else
940 {
941 gnutls_assert ();
942 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
943 }
944 return 0;
945
946}
947
948int
949_gnutls_set_write_compression (gnutls_session_t session,
950 gnutls_compression_method_t algo)
951{
952
953 if (_gnutls_compression_is_ok (algo) == 0)
954 {
955 session->security_parameters.write_compression_algorithm = algo;
956 }
957 else
958 {
959 gnutls_assert ();
960 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
961 }
962 return 0;
963
964}
965
966/* Sets the specified kx algorithm into pending session
967 */
968int
969_gnutls_set_kx (gnutls_session_t session, gnutls_kx_algorithm_t algo)
970{
971
972 if (_gnutls_kx_is_ok (algo) == 0)
973 {
974 session->security_parameters.kx_algorithm = algo;
975 }
976 else
977 {
978 gnutls_assert ();
979 return GNUTLS_E_INTERNAL_ERROR;
980 }
981 if (_gnutls_kx_priority (session, algo) < 0)
982 {
983 gnutls_assert ();
984 /* we shouldn't get here */
985 return GNUTLS_E_UNWANTED_ALGORITHM;
986 }
987
988 return 0;
989
990}
991
992/* Sets the specified mac algorithm into pending session */
993int
994_gnutls_set_read_mac (gnutls_session_t session, gnutls_mac_algorithm_t algo)
995{
996
997 if (_gnutls_mac_is_ok (algo) == 0)
998 {
999 session->security_parameters.read_mac_algorithm = algo;
1000 }
1001 else
1002 {
1003 gnutls_assert ();
1004 return GNUTLS_E_INTERNAL_ERROR;
1005 }
1006 if (_gnutls_mac_priority (session, algo) < 0)
1007 {
1008 gnutls_assert ();
1009 return GNUTLS_E_UNWANTED_ALGORITHM;
1010 }
1011
1012
1013 return 0;
1014
1015}
1016
1017int
1018_gnutls_set_write_mac (gnutls_session_t session, gnutls_mac_algorithm_t algo)
1019{
1020
1021 if (_gnutls_mac_is_ok (algo) == 0)
1022 {
1023 session->security_parameters.write_mac_algorithm = algo;
1024 }
1025 else
1026 {
1027 gnutls_assert ();
1028 return GNUTLS_E_INTERNAL_ERROR;
1029 }
1030 if (_gnutls_mac_priority (session, algo) < 0)
1031 {
1032 gnutls_assert ();
1033 return GNUTLS_E_UNWANTED_ALGORITHM;
1034 }
1035
1036
1037 return 0;
1038
1039}
diff --git a/src/daemon/https/tls/gnutls_constate.h b/src/daemon/https/tls/gnutls_constate.h
new file mode 100644
index 00000000..f58c8b14
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_constate.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_connection_state_init (gnutls_session_t session);
26int _gnutls_read_connection_state_init (gnutls_session_t session);
27int _gnutls_write_connection_state_init (gnutls_session_t session);
28int _gnutls_set_write_cipher (gnutls_session_t session,
29 gnutls_cipher_algorithm_t algo);
30int _gnutls_set_write_mac (gnutls_session_t session,
31 gnutls_mac_algorithm_t algo);
32int _gnutls_set_read_cipher (gnutls_session_t session,
33 gnutls_cipher_algorithm_t algo);
34int _gnutls_set_read_mac (gnutls_session_t session,
35 gnutls_mac_algorithm_t algo);
36int _gnutls_set_read_compression (gnutls_session_t session,
37 gnutls_compression_method_t algo);
38int _gnutls_set_write_compression (gnutls_session_t session,
39 gnutls_compression_method_t algo);
40int _gnutls_set_kx (gnutls_session_t session, gnutls_kx_algorithm_t algo);
diff --git a/src/daemon/https/tls/gnutls_datum.c b/src/daemon/https/tls/gnutls_datum.c
new file mode 100644
index 00000000..4b2eb1f4
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_datum.c
@@ -0,0 +1,114 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* contains functions that make it easier to
26 * write vectors of <size|data>. The destination size
27 * should be preallocated (datum.size+(bits/8))
28 */
29
30#include <gnutls_int.h>
31#include <gnutls_num.h>
32#include <gnutls_datum.h>
33#include <gnutls_errors.h>
34
35
36void
37_gnutls_write_datum16 (opaque * dest, gnutls_datum_t dat)
38{
39 _gnutls_write_uint16 (dat.size, dest);
40 if (dat.data != NULL)
41 memcpy (&dest[2], dat.data, dat.size);
42}
43
44void
45_gnutls_write_datum24 (opaque * dest, gnutls_datum_t dat)
46{
47 _gnutls_write_uint24 (dat.size, dest);
48 if (dat.data != NULL)
49 memcpy (&dest[3], dat.data, dat.size);
50}
51
52void
53_gnutls_write_datum32 (opaque * dest, gnutls_datum_t dat)
54{
55 _gnutls_write_uint32 (dat.size, dest);
56 if (dat.data != NULL)
57 memcpy (&dest[4], dat.data, dat.size);
58}
59
60void
61_gnutls_write_datum8 (opaque * dest, gnutls_datum_t dat)
62{
63 dest[0] = (uint8_t) dat.size;
64 if (dat.data != NULL)
65 memcpy (&dest[1], dat.data, dat.size);
66}
67
68
69int
70_gnutls_set_datum_m (gnutls_datum_t * dat, const void *data,
71 size_t data_size, gnutls_alloc_function galloc_func)
72{
73 if (data_size == 0 || data == NULL)
74 {
75 dat->data = NULL;
76 dat->size = 0;
77 return 0;
78 }
79
80 dat->data = galloc_func (data_size);
81 if (dat->data == NULL)
82 return GNUTLS_E_MEMORY_ERROR;
83
84 dat->size = data_size;
85 memcpy (dat->data, data, data_size);
86
87 return 0;
88}
89
90int
91_gnutls_datum_append_m (gnutls_datum_t * dst, const void *data,
92 size_t data_size,
93 gnutls_realloc_function grealloc_func)
94{
95
96 dst->data = grealloc_func (dst->data, data_size + dst->size);
97 if (dst->data == NULL)
98 return GNUTLS_E_MEMORY_ERROR;
99
100 memcpy (&dst->data[dst->size], data, data_size);
101 dst->size += data_size;
102
103 return 0;
104}
105
106void
107_gnutls_free_datum_m (gnutls_datum_t * dat, gnutls_free_function gfree_func)
108{
109 if (dat->data != NULL)
110 gfree_func (dat->data);
111
112 dat->data = NULL;
113 dat->size = 0;
114}
diff --git a/src/daemon/https/tls/gnutls_datum.h b/src/daemon/https/tls/gnutls_datum.h
new file mode 100644
index 00000000..0f609531
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_datum.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25void _gnutls_write_datum16 (opaque * dest, gnutls_datum_t dat);
26void _gnutls_write_datum24 (opaque * dest, gnutls_datum_t dat);
27void _gnutls_write_datum32 (opaque * dest, gnutls_datum_t dat);
28void _gnutls_write_datum8 (opaque * dest, gnutls_datum_t dat);
29
30int _gnutls_set_datum_m (gnutls_datum_t * dat, const void *data,
31 size_t data_size, gnutls_alloc_function);
32#define _gnutls_set_datum( x, y, z) _gnutls_set_datum_m(x,y,z, gnutls_malloc)
33#define _gnutls_sset_datum( x, y, z) _gnutls_set_datum_m(x,y,z, gnutls_secure_malloc)
34
35int _gnutls_datum_append_m (gnutls_datum_t * dat, const void *data,
36 size_t data_size, gnutls_realloc_function);
37#define _gnutls_datum_append(x,y,z) _gnutls_datum_append_m(x,y,z, gnutls_realloc)
38
39void _gnutls_free_datum_m (gnutls_datum_t * dat, gnutls_free_function);
40#define _gnutls_free_datum(x) _gnutls_free_datum_m(x, gnutls_free)
diff --git a/src/daemon/https/tls/gnutls_db.c b/src/daemon/https/tls/gnutls_db.c
new file mode 100644
index 00000000..701be2f0
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_db.c
@@ -0,0 +1,386 @@
1/*
2 * Copyright (C) 2000, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains functions that manipulate a database backend
26 * for resumed sessions.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_errors.h"
31#include "gnutls_session.h"
32#include <gnutls_db.h>
33#include "debug.h"
34#include <gnutls_session_pack.h>
35#include <gnutls_datum.h>
36
37/**
38 * gnutls_db_set_retrieve_function - Sets the function that will be used to get data
39 * @session: is a #gnutls_session_t structure.
40 * @retr_func: is the function.
41 *
42 * Sets the function that will be used to retrieve data from the resumed
43 * sessions database. This function must return a gnutls_datum_t containing the
44 * data on success, or a gnutls_datum_t containing null and 0 on failure.
45 *
46 * The datum's data must be allocated using the function
47 * gnutls_malloc().
48 *
49 * The first argument to retr_func() will be null unless gnutls_db_set_ptr()
50 * has been called.
51 *
52 **/
53void
54gnutls_db_set_retrieve_function (gnutls_session_t session,
55 gnutls_db_retr_func retr_func)
56{
57 session->internals.db_retrieve_func = retr_func;
58}
59
60/**
61 * gnutls_db_set_remove_function - Sets the function that will be used to remove data
62 * @session: is a #gnutls_session_t structure.
63 * @rem_func: is the function.
64 *
65 * Sets the function that will be used to remove data from the resumed
66 * sessions database. This function must return 0 on success.
67 *
68 * The first argument to rem_func() will be null unless gnutls_db_set_ptr()
69 * has been called.
70 *
71 **/
72void
73gnutls_db_set_remove_function (gnutls_session_t session,
74 gnutls_db_remove_func rem_func)
75{
76 session->internals.db_remove_func = rem_func;
77}
78
79/**
80 * gnutls_db_set_store_function - Sets the function that will be used to put data
81 * @session: is a #gnutls_session_t structure.
82 * @store_func: is the function
83 *
84 * Sets the function that will be used to store data from the resumed
85 * sessions database. This function must remove 0 on success.
86 *
87 * The first argument to store_func() will be null unless gnutls_db_set_ptr()
88 * has been called.
89 *
90 **/
91void
92gnutls_db_set_store_function (gnutls_session_t session,
93 gnutls_db_store_func store_func)
94{
95 session->internals.db_store_func = store_func;
96}
97
98/**
99 * gnutls_db_set_ptr - Sets a pointer to be sent to db functions
100 * @session: is a #gnutls_session_t structure.
101 * @ptr: is the pointer
102 *
103 * Sets the pointer that will be provided to db store, retrieve and delete functions, as
104 * the first argument.
105 *
106 **/
107void
108gnutls_db_set_ptr (gnutls_session_t session, void *ptr)
109{
110 session->internals.db_ptr = ptr;
111}
112
113/**
114 * gnutls_db_get_ptr - Returns the pointer which is sent to db functions
115 * @session: is a #gnutls_session_t structure.
116 *
117 * Returns the pointer that will be sent to db store, retrieve and delete functions, as
118 * the first argument.
119 *
120 **/
121void *
122gnutls_db_get_ptr (gnutls_session_t session)
123{
124 return session->internals.db_ptr;
125}
126
127/**
128 * gnutls_db_set_cache_expiration - Sets the expiration time for resumed sessions.
129 * @session: is a #gnutls_session_t structure.
130 * @seconds: is the number of seconds.
131 *
132 * Sets the expiration time for resumed sessions. The default is 3600 (one hour)
133 * at the time writing this.
134 **/
135void
136gnutls_db_set_cache_expiration (gnutls_session_t session, int seconds)
137{
138 session->internals.expire_time = seconds;
139}
140
141/**
142 * gnutls_db_check_entry - checks if the given db entry has expired
143 * @session: is a #gnutls_session_t structure.
144 * @session_entry: is the session data (not key)
145 *
146 * This function returns GNUTLS_E_EXPIRED, if the database entry
147 * has expired or 0 otherwise. This function is to be used when
148 * you want to clear unnesessary session which occupy space in your
149 * backend.
150 *
151 **/
152int
153gnutls_db_check_entry (gnutls_session_t session, gnutls_datum_t session_entry)
154{
155 time_t timestamp;
156
157 timestamp = time (0);
158
159 if (session_entry.data != NULL)
160 if (timestamp -
161 ((security_parameters_st *) (session_entry.data))->timestamp <=
162 session->internals.expire_time
163 || ((security_parameters_st *) (session_entry.data))->
164 timestamp > timestamp
165 || ((security_parameters_st *) (session_entry.data))->timestamp == 0)
166 return GNUTLS_E_EXPIRED;
167
168 return 0;
169}
170
171/* The format of storing data is:
172 * (forget it). Check gnutls_session_pack.c
173 */
174int
175_gnutls_server_register_current_session (gnutls_session_t session)
176{
177 gnutls_datum_t key;
178 gnutls_datum_t content;
179 int ret = 0;
180
181 key.data = session->security_parameters.session_id;
182 key.size = session->security_parameters.session_id_size;
183
184 if (session->internals.resumable == RESUME_FALSE)
185 {
186 gnutls_assert ();
187 return GNUTLS_E_INVALID_SESSION;
188 }
189
190 if (session->security_parameters.session_id == NULL
191 || session->security_parameters.session_id_size == 0)
192 {
193 gnutls_assert ();
194 return GNUTLS_E_INVALID_SESSION;
195 }
196
197/* copy data */
198 ret = _gnutls_session_pack (session, &content);
199 if (ret < 0)
200 {
201 gnutls_assert ();
202 return ret;
203 }
204
205 ret = _gnutls_store_session (session, key, content);
206 _gnutls_free_datum (&content);
207
208 return ret;
209}
210
211/* Checks if both db_store and db_retrieve functions have
212 * been set up.
213 */
214static int
215_gnutls_db_func_is_ok (gnutls_session_t session)
216{
217 if (session->internals.db_store_func != NULL &&
218 session->internals.db_retrieve_func != NULL &&
219 session->internals.db_remove_func != NULL)
220 return 0;
221 else
222 return GNUTLS_E_DB_ERROR;
223}
224
225
226int
227_gnutls_server_restore_session (gnutls_session_t session,
228 uint8_t * session_id, int session_id_size)
229{
230 gnutls_datum_t data;
231 gnutls_datum_t key;
232 int ret;
233
234 key.data = session_id;
235 key.size = session_id_size;
236
237 if (_gnutls_db_func_is_ok (session) != 0)
238 {
239 gnutls_assert ();
240 return GNUTLS_E_INVALID_SESSION;
241 }
242
243 data = _gnutls_retrieve_session (session, key);
244
245 if (data.data == NULL)
246 {
247 gnutls_assert ();
248 return GNUTLS_E_INVALID_SESSION;
249 }
250
251 /* expiration check is performed inside */
252 ret = gnutls_session_set_data (session, data.data, data.size);
253 if (ret < 0)
254 {
255 gnutls_assert ();
256 return ret;
257 }
258
259 gnutls_free (data.data);
260
261 return 0;
262}
263
264int
265_gnutls_db_remove_session (gnutls_session_t session, uint8_t * session_id,
266 int session_id_size)
267{
268 gnutls_datum_t key;
269
270 key.data = session_id;
271 key.size = session_id_size;
272
273 return _gnutls_remove_session (session, key);
274}
275
276
277/* Stores session data to the db backend.
278 */
279int
280_gnutls_store_session (gnutls_session_t session,
281 gnutls_datum_t session_id, gnutls_datum_t session_data)
282{
283 int ret = 0;
284
285 if (session->internals.resumable == RESUME_FALSE)
286 {
287 gnutls_assert ();
288 return GNUTLS_E_INVALID_SESSION;
289 }
290
291 if (_gnutls_db_func_is_ok (session) != 0)
292 {
293 return GNUTLS_E_DB_ERROR;
294 }
295
296 if (session_id.data == NULL || session_id.size == 0)
297 {
298 gnutls_assert ();
299 return GNUTLS_E_INVALID_SESSION;
300 }
301
302 if (session_data.data == NULL || session_data.size == 0)
303 {
304 gnutls_assert ();
305 return GNUTLS_E_INVALID_SESSION;
306 }
307 /* if we can't read why bother writing? */
308
309 if (session->internals.db_store_func != NULL)
310 ret =
311 session->internals.db_store_func (session->internals.db_ptr,
312 session_id, session_data);
313
314 return (ret == 0 ? ret : GNUTLS_E_DB_ERROR);
315
316}
317
318/* Retrieves session data from the db backend.
319 */
320gnutls_datum_t
321_gnutls_retrieve_session (gnutls_session_t session, gnutls_datum_t session_id)
322{
323 gnutls_datum_t ret = { NULL, 0 };
324
325 if (session_id.data == NULL || session_id.size == 0)
326 {
327 gnutls_assert ();
328 return ret;
329 }
330
331 if (session->internals.db_retrieve_func != NULL)
332 ret =
333 session->internals.db_retrieve_func (session->internals.db_ptr,
334 session_id);
335
336 return ret;
337
338}
339
340/* Removes session data from the db backend.
341 */
342int
343_gnutls_remove_session (gnutls_session_t session, gnutls_datum_t session_id)
344{
345 int ret = 0;
346
347 if (_gnutls_db_func_is_ok (session) != 0)
348 {
349 return GNUTLS_E_DB_ERROR;
350 }
351
352 if (session_id.data == NULL || session_id.size == 0)
353 return GNUTLS_E_INVALID_SESSION;
354
355 /* if we can't read why bother writing? */
356 if (session->internals.db_remove_func != NULL)
357 ret =
358 session->internals.db_remove_func (session->internals.db_ptr,
359 session_id);
360
361 return (ret == 0 ? ret : GNUTLS_E_DB_ERROR);
362
363}
364
365/**
366 * gnutls_db_remove_session - This function will remove the current session data from the database
367 * @session: is a #gnutls_session_t structure.
368 *
369 * This function will remove the current session data from the session
370 * database. This will prevent future handshakes reusing these session
371 * data. This function should be called if a session was terminated
372 * abnormally, and before gnutls_deinit() is called.
373 *
374 * Normally gnutls_deinit() will remove abnormally terminated sessions.
375 *
376 **/
377void
378gnutls_db_remove_session (gnutls_session_t session)
379{
380 /* if the session has failed abnormally it has
381 * to be removed from the db
382 */
383 _gnutls_db_remove_session (session,
384 session->security_parameters.session_id,
385 session->security_parameters.session_id_size);
386}
diff --git a/src/daemon/https/tls/gnutls_db.h b/src/daemon/https/tls/gnutls_db.h
new file mode 100644
index 00000000..9adece4e
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_db.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_server_register_current_session (gnutls_session_t session);
26int _gnutls_server_restore_session (gnutls_session_t session,
27 uint8_t * session_id,
28 int session_id_size);
29int _gnutls_db_remove_session (gnutls_session_t session, uint8_t * session_id,
30 int session_id_size);
31int _gnutls_store_session (gnutls_session_t session,
32 gnutls_datum_t session_id,
33 gnutls_datum_t session_data);
34gnutls_datum_t _gnutls_retrieve_session (gnutls_session_t session,
35 gnutls_datum_t session_id);
36int _gnutls_remove_session (gnutls_session_t session,
37 gnutls_datum_t session_id);
diff --git a/src/daemon/https/tls/gnutls_dh.c b/src/daemon/https/tls/gnutls_dh.c
new file mode 100644
index 00000000..19322c73
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_dh.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27
28
29/*
30 --Example--
31 you: X = g ^ x mod p;
32 peer:Y = g ^ y mod p;
33
34 your_key = Y ^ x mod p;
35 his_key = X ^ y mod p;
36
37// generate our secret and the public value (X) for it
38 X = gnutls_calc_dh_secret(&x, g, p);
39// now we can calculate the shared secret
40 key = gnutls_calc_dh_key(Y, x, g, p);
41 _gnutls_mpi_release(x);
42 _gnutls_mpi_release(g);
43*/
44
45#define MAX_BITS 18000
46
47/* returns the public value (X), and the secret (ret_x).
48 */
49mpi_t
50gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime)
51{
52 mpi_t e, x;
53 int x_size = _gnutls_mpi_get_nbits (prime) - 1;
54 /* The size of the secret key is less than
55 * prime/2
56 */
57
58 if (x_size > MAX_BITS || x_size <= 0)
59 {
60 gnutls_assert ();
61 return NULL;
62 }
63
64 x = _gnutls_mpi_new (x_size);
65 if (x == NULL)
66 {
67 gnutls_assert ();
68 if (ret_x)
69 *ret_x = NULL;
70
71 return NULL;
72 }
73
74 /* FIXME: (x_size/8)*8 is there to overcome a bug in libgcrypt
75 * which does not really check the bits given but the bytes.
76 */
77 do
78 {
79 _gnutls_mpi_randomize (x, (x_size / 8) * 8, GCRY_STRONG_RANDOM);
80 /* Check whether x is zero.
81 */
82 }
83 while (_gnutls_mpi_cmp_ui (x, 0) == 0);
84
85 e = _gnutls_mpi_alloc_like (prime);
86 if (e == NULL)
87 {
88 gnutls_assert ();
89 if (ret_x)
90 *ret_x = NULL;
91
92 _gnutls_mpi_release (&x);
93 return NULL;
94 }
95
96 _gnutls_mpi_powm (e, g, x, prime);
97
98 if (ret_x)
99 *ret_x = x;
100 else
101 _gnutls_mpi_release (&x);
102 return e;
103}
104
105
106mpi_t
107gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime)
108{
109 mpi_t k;
110 int bits;
111
112 bits = _gnutls_mpi_get_nbits (prime);
113 if (bits <= 0 || bits > MAX_BITS)
114 {
115 gnutls_assert ();
116 return NULL;
117 }
118
119 k = _gnutls_mpi_alloc_like (prime);
120 if (k == NULL)
121 return NULL;
122 _gnutls_mpi_powm (k, f, x, prime);
123 return k;
124}
125
126/*-
127 * _gnutls_get_dh_params - Returns the DH parameters pointer
128 * @dh_params: is an DH parameters structure, or NULL.
129 * @func: is a callback function to receive the parameters or NULL.
130 * @session: a gnutls session.
131 *
132 * This function will return the dh parameters pointer.
133 *
134 -*/
135gnutls_dh_params_t
136_gnutls_get_dh_params (gnutls_dh_params_t dh_params,
137 gnutls_params_function * func,
138 gnutls_session_t session)
139{
140 gnutls_params_st params;
141 int ret;
142
143 /* if cached return the cached */
144 if (session->internals.params.dh_params)
145 return session->internals.params.dh_params;
146
147 if (dh_params)
148 {
149 session->internals.params.dh_params = dh_params;
150 }
151 else if (func)
152 {
153 ret = func (session, GNUTLS_PARAMS_DH, &params);
154 if (ret == 0 && params.type == GNUTLS_PARAMS_DH)
155 {
156 session->internals.params.dh_params = params.params.dh;
157 session->internals.params.free_dh_params = params.deinit;
158 }
159 }
160
161 return session->internals.params.dh_params;
162}
diff --git a/src/daemon/https/tls/gnutls_dh.h b/src/daemon/https/tls/gnutls_dh.h
new file mode 100644
index 00000000..dc8a129d
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_dh.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_DH_H
26# define GNUTLS_DH_H
27
28const mpi_t *_gnutls_dh_params_to_mpi (gnutls_dh_params_t);
29mpi_t gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime);
30mpi_t gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime);
31int _gnutls_dh_generate_prime (mpi_t * ret_g, mpi_t * ret_n, unsigned bits);
32
33gnutls_dh_params_t
34_gnutls_get_dh_params (gnutls_dh_params_t dh_params,
35 gnutls_params_function * func,
36 gnutls_session_t session);
37
38#endif
diff --git a/src/daemon/https/tls/gnutls_dh_primes.c b/src/daemon/https/tls/gnutls_dh_primes.c
new file mode 100644
index 00000000..0aea5b5f
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_dh_primes.c
@@ -0,0 +1,626 @@
1/*
2 * Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_datum.h>
28#include <x509_b64.h> /* for PKCS3 PEM decoding */
29#include <gnutls_global.h>
30#include <gnutls_dh.h>
31#include "debug.h"
32/* x509 */
33#include "mpi.h"
34
35
36/* returns the prime and the generator of DH params.
37 */
38const mpi_t *
39_gnutls_dh_params_to_mpi (gnutls_dh_params_t dh_primes)
40{
41 if (dh_primes == NULL || dh_primes->params[1] == NULL
42 || dh_primes->params[0] == NULL)
43 {
44 return NULL;
45 }
46
47 return dh_primes->params;
48}
49
50int
51_gnutls_dh_generate_prime (mpi_t * ret_g, mpi_t * ret_n, unsigned int bits)
52{
53 mpi_t g = NULL, prime = NULL;
54 gcry_error_t err;
55 int result, times = 0, qbits;
56 mpi_t *factors = NULL;
57
58 /* Calculate the size of a prime factor of (prime-1)/2.
59 * This is an emulation of the values in "Selecting Cryptographic Key Sizes" paper.
60 */
61 if (bits < 256)
62 qbits = bits / 2;
63 else
64 {
65 qbits = (bits / 40) + 105;
66 }
67
68 if (qbits & 1) /* better have an even number */
69 qbits++;
70
71 /* find a prime number of size bits.
72 */
73 do
74 {
75
76 if (times)
77 {
78 _gnutls_mpi_release (&prime);
79 gcry_prime_release_factors (factors);
80 }
81
82 err = gcry_prime_generate (&prime, bits, qbits, &factors, NULL, NULL,
83 GCRY_STRONG_RANDOM,
84 GCRY_PRIME_FLAG_SPECIAL_FACTOR);
85
86 if (err != 0)
87 {
88 gnutls_assert ();
89 result = GNUTLS_E_INTERNAL_ERROR;
90 goto cleanup;
91 }
92
93 err = gcry_prime_check (prime, 0);
94
95 times++;
96 }
97 while (err != 0 && times < 10);
98
99 if (err != 0)
100 {
101 gnutls_assert ();
102 result = GNUTLS_E_INTERNAL_ERROR;
103 goto cleanup;
104 }
105
106 /* generate the group generator.
107 */
108 err = gcry_prime_group_generator (&g, prime, factors, NULL);
109 if (err != 0)
110 {
111 gnutls_assert ();
112 result = GNUTLS_E_INTERNAL_ERROR;
113 goto cleanup;
114 }
115
116 gcry_prime_release_factors (factors);
117 factors = NULL;
118
119 if (ret_g)
120 *ret_g = g;
121 else
122 _gnutls_mpi_release (&g);
123 if (ret_n)
124 *ret_n = prime;
125 else
126 _gnutls_mpi_release (&prime);
127
128 return 0;
129
130cleanup:gcry_prime_release_factors (factors);
131 _gnutls_mpi_release (&g);
132 _gnutls_mpi_release (&prime);
133
134 return result;
135
136}
137
138/* Replaces the prime in the static DH parameters, with a randomly
139 * generated one.
140 */
141/**
142 * gnutls_dh_params_import_raw - This function will import DH parameters
143 * @dh_params: Is a structure that will hold the prime numbers
144 * @prime: holds the new prime
145 * @generator: holds the new generator
146 *
147 * This function will replace the pair of prime and generator for use in
148 * the Diffie-Hellman key exchange. The new parameters should be stored in the
149 * appropriate gnutls_datum.
150 *
151 **/
152int
153gnutls_dh_params_import_raw (gnutls_dh_params_t dh_params,
154 const gnutls_datum_t * prime,
155 const gnutls_datum_t * generator)
156{
157 mpi_t tmp_prime, tmp_g;
158 size_t siz;
159
160 siz = prime->size;
161 if (_gnutls_mpi_scan_nz (&tmp_prime, prime->data, &siz))
162 {
163 gnutls_assert ();
164 return GNUTLS_E_MPI_SCAN_FAILED;
165 }
166
167 siz = generator->size;
168 if (_gnutls_mpi_scan_nz (&tmp_g, generator->data, &siz))
169 {
170 _gnutls_mpi_release (&tmp_prime);
171 gnutls_assert ();
172 return GNUTLS_E_MPI_SCAN_FAILED;
173 }
174
175 /* store the generated values
176 */
177 dh_params->params[0] = tmp_prime;
178 dh_params->params[1] = tmp_g;
179
180 return 0;
181
182}
183
184/**
185 * gnutls_dh_params_init - This function will initialize the DH parameters
186 * @dh_params: Is a structure that will hold the prime numbers
187 *
188 * This function will initialize the DH parameters structure.
189 *
190 **/
191int
192gnutls_dh_params_init (gnutls_dh_params_t * dh_params)
193{
194
195 (*dh_params) = gnutls_calloc (1, sizeof (dh_params_st));
196 if (*dh_params == NULL)
197 {
198 gnutls_assert ();
199 return GNUTLS_E_MEMORY_ERROR;
200 }
201
202 return 0;
203
204}
205
206/**
207 * gnutls_dh_params_deinit - This function will deinitialize the DH parameters
208 * @dh_params: Is a structure that holds the prime numbers
209 *
210 * This function will deinitialize the DH parameters structure.
211 *
212 **/
213void
214gnutls_dh_params_deinit (gnutls_dh_params_t dh_params)
215{
216 if (dh_params == NULL)
217 return;
218
219 _gnutls_mpi_release (&dh_params->params[0]);
220 _gnutls_mpi_release (&dh_params->params[1]);
221
222 gnutls_free (dh_params);
223
224}
225
226/**
227 * gnutls_dh_params_cpy - This function will copy a DH parameters structure
228 * @dst: Is the destination structure, which should be initialized.
229 * @src: Is the source structure
230 *
231 * This function will copy the DH parameters structure from source
232 * to destination.
233 *
234 **/
235int
236gnutls_dh_params_cpy (gnutls_dh_params_t dst, gnutls_dh_params_t src)
237{
238 if (src == NULL)
239 return GNUTLS_E_INVALID_REQUEST;
240
241 dst->params[0] = _gnutls_mpi_copy (src->params[0]);
242 dst->params[1] = _gnutls_mpi_copy (src->params[1]);
243
244 if (dst->params[0] == NULL || dst->params[1] == NULL)
245 return GNUTLS_E_MEMORY_ERROR;
246
247 return 0;
248}
249
250/**
251 * gnutls_dh_params_generate2 - This function will generate new DH parameters
252 * @params: Is the structure that the DH parameters will be stored
253 * @bits: is the prime's number of bits
254 *
255 * This function will generate a new pair of prime and generator for use in
256 * the Diffie-Hellman key exchange. The new parameters will be allocated using
257 * gnutls_malloc() and will be stored in the appropriate datum.
258 * This function is normally slow.
259 *
260 * Note that the bits value should be one of 768, 1024, 2048, 3072 or 4096.
261 * Also note that the DH parameters are only useful to servers.
262 * Since clients use the parameters sent by the server, it's of
263 * no use to call this in client side.
264 *
265 **/
266int
267gnutls_dh_params_generate2 (gnutls_dh_params_t params, unsigned int bits)
268{
269 int ret;
270
271 ret =
272 _gnutls_dh_generate_prime (&params->params[1], &params->params[0], bits);
273 if (ret < 0)
274 {
275 gnutls_assert ();
276 return ret;
277 }
278
279 return 0;
280}
281
282/**
283 * gnutls_dh_params_import_pkcs3 - This function will import DH params from a pkcs3 structure
284 * @params: A structure where the parameters will be copied to
285 * @pkcs3_params: should contain a PKCS3 DHParams structure PEM or DER encoded
286 * @format: the format of params. PEM or DER.
287 *
288 * This function will extract the DHParams found in a PKCS3 formatted
289 * structure. This is the format generated by "openssl dhparam" tool.
290 *
291 * If the structure is PEM encoded, it should have a header
292 * of "BEGIN DH PARAMETERS".
293 *
294 * In case of failure a negative value will be returned, and
295 * 0 on success.
296 *
297 **/
298int
299gnutls_dh_params_import_pkcs3 (gnutls_dh_params_t params,
300 const gnutls_datum_t * pkcs3_params,
301 gnutls_x509_crt_fmt_t format)
302{
303 ASN1_TYPE c2;
304 int result, need_free = 0;
305 gnutls_datum_t _params;
306
307 if (format == GNUTLS_X509_FMT_PEM)
308 {
309 opaque *out;
310
311 result = _gnutls_fbase64_decode ("DH PARAMETERS", pkcs3_params->data,
312 pkcs3_params->size, &out);
313
314 if (result <= 0)
315 {
316 if (result == 0)
317 result = GNUTLS_E_INTERNAL_ERROR;
318 gnutls_assert ();
319 return result;
320 }
321
322 _params.data = out;
323 _params.size = result;
324
325 need_free = 1;
326
327 }
328 else
329 {
330 _params.data = pkcs3_params->data;
331 _params.size = pkcs3_params->size;
332 }
333
334 if ((result =
335 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DHParameter",
336 &c2)) != ASN1_SUCCESS)
337 {
338 gnutls_assert ();
339 if (need_free != 0)
340 {
341 gnutls_free (_params.data);
342 _params.data = NULL;
343 }
344 return _gnutls_asn2err (result);
345 }
346
347 result = asn1_der_decoding (&c2, _params.data, _params.size, NULL);
348
349 if (need_free != 0)
350 {
351 gnutls_free (_params.data);
352 _params.data = NULL;
353 }
354
355 if (result != ASN1_SUCCESS)
356 {
357 /* couldn't decode DER */
358
359 _gnutls_x509_log ("DHParams: Decoding error %d\n", result);
360 gnutls_assert ();
361 asn1_delete_structure (&c2);
362 return _gnutls_asn2err (result);
363 }
364
365 /* Read PRIME
366 */
367 result = _gnutls_x509_read_int (c2, "prime", &params->params[0]);
368 if (result < 0)
369 {
370 asn1_delete_structure (&c2);
371 gnutls_assert ();
372 return result;
373 }
374
375 /* read the generator
376 */
377 result = _gnutls_x509_read_int (c2, "base", &params->params[1]);
378 if (result < 0)
379 {
380 asn1_delete_structure (&c2);
381 _gnutls_mpi_release (&params->params[0]);
382 gnutls_assert ();
383 return result;
384 }
385
386 asn1_delete_structure (&c2);
387
388 return 0;
389}
390
391/**
392 * gnutls_dh_params_export_pkcs3 - This function will export DH params to a pkcs3 structure
393 * @params: Holds the DH parameters
394 * @format: the format of output params. One of PEM or DER.
395 * @params_data: will contain a PKCS3 DHParams structure PEM or DER encoded
396 * @params_data_size: holds the size of params_data (and will be replaced by the actual size of parameters)
397 *
398 * This function will export the given dh parameters to a PKCS3
399 * DHParams structure. This is the format generated by "openssl dhparam" tool.
400 * If the buffer provided is not long enough to hold the output, then
401 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
402 *
403 * If the structure is PEM encoded, it will have a header
404 * of "BEGIN DH PARAMETERS".
405 *
406 * In case of failure a negative value will be returned, and
407 * 0 on success.
408 *
409 **/
410int
411gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
412 gnutls_x509_crt_fmt_t format,
413 unsigned char *params_data,
414 size_t * params_data_size)
415{
416 ASN1_TYPE c2;
417 int result, _params_data_size;
418 size_t g_size, p_size;
419 opaque *p_data, *g_data;
420 opaque *all_data;
421
422 _gnutls_mpi_print_lz (NULL, &g_size, params->params[1]);
423 _gnutls_mpi_print_lz (NULL, &p_size, params->params[0]);
424
425 all_data = gnutls_malloc (g_size + p_size);
426 if (all_data == NULL)
427 {
428 gnutls_assert ();
429 return GNUTLS_E_MEMORY_ERROR;
430 }
431
432 p_data = &all_data[0];
433 g_data = &all_data[p_size];
434
435 _gnutls_mpi_print_lz (p_data, &p_size, params->params[0]);
436 _gnutls_mpi_print_lz (g_data, &g_size, params->params[1]);
437
438 /* Ok. Now we have the data. Create the asn1 structures
439 */
440
441 if ((result =
442 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DHParameter",
443 &c2)) != ASN1_SUCCESS)
444 {
445 gnutls_assert ();
446 gnutls_free (all_data);
447 return _gnutls_asn2err (result);
448 }
449
450 /* Write PRIME
451 */
452 if ((result =
453 asn1_write_value (c2, "prime", p_data, p_size)) != ASN1_SUCCESS)
454 {
455 gnutls_assert ();
456 gnutls_free (all_data);
457 asn1_delete_structure (&c2);
458 return _gnutls_asn2err (result);
459 }
460
461 /* Write the GENERATOR
462 */
463 if ((result =
464 asn1_write_value (c2, "base", g_data, g_size)) != ASN1_SUCCESS)
465 {
466 gnutls_assert ();
467 gnutls_free (all_data);
468 asn1_delete_structure (&c2);
469 return _gnutls_asn2err (result);
470 }
471
472 gnutls_free (all_data);
473
474 if ((result = asn1_write_value (c2, "privateValueLength",
475 NULL, 0)) != ASN1_SUCCESS)
476 {
477 gnutls_assert ();
478 asn1_delete_structure (&c2);
479 return _gnutls_asn2err (result);
480 }
481
482 if (format == GNUTLS_X509_FMT_DER)
483 {
484 if (params_data == NULL)
485 *params_data_size = 0;
486
487 _params_data_size = *params_data_size;
488 result =
489 asn1_der_coding (c2, "", params_data, &_params_data_size, NULL);
490 *params_data_size = _params_data_size;
491 asn1_delete_structure (&c2);
492
493 if (result != ASN1_SUCCESS)
494 {
495 gnutls_assert ();
496 if (result == ASN1_MEM_ERROR)
497 return GNUTLS_E_SHORT_MEMORY_BUFFER;
498
499 return _gnutls_asn2err (result);
500 }
501
502 }
503 else
504 { /* PEM */
505 opaque *tmp;
506 opaque *out;
507 int len;
508
509 len = 0;
510 asn1_der_coding (c2, "", NULL, &len, NULL);
511
512 tmp = gnutls_malloc (len);
513 if (tmp == NULL)
514 {
515 gnutls_assert ();
516 asn1_delete_structure (&c2);
517 return GNUTLS_E_MEMORY_ERROR;
518 }
519
520 if ((result =
521 asn1_der_coding (c2, "", tmp, &len, NULL)) != ASN1_SUCCESS)
522 {
523 gnutls_assert ();
524 gnutls_free (tmp);
525 asn1_delete_structure (&c2);
526 return _gnutls_asn2err (result);
527 }
528
529 asn1_delete_structure (&c2);
530
531 result = _gnutls_fbase64_encode ("DH PARAMETERS", tmp, len, &out);
532
533 gnutls_free (tmp);
534
535 if (result < 0)
536 {
537 gnutls_assert ();
538 return result;
539 }
540
541 if (result == 0)
542 { /* oooops */
543 gnutls_assert ();
544 gnutls_free (out);
545 return GNUTLS_E_INTERNAL_ERROR;
546 }
547
548 if ((unsigned) result + 1 > *params_data_size)
549 {
550 gnutls_assert ();
551 gnutls_free (out);
552 *params_data_size = result + 1;
553 return GNUTLS_E_SHORT_MEMORY_BUFFER;
554 }
555
556 *params_data_size = result;
557
558 if (params_data)
559 {
560 memcpy (params_data, out, result);
561 params_data[result] = 0;
562 }
563 gnutls_free (out);
564
565 }
566
567 return 0;
568}
569
570/**
571 * gnutls_dh_params_export_raw - This function will export the raw DH parameters
572 * @params: Holds the DH parameters
573 * @prime: will hold the new prime
574 * @generator: will hold the new generator
575 * @bits: if non null will hold is the prime's number of bits
576 *
577 * This function will export the pair of prime and generator for use in
578 * the Diffie-Hellman key exchange. The new parameters will be allocated using
579 * gnutls_malloc() and will be stored in the appropriate datum.
580 *
581 **/
582int
583gnutls_dh_params_export_raw (gnutls_dh_params_t params,
584 gnutls_datum_t * prime,
585 gnutls_datum_t * generator, unsigned int *bits)
586{
587
588 size_t size;
589
590 if (params->params[1] == NULL || params->params[0] == NULL)
591 {
592 gnutls_assert ();
593 return GNUTLS_E_INVALID_REQUEST;
594 }
595
596 size = 0;
597 _gnutls_mpi_print (NULL, &size, params->params[1]);
598
599 generator->data = gnutls_malloc (size);
600 if (generator->data == NULL)
601 {
602 return GNUTLS_E_MEMORY_ERROR;
603 }
604
605 generator->size = size;
606 _gnutls_mpi_print (generator->data, &size, params->params[1]);
607
608 size = 0;
609 _gnutls_mpi_print (NULL, &size, params->params[0]);
610
611 prime->data = gnutls_malloc (size);
612 if (prime->data == NULL)
613 {
614 gnutls_free (generator->data);
615 generator->data = NULL;
616 return GNUTLS_E_MEMORY_ERROR;
617 }
618 prime->size = size;
619 _gnutls_mpi_print (prime->data, &size, params->params[0]);
620
621 if (bits)
622 *bits = _gnutls_mpi_get_nbits (params->params[0]);
623
624 return 0;
625
626}
diff --git a/src/daemon/https/tls/gnutls_errors.c b/src/daemon/https/tls/gnutls_errors.c
new file mode 100644
index 00000000..9916dc96
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_errors.c
@@ -0,0 +1,422 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include "gnutls_errors.h"
27#include <libtasn1.h>
28#ifdef STDC_HEADERS
29# include <stdarg.h>
30#endif
31
32/* I18n of error codes. */
33#include "gettext.h"
34#define _(String) dgettext (PACKAGE, String)
35#define N_(String) gettext_noop (String)
36
37extern LOG_FUNC _gnutls_log_func;
38
39#define ERROR_ENTRY(desc, name, fatal) \
40 { desc, #name, name, fatal}
41
42struct gnutls_error_entry
43{
44 const char *desc;
45 const char *_name;
46 int number;
47 int fatal;
48};
49typedef struct gnutls_error_entry gnutls_error_entry;
50
51static const gnutls_error_entry error_algorithms[] = {
52 /* "Short Description", Error code define, critical (0,1) -- 1 in most cases */
53 ERROR_ENTRY (N_("Success."), GNUTLS_E_SUCCESS, 0),
54 ERROR_ENTRY (N_("Could not negotiate a supported cipher suite."),
55 GNUTLS_E_UNKNOWN_CIPHER_SUITE, 1),
56 ERROR_ENTRY (N_("The cipher type is unsupported."),
57 GNUTLS_E_UNKNOWN_CIPHER_TYPE, 1),
58 ERROR_ENTRY (N_("The certificate and the given key do not match."),
59 GNUTLS_E_CERTIFICATE_KEY_MISMATCH, 1),
60 ERROR_ENTRY (N_("Could not negotiate a supported compression method."),
61 GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM, 1),
62 ERROR_ENTRY (N_("An unknown public key algorithm was encountered."),
63 GNUTLS_E_UNKNOWN_PK_ALGORITHM, 1),
64
65 ERROR_ENTRY (N_("An algorithm that is not enabled was negotiated."),
66 GNUTLS_E_UNWANTED_ALGORITHM, 1),
67 ERROR_ENTRY (N_("A large TLS record packet was received."),
68 GNUTLS_E_LARGE_PACKET, 1),
69 ERROR_ENTRY (N_("A record packet with illegal version was received."),
70 GNUTLS_E_UNSUPPORTED_VERSION_PACKET, 1),
71 ERROR_ENTRY (N_
72 ("The Diffie Hellman prime sent by the server is not acceptable (not long enough)."),
73 GNUTLS_E_DH_PRIME_UNACCEPTABLE, 1),
74 ERROR_ENTRY (N_("A TLS packet with unexpected length was received."),
75 GNUTLS_E_UNEXPECTED_PACKET_LENGTH, 1),
76 ERROR_ENTRY (N_
77 ("The specified session has been invalidated for some reason."),
78 GNUTLS_E_INVALID_SESSION, 1),
79
80 ERROR_ENTRY (N_("GnuTLS internal error."), GNUTLS_E_INTERNAL_ERROR, 1),
81 ERROR_ENTRY (N_("An illegal TLS extension was received."),
82 GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION, 1),
83 ERROR_ENTRY (N_("A TLS fatal alert has been received."),
84 GNUTLS_E_FATAL_ALERT_RECEIVED, 1),
85 ERROR_ENTRY (N_("An unexpected TLS packet was received."),
86 GNUTLS_E_UNEXPECTED_PACKET, 1),
87 ERROR_ENTRY (N_("A TLS warning alert has been received."),
88 GNUTLS_E_WARNING_ALERT_RECEIVED, 0),
89 ERROR_ENTRY (N_
90 ("An error was encountered at the TLS Finished packet calculation."),
91 GNUTLS_E_ERROR_IN_FINISHED_PACKET, 1),
92 ERROR_ENTRY (N_("The peer did not send any certificate."),
93 GNUTLS_E_NO_CERTIFICATE_FOUND, 1),
94
95 ERROR_ENTRY (N_("No temporary RSA parameters were found."),
96 GNUTLS_E_NO_TEMPORARY_RSA_PARAMS, 1),
97 ERROR_ENTRY (N_("No temporary DH parameters were found."),
98 GNUTLS_E_NO_TEMPORARY_DH_PARAMS, 1),
99 ERROR_ENTRY (N_("An unexpected TLS handshake packet was received."),
100 GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET, 1),
101 ERROR_ENTRY (N_("The scanning of a large integer has failed."),
102 GNUTLS_E_MPI_SCAN_FAILED, 1),
103 ERROR_ENTRY (N_("Could not export a large integer."),
104 GNUTLS_E_MPI_PRINT_FAILED, 1),
105 ERROR_ENTRY (N_("Decryption has failed."), GNUTLS_E_DECRYPTION_FAILED, 1),
106 ERROR_ENTRY (N_("Encryption has failed."), GNUTLS_E_ENCRYPTION_FAILED, 1),
107 ERROR_ENTRY (N_("Public key decryption has failed."),
108 GNUTLS_E_PK_DECRYPTION_FAILED, 1),
109 ERROR_ENTRY (N_("Public key encryption has failed."),
110 GNUTLS_E_PK_ENCRYPTION_FAILED, 1),
111 ERROR_ENTRY (N_("Public key signing has failed."), GNUTLS_E_PK_SIGN_FAILED,
112 1),
113 ERROR_ENTRY (N_("Public key signature verification has failed."),
114 GNUTLS_E_PK_SIG_VERIFY_FAILED, 1),
115 ERROR_ENTRY (N_("Decompression of the TLS record packet has failed."),
116 GNUTLS_E_DECOMPRESSION_FAILED, 1),
117 ERROR_ENTRY (N_("Compression of the TLS record packet has failed."),
118 GNUTLS_E_COMPRESSION_FAILED, 1),
119
120 ERROR_ENTRY (N_("Internal error in memory allocation."),
121 GNUTLS_E_MEMORY_ERROR, 1),
122 ERROR_ENTRY (N_("An unimplemented or disabled feature has been requested."),
123 GNUTLS_E_UNIMPLEMENTED_FEATURE, 1),
124 ERROR_ENTRY (N_("Insufficient credentials for that request."),
125 GNUTLS_E_INSUFFICIENT_CREDENTIALS, 1),
126 ERROR_ENTRY (N_("Error in password file."), GNUTLS_E_SRP_PWD_ERROR, 1),
127 ERROR_ENTRY (N_("Wrong padding in PKCS1 packet."), GNUTLS_E_PKCS1_WRONG_PAD,
128 1),
129 ERROR_ENTRY (N_("The requested session has expired."), GNUTLS_E_EXPIRED, 1),
130 ERROR_ENTRY (N_("Hashing has failed."), GNUTLS_E_HASH_FAILED, 1),
131 ERROR_ENTRY (N_("Base64 decoding error."), GNUTLS_E_BASE64_DECODING_ERROR,
132 1),
133 ERROR_ENTRY (N_("Base64 unexpected header error."),
134 GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR,
135 1),
136 ERROR_ENTRY (N_("Base64 encoding error."), GNUTLS_E_BASE64_ENCODING_ERROR,
137 1),
138 ERROR_ENTRY (N_("Parsing error in password file."),
139 GNUTLS_E_SRP_PWD_PARSING_ERROR, 1),
140 ERROR_ENTRY (N_("The requested data were not available."),
141 GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE, 0),
142 ERROR_ENTRY (N_("Error in the pull function."), GNUTLS_E_PULL_ERROR, 1),
143 ERROR_ENTRY (N_("Error in the push function."), GNUTLS_E_PUSH_ERROR, 1),
144 ERROR_ENTRY (N_
145 ("The upper limit of record packet sequence numbers has been reached. Wow!"),
146 GNUTLS_E_RECORD_LIMIT_REACHED, 1),
147 ERROR_ENTRY (N_("Error in the certificate."), GNUTLS_E_CERTIFICATE_ERROR,
148 1),
149 ERROR_ENTRY (N_("Unknown Subject Alternative name in X.509 certificate."),
150 GNUTLS_E_X509_UNKNOWN_SAN, 1),
151
152 ERROR_ENTRY (N_("Unsupported critical extension in X.509 certificate."),
153 GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION, 1),
154 ERROR_ENTRY (N_("Key usage violation in certificate has been detected."),
155 GNUTLS_E_KEY_USAGE_VIOLATION, 1),
156 ERROR_ENTRY (N_("Function was interrupted."), GNUTLS_E_AGAIN, 0),
157 ERROR_ENTRY (N_("Function was interrupted."), GNUTLS_E_INTERRUPTED, 0),
158 ERROR_ENTRY (N_("Rehandshake was requested by the peer."),
159 GNUTLS_E_REHANDSHAKE, 0),
160 ERROR_ENTRY (N_
161 ("TLS Application data were received, while expecting handshake data."),
162 GNUTLS_E_GOT_APPLICATION_DATA, 1),
163 ERROR_ENTRY (N_("Error in Database backend."), GNUTLS_E_DB_ERROR, 1),
164 ERROR_ENTRY (N_("The certificate type is not supported."),
165 GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE, 1),
166 ERROR_ENTRY (N_("The given memory buffer is too short to hold parameters."),
167 GNUTLS_E_SHORT_MEMORY_BUFFER, 1),
168 ERROR_ENTRY (N_("The request is invalid."), GNUTLS_E_INVALID_REQUEST, 1),
169 ERROR_ENTRY (N_("An illegal parameter has been received."),
170 GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER, 1),
171 ERROR_ENTRY (N_("Error while reading file."), GNUTLS_E_FILE_ERROR, 1),
172
173 ERROR_ENTRY (N_("ASN1 parser: Element was not found."),
174 GNUTLS_E_ASN1_ELEMENT_NOT_FOUND, 1),
175 ERROR_ENTRY (N_("ASN1 parser: Identifier was not found"),
176 GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND, 1),
177 ERROR_ENTRY (N_("ASN1 parser: Error in DER parsing."),
178 GNUTLS_E_ASN1_DER_ERROR, 1),
179 ERROR_ENTRY (N_("ASN1 parser: Value was not found."),
180 GNUTLS_E_ASN1_VALUE_NOT_FOUND, 1),
181 ERROR_ENTRY (N_("ASN1 parser: Generic parsing error."),
182 GNUTLS_E_ASN1_GENERIC_ERROR, 1),
183 ERROR_ENTRY (N_("ASN1 parser: Value is not valid."),
184 GNUTLS_E_ASN1_VALUE_NOT_VALID, 1),
185 ERROR_ENTRY (N_("ASN1 parser: Error in TAG."), GNUTLS_E_ASN1_TAG_ERROR, 1),
186 ERROR_ENTRY (N_("ASN1 parser: error in implicit tag"),
187 GNUTLS_E_ASN1_TAG_IMPLICIT, 1),
188 ERROR_ENTRY (N_("ASN1 parser: Error in type 'ANY'."),
189 GNUTLS_E_ASN1_TYPE_ANY_ERROR, 1),
190 ERROR_ENTRY (N_("ASN1 parser: Syntax error."), GNUTLS_E_ASN1_SYNTAX_ERROR,
191 1),
192 ERROR_ENTRY (N_("ASN1 parser: Overflow in DER parsing."),
193 GNUTLS_E_ASN1_DER_OVERFLOW, 1),
194
195 ERROR_ENTRY (N_("Too many empty record packets have been received."),
196 GNUTLS_E_TOO_MANY_EMPTY_PACKETS, 1),
197 ERROR_ENTRY (N_("The initialization of GnuTLS-extra has failed."),
198 GNUTLS_E_INIT_LIBEXTRA, 1),
199 ERROR_ENTRY (N_
200 ("The GnuTLS library version does not match the GnuTLS-extra library version."),
201 GNUTLS_E_LIBRARY_VERSION_MISMATCH, 1),
202 ERROR_ENTRY (N_("The gcrypt library version is too old."),
203 GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY, 1),
204
205 ERROR_ENTRY (N_("The tasn1 library version is too old."),
206 GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY, 1),
207
208 ERROR_ENTRY (N_("Error loading the keyring."),
209 GNUTLS_E_OPENPGP_KEYRING_ERROR, 1),
210 ERROR_ENTRY (N_("The initialization of LZO has failed."),
211 GNUTLS_E_LZO_INIT_FAILED, 1),
212 ERROR_ENTRY (N_("No supported compression algorithms have been found."),
213 GNUTLS_E_NO_COMPRESSION_ALGORITHMS, 1),
214 ERROR_ENTRY (N_("No supported cipher suites have been found."),
215 GNUTLS_E_NO_CIPHER_SUITES, 1),
216 ERROR_ENTRY (N_("Could not get OpenPGP key."),
217 GNUTLS_E_OPENPGP_GETKEY_FAILED, 1),
218
219 ERROR_ENTRY (N_("The SRP username supplied is illegal."),
220 GNUTLS_E_ILLEGAL_SRP_USERNAME, 1),
221
222 ERROR_ENTRY (N_("The OpenPGP fingerprint is not supported."),
223 GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED, 1),
224 ERROR_ENTRY (N_("The certificate has unsupported attributes."),
225 GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE, 1),
226 ERROR_ENTRY (N_("The OID is not supported."), GNUTLS_E_X509_UNSUPPORTED_OID,
227 1),
228 ERROR_ENTRY (N_("The hash algorithm is unknown."),
229 GNUTLS_E_UNKNOWN_HASH_ALGORITHM, 1),
230 ERROR_ENTRY (N_("The PKCS structure's content type is unknown."),
231 GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE, 1),
232 ERROR_ENTRY (N_("The PKCS structure's bag type is unknown."),
233 GNUTLS_E_UNKNOWN_PKCS_BAG_TYPE, 1),
234 ERROR_ENTRY (N_("The given password contains invalid characters."),
235 GNUTLS_E_INVALID_PASSWORD, 1),
236 ERROR_ENTRY (N_("The Message Authentication Code verification failed."),
237 GNUTLS_E_MAC_VERIFY_FAILED, 1),
238 ERROR_ENTRY (N_("Some constraint limits were reached."),
239 GNUTLS_E_CONSTRAINT_ERROR, 1),
240 ERROR_ENTRY (N_("Failed to acquire random data."), GNUTLS_E_RANDOM_FAILED,
241 1),
242
243 ERROR_ENTRY (N_("Received a TLS/IA Intermediate Phase Finished message"),
244 GNUTLS_E_WARNING_IA_IPHF_RECEIVED, 0),
245 ERROR_ENTRY (N_("Received a TLS/IA Final Phase Finished message"),
246 GNUTLS_E_WARNING_IA_FPHF_RECEIVED, 0),
247 ERROR_ENTRY (N_("Verifying TLS/IA phase checksum failed"),
248 GNUTLS_E_IA_VERIFY_FAILED, 1),
249
250 ERROR_ENTRY (N_("The specified algorithm or protocol is unknown."),
251 GNUTLS_E_UNKNOWN_ALGORITHM, 1),
252
253 {NULL, NULL, 0, 0}
254};
255
256#define GNUTLS_ERROR_LOOP(b) \
257 const gnutls_error_entry *p; \
258 for(p = error_algorithms; p->desc != NULL; p++) { b ; }
259
260#define GNUTLS_ERROR_ALG_LOOP(a) \
261 GNUTLS_ERROR_LOOP( if(p->number == error) { a; break; } )
262
263
264
265/**
266 * gnutls_error_is_fatal - Returns non-zero in case of a fatal error
267 * @error: is an error returned by a gnutls function. Error should be a negative value.
268 *
269 * If a function returns a negative value you may feed that value
270 * to this function to see if it is fatal. Returns 1 for a fatal
271 * error 0 otherwise. However you may want to check the
272 * error code manually, since some non-fatal errors to the protocol
273 * may be fatal for you (your program).
274 *
275 * This is only useful if you are dealing with errors from the
276 * record layer or the handshake layer.
277 *
278 * For positive @error values, 0 is returned.
279 *
280 **/
281int
282gnutls_error_is_fatal (int error)
283{
284 int ret = 1;
285
286 /* Input sanitzation. Positive values are not errors at all, and
287 definitely not fatal. */
288 if (error > 0)
289 return 0;
290
291 GNUTLS_ERROR_ALG_LOOP (ret = p->fatal);
292
293 return ret;
294}
295
296/**
297 * gnutls_perror - prints a string to stderr with a description of an error
298 * @error: is an error returned by a gnutls function. Error is always a negative value.
299 *
300 * This function is like perror(). The only difference is that it accepts an
301 * error number returned by a gnutls function.
302 **/
303void
304gnutls_perror (int error)
305{
306 const char *ret = NULL;
307
308 /* avoid prefix */
309 GNUTLS_ERROR_ALG_LOOP (ret = p->desc);
310 if (ret == NULL)
311 ret = "(unknown)";
312 fprintf (stderr, "GNUTLS ERROR: %s\n", _(ret));
313}
314
315
316/**
317 * gnutls_strerror - Returns a string with a description of an error
318 * @error: is an error returned by a gnutls function. Error is always a negative value.
319 *
320 * This function is similar to strerror(). Differences: it accepts an error
321 * number returned by a gnutls function; In case of an unknown error
322 * a descriptive string is sent instead of NULL.
323 **/
324const char *
325gnutls_strerror (int error)
326{
327 const char *ret = NULL;
328
329 /* avoid prefix */
330 GNUTLS_ERROR_ALG_LOOP (ret = p->desc);
331 if (ret == NULL)
332 return "(unknown error code)";
333 return _(ret);
334}
335
336/* This will print the actual define of the
337 * given error code.
338 */
339const char *
340_gnutls_strerror (int error)
341{
342 const char *ret = NULL;
343
344 /* avoid prefix */
345 GNUTLS_ERROR_ALG_LOOP (ret = p->_name);
346
347 return _(ret);
348}
349
350int
351_gnutls_asn2err (int asn_err)
352{
353 switch (asn_err)
354 {
355 case ASN1_FILE_NOT_FOUND:
356 return GNUTLS_E_FILE_ERROR;
357 case ASN1_ELEMENT_NOT_FOUND:
358 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
359 case ASN1_IDENTIFIER_NOT_FOUND:
360 return GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND;
361 case ASN1_DER_ERROR:
362 return GNUTLS_E_ASN1_DER_ERROR;
363 case ASN1_VALUE_NOT_FOUND:
364 return GNUTLS_E_ASN1_VALUE_NOT_FOUND;
365 case ASN1_GENERIC_ERROR:
366 return GNUTLS_E_ASN1_GENERIC_ERROR;
367 case ASN1_VALUE_NOT_VALID:
368 return GNUTLS_E_ASN1_VALUE_NOT_VALID;
369 case ASN1_TAG_ERROR:
370 return GNUTLS_E_ASN1_TAG_ERROR;
371 case ASN1_TAG_IMPLICIT:
372 return GNUTLS_E_ASN1_TAG_IMPLICIT;
373 case ASN1_ERROR_TYPE_ANY:
374 return GNUTLS_E_ASN1_TYPE_ANY_ERROR;
375 case ASN1_SYNTAX_ERROR:
376 return GNUTLS_E_ASN1_SYNTAX_ERROR;
377 case ASN1_MEM_ERROR:
378 return GNUTLS_E_SHORT_MEMORY_BUFFER;
379 case ASN1_MEM_ALLOC_ERROR:
380 return GNUTLS_E_MEMORY_ERROR;
381 case ASN1_DER_OVERFLOW:
382 return GNUTLS_E_ASN1_DER_OVERFLOW;
383 default:
384 return GNUTLS_E_ASN1_GENERIC_ERROR;
385 }
386}
387
388
389/* this function will output a message using the
390 * caller provided function
391 */
392void
393_gnutls_log (int level, const char *fmt, ...)
394{
395 va_list args;
396 char str[MAX_LOG_SIZE];
397 void (*log_func) (int, const char *) = _gnutls_log_func;
398
399 if (_gnutls_log_func == NULL)
400 return;
401
402 va_start (args, fmt);
403 vsnprintf (str, MAX_LOG_SIZE - 1, fmt, args); /* Flawfinder: ignore */
404 va_end (args);
405
406 log_func (level, str);
407}
408
409#ifndef DEBUG
410# ifndef C99_MACROS
411
412/* Without C99 macros these functions have to
413 * be called. This may affect performance.
414 */
415void
416_gnutls_null_log (void *x, ...)
417{
418 return;
419}
420
421# endif /* C99_MACROS */
422#endif /* DEBUG */
diff --git a/src/daemon/https/tls/gnutls_errors.h b/src/daemon/https/tls/gnutls_errors.h
new file mode 100644
index 00000000..667bd62b
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_errors.h
@@ -0,0 +1,73 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <defines.h>
26
27#define GNUTLS_E_INT_RET_0 -1251
28
29#ifdef __FILE__
30# ifdef __LINE__
31# define gnutls_assert() _gnutls_debug_log( "ASSERT: %s:%d\n", __FILE__,__LINE__);
32# else
33# define gnutls_assert()
34# endif
35#else /* __FILE__ not defined */
36# define gnutls_assert()
37#endif
38
39int _gnutls_asn2err (int asn_err);
40void _gnutls_log (int, const char *fmt, ...);
41
42extern int _gnutls_log_level;
43
44#ifdef C99_MACROS
45#define LEVEL(l, ...) if (_gnutls_log_level >= l || _gnutls_log_level > 9) \
46 _gnutls_log( l, __VA_ARGS__)
47
48#define LEVEL_EQ(l, ...) if (_gnutls_log_level == l || _gnutls_log_level > 9) \
49 _gnutls_log( l, __VA_ARGS__)
50
51# define _gnutls_debug_log(...) LEVEL(2, __VA_ARGS__)
52# define _gnutls_handshake_log(...) LEVEL(3, __VA_ARGS__)
53# define _gnutls_io_log(...) LEVEL_EQ(5, __VA_ARGS__)
54# define _gnutls_buffers_log(...) LEVEL_EQ(6, __VA_ARGS__)
55# define _gnutls_hard_log(...) LEVEL(9, __VA_ARGS__)
56# define _gnutls_record_log(...) LEVEL(4, __VA_ARGS__)
57# define _gnutls_read_log(...) LEVEL_EQ(7, __VA_ARGS__)
58# define _gnutls_write_log(...) LEVEL_EQ(7, __VA_ARGS__)
59# define _gnutls_x509_log(...) LEVEL(1, __VA_ARGS__)
60#else
61# define _gnutls_debug_log _gnutls_null_log
62# define _gnutls_handshake_log _gnutls_null_log
63# define _gnutls_io_log _gnutls_null_log
64# define _gnutls_buffers_log _gnutls_null_log
65# define _gnutls_hard_log _gnutls_null_log
66# define _gnutls_record_log _gnutls_null_log
67# define _gnutls_read_log _gnutls_null_log
68# define _gnutls_write_log _gnutls_null_log
69# define _gnutls_x509_log _gnutls_null_log
70
71void _gnutls_null_log (void *, ...);
72
73#endif /* C99_MACROS */
diff --git a/src/daemon/https/tls/gnutls_extensions.c b/src/daemon/https/tls/gnutls_extensions.c
new file mode 100644
index 00000000..603446d7
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_extensions.c
@@ -0,0 +1,318 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Functions that relate to the TLS hello extension parsing.
26 * Hello extensions are packets appended in the TLS hello packet, and
27 * allow for extra functionality.
28 */
29
30#include "gnutls_int.h"
31#include "gnutls_extensions.h"
32#include "gnutls_errors.h"
33#include "ext_max_record.h"
34#include <ext_cert_type.h>
35#include <ext_server_name.h>
36#include <ext_oprfi.h>
37#include <ext_inner_application.h>
38#include <gnutls_num.h>
39
40/* Key Exchange Section */
41#define GNUTLS_EXTENSION_ENTRY(type, parse_type, ext_func_recv, ext_func_send) \
42 { #type, type, parse_type, ext_func_recv, ext_func_send }
43
44
45#define MAX_EXT_SIZE 10
46const int _gnutls_extensions_size = MAX_EXT_SIZE;
47
48gnutls_extension_entry _gnutls_extensions[MAX_EXT_SIZE] = {
49 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_MAX_RECORD_SIZE,
50 EXTENSION_TLS,
51 _gnutls_max_record_recv_params,
52 _gnutls_max_record_send_params),
53 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_CERT_TYPE,
54 EXTENSION_TLS,
55 _gnutls_cert_type_recv_params,
56 _gnutls_cert_type_send_params),
57 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_SERVER_NAME,
58 EXTENSION_APPLICATION,
59 _gnutls_server_name_recv_params,
60 _gnutls_server_name_send_params),
61#ifdef ENABLE_OPRFI
62 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_OPAQUE_PRF_INPUT,
63 EXTENSION_TLS,
64 _gnutls_oprfi_recv_params,
65 _gnutls_oprfi_send_params),
66#endif
67#ifdef ENABLE_SRP
68 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_SRP,
69 EXTENSION_TLS,
70 _gnutls_srp_recv_params,
71 _gnutls_srp_send_params),
72#endif
73 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_INNER_APPLICATION,
74 EXTENSION_TLS,
75 _gnutls_inner_application_recv_params,
76 _gnutls_inner_application_send_params),
77 {0, 0, 0, 0}
78};
79
80#define GNUTLS_EXTENSION_LOOP2(b) \
81 gnutls_extension_entry *p; \
82 for(p = _gnutls_extensions; p->name != NULL; p++) { b ; }
83
84#define GNUTLS_EXTENSION_LOOP(a) \
85 GNUTLS_EXTENSION_LOOP2( if(p->type == type) { a; break; } )
86
87
88/* EXTENSION functions */
89
90ext_recv_func
91_gnutls_ext_func_recv (uint16_t type, tls_ext_parse_type_t parse_type)
92{
93 ext_recv_func ret = NULL;
94 GNUTLS_EXTENSION_LOOP (if
95 (parse_type == EXTENSION_ANY
96 || p->parse_type == parse_type) ret =
97 p->gnutls_ext_func_recv);
98 return ret;
99
100}
101
102ext_send_func
103_gnutls_ext_func_send (uint16_t type)
104{
105 ext_send_func ret = NULL;
106 GNUTLS_EXTENSION_LOOP (ret = p->gnutls_ext_func_send);
107 return ret;
108
109}
110
111const char *
112_gnutls_extension_get_name (uint16_t type)
113{
114 const char *ret = NULL;
115
116 /* avoid prefix */
117 GNUTLS_EXTENSION_LOOP (ret = p->name + sizeof ("GNUTLS_EXTENSION_") - 1);
118
119 return ret;
120}
121
122/* Checks if the extension we just received is one of the
123 * requested ones. Otherwise it's a fatal error.
124 */
125static int
126_gnutls_extension_list_check (gnutls_session_t session, uint16_t type)
127{
128 if (session->security_parameters.entity == GNUTLS_CLIENT)
129 {
130 int i;
131 for (i = 0; i < session->internals.extensions_sent_size; i++)
132 {
133 if (type == session->internals.extensions_sent[i])
134 return 0; /* ok found */
135 }
136 return GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION;
137 }
138
139 return 0;
140}
141
142int
143_gnutls_parse_extensions (gnutls_session_t session,
144 tls_ext_parse_type_t parse_type,
145 const opaque * data, int data_size)
146{
147 int next, ret;
148 int pos = 0;
149 uint16_t type;
150 const opaque *sdata;
151 ext_recv_func ext_recv;
152 uint16_t size;
153
154#ifdef DEBUG
155 int i;
156
157 if (session->security_parameters.entity == GNUTLS_CLIENT)
158 for (i = 0; i < session->internals.extensions_sent_size; i++)
159 {
160 _gnutls_debug_log ("EXT[%d]: expecting extension '%s'\n",
161 session,
162 _gnutls_extension_get_name (session->
163 internals.
164 extensions_sent[i]));
165 }
166#endif
167
168 DECR_LENGTH_RET (data_size, 2, 0);
169 next = _gnutls_read_uint16 (data);
170 pos += 2;
171
172 DECR_LENGTH_RET (data_size, next, 0);
173
174 do
175 {
176 DECR_LENGTH_RET (next, 2, 0);
177 type = _gnutls_read_uint16 (&data[pos]);
178 pos += 2;
179
180 _gnutls_debug_log ("EXT[%x]: Received extension '%s/%d'\n", session,
181 _gnutls_extension_get_name (type), type);
182
183 if ((ret = _gnutls_extension_list_check (session, type)) < 0)
184 {
185 gnutls_assert ();
186 return ret;
187 }
188
189 DECR_LENGTH_RET (next, 2, 0);
190 size = _gnutls_read_uint16 (&data[pos]);
191 pos += 2;
192
193 DECR_LENGTH_RET (next, size, 0);
194 sdata = &data[pos];
195 pos += size;
196
197 ext_recv = _gnutls_ext_func_recv (type, parse_type);
198 if (ext_recv == NULL)
199 continue;
200 if ((ret = ext_recv (session, sdata, size)) < 0)
201 {
202 gnutls_assert ();
203 return ret;
204 }
205
206 }
207 while (next > 2);
208
209 return 0;
210
211}
212
213/* Adds the extension we want to send in the extensions list.
214 * This list is used to check whether the (later) received
215 * extensions are the ones we requested.
216 */
217static void
218_gnutls_extension_list_add (gnutls_session_t session, uint16_t type)
219{
220
221 if (session->security_parameters.entity == GNUTLS_CLIENT)
222 {
223 if (session->internals.extensions_sent_size < MAX_EXT_TYPES)
224 {
225 session->internals.extensions_sent[session->internals.
226 extensions_sent_size] = type;
227 session->internals.extensions_sent_size++;
228 }
229 else
230 {
231 _gnutls_debug_log ("extensions: Increase MAX_EXT_TYPES\n");
232 }
233 }
234}
235
236int
237_gnutls_gen_extensions (gnutls_session_t session, opaque * data,
238 size_t data_size)
239{
240 int size;
241 uint16_t pos = 0;
242 opaque *sdata;
243 int sdata_size;
244 ext_send_func ext_send;
245 gnutls_extension_entry *p;
246
247 if (data_size < 2)
248 {
249 gnutls_assert ();
250 return GNUTLS_E_INTERNAL_ERROR;
251 }
252
253 /* allocate enough data for each extension.
254 */
255 sdata_size = data_size;
256 sdata = gnutls_malloc (sdata_size);
257 if (sdata == NULL)
258 {
259 gnutls_assert ();
260 return GNUTLS_E_MEMORY_ERROR;
261 }
262
263 pos += 2;
264 for (p = _gnutls_extensions; p->name != NULL; p++)
265 {
266 ext_send = _gnutls_ext_func_send (p->type);
267 if (ext_send == NULL)
268 continue;
269 size = ext_send (session, sdata, sdata_size);
270 if (size > 0)
271 {
272 if (data_size < pos + (size_t) size + 4)
273 {
274 gnutls_assert ();
275 gnutls_free (sdata);
276 return GNUTLS_E_INTERNAL_ERROR;
277 }
278
279 /* write extension type */
280 _gnutls_write_uint16 (p->type, &data[pos]);
281 pos += 2;
282
283 /* write size */
284 _gnutls_write_uint16 (size, &data[pos]);
285 pos += 2;
286
287 memcpy (&data[pos], sdata, size);
288 pos += size;
289
290 /* add this extension to the extension list
291 */
292 _gnutls_extension_list_add (session, p->type);
293
294 _gnutls_debug_log ("EXT[%x]: Sending extension %s\n", session,
295 _gnutls_extension_get_name (p->type));
296 }
297 else if (size < 0)
298 {
299 gnutls_assert ();
300 gnutls_free (sdata);
301 return size;
302 }
303 }
304
305 size = pos;
306 pos -= 2; /* remove the size of the size header! */
307
308 _gnutls_write_uint16 (pos, data);
309
310 if (size == 2)
311 { /* empty */
312 size = 0;
313 }
314
315 gnutls_free (sdata);
316 return size;
317
318}
diff --git a/src/daemon/https/tls/gnutls_extensions.h b/src/daemon/https/tls/gnutls_extensions.h
new file mode 100644
index 00000000..c305846c
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_extensions.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26
27const char *_gnutls_extension_get_name (uint16_t type);
28int _gnutls_parse_extensions (gnutls_session_t, tls_ext_parse_type_t, const opaque *, int);
29int _gnutls_gen_extensions (gnutls_session_t session, opaque * data,
30 size_t data_size);
31
32typedef int (*ext_recv_func) (gnutls_session_t, const opaque *, size_t); /* recv data */
33typedef int (*ext_send_func) (gnutls_session_t, opaque *, size_t); /* send data */
34
35ext_send_func _gnutls_ext_func_send (uint16_t type);
36ext_recv_func _gnutls_ext_func_recv (uint16_t type, tls_ext_parse_type_t);
37
38typedef struct
39{
40 const char *name;
41 uint16_t type;
42 tls_ext_parse_type_t parse_type;
43 ext_recv_func gnutls_ext_func_recv;
44 ext_send_func gnutls_ext_func_send;
45} gnutls_extension_entry;
diff --git a/src/daemon/https/tls/gnutls_extra_hooks.c b/src/daemon/https/tls/gnutls_extra_hooks.c
new file mode 100644
index 00000000..f7852f64
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_extra_hooks.c
@@ -0,0 +1,78 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_extra_hooks.h>
27
28/* Variables used by libgnutls, set by
29 _gnutls_add_openpgp_functions(), typically invoked by
30 libgnutls_extra. */
31_gnutls_openpgp_verify_key_func _E_gnutls_openpgp_verify_key = NULL;
32_gnutls_openpgp_crt_creation_time_func
33 _E_gnutls_openpgp_get_raw_key_creation_time = NULL;
34_gnutls_openpgp_crt_expiration_time_func
35 _E_gnutls_openpgp_get_raw_key_expiration_time = NULL;
36_gnutls_openpgp_fingerprint_func _E_gnutls_openpgp_fingerprint = NULL;
37_gnutls_openpgp_crt_request_func _E_gnutls_openpgp_request_key = NULL;
38_gnutls_openpgp_raw_key_to_gcert_func _E_gnutls_openpgp_raw_key_to_gcert =
39 NULL;
40_gnutls_openpgp_raw_privkey_to_gkey_func _E_gnutls_openpgp_raw_privkey_to_gkey
41 = NULL;
42_gnutls_openpgp_crt_to_gcert_func _E_gnutls_openpgp_crt_to_gcert = NULL;
43_gnutls_openpgp_privkey_to_gkey_func _E_gnutls_openpgp_privkey_to_gkey = NULL;
44_gnutls_openpgp_crt_deinit_func _E_gnutls_openpgp_crt_deinit = NULL;
45_gnutls_openpgp_keyring_deinit_func _E_gnutls_openpgp_keyring_deinit = NULL;
46_gnutls_openpgp_privkey_deinit_func _E_gnutls_openpgp_privkey_deinit = NULL;
47
48/* Called by libgnutls_extra to set the OpenPGP functions that are
49 needed by GnuTLS. */
50extern void
51 _gnutls_add_openpgp_functions
52 (_gnutls_openpgp_verify_key_func verify_key,
53 _gnutls_openpgp_crt_creation_time_func key_creation_time,
54 _gnutls_openpgp_crt_expiration_time_func key_expiration_time,
55 _gnutls_openpgp_fingerprint_func fingerprint,
56 _gnutls_openpgp_crt_request_func request_key,
57 _gnutls_openpgp_raw_key_to_gcert_func raw_key_to_gcert,
58 _gnutls_openpgp_raw_privkey_to_gkey_func raw_privkey_to_gkey,
59 _gnutls_openpgp_crt_to_gcert_func key_to_gcert,
60 _gnutls_openpgp_privkey_to_gkey_func privkey_to_gkey,
61 _gnutls_openpgp_crt_deinit_func key_deinit,
62 _gnutls_openpgp_keyring_deinit_func keyring_deinit,
63 _gnutls_openpgp_privkey_deinit_func privkey_deinit)
64{
65 _E_gnutls_openpgp_verify_key = verify_key;
66 _E_gnutls_openpgp_get_raw_key_creation_time = key_creation_time;
67 _E_gnutls_openpgp_get_raw_key_expiration_time = key_expiration_time;
68 _E_gnutls_openpgp_fingerprint = fingerprint;
69 _E_gnutls_openpgp_request_key = request_key;
70 _E_gnutls_openpgp_raw_key_to_gcert = raw_key_to_gcert;
71 _E_gnutls_openpgp_raw_privkey_to_gkey = raw_privkey_to_gkey;
72 _E_gnutls_openpgp_crt_to_gcert = key_to_gcert;
73 _E_gnutls_openpgp_privkey_to_gkey = privkey_to_gkey;
74 _E_gnutls_openpgp_crt_deinit = key_deinit;
75 _E_gnutls_openpgp_keyring_deinit = keyring_deinit;
76 _E_gnutls_openpgp_privkey_deinit = privkey_deinit;
77
78}
diff --git a/src/daemon/https/tls/gnutls_extra_hooks.h b/src/daemon/https/tls/gnutls_extra_hooks.h
new file mode 100644
index 00000000..ac55d06a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_extra_hooks.h
@@ -0,0 +1,106 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file is included by libgnutls-extra, and it will call the
26 _gnutls_add_openpgp_functions() function to register its OpenPGP
27 functions. */
28
29#include <auth_cert.h>
30
31typedef int (*_gnutls_openpgp_verify_key_func)
32(const gnutls_certificate_credentials_t,
33 const gnutls_datum_t *, int,
34 unsigned int *);
35
36typedef time_t (*_gnutls_openpgp_crt_creation_time_func)
37(const gnutls_datum_t *);
38
39typedef time_t (*_gnutls_openpgp_crt_expiration_time_func)
40(const gnutls_datum_t *);
41
42typedef int (*_gnutls_openpgp_crt_request_func)
43(gnutls_session_t, gnutls_datum_t *,
44 const gnutls_certificate_credentials_t,
45 opaque *, int);
46
47typedef int (*_gnutls_openpgp_fingerprint_func)
48(const gnutls_datum_t *,
49 unsigned char *, size_t *);
50
51typedef int (*_gnutls_openpgp_raw_key_to_gcert_func)
52(gnutls_cert *,
53 const gnutls_datum_t *);
54typedef int (*_gnutls_openpgp_raw_privkey_to_gkey_func)
55(gnutls_privkey *,
56 const gnutls_datum_t *,
57 gnutls_openpgp_crt_fmt_t);
58
59typedef int (*_gnutls_openpgp_crt_to_gcert_func)
60(gnutls_cert *, gnutls_openpgp_crt_t);
61
62typedef int (*_gnutls_openpgp_privkey_to_gkey_func)
63(gnutls_privkey *,
64 gnutls_openpgp_privkey_t);
65
66typedef void (*_gnutls_openpgp_crt_deinit_func)
67(gnutls_openpgp_crt_t);
68
69typedef void (*_gnutls_openpgp_keyring_deinit_func)
70(gnutls_openpgp_keyring_t);
71
72typedef void (*_gnutls_openpgp_privkey_deinit_func)
73(gnutls_openpgp_privkey_t);
74
75/* These are defined in libgnutls, but not exported from libgnutls,
76 and not intended to be used by libgnutls-extra or elsewhere. They
77 are declared here, because this file is included by auth_cert.c and
78 gnutls_cert.c too. */
79extern _gnutls_openpgp_verify_key_func _E_gnutls_openpgp_verify_key;
80extern _gnutls_openpgp_crt_creation_time_func
81_E_gnutls_openpgp_get_raw_key_creation_time;
82extern _gnutls_openpgp_crt_expiration_time_func
83_E_gnutls_openpgp_get_raw_key_expiration_time;
84extern _gnutls_openpgp_fingerprint_func _E_gnutls_openpgp_fingerprint;
85extern _gnutls_openpgp_crt_request_func _E_gnutls_openpgp_request_key;
86extern _gnutls_openpgp_raw_key_to_gcert_func _E_gnutls_openpgp_raw_key_to_gcert;
87extern _gnutls_openpgp_raw_privkey_to_gkey_func _E_gnutls_openpgp_raw_privkey_to_gkey;
88extern _gnutls_openpgp_crt_to_gcert_func _E_gnutls_openpgp_crt_to_gcert;
89extern _gnutls_openpgp_privkey_to_gkey_func _E_gnutls_openpgp_privkey_to_gkey;
90extern _gnutls_openpgp_crt_deinit_func _E_gnutls_openpgp_crt_deinit;
91extern _gnutls_openpgp_keyring_deinit_func _E_gnutls_openpgp_keyring_deinit;
92extern _gnutls_openpgp_privkey_deinit_func _E_gnutls_openpgp_privkey_deinit;
93
94extern void _gnutls_add_openpgp_functions
95(_gnutls_openpgp_verify_key_func verify_key,
96 _gnutls_openpgp_crt_creation_time_func key_creation_time,
97 _gnutls_openpgp_crt_expiration_time_func key_expiration_time,
98 _gnutls_openpgp_fingerprint_func fingerprint,
99 _gnutls_openpgp_crt_request_func request_key,
100 _gnutls_openpgp_raw_key_to_gcert_func raw_key_to_gcert,
101 _gnutls_openpgp_raw_privkey_to_gkey_func raw_privkey_to_gkey,
102 _gnutls_openpgp_crt_to_gcert_func key_to_gcert,
103 _gnutls_openpgp_privkey_to_gkey_func privkey_to_gkey,
104 _gnutls_openpgp_crt_deinit_func key_deinit,
105 _gnutls_openpgp_keyring_deinit_func keyring_deinit,
106 _gnutls_openpgp_privkey_deinit_func privkey_deinit);
diff --git a/src/daemon/https/tls/gnutls_global.c b/src/daemon/https/tls/gnutls_global.c
new file mode 100644
index 00000000..d019dcda
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_global.c
@@ -0,0 +1,375 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <libtasn1.h>
28#include <gnutls_dh.h>
29
30#ifdef HAVE_WINSOCK
31# include <winsock2.h>
32#endif
33
34#include "gettext.h"
35
36#define gnutls_log_func LOG_FUNC
37
38/* created by asn1c */
39extern const ASN1_ARRAY_TYPE gnutls_asn1_tab[];
40extern const ASN1_ARRAY_TYPE pkix_asn1_tab[];
41
42LOG_FUNC _gnutls_log_func;
43int _gnutls_log_level = 0; /* default log level */
44
45ASN1_TYPE _gnutls_pkix1_asn;
46ASN1_TYPE _gnutls_gnutls_asn;
47
48/**
49 * gnutls_global_set_log_function - This function sets the logging function
50 * @log_func: it's a log function
51 *
52 * This is the function where you set the logging function gnutls
53 * is going to use. This function only accepts a character array.
54 * Normally you may not use this function since it is only used
55 * for debugging purposes.
56 *
57 * gnutls_log_func is of the form,
58 * void (*gnutls_log_func)( int level, const char*);
59 **/
60void gnutls_global_set_log_function(gnutls_log_func log_func)
61{
62 _gnutls_log_func = log_func;
63}
64
65/**
66 * gnutls_global_set_log_level - This function sets the logging level
67 * @level: it's an integer from 0 to 9.
68 *
69 * This is the function that allows you to set the log level.
70 * The level is an integer between 0 and 9. Higher values mean
71 * more verbosity. The default value is 0. Larger values should
72 * only be used with care, since they may reveal sensitive information.
73 *
74 * Use a log level over 10 to enable all debugging options.
75 *
76 **/
77void gnutls_global_set_log_level(int level)
78{
79 _gnutls_log_level = level;
80}
81
82#ifdef DEBUG
83/* default logging function */
84static void
85dlog (int level, const char *str)
86 {
87 fputs (str, stderr);
88 }
89#endif
90
91extern gnutls_alloc_function gnutls_secure_malloc;
92extern gnutls_alloc_function gnutls_malloc;
93extern gnutls_free_function gnutls_free;
94extern int (*_gnutls_is_secure_memory)(const void *);
95extern gnutls_realloc_function gnutls_realloc;
96extern char *(*gnutls_strdup)(const char *);
97extern void *(*gnutls_calloc)(size_t,
98 size_t);
99
100int _gnutls_is_secure_mem_null(const void *);
101
102/**
103 * gnutls_global_set_mem_functions - This function sets the memory allocation functions
104 * @alloc_func: it's the default memory allocation function. Like malloc().
105 * @secure_alloc_func: This is the memory allocation function that will be used for sensitive data.
106 * @is_secure_func: a function that returns 0 if the memory given is not secure. May be NULL.
107 * @realloc_func: A realloc function
108 * @free_func: The function that frees allocated data. Must accept a NULL pointer.
109 *
110 * This is the function were you set the memory allocation functions gnutls
111 * is going to use. By default the libc's allocation functions (malloc(), free()),
112 * are used by gnutls, to allocate both sensitive and not sensitive data.
113 * This function is provided to set the memory allocation functions to
114 * something other than the defaults (ie the gcrypt allocation functions).
115 *
116 * This function must be called before gnutls_global_init() is called.
117 *
118 **/
119void gnutls_global_set_mem_functions(gnutls_alloc_function alloc_func,
120 gnutls_alloc_function
121 secure_alloc_func,
122 gnutls_is_secure_function
123 is_secure_func,
124 gnutls_realloc_function realloc_func,
125 gnutls_free_function free_func)
126{
127 gnutls_secure_malloc = secure_alloc_func;
128 gnutls_malloc = alloc_func;
129 gnutls_realloc = realloc_func;
130 gnutls_free = free_func;
131
132 if (is_secure_func != NULL)
133 _gnutls_is_secure_memory = is_secure_func;
134 else
135 _gnutls_is_secure_memory = _gnutls_is_secure_mem_null;
136
137 /* if using the libc's default malloc
138 * use libc's calloc as well.
139 */
140 if (gnutls_malloc == malloc)
141 {
142 gnutls_calloc = calloc;
143 }
144 else
145 { /* use the included ones */
146 gnutls_calloc = _gnutls_calloc;
147 }
148 gnutls_strdup = _gnutls_strdup;
149
150}
151
152#ifdef DEBUG
153static void
154_gnutls_gcry_log_handler (void *dummy, int level,
155 const char *fmt, va_list list)
156 {
157 _gnutls_log (fmt, list);
158 }
159#endif
160
161static int _gnutls_init = 0;
162
163/**
164 * gnutls_global_init - This function initializes the global data to defaults.
165 *
166 * This function initializes the global data to defaults.
167 * Every gnutls application has a global data which holds common parameters
168 * shared by gnutls session structures.
169 * You must call gnutls_global_deinit() when gnutls usage is no longer needed
170 * Returns zero on success.
171 *
172 * Note that this function will also initialize libgcrypt, if it has not
173 * been initialized before. Thus if you want to manually initialize libgcrypt
174 * you must do it before calling this function. This is useful in cases you
175 * want to disable libgcrypt's internal lockings etc.
176 *
177 * This function increment a global counter, so that
178 * gnutls_global_deinit() only releases resources when it has been
179 * called as many times as gnutls_global_init(). This is useful when
180 * GnuTLS is used by more than one library in an application. This
181 * function can be called many times, but will only do something the
182 * first time.
183 *
184 * Note! This function is not thread safe. If two threads call this
185 * function simultaneously, they can cause a race between checking
186 * the global counter and incrementing it, causing both threads to
187 * execute the library initialization code. That would lead to a
188 * memory leak. To handle this, your application could invoke this
189 * function after aquiring a thread mutex. To ignore the potential
190 * memory leak is also an option.
191 *
192 **/
193int gnutls_global_init(void)
194{
195 int result = 0;
196 int res;
197 char c;
198
199 if (_gnutls_init++)
200 return;
201
202#if HAVE_WINSOCK
203 {
204 WORD requested;
205 WSADATA data;
206 int err;
207
208 requested = MAKEWORD (1, 1);
209 err = WSAStartup (requested, &data);
210 if (err != 0)
211 {
212 _gnutls_debug_log ("WSAStartup failed: %d.\n", err);
213 return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
214 }
215
216 if (data.wVersion < requested)
217 {
218 _gnutls_debug_log ("WSAStartup version check failed (%d < %d).\n",
219 data.wVersion, requested);
220 WSACleanup ();
221 return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
222 }
223 }
224#endif
225
226 // TODO rm ? bindtextdomain(PACKAGE, LOCALEDIR);
227
228 if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
229 {
230 /* for gcrypt in order to be able to allocate memory */
231 gcry_set_allocation_handler(gnutls_malloc, gnutls_secure_malloc,
232 _gnutls_is_secure_memory, gnutls_realloc,
233 gnutls_free);
234
235 /* gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING, NULL, 0); */
236
237 gcry_control(GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
238
239#ifdef DEBUG
240 /* applications may want to override that, so we only use
241 * it in debugging mode.
242 */
243 gcry_set_log_handler (_gnutls_gcry_log_handler, NULL);
244#endif
245 }
246
247 if (gc_init() != GC_OK)
248 {
249 gnutls_assert ();
250 _gnutls_debug_log ("Initializing crypto backend failed\n");
251 return GNUTLS_E_INCOMPATIBLE_CRYPTO_LIBRARY;
252 }
253
254#ifdef DEBUG
255 gnutls_global_set_log_function (dlog);
256#endif
257
258 /* initialize parser
259 * This should not deal with files in the final
260 * version.
261 */
262
263 res = asn1_array2tree(pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
264 if (res != ASN1_SUCCESS)
265 {
266 result = _gnutls_asn2err(res);
267 return result;
268 }
269
270 res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
271 if (res != ASN1_SUCCESS)
272 {
273 asn1_delete_structure(&_gnutls_pkix1_asn);
274 result = _gnutls_asn2err(res);
275 return result;
276 }
277
278 /* Initialize the gcrypt (if used random generator) */
279 gc_pseudo_random(&c, 1);
280
281 return result;
282}
283
284/**
285 * gnutls_global_deinit - This function deinitializes the global data
286 *
287 * This function deinitializes the global data, that were initialized
288 * using gnutls_global_init().
289 *
290 * Note! This function is not thread safe. See the discussion for
291 * gnutls_global_init() for more information.
292 *
293 **/
294void gnutls_global_deinit(void)
295{
296 if (_gnutls_init == 1)
297 {
298#if HAVE_WINSOCK
299 WSACleanup ();
300#endif
301 asn1_delete_structure(&_gnutls_gnutls_asn);
302 asn1_delete_structure(&_gnutls_pkix1_asn);
303 gc_done();
304 }
305 _gnutls_init--;
306}
307
308/* These functions should be elsewere. Kept here for
309 * historical reasons.
310 */
311
312/**
313 * gnutls_transport_set_pull_function - This function sets a read like function
314 * @pull_func: a callback function similar to read()
315 * @session: gnutls session
316 *
317 * This is the function where you set a function for gnutls
318 * to receive data. Normally, if you use berkeley style sockets,
319 * do not need to use this function since the default (recv(2)) will
320 * probably be ok.
321 *
322 * PULL_FUNC is of the form,
323 * ssize_t (*gnutls_pull_func)(gnutls_transport_ptr_t, void*, size_t);
324 **/
325void gnutls_transport_set_pull_function(gnutls_session_t session,
326 gnutls_pull_func pull_func)
327{
328 session->internals._gnutls_pull_func = pull_func;
329}
330
331/**
332 * gnutls_transport_set_push_function - This function sets the function to send data
333 * @push_func: a callback function similar to write()
334 * @session: gnutls session
335 *
336 * This is the function where you set a push function for gnutls
337 * to use in order to send data. If you are going to use berkeley style
338 * sockets, you do not need to use this function since
339 * the default (send(2)) will probably be ok. Otherwise you should
340 * specify this function for gnutls to be able to send data.
341 *
342 * PUSH_FUNC is of the form,
343 * ssize_t (*gnutls_push_func)(gnutls_transport_ptr_t, const void*, size_t);
344 **/
345void gnutls_transport_set_push_function(gnutls_session_t session,
346 gnutls_push_func push_func)
347{
348 session->internals._gnutls_push_func = push_func;
349}
350
351#include <strverscmp.h>
352
353/**
354 * gnutls_check_version - This function checks the library's version
355 * @req_version: the version to check
356 *
357 * Check that the version of the library is at minimum the requested one
358 * and return the version string; return NULL if the condition is not
359 * satisfied. If a NULL is passed to this function, no check is done,
360 * but the version string is simply returned.
361 *
362 * See %LIBGNUTLS_VERSION for a suitable @req_version string.
363 *
364 * Return value: Version string of run-time library, or NULL if the
365 * run-time library does not meet the required version number. If
366 * %NULL is passed to this function no check is done and only the
367 * version string is returned.
368 **/
369const char * gnutls_check_version(const char *req_version)
370{
371 if (!req_version || strverscmp(req_version, VERSION) <= 0)
372 return VERSION;
373
374 return NULL;
375}
diff --git a/src/daemon/https/tls/gnutls_global.h b/src/daemon/https/tls/gnutls_global.h
new file mode 100644
index 00000000..3305ebad
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_global.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_GLOBAL_H
26# define GNUTLS_GLOBAL_H
27
28#include <libtasn1.h>
29
30int gnutls_is_secure_memory (const void *mem);
31
32extern ASN1_TYPE _gnutls_pkix1_asn;
33extern ASN1_TYPE _gnutls_gnutls_asn;
34
35/* removed const from node_asn* to
36 * prevent warnings, since libtasn1 doesn't
37 * use the const keywork in its functions.
38 */
39#define _gnutls_get_gnutls_asn() ((node_asn*) _gnutls_gnutls_asn)
40#define _gnutls_get_pkix() ((node_asn*) _gnutls_pkix1_asn)
41
42#endif
diff --git a/src/daemon/https/tls/gnutls_handshake.c b/src/daemon/https/tls/gnutls_handshake.c
new file mode 100644
index 00000000..1af07a91
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_handshake.c
@@ -0,0 +1,3029 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Functions that relate to the TLS handshake procedure.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_errors.h"
30#include "gnutls_dh.h"
31#include "debug.h"
32#include "gnutls_algorithms.h"
33#include "gnutls_compress.h"
34#include "gnutls_cipher.h"
35#include "gnutls_buffers.h"
36#include "gnutls_kx.h"
37#include "gnutls_handshake.h"
38#include "gnutls_num.h"
39#include "gnutls_hash_int.h"
40#include "gnutls_db.h"
41#include "gnutls_extensions.h"
42#include "gnutls_supplemental.h"
43#include "gnutls_auth_int.h"
44#include "gnutls_v2_compat.h"
45#include "auth_cert.h"
46#include "gnutls_cert.h"
47#include "gnutls_constate.h"
48#include <gnutls_record.h>
49#include <gnutls_state.h>
50#include <gnutls_rsa_export.h> /* for gnutls_get_rsa_params() */
51#include <auth_anon.h> /* for gnutls_anon_server_credentials_t */
52#include <gc.h>
53
54#ifdef HANDSHAKE_DEBUG
55#define ERR(x, y) _gnutls_handshake_log( "HSK[%x]: %s (%d)\n", session, x,y)
56#else
57#define ERR(x, y)
58#endif
59
60#define TRUE 1
61#define FALSE 0
62
63int _gnutls_server_select_comp_method (gnutls_session_t session,
64 opaque * data, int datalen);
65
66
67/* Clears the handshake hash buffers and handles.
68 */
69inline static void
70_gnutls_handshake_hash_buffers_clear (gnutls_session_t session)
71{
72 _gnutls_hash_deinit (session->internals.handshake_mac_handle_md5, NULL);
73 _gnutls_hash_deinit (session->internals.handshake_mac_handle_sha, NULL);
74 session->internals.handshake_mac_handle_md5 = NULL;
75 session->internals.handshake_mac_handle_sha = NULL;
76 _gnutls_handshake_buffer_clear (session);
77}
78
79/* this will copy the required values for resuming to
80 * internals, and to security_parameters.
81 * this will keep as less data to security_parameters.
82 */
83static void
84resume_copy_required_values (gnutls_session_t session)
85{
86 /* get the new random values */
87 memcpy (session->internals.resumed_security_parameters.
88 server_random,
89 session->security_parameters.server_random, TLS_RANDOM_SIZE);
90 memcpy (session->internals.resumed_security_parameters.
91 client_random,
92 session->security_parameters.client_random, TLS_RANDOM_SIZE);
93
94 /* keep the ciphersuite and compression
95 * That is because the client must see these in our
96 * hello message.
97 */
98 memcpy (session->security_parameters.current_cipher_suite.
99 suite,
100 session->internals.resumed_security_parameters.
101 current_cipher_suite.suite, 2);
102
103 session->internals.compression_method =
104 session->internals.resumed_security_parameters.read_compression_algorithm;
105 /* or write_compression_algorithm
106 * they are the same
107 */
108
109 session->security_parameters.entity =
110 session->internals.resumed_security_parameters.entity;
111
112 _gnutls_set_current_version (session,
113 session->internals.
114 resumed_security_parameters.version);
115
116 session->security_parameters.cert_type =
117 session->internals.resumed_security_parameters.cert_type;
118
119 memcpy (session->security_parameters.session_id,
120 session->internals.resumed_security_parameters.
121 session_id, sizeof (session->security_parameters.session_id));
122 session->security_parameters.session_id_size =
123 session->internals.resumed_security_parameters.session_id_size;
124}
125
126void
127_gnutls_set_server_random (gnutls_session_t session, uint8_t * rnd)
128{
129 memcpy (session->security_parameters.server_random, rnd, TLS_RANDOM_SIZE);
130}
131
132void
133_gnutls_set_client_random (gnutls_session_t session, uint8_t * rnd)
134{
135 memcpy (session->security_parameters.client_random, rnd, TLS_RANDOM_SIZE);
136}
137
138/* Calculate The SSL3 Finished message
139 */
140#define SSL3_CLIENT_MSG "CLNT"
141#define SSL3_SERVER_MSG "SRVR"
142#define SSL_MSG_LEN 4
143static int
144_gnutls_ssl3_finished (gnutls_session_t session, int type, opaque * ret)
145{
146 const int siz = SSL_MSG_LEN;
147 mac_hd_t td_md5;
148 mac_hd_t td_sha;
149 const char *mesg;
150
151 td_md5 = _gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
152 if (td_md5 == NULL)
153 {
154 gnutls_assert ();
155 return GNUTLS_E_HASH_FAILED;
156 }
157
158 td_sha = _gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
159 if (td_sha == NULL)
160 {
161 gnutls_assert ();
162 _gnutls_hash_deinit (td_md5, NULL);
163 return GNUTLS_E_HASH_FAILED;
164 }
165
166 if (type == GNUTLS_SERVER)
167 {
168 mesg = SSL3_SERVER_MSG;
169 }
170 else
171 {
172 mesg = SSL3_CLIENT_MSG;
173 }
174
175 _gnutls_hash (td_md5, mesg, siz);
176 _gnutls_hash (td_sha, mesg, siz);
177
178 _gnutls_mac_deinit_ssl3_handshake (td_md5, ret,
179 session->security_parameters.
180 master_secret, TLS_MASTER_SIZE);
181 _gnutls_mac_deinit_ssl3_handshake (td_sha, &ret[16],
182 session->security_parameters.
183 master_secret, TLS_MASTER_SIZE);
184
185 return 0;
186}
187
188/* Hash the handshake messages as required by TLS 1.0
189 */
190#define SERVER_MSG "server finished"
191#define CLIENT_MSG "client finished"
192#define TLS_MSG_LEN 15
193int
194_gnutls_finished (gnutls_session_t session, int type, void *ret)
195{
196 const int siz = TLS_MSG_LEN;
197 opaque concat[36];
198 size_t len;
199 const char *mesg;
200 mac_hd_t td_md5 = NULL;
201 mac_hd_t td_sha;
202 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
203
204 if (ver < GNUTLS_TLS1_2)
205 {
206 td_md5 =
207 _gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
208 if (td_md5 == NULL)
209 {
210 gnutls_assert ();
211 return GNUTLS_E_HASH_FAILED;
212 }
213 }
214
215 td_sha = _gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
216 if (td_sha == NULL)
217 {
218 gnutls_assert ();
219 _gnutls_hash_deinit (td_md5, NULL);
220 return GNUTLS_E_HASH_FAILED;
221 }
222
223 if (ver < GNUTLS_TLS1_2)
224 {
225 _gnutls_hash_deinit (td_md5, concat);
226 _gnutls_hash_deinit (td_sha, &concat[16]);
227 len = 20 + 16;
228 }
229 else
230 {
231 _gnutls_hash_deinit (td_sha, concat);
232 len = 20;
233 }
234
235 if (type == GNUTLS_SERVER)
236 {
237 mesg = SERVER_MSG;
238 }
239 else
240 {
241 mesg = CLIENT_MSG;
242 }
243
244 return _gnutls_PRF (session, session->security_parameters.master_secret,
245 TLS_MASTER_SIZE, mesg, siz, concat, len, 12, ret);
246}
247
248/* this function will produce TLS_RANDOM_SIZE==32 bytes of random data
249 * and put it to dst.
250 */
251int
252_gnutls_tls_create_random (opaque * dst)
253{
254 uint32_t tim;
255
256 /* Use weak random numbers for the most of the
257 * buffer except for the first 4 that are the
258 * system's time.
259 */
260
261 tim = time (NULL);
262 /* generate server random value */
263 _gnutls_write_uint32 (tim, dst);
264
265 if (gc_nonce (&dst[4], TLS_RANDOM_SIZE - 4) != GC_OK)
266 {
267 gnutls_assert ();
268 return GNUTLS_E_RANDOM_FAILED;
269 }
270
271 return 0;
272}
273
274/* returns the 0 on success or a negative value.
275 */
276int
277_gnutls_negotiate_version (gnutls_session_t session,
278 gnutls_protocol_t adv_version)
279{
280 int ret;
281
282 /* if we do not support that version */
283 if (_gnutls_version_is_supported (session, adv_version) == 0)
284 {
285 /* If he requested something we do not support
286 * then we send him the highest we support.
287 */
288 ret = _gnutls_version_max (session);
289 if (ret == GNUTLS_VERSION_UNKNOWN)
290 {
291 /* this check is not really needed.
292 */
293 gnutls_assert ();
294 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
295 }
296 }
297 else
298 {
299 ret = adv_version;
300 }
301
302 _gnutls_set_current_version (session, ret);
303
304 return ret;
305}
306
307int
308_gnutls_user_hello_func (gnutls_session session,
309 gnutls_protocol_t adv_version)
310{
311 int ret;
312
313 if (session->internals.user_hello_func != NULL)
314 {
315 ret = session->internals.user_hello_func (session);
316 if (ret < 0)
317 {
318 gnutls_assert ();
319 return ret;
320 }
321 /* Here we need to renegotiate the version since the callee might
322 * have disabled some TLS versions.
323 */
324 ret = _gnutls_negotiate_version (session, adv_version);
325 if (ret < 0)
326 {
327 gnutls_assert ();
328 return ret;
329 }
330 }
331 return 0;
332}
333
334/* Read a client hello packet.
335 * A client hello must be a known version client hello
336 * or version 2.0 client hello (only for compatibility
337 * since SSL version 2.0 is not supported).
338 */
339int
340_gnutls_read_client_hello (gnutls_session_t session, opaque * data,
341 int datalen)
342{
343 uint8_t session_id_len;
344 int pos = 0, ret;
345 uint16_t suite_size, comp_size;
346 gnutls_protocol_t adv_version;
347 int neg_version;
348 int len = datalen;
349 opaque rnd[TLS_RANDOM_SIZE], *suite_ptr, *comp_ptr;
350
351 if (session->internals.v2_hello != 0)
352 { /* version 2.0 */
353 return _gnutls_read_client_hello_v2 (session, data, datalen);
354 }
355 DECR_LEN (len, 2);
356
357 _gnutls_handshake_log ("HSK[%x]: Client's version: %d.%d\n", session,
358 data[pos], data[pos + 1]);
359
360 adv_version = _gnutls_version_get (data[pos], data[pos + 1]);
361 set_adv_version (session, data[pos], data[pos + 1]);
362 pos += 2;
363
364 neg_version = _gnutls_negotiate_version (session, adv_version);
365 if (neg_version < 0)
366 {
367 gnutls_assert ();
368 return ret;
369 }
370
371 /* Read client random value.
372 */
373 DECR_LEN (len, TLS_RANDOM_SIZE);
374 _gnutls_set_client_random (session, &data[pos]);
375 pos += TLS_RANDOM_SIZE;
376
377 _gnutls_tls_create_random (rnd);
378 _gnutls_set_server_random (session, rnd);
379
380 session->security_parameters.timestamp = time (NULL);
381
382 DECR_LEN (len, 1);
383 session_id_len = data[pos++];
384
385 /* RESUME SESSION
386 */
387 if (session_id_len > TLS_MAX_SESSION_ID_SIZE)
388 {
389 gnutls_assert ();
390 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
391 }
392 DECR_LEN (len, session_id_len);
393
394 ret = _gnutls_server_restore_session (session, &data[pos], session_id_len);
395 pos += session_id_len;
396
397 if (ret == 0)
398 { /* resumed! */
399 resume_copy_required_values (session);
400 session->internals.resumed = RESUME_TRUE;
401 return _gnutls_user_hello_func (session, adv_version);
402 }
403 else
404 {
405 _gnutls_generate_session_id (session->security_parameters.
406 session_id,
407 &session->security_parameters.
408 session_id_size);
409
410 session->internals.resumed = RESUME_FALSE;
411 }
412
413 /* Remember ciphersuites for later
414 */
415 DECR_LEN (len, 2);
416 suite_size = _gnutls_read_uint16 (&data[pos]);
417 pos += 2;
418
419 DECR_LEN (len, suite_size);
420 suite_ptr = &data[pos];
421 pos += suite_size;
422
423 /* Point to the compression methods
424 */
425 DECR_LEN (len, 1);
426 comp_size = data[pos++]; /* z is the number of compression methods */
427
428 DECR_LEN (len, comp_size);
429 comp_ptr = &data[pos];
430 pos += comp_size;
431
432 /* Parse the extensions (if any)
433 */
434 if (neg_version >= GNUTLS_TLS1)
435 {
436 ret = _gnutls_parse_extensions (session, EXTENSION_APPLICATION, &data[pos], len); /* len is the rest of the parsed length */
437 if (ret < 0)
438 {
439 gnutls_assert ();
440 return ret;
441 }
442 }
443
444 ret = _gnutls_user_hello_func (session, adv_version);
445 if (ret < 0)
446 {
447 gnutls_assert ();
448 return ret;
449 }
450
451 if (neg_version >= GNUTLS_TLS1)
452 {
453 ret = _gnutls_parse_extensions (session, EXTENSION_TLS, &data[pos], len); /* len is the rest of the parsed length */
454 if (ret < 0)
455 {
456 gnutls_assert ();
457 return ret;
458 }
459 }
460
461 /* select an appropriate cipher suite
462 */
463 ret = _gnutls_server_select_suite (session, suite_ptr, suite_size);
464 if (ret < 0)
465 {
466 gnutls_assert ();
467 return ret;
468 }
469
470 /* select appropriate compression method */
471 ret = _gnutls_server_select_comp_method (session, comp_ptr, comp_size);
472 if (ret < 0)
473 {
474 gnutls_assert ();
475 return ret;
476 }
477
478 return 0;
479}
480
481/* here we hash all pending data.
482 */
483inline static int
484_gnutls_handshake_hash_pending (gnutls_session_t session)
485{
486 size_t siz;
487 int ret;
488 opaque *data;
489
490 if (session->internals.handshake_mac_handle_sha == NULL ||
491 session->internals.handshake_mac_handle_md5 == NULL)
492 {
493 gnutls_assert ();
494 return GNUTLS_E_INTERNAL_ERROR;
495 }
496
497 /* We check if there are pending data to hash.
498 */
499 if ((ret = _gnutls_handshake_buffer_get_ptr (session, &data, &siz)) < 0)
500 {
501 gnutls_assert ();
502 return ret;
503 }
504
505 if (siz > 0)
506 {
507 _gnutls_hash (session->internals.handshake_mac_handle_sha, data, siz);
508 _gnutls_hash (session->internals.handshake_mac_handle_md5, data, siz);
509 }
510
511 _gnutls_handshake_buffer_empty (session);
512
513 return 0;
514}
515
516
517/* This is to be called after sending CHANGE CIPHER SPEC packet
518 * and initializing encryption. This is the first encrypted message
519 * we send.
520 */
521int
522_gnutls_send_finished (gnutls_session_t session, int again)
523{
524 uint8_t data[36];
525 int ret;
526 int data_size = 0;
527
528
529 if (again == 0)
530 {
531
532 /* This is needed in order to hash all the required
533 * messages.
534 */
535 if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
536 {
537 gnutls_assert ();
538 return ret;
539 }
540
541 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
542 {
543 ret =
544 _gnutls_ssl3_finished (session,
545 session->security_parameters.entity, data);
546 data_size = 36;
547 }
548 else
549 { /* TLS 1.0 */
550 ret =
551 _gnutls_finished (session,
552 session->security_parameters.entity, data);
553 data_size = 12;
554 }
555
556 if (ret < 0)
557 {
558 gnutls_assert ();
559 return ret;
560 }
561
562 }
563
564 ret =
565 _gnutls_send_handshake (session, data, data_size,
566 GNUTLS_HANDSHAKE_FINISHED);
567
568 return ret;
569}
570
571/* This is to be called after sending our finished message. If everything
572 * went fine we have negotiated a secure connection
573 */
574int
575_gnutls_recv_finished (gnutls_session_t session)
576{
577 uint8_t data[36], *vrfy;
578 int data_size;
579 int ret;
580 int vrfysize;
581
582 ret =
583 _gnutls_recv_handshake (session, &vrfy, &vrfysize,
584 GNUTLS_HANDSHAKE_FINISHED, MANDATORY_PACKET);
585 if (ret < 0)
586 {
587 ERR ("recv finished int", ret);
588 gnutls_assert ();
589 return ret;
590 }
591
592
593 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
594 {
595 data_size = 36;
596 }
597 else
598 {
599 data_size = 12;
600 }
601
602 if (vrfysize != data_size)
603 {
604 gnutls_assert ();
605 gnutls_free (vrfy);
606 return GNUTLS_E_ERROR_IN_FINISHED_PACKET;
607 }
608
609 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
610 {
611 ret =
612 _gnutls_ssl3_finished (session,
613 (session->security_parameters.
614 entity + 1) % 2, data);
615 }
616 else
617 { /* TLS 1.0 */
618 ret =
619 _gnutls_finished (session,
620 (session->security_parameters.entity +
621 1) % 2, data);
622 }
623
624 if (ret < 0)
625 {
626 gnutls_assert ();
627 gnutls_free (vrfy);
628 return ret;
629 }
630
631 if (memcmp (vrfy, data, data_size) != 0)
632 {
633 gnutls_assert ();
634 ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
635 }
636 gnutls_free (vrfy);
637
638 return ret;
639}
640
641/* returns PK_RSA if the given cipher suite list only supports,
642 * RSA algorithms, PK_DSA if DSS, and PK_ANY for both or PK_NONE for none.
643 */
644static int
645_gnutls_server_find_pk_algos_in_ciphersuites (const opaque *
646 data, int datalen)
647{
648 int j;
649 gnutls_pk_algorithm_t algo = GNUTLS_PK_NONE, prev_algo = 0;
650 gnutls_kx_algorithm_t kx;
651 cipher_suite_st cs;
652
653 if (datalen % 2 != 0)
654 {
655 gnutls_assert ();
656 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
657 }
658
659 for (j = 0; j < datalen; j += 2)
660 {
661 memcpy (&cs.suite, &data[j], 2);
662 kx = _gnutls_cipher_suite_get_kx_algo (&cs);
663
664 if (_gnutls_map_kx_get_cred (kx, 1) == GNUTLS_CRD_CERTIFICATE)
665 {
666 algo = _gnutls_map_pk_get_pk (kx);
667
668 if (algo != prev_algo && prev_algo != 0)
669 return GNUTLS_PK_ANY;
670 prev_algo = algo;
671 }
672 }
673
674 return algo;
675}
676
677
678/* This selects the best supported ciphersuite from the given ones. Then
679 * it adds the suite to the session and performs some checks.
680 */
681int
682_gnutls_server_select_suite (gnutls_session_t session, opaque * data,
683 int datalen)
684{
685 int x, i, j;
686 cipher_suite_st *ciphers, cs;
687 int retval, err;
688 gnutls_pk_algorithm_t pk_algo; /* will hold the pk algorithms
689 * supported by the peer.
690 */
691
692 pk_algo = _gnutls_server_find_pk_algos_in_ciphersuites (data, datalen);
693
694 x = _gnutls_supported_ciphersuites (session, &ciphers);
695 if (x < 0)
696 { /* the case x==0 is handled within the function. */
697 gnutls_assert ();
698 return x;
699 }
700
701 /* Here we remove any ciphersuite that does not conform
702 * the certificate requested, or to the
703 * authentication requested (e.g. SRP).
704 */
705 x = _gnutls_remove_unwanted_ciphersuites (session, &ciphers, x, pk_algo);
706 if (x <= 0)
707 {
708 gnutls_assert ();
709 gnutls_free (ciphers);
710 if (x < 0)
711 return x;
712 else
713 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
714 }
715
716 /* Data length should be zero mod 2 since
717 * every ciphersuite is 2 bytes. (this check is needed
718 * see below).
719 */
720 if (datalen % 2 != 0)
721 {
722 gnutls_assert ();
723 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
724 }
725#ifdef HANDSHAKE_DEBUG
726
727 _gnutls_handshake_log ("HSK[%x]: Requested cipher suites: \n", session);
728 for (j = 0; j < datalen; j += 2)
729 {
730 memcpy (&cs.suite, &data[j], 2);
731 _gnutls_handshake_log ("\t%s\n", _gnutls_cipher_suite_get_name (&cs));
732 }
733 _gnutls_handshake_log ("HSK[%x]: Supported cipher suites: \n", session);
734 for (j = 0; j < x; j++)
735 _gnutls_handshake_log ("\t%s\n",
736 _gnutls_cipher_suite_get_name (&ciphers[j]));
737#endif
738 memset (session->security_parameters.current_cipher_suite.suite, '\0', 2);
739
740 retval = GNUTLS_E_UNKNOWN_CIPHER_SUITE;
741
742 for (j = 0; j < datalen; j += 2)
743 {
744 for (i = 0; i < x; i++)
745 {
746 if (memcmp (ciphers[i].suite, &data[j], 2) == 0)
747 {
748 memcpy (&cs.suite, &data[j], 2);
749
750 _gnutls_handshake_log
751 ("HSK[%x]: Selected cipher suite: %s\n", session,
752 _gnutls_cipher_suite_get_name (&cs));
753 memcpy (session->security_parameters.current_cipher_suite.
754 suite, ciphers[i].suite, 2);
755 retval = 0;
756 goto finish;
757 }
758 }
759 }
760
761finish:
762 gnutls_free (ciphers);
763
764 if (retval != 0)
765 {
766 gnutls_assert ();
767 return retval;
768 }
769
770 /* check if the credentials (username, public key etc.) are ok
771 */
772 if (_gnutls_get_kx_cred
773 (session,
774 _gnutls_cipher_suite_get_kx_algo (&session->security_parameters.
775 current_cipher_suite),
776 &err) == NULL && err != 0)
777 {
778 gnutls_assert ();
779 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
780 }
781
782
783 /* set the mod_auth_st to the appropriate struct
784 * according to the KX algorithm. This is needed since all the
785 * handshake functions are read from there;
786 */
787 session->internals.auth_struct =
788 _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo
789 (&session->security_parameters.
790 current_cipher_suite));
791 if (session->internals.auth_struct == NULL)
792 {
793
794 _gnutls_handshake_log
795 ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n",
796 session);
797 gnutls_assert ();
798 return GNUTLS_E_INTERNAL_ERROR;
799 }
800
801 return 0;
802
803}
804
805
806/* This selects the best supported compression method from the ones provided
807 */
808int
809_gnutls_server_select_comp_method (gnutls_session_t session,
810 opaque * data, int datalen)
811{
812 int x, i, j;
813 uint8_t *comps;
814
815 x = _gnutls_supported_compression_methods (session, &comps);
816 if (x < 0)
817 {
818 gnutls_assert ();
819 return x;
820 }
821
822 memset (&session->internals.compression_method, 0,
823 sizeof (gnutls_compression_method_t));
824
825 for (j = 0; j < datalen; j++)
826 {
827 for (i = 0; i < x; i++)
828 {
829 if (comps[i] == data[j])
830 {
831 gnutls_compression_method_t method =
832 _gnutls_compression_get_id (comps[i]);
833
834 session->internals.compression_method = method;
835 gnutls_free (comps);
836
837 _gnutls_handshake_log
838 ("HSK[%x]: Selected Compression Method: %s\n", session,
839 gnutls_compression_get_name (session->internals.
840 compression_method));
841
842
843 return 0;
844 }
845 }
846 }
847
848 /* we were not able to find a compatible compression
849 * algorithm
850 */
851 gnutls_free (comps);
852 gnutls_assert ();
853 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
854
855}
856
857/* This function sends an empty handshake packet. (like hello request).
858 * If the previous _gnutls_send_empty_handshake() returned
859 * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
860 * (until it returns ok), with NULL parameters.
861 */
862int
863_gnutls_send_empty_handshake (gnutls_session_t session,
864 gnutls_handshake_description_t type, int again)
865{
866 opaque data = 0;
867 opaque *ptr;
868
869 if (again == 0)
870 ptr = &data;
871 else
872 ptr = NULL;
873
874 return _gnutls_send_handshake (session, ptr, 0, type);
875}
876
877
878/* This function will hash the handshake message we sent.
879 */
880static int
881_gnutls_handshake_hash_add_sent (gnutls_session_t session,
882 gnutls_handshake_description_t type,
883 opaque * dataptr, uint32_t datalen)
884{
885 int ret;
886
887 if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
888 {
889 gnutls_assert ();
890 return ret;
891 }
892
893 if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
894 {
895 _gnutls_hash (session->internals.handshake_mac_handle_sha, dataptr,
896 datalen);
897 _gnutls_hash (session->internals.handshake_mac_handle_md5, dataptr,
898 datalen);
899 }
900
901 return 0;
902}
903
904
905/* This function sends a handshake message of type 'type' containing the
906 * data specified here. If the previous _gnutls_send_handshake() returned
907 * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
908 * (until it returns ok), with NULL parameters.
909 */
910int
911_gnutls_send_handshake (gnutls_session_t session, void *i_data,
912 uint32_t i_datasize,
913 gnutls_handshake_description_t type)
914{
915 int ret;
916 uint8_t *data;
917 uint32_t datasize;
918 int pos = 0;
919
920 if (i_data == NULL && i_datasize == 0)
921 {
922 /* we are resuming a previously interrupted
923 * send.
924 */
925 ret = _gnutls_handshake_io_write_flush (session);
926 return ret;
927
928 }
929
930 if (i_data == NULL && i_datasize > 0)
931 {
932 gnutls_assert ();
933 return GNUTLS_E_INVALID_REQUEST;
934 }
935
936 /* first run */
937 datasize = i_datasize + HANDSHAKE_HEADER_SIZE;
938 data = gnutls_alloca (datasize);
939 if (data == NULL)
940 {
941 gnutls_assert ();
942 return GNUTLS_E_MEMORY_ERROR;
943 }
944
945 data[pos++] = (uint8_t) type;
946 _gnutls_write_uint24 (i_datasize, &data[pos]);
947 pos += 3;
948
949 if (i_datasize > 0)
950 memcpy (&data[pos], i_data, i_datasize);
951
952 _gnutls_handshake_log ("HSK[%x]: %s was send [%ld bytes]\n",
953 session, _gnutls_handshake2str (type), datasize);
954
955
956 /* Here we keep the handshake messages in order to hash them...
957 */
958 if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
959 if ((ret =
960 _gnutls_handshake_hash_add_sent (session, type, data, datasize)) < 0)
961 {
962 gnutls_assert ();
963 gnutls_afree (data);
964 return ret;
965 }
966
967 session->internals.last_handshake_out = type;
968
969 ret =
970 _gnutls_handshake_io_send_int (session, GNUTLS_HANDSHAKE, type,
971 data, datasize);
972
973 gnutls_afree (data);
974
975 return ret;
976}
977
978/* This function will read the handshake header and return it to the caller. If the
979 * received handshake packet is not the one expected then it buffers the header, and
980 * returns UNEXPECTED_HANDSHAKE_PACKET.
981 *
982 * FIXME: This function is complex.
983 */
984#define SSL2_HEADERS 1
985static int
986_gnutls_recv_handshake_header (gnutls_session_t session,
987 gnutls_handshake_description_t type,
988 gnutls_handshake_description_t * recv_type)
989{
990 int ret;
991 uint32_t length32 = 0;
992 uint8_t *dataptr = NULL; /* for realloc */
993 size_t handshake_header_size = HANDSHAKE_HEADER_SIZE;
994
995 /* if we have data into the buffer then return them, do not read the next packet.
996 * In order to return we need a full TLS handshake header, or in case of a version 2
997 * packet, then we return the first byte.
998 */
999 if (session->internals.handshake_header_buffer.header_size ==
1000 handshake_header_size || (session->internals.v2_hello != 0
1001 && type == GNUTLS_HANDSHAKE_CLIENT_HELLO
1002 && session->internals.
1003 handshake_header_buffer.packet_length > 0))
1004 {
1005
1006 *recv_type = session->internals.handshake_header_buffer.recv_type;
1007
1008 return session->internals.handshake_header_buffer.packet_length;
1009 }
1010
1011 /* Note: SSL2_HEADERS == 1 */
1012
1013 dataptr = session->internals.handshake_header_buffer.header;
1014
1015 /* If we haven't already read the handshake headers.
1016 */
1017 if (session->internals.handshake_header_buffer.header_size < SSL2_HEADERS)
1018 {
1019 ret =
1020 _gnutls_handshake_io_recv_int (session, GNUTLS_HANDSHAKE,
1021 type, dataptr, SSL2_HEADERS);
1022
1023 if (ret < 0)
1024 {
1025 gnutls_assert ();
1026 return ret;
1027 }
1028
1029 /* The case ret==0 is caught here.
1030 */
1031 if (ret != SSL2_HEADERS)
1032 {
1033 gnutls_assert ();
1034 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1035 }
1036 session->internals.handshake_header_buffer.header_size = SSL2_HEADERS;
1037 }
1038
1039 if (session->internals.v2_hello == 0
1040 || type != GNUTLS_HANDSHAKE_CLIENT_HELLO)
1041 {
1042 ret =
1043 _gnutls_handshake_io_recv_int (session, GNUTLS_HANDSHAKE,
1044 type,
1045 &dataptr[session->
1046 internals.
1047 handshake_header_buffer.
1048 header_size],
1049 HANDSHAKE_HEADER_SIZE -
1050 session->internals.
1051 handshake_header_buffer.header_size);
1052 if (ret <= 0)
1053 {
1054 gnutls_assert ();
1055 return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1056 }
1057 if ((size_t) ret !=
1058 HANDSHAKE_HEADER_SIZE -
1059 session->internals.handshake_header_buffer.header_size)
1060 {
1061 gnutls_assert ();
1062 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1063 }
1064 *recv_type = dataptr[0];
1065
1066 /* we do not use DECR_LEN because we know
1067 * that the packet has enough data.
1068 */
1069 length32 = _gnutls_read_uint24 (&dataptr[1]);
1070 handshake_header_size = HANDSHAKE_HEADER_SIZE;
1071
1072 _gnutls_handshake_log ("HSK[%x]: %s was received [%ld bytes]\n",
1073 session, _gnutls_handshake2str (dataptr[0]),
1074 length32 + HANDSHAKE_HEADER_SIZE);
1075
1076 }
1077 else
1078 { /* v2 hello */
1079 length32 = session->internals.v2_hello - SSL2_HEADERS; /* we've read the first byte */
1080
1081 handshake_header_size = SSL2_HEADERS; /* we've already read one byte */
1082
1083 *recv_type = dataptr[0];
1084
1085 _gnutls_handshake_log ("HSK[%x]: %s(v2) was received [%ld bytes]\n",
1086 session, _gnutls_handshake2str (*recv_type),
1087 length32 + handshake_header_size);
1088
1089 if (*recv_type != GNUTLS_HANDSHAKE_CLIENT_HELLO)
1090 { /* it should be one or nothing */
1091 gnutls_assert ();
1092 return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
1093 }
1094 }
1095
1096 /* put the packet into the buffer */
1097 session->internals.handshake_header_buffer.header_size =
1098 handshake_header_size;
1099 session->internals.handshake_header_buffer.packet_length = length32;
1100 session->internals.handshake_header_buffer.recv_type = *recv_type;
1101
1102 if (*recv_type != type)
1103 {
1104 gnutls_assert ();
1105 return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
1106 }
1107
1108 return length32;
1109}
1110
1111#define _gnutls_handshake_header_buffer_clear( session) session->internals.handshake_header_buffer.header_size = 0
1112
1113
1114
1115/* This function will hash the handshake headers and the
1116 * handshake data.
1117 */
1118static int
1119_gnutls_handshake_hash_add_recvd (gnutls_session_t session,
1120 gnutls_handshake_description_t recv_type,
1121 opaque * header, uint16_t header_size,
1122 opaque * dataptr, uint32_t datalen)
1123{
1124 int ret;
1125
1126 /* The idea here is to hash the previous message we received,
1127 * and add the one we just received into the handshake_hash_buffer.
1128 */
1129
1130 if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
1131 {
1132 gnutls_assert ();
1133 return ret;
1134 }
1135
1136 /* here we buffer the handshake messages - needed at Finished message */
1137 if (recv_type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
1138 {
1139
1140 if ((ret =
1141 _gnutls_handshake_buffer_put (session, header, header_size)) < 0)
1142 {
1143 gnutls_assert ();
1144 return ret;
1145 }
1146
1147 if (datalen > 0)
1148 {
1149 if ((ret =
1150 _gnutls_handshake_buffer_put (session, dataptr, datalen)) < 0)
1151 {
1152 gnutls_assert ();
1153 return ret;
1154 }
1155 }
1156 }
1157
1158 return 0;
1159}
1160
1161
1162/* This function will receive handshake messages of the given types,
1163 * and will pass the message to the right place in order to be processed.
1164 * E.g. for the SERVER_HELLO message (if it is expected), it will be
1165 * passed to _gnutls_recv_hello().
1166 */
1167int
1168_gnutls_recv_handshake (gnutls_session_t session, uint8_t ** data,
1169 int *datalen, gnutls_handshake_description_t type,
1170 Optional optional)
1171{
1172 int ret;
1173 uint32_t length32 = 0;
1174 opaque *dataptr = NULL;
1175 gnutls_handshake_description_t recv_type;
1176
1177 ret = _gnutls_recv_handshake_header (session, type, &recv_type);
1178 if (ret < 0)
1179 {
1180
1181 if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET
1182 && optional == OPTIONAL_PACKET)
1183 {
1184 if (datalen != NULL)
1185 *datalen = 0;
1186 if (data != NULL)
1187 *data = NULL;
1188 return 0; /* ok just ignore the packet */
1189 }
1190
1191 return ret;
1192 }
1193
1194 session->internals.last_handshake_in = recv_type;
1195
1196 length32 = ret;
1197
1198 if (length32 > 0)
1199 dataptr = gnutls_malloc (length32);
1200 else if (recv_type != GNUTLS_HANDSHAKE_SERVER_HELLO_DONE)
1201 {
1202 gnutls_assert ();
1203 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1204 }
1205
1206 if (dataptr == NULL && length32 > 0)
1207 {
1208 gnutls_assert ();
1209 return GNUTLS_E_MEMORY_ERROR;
1210 }
1211
1212 if (datalen != NULL)
1213 *datalen = length32;
1214
1215 if (length32 > 0)
1216 {
1217 ret =
1218 _gnutls_handshake_io_recv_int (session, GNUTLS_HANDSHAKE,
1219 type, dataptr, length32);
1220 if (ret <= 0)
1221 {
1222 gnutls_assert ();
1223 gnutls_free (dataptr);
1224 return (ret == 0) ? GNUTLS_E_UNEXPECTED_PACKET_LENGTH : ret;
1225 }
1226 }
1227
1228 if (data != NULL && length32 > 0)
1229 *data = dataptr;
1230
1231
1232 ret = _gnutls_handshake_hash_add_recvd (session, recv_type,
1233 session->internals.
1234 handshake_header_buffer.header,
1235 session->internals.
1236 handshake_header_buffer.
1237 header_size, dataptr, length32);
1238 if (ret < 0)
1239 {
1240 gnutls_assert ();
1241 _gnutls_handshake_header_buffer_clear (session);
1242 return ret;
1243 }
1244
1245 /* If we fail before this then we will reuse the handshake header
1246 * have have received above. if we get here the we clear the handshake
1247 * header we received.
1248 */
1249 _gnutls_handshake_header_buffer_clear (session);
1250
1251 switch (recv_type)
1252 {
1253 case GNUTLS_HANDSHAKE_CLIENT_HELLO:
1254 case GNUTLS_HANDSHAKE_SERVER_HELLO:
1255 ret = _gnutls_recv_hello (session, dataptr, length32);
1256 /* dataptr is freed because the caller does not
1257 * need it */
1258 gnutls_free (dataptr);
1259 if (data != NULL)
1260 *data = NULL;
1261 break;
1262 case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
1263 if (length32 == 0)
1264 ret = 0;
1265 else
1266 ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1267 break;
1268 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
1269 case GNUTLS_HANDSHAKE_FINISHED:
1270 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
1271 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
1272 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
1273 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
1274 case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
1275 ret = length32;
1276 break;
1277 default:
1278 gnutls_assert ();
1279 gnutls_free (dataptr);
1280 if (data != NULL)
1281 *data = NULL;
1282 ret = GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
1283 }
1284
1285 return ret;
1286}
1287
1288/* This function checks if the given cipher suite is supported, and sets it
1289 * to the session;
1290 */
1291static int
1292_gnutls_client_set_ciphersuite (gnutls_session_t session, opaque suite[2])
1293{
1294 uint8_t z;
1295 cipher_suite_st *cipher_suites;
1296 int cipher_suite_num;
1297 int i, err;
1298
1299 z = 1;
1300 cipher_suite_num = _gnutls_supported_ciphersuites (session, &cipher_suites);
1301 if (cipher_suite_num < 0)
1302 {
1303 gnutls_assert ();
1304 return cipher_suite_num;
1305 }
1306
1307 for (i = 0; i < cipher_suite_num; i++)
1308 {
1309 if (memcmp (&cipher_suites[i], suite, 2) == 0)
1310 {
1311 z = 0;
1312 break;
1313 }
1314 }
1315
1316 gnutls_free (cipher_suites);
1317
1318 if (z != 0)
1319 {
1320 gnutls_assert ();
1321 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
1322 }
1323
1324 memcpy (session->security_parameters.current_cipher_suite.suite, suite, 2);
1325
1326 _gnutls_handshake_log ("HSK[%x]: Selected cipher suite: %s\n", session,
1327 _gnutls_cipher_suite_get_name (&session->
1328 security_parameters.
1329 current_cipher_suite));
1330
1331
1332 /* check if the credentials (username, public key etc.) are ok.
1333 * Actually checks if they exist.
1334 */
1335 if (_gnutls_get_kx_cred
1336 (session, _gnutls_cipher_suite_get_kx_algo (&session->
1337 security_parameters.
1338 current_cipher_suite),
1339 &err) == NULL && err != 0)
1340 {
1341 gnutls_assert ();
1342 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1343 }
1344
1345
1346 /* set the mod_auth_st to the appropriate struct
1347 * according to the KX algorithm. This is needed since all the
1348 * handshake functions are read from there;
1349 */
1350 session->internals.auth_struct =
1351 _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo
1352 (&session->security_parameters.
1353 current_cipher_suite));
1354
1355 if (session->internals.auth_struct == NULL)
1356 {
1357
1358 _gnutls_handshake_log
1359 ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n",
1360 session);
1361 gnutls_assert ();
1362 return GNUTLS_E_INTERNAL_ERROR;
1363 }
1364
1365
1366 return 0;
1367}
1368
1369/* This function sets the given comp method to the session.
1370 */
1371static int
1372_gnutls_client_set_comp_method (gnutls_session_t session, opaque comp_method)
1373{
1374 int comp_methods_num;
1375 uint8_t *compression_methods;
1376 int i;
1377
1378 comp_methods_num = _gnutls_supported_compression_methods (session,
1379 &compression_methods);
1380 if (comp_methods_num < 0)
1381 {
1382 gnutls_assert ();
1383 return comp_methods_num;
1384 }
1385
1386 for (i = 0; i < comp_methods_num; i++)
1387 {
1388 if (compression_methods[i] == comp_method)
1389 {
1390 comp_methods_num = 0;
1391 break;
1392 }
1393 }
1394
1395 gnutls_free (compression_methods);
1396
1397 if (comp_methods_num != 0)
1398 {
1399 gnutls_assert ();
1400 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
1401 }
1402
1403 session->internals.compression_method =
1404 _gnutls_compression_get_id (comp_method);
1405
1406
1407 return 0;
1408}
1409
1410/* This function returns 0 if we are resuming a session or -1 otherwise.
1411 * This also sets the variables in the session. Used only while reading a server
1412 * hello.
1413 */
1414static int
1415_gnutls_client_check_if_resuming (gnutls_session_t session,
1416 opaque * session_id, int session_id_len)
1417{
1418 opaque buf[2 * TLS_MAX_SESSION_ID_SIZE + 1];
1419
1420 _gnutls_handshake_log ("HSK[%x]: SessionID length: %d\n", session,
1421 session_id_len);
1422 _gnutls_handshake_log ("HSK[%x]: SessionID: %s\n", session,
1423 _gnutls_bin2hex (session_id, session_id_len, buf,
1424 sizeof (buf)));
1425
1426 if (session_id_len > 0 &&
1427 session->internals.resumed_security_parameters.session_id_size ==
1428 session_id_len
1429 && memcmp (session_id,
1430 session->internals.resumed_security_parameters.
1431 session_id, session_id_len) == 0)
1432 {
1433 /* resume session */
1434 memcpy (session->internals.
1435 resumed_security_parameters.server_random,
1436 session->security_parameters.server_random, TLS_RANDOM_SIZE);
1437 memcpy (session->internals.
1438 resumed_security_parameters.client_random,
1439 session->security_parameters.client_random, TLS_RANDOM_SIZE);
1440 session->internals.resumed = RESUME_TRUE; /* we are resuming */
1441
1442 return 0;
1443 }
1444 else
1445 {
1446 /* keep the new session id */
1447 session->internals.resumed = RESUME_FALSE; /* we are not resuming */
1448 session->security_parameters.session_id_size = session_id_len;
1449 memcpy (session->security_parameters.session_id,
1450 session_id, session_id_len);
1451
1452 return -1;
1453 }
1454}
1455
1456
1457/* This function reads and parses the server hello handshake message.
1458 * This function also restores resumed parameters if we are resuming a
1459 * session.
1460 */
1461static int
1462_gnutls_read_server_hello (gnutls_session_t session,
1463 opaque * data, int datalen)
1464{
1465 uint8_t session_id_len = 0;
1466 int pos = 0;
1467 int ret = 0;
1468 gnutls_protocol_t version;
1469 int len = datalen;
1470
1471 if (datalen < 38)
1472 {
1473 gnutls_assert ();
1474 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1475 }
1476
1477 _gnutls_handshake_log ("HSK[%x]: Server's version: %d.%d\n",
1478 session, data[pos], data[pos + 1]);
1479
1480 DECR_LEN (len, 2);
1481 version = _gnutls_version_get (data[pos], data[pos + 1]);
1482 if (_gnutls_version_is_supported (session, version) == 0)
1483 {
1484 gnutls_assert ();
1485 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
1486 }
1487 else
1488 {
1489 _gnutls_set_current_version (session, version);
1490 }
1491
1492 pos += 2;
1493
1494 DECR_LEN (len, TLS_RANDOM_SIZE);
1495 _gnutls_set_server_random (session, &data[pos]);
1496 pos += TLS_RANDOM_SIZE;
1497
1498
1499 /* Read session ID
1500 */
1501 DECR_LEN (len, 1);
1502 session_id_len = data[pos++];
1503
1504 if (len < session_id_len)
1505 {
1506 gnutls_assert ();
1507 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
1508 }
1509 DECR_LEN (len, session_id_len);
1510
1511
1512 /* check if we are resuming and set the appropriate
1513 * values;
1514 */
1515 if (_gnutls_client_check_if_resuming
1516 (session, &data[pos], session_id_len) == 0)
1517 return 0;
1518 pos += session_id_len;
1519
1520
1521 /* Check if the given cipher suite is supported and copy
1522 * it to the session.
1523 */
1524
1525 DECR_LEN (len, 2);
1526 ret = _gnutls_client_set_ciphersuite (session, &data[pos]);
1527 if (ret < 0)
1528 {
1529 gnutls_assert ();
1530 return ret;
1531 }
1532 pos += 2;
1533
1534
1535
1536 /* move to compression
1537 */
1538 DECR_LEN (len, 1);
1539
1540 ret = _gnutls_client_set_comp_method (session, data[pos++]);
1541 if (ret < 0)
1542 {
1543 gnutls_assert ();
1544 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
1545 }
1546
1547 /* Parse extensions.
1548 */
1549 if (version >= GNUTLS_TLS1)
1550 {
1551 ret = _gnutls_parse_extensions (session, EXTENSION_ANY, &data[pos], len); /* len is the rest of the parsed length */
1552 if (ret < 0)
1553 {
1554 gnutls_assert ();
1555 return ret;
1556 }
1557 }
1558 return ret;
1559}
1560
1561
1562/* This function copies the appropriate ciphersuites to a locally allocated buffer
1563 * Needed in client hello messages. Returns the new data length.
1564 */
1565static int
1566_gnutls_copy_ciphersuites (gnutls_session_t session,
1567 opaque * ret_data, size_t ret_data_size)
1568{
1569 int ret, i;
1570 cipher_suite_st *cipher_suites;
1571 uint16_t cipher_num;
1572 int datalen, pos;
1573
1574 ret = _gnutls_supported_ciphersuites_sorted (session, &cipher_suites);
1575 if (ret < 0)
1576 {
1577 gnutls_assert ();
1578 return ret;
1579 }
1580
1581 /* Here we remove any ciphersuite that does not conform
1582 * the certificate requested, or to the
1583 * authentication requested (eg SRP).
1584 */
1585 ret =
1586 _gnutls_remove_unwanted_ciphersuites (session, &cipher_suites, ret, -1);
1587 if (ret < 0)
1588 {
1589 gnutls_assert ();
1590 gnutls_free (cipher_suites);
1591 return ret;
1592 }
1593
1594 /* If no cipher suites were enabled.
1595 */
1596 if (ret == 0)
1597 {
1598 gnutls_assert ();
1599 gnutls_free (cipher_suites);
1600 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1601 }
1602
1603 cipher_num = ret;
1604
1605 cipher_num *= sizeof (uint16_t); /* in order to get bytes */
1606
1607 datalen = pos = 0;
1608
1609 datalen += sizeof (uint16_t) + cipher_num;
1610
1611 if ((size_t) datalen > ret_data_size)
1612 {
1613 gnutls_assert ();
1614 return GNUTLS_E_INTERNAL_ERROR;
1615 }
1616
1617 _gnutls_write_uint16 (cipher_num, ret_data);
1618 pos += 2;
1619
1620 for (i = 0; i < (cipher_num / 2); i++)
1621 {
1622 memcpy (&ret_data[pos], cipher_suites[i].suite, 2);
1623 pos += 2;
1624 }
1625 gnutls_free (cipher_suites);
1626
1627 return datalen;
1628}
1629
1630
1631/* This function copies the appropriate compression methods, to a locally allocated buffer
1632 * Needed in hello messages. Returns the new data length.
1633 */
1634static int
1635_gnutls_copy_comp_methods (gnutls_session_t session,
1636 opaque * ret_data, size_t ret_data_size)
1637{
1638 int ret, i;
1639 uint8_t *compression_methods, comp_num;
1640 int datalen, pos;
1641
1642 ret = _gnutls_supported_compression_methods (session, &compression_methods);
1643 if (ret < 0)
1644 {
1645 gnutls_assert ();
1646 return ret;
1647 }
1648
1649 comp_num = ret;
1650
1651 datalen = pos = 0;
1652 datalen += comp_num + 1;
1653
1654 if ((size_t) datalen > ret_data_size)
1655 {
1656 gnutls_assert ();
1657 return GNUTLS_E_INTERNAL_ERROR;
1658 }
1659
1660 ret_data[pos++] = comp_num; /* put the number of compression methods */
1661
1662 for (i = 0; i < comp_num; i++)
1663 {
1664 ret_data[pos++] = compression_methods[i];
1665 }
1666
1667 gnutls_free (compression_methods);
1668
1669 return datalen;
1670}
1671
1672/* This should be sufficient by now. It should hold all the extensions
1673 * plus the headers in a hello message.
1674 */
1675#define MAX_EXT_DATA_LENGTH 1024
1676
1677/* This function sends the client hello handshake message.
1678 */
1679static int
1680_gnutls_send_client_hello (gnutls_session_t session, int again)
1681{
1682 opaque *data = NULL;
1683 int extdatalen;
1684 int pos = 0;
1685 int datalen = 0, ret = 0;
1686 opaque rnd[TLS_RANDOM_SIZE];
1687 gnutls_protocol_t hver;
1688 opaque extdata[MAX_EXT_DATA_LENGTH];
1689
1690 opaque *SessionID =
1691 session->internals.resumed_security_parameters.session_id;
1692 uint8_t session_id_len =
1693 session->internals.resumed_security_parameters.session_id_size;
1694
1695 if (SessionID == NULL)
1696 session_id_len = 0;
1697 else if (session_id_len == 0)
1698 SessionID = NULL;
1699
1700 if (again == 0)
1701 {
1702
1703 datalen = 2 + (session_id_len + 1) + TLS_RANDOM_SIZE;
1704 /* 2 for version, (4 for unix time + 28 for random bytes==TLS_RANDOM_SIZE)
1705 */
1706
1707 data = gnutls_malloc (datalen);
1708 if (data == NULL)
1709 {
1710 gnutls_assert ();
1711 return GNUTLS_E_MEMORY_ERROR;
1712 }
1713
1714 /* if we are resuming a session then we set the
1715 * version number to the previously established.
1716 */
1717 if (SessionID == NULL)
1718 hver = _gnutls_version_max (session);
1719 else
1720 { /* we are resuming a session */
1721 hver = session->internals.resumed_security_parameters.version;
1722 }
1723
1724 if (hver == GNUTLS_VERSION_UNKNOWN || hver == 0)
1725 {
1726 gnutls_assert ();
1727 gnutls_free (data);
1728 return GNUTLS_E_INTERNAL_ERROR;
1729 }
1730
1731 data[pos++] = _gnutls_version_get_major (hver);
1732 data[pos++] = _gnutls_version_get_minor (hver);
1733
1734 /* Set the version we advertized as maximum
1735 * (RSA uses it).
1736 */
1737 _gnutls_set_adv_version (session, hver);
1738
1739 /* Some old implementations do not interoperate if we send a
1740 * different version in the record layer.
1741 * It seems they prefer to read the record's version
1742 * as the one we actually requested.
1743 * The proper behaviour is to use the one in the client hello
1744 * handshake packet and ignore the one in the packet's record
1745 * header.
1746 */
1747 _gnutls_set_current_version (session, hver);
1748
1749 /* In order to know when this session was initiated.
1750 */
1751 session->security_parameters.timestamp = time (NULL);
1752
1753 /* Generate random data
1754 */
1755 _gnutls_tls_create_random (rnd);
1756 _gnutls_set_client_random (session, rnd);
1757
1758 memcpy (&data[pos], rnd, TLS_RANDOM_SIZE);
1759 pos += TLS_RANDOM_SIZE;
1760
1761 /* Copy the Session ID
1762 */
1763 data[pos++] = session_id_len;
1764
1765 if (session_id_len > 0)
1766 {
1767 memcpy (&data[pos], SessionID, session_id_len);
1768 pos += session_id_len;
1769 }
1770
1771
1772 /* Copy the ciphersuites.
1773 */
1774 extdatalen =
1775 _gnutls_copy_ciphersuites (session, extdata, sizeof (extdata));
1776 if (extdatalen > 0)
1777 {
1778 datalen += extdatalen;
1779 data = gnutls_realloc_fast (data, datalen);
1780 if (data == NULL)
1781 {
1782 gnutls_assert ();
1783 return GNUTLS_E_MEMORY_ERROR;
1784 }
1785
1786 memcpy (&data[pos], extdata, extdatalen);
1787 pos += extdatalen;
1788
1789 }
1790 else
1791 {
1792 if (extdatalen == 0)
1793 extdatalen = GNUTLS_E_INTERNAL_ERROR;
1794 gnutls_free (data);
1795 gnutls_assert ();
1796 return extdatalen;
1797 }
1798
1799
1800 /* Copy the compression methods.
1801 */
1802 extdatalen =
1803 _gnutls_copy_comp_methods (session, extdata, sizeof (extdata));
1804 if (extdatalen > 0)
1805 {
1806 datalen += extdatalen;
1807 data = gnutls_realloc_fast (data, datalen);
1808 if (data == NULL)
1809 {
1810 gnutls_assert ();
1811 return GNUTLS_E_MEMORY_ERROR;
1812 }
1813
1814 memcpy (&data[pos], extdata, extdatalen);
1815 pos += extdatalen;
1816
1817 }
1818 else
1819 {
1820 if (extdatalen == 0)
1821 extdatalen = GNUTLS_E_INTERNAL_ERROR;
1822 gnutls_free (data);
1823 gnutls_assert ();
1824 return extdatalen;
1825 }
1826
1827 /* Generate and copy TLS extensions.
1828 */
1829 if (hver >= GNUTLS_TLS1)
1830 {
1831 extdatalen =
1832 _gnutls_gen_extensions (session, extdata, sizeof (extdata));
1833
1834 if (extdatalen > 0)
1835 {
1836 datalen += extdatalen;
1837 data = gnutls_realloc_fast (data, datalen);
1838 if (data == NULL)
1839 {
1840 gnutls_assert ();
1841 return GNUTLS_E_MEMORY_ERROR;
1842 }
1843
1844 memcpy (&data[pos], extdata, extdatalen);
1845 }
1846 else if (extdatalen < 0)
1847 {
1848 gnutls_assert ();
1849 gnutls_free (data);
1850 return extdatalen;
1851 }
1852 }
1853 }
1854
1855 ret =
1856 _gnutls_send_handshake (session, data, datalen,
1857 GNUTLS_HANDSHAKE_CLIENT_HELLO);
1858 gnutls_free (data);
1859
1860 return ret;
1861}
1862
1863static int
1864_gnutls_send_server_hello (gnutls_session_t session, int again)
1865{
1866 opaque *data = NULL;
1867 opaque extdata[MAX_EXT_DATA_LENGTH];
1868 int extdatalen;
1869 int pos = 0;
1870 int datalen, ret = 0;
1871 uint8_t comp;
1872 opaque *SessionID = session->security_parameters.session_id;
1873 uint8_t session_id_len = session->security_parameters.session_id_size;
1874 opaque buf[2 * TLS_MAX_SESSION_ID_SIZE + 1];
1875
1876 if (SessionID == NULL)
1877 session_id_len = 0;
1878
1879 datalen = 0;
1880
1881#ifdef ENABLE_SRP
1882 if (IS_SRP_KX
1883 (_gnutls_cipher_suite_get_kx_algo
1884 (&session->security_parameters.current_cipher_suite)))
1885 {
1886 /* While resuming we cannot check the username extension since it is
1887 * not available at this point. It will be copied on connection
1888 * state activation.
1889 */
1890 if (session->internals.resumed == RESUME_FALSE &&
1891 session->security_parameters.extensions.srp_username[0] == 0)
1892 {
1893 /* The peer didn't send a valid SRP extension with the
1894 * SRP username. The draft requires that we send a fatal
1895 * alert and abort.
1896 */
1897 gnutls_assert ();
1898 ret = gnutls_alert_send (session, GNUTLS_AL_FATAL,
1899 GNUTLS_A_UNKNOWN_PSK_IDENTITY);
1900 if (ret < 0)
1901 {
1902 gnutls_assert ();
1903 return ret;
1904 }
1905
1906 return GNUTLS_E_ILLEGAL_SRP_USERNAME;
1907 }
1908 }
1909#endif
1910
1911 if (again == 0)
1912 {
1913 datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE + 3;
1914 extdatalen =
1915 _gnutls_gen_extensions (session, extdata, sizeof (extdata));
1916
1917 if (extdatalen < 0)
1918 {
1919 gnutls_assert ();
1920 return extdatalen;
1921 }
1922
1923 data = gnutls_alloca (datalen + extdatalen);
1924 if (data == NULL)
1925 {
1926 gnutls_assert ();
1927 return GNUTLS_E_MEMORY_ERROR;
1928 }
1929
1930 data[pos++] =
1931 _gnutls_version_get_major (session->security_parameters.version);
1932 data[pos++] =
1933 _gnutls_version_get_minor (session->security_parameters.version);
1934
1935 memcpy (&data[pos],
1936 session->security_parameters.server_random, TLS_RANDOM_SIZE);
1937 pos += TLS_RANDOM_SIZE;
1938
1939 data[pos++] = session_id_len;
1940 if (session_id_len > 0)
1941 {
1942 memcpy (&data[pos], SessionID, session_id_len);
1943 }
1944 pos += session_id_len;
1945
1946 _gnutls_handshake_log ("HSK[%x]: SessionID: %s\n", session,
1947 _gnutls_bin2hex (SessionID, session_id_len,
1948 buf, sizeof (buf)));
1949
1950 memcpy (&data[pos],
1951 session->security_parameters.current_cipher_suite.suite, 2);
1952 pos += 2;
1953
1954 comp =
1955 (uint8_t) _gnutls_compression_get_num (session->
1956 internals.compression_method);
1957 data[pos++] = comp;
1958
1959
1960 if (extdatalen > 0)
1961 {
1962 datalen += extdatalen;
1963
1964 memcpy (&data[pos], extdata, extdatalen);
1965 }
1966 }
1967
1968 ret =
1969 _gnutls_send_handshake (session, data, datalen,
1970 GNUTLS_HANDSHAKE_SERVER_HELLO);
1971 gnutls_afree (data);
1972
1973 return ret;
1974}
1975
1976int
1977_gnutls_send_hello (gnutls_session_t session, int again)
1978{
1979 int ret;
1980
1981 if (session->security_parameters.entity == GNUTLS_CLIENT)
1982 {
1983 ret = _gnutls_send_client_hello (session, again);
1984
1985 }
1986 else
1987 { /* SERVER */
1988 ret = _gnutls_send_server_hello (session, again);
1989 }
1990
1991 return ret;
1992}
1993
1994/* RECEIVE A HELLO MESSAGE. This should be called from gnutls_recv_handshake_int only if a
1995 * hello message is expected. It uses the security_parameters.current_cipher_suite
1996 * and internals.compression_method.
1997 */
1998int
1999_gnutls_recv_hello (gnutls_session_t session, opaque * data, int datalen)
2000{
2001 int ret;
2002
2003 if (session->security_parameters.entity == GNUTLS_CLIENT)
2004 {
2005 ret = _gnutls_read_server_hello (session, data, datalen);
2006 if (ret < 0)
2007 {
2008 gnutls_assert ();
2009 return ret;
2010 }
2011 }
2012 else
2013 { /* Server side reading a client hello */
2014
2015 ret = _gnutls_read_client_hello (session, data, datalen);
2016 if (ret < 0)
2017 {
2018 gnutls_assert ();
2019 return ret;
2020 }
2021 }
2022
2023 return ret;
2024}
2025
2026/* The packets in gnutls_handshake (it's more broad than original TLS handshake)
2027 *
2028 * Client Server
2029 *
2030 * ClientHello -------->
2031 * <-------- ServerHello
2032 *
2033 * Certificate*
2034 * ServerKeyExchange*
2035 * <-------- CertificateRequest*
2036 *
2037 * <-------- ServerHelloDone
2038 * Certificate*
2039 * ClientKeyExchange
2040 * CertificateVerify*
2041 * [ChangeCipherSpec]
2042 * Finished -------->
2043 * [ChangeCipherSpec]
2044 * <-------- Finished
2045 *
2046 * (*): means optional packet.
2047 */
2048
2049/**
2050 * gnutls_rehandshake - This function will renegotiate security parameters
2051 * @session: is a #gnutls_session_t structure.
2052 *
2053 * This function will renegotiate security parameters with the
2054 * client. This should only be called in case of a server.
2055 *
2056 * This message informs the peer that we want to renegotiate
2057 * parameters (perform a handshake).
2058 *
2059 * If this function succeeds (returns 0), you must call the
2060 * gnutls_handshake() function in order to negotiate the new
2061 * parameters.
2062 *
2063 * If the client does not wish to renegotiate parameters he will
2064 * should with an alert message, thus the return code will be
2065 * %GNUTLS_E_WARNING_ALERT_RECEIVED and the alert will be
2066 * %GNUTLS_A_NO_RENEGOTIATION. A client may also choose to ignore
2067 * this message.
2068 *
2069 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
2070 *
2071 **/
2072int
2073gnutls_rehandshake (gnutls_session_t session)
2074{
2075 int ret;
2076
2077 /* only server sends that handshake packet */
2078 if (session->security_parameters.entity == GNUTLS_CLIENT)
2079 return GNUTLS_E_INVALID_REQUEST;
2080
2081 ret =
2082 _gnutls_send_empty_handshake (session, GNUTLS_HANDSHAKE_HELLO_REQUEST,
2083 AGAIN (STATE50));
2084 STATE = STATE50;
2085
2086 if (ret < 0)
2087 {
2088 gnutls_assert ();
2089 return ret;
2090 }
2091 STATE = STATE0;
2092
2093 return 0;
2094}
2095
2096inline static int
2097_gnutls_abort_handshake (gnutls_session_t session, int ret)
2098{
2099 if (((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) &&
2100 (gnutls_alert_get (session) == GNUTLS_A_NO_RENEGOTIATION))
2101 || ret == GNUTLS_E_GOT_APPLICATION_DATA)
2102 return 0;
2103
2104 /* this doesn't matter */
2105 return GNUTLS_E_INTERNAL_ERROR;
2106}
2107
2108
2109/* This function initialized the handshake hash session.
2110 * required for finished messages.
2111 */
2112inline static int
2113_gnutls_handshake_hash_init (gnutls_session_t session)
2114{
2115
2116 if (session->internals.handshake_mac_handle_md5 == NULL)
2117 {
2118 session->internals.handshake_mac_handle_md5 =
2119 _gnutls_hash_init (GNUTLS_MAC_MD5);
2120
2121 if (session->internals.handshake_mac_handle_md5 == GNUTLS_HASH_FAILED)
2122 {
2123 gnutls_assert ();
2124 return GNUTLS_E_MEMORY_ERROR;
2125 }
2126 }
2127
2128 if (session->internals.handshake_mac_handle_sha == NULL)
2129 {
2130 session->internals.handshake_mac_handle_sha =
2131 _gnutls_hash_init (GNUTLS_MAC_SHA1);
2132 if (session->internals.handshake_mac_handle_sha == GNUTLS_HASH_FAILED)
2133 {
2134 gnutls_assert ();
2135 return GNUTLS_E_MEMORY_ERROR;
2136 }
2137 }
2138
2139 return 0;
2140}
2141
2142int
2143_gnutls_send_supplemental (gnutls_session_t session, int again)
2144{
2145 int ret = 0;
2146
2147 _gnutls_debug_log ("EXT[%x]: Sending supplemental data\n", session);
2148
2149 if (again)
2150 ret = _gnutls_send_handshake (session, NULL, 0,
2151 GNUTLS_HANDSHAKE_SUPPLEMENTAL);
2152 else
2153 {
2154 gnutls_buffer buf;
2155 _gnutls_buffer_init (&buf);
2156
2157 ret = _gnutls_gen_supplemental (session, &buf);
2158 if (ret < 0)
2159 {
2160 gnutls_assert ();
2161 return ret;
2162 }
2163
2164 ret = _gnutls_send_handshake (session, buf.data, buf.length,
2165 GNUTLS_HANDSHAKE_SUPPLEMENTAL);
2166 _gnutls_buffer_clear (&buf);
2167 }
2168
2169 return ret;
2170}
2171
2172int
2173_gnutls_recv_supplemental (gnutls_session_t session)
2174{
2175 uint8_t *data = NULL;
2176 int datalen = 0;
2177 int ret;
2178
2179 _gnutls_debug_log ("EXT[%x]: Expecting supplemental data\n", session);
2180
2181 ret = _gnutls_recv_handshake (session, &data, &datalen,
2182 GNUTLS_HANDSHAKE_SUPPLEMENTAL,
2183 OPTIONAL_PACKET);
2184 if (ret < 0)
2185 {
2186 gnutls_assert ();
2187 return ret;
2188 }
2189
2190 ret = _gnutls_parse_supplemental (session, data, datalen);
2191 if (ret < 0)
2192 {
2193 gnutls_assert ();
2194 return ret;
2195 }
2196
2197 gnutls_free (data);
2198
2199 return ret;
2200}
2201
2202/**
2203 * gnutls_handshake - This is the main function in the handshake protocol.
2204 * @session: is a #gnutls_session_t structure.
2205 *
2206 * This function does the handshake of the TLS/SSL protocol, and
2207 * initializes the TLS connection.
2208 *
2209 * This function will fail if any problem is encountered, and will
2210 * return a negative error code. In case of a client, if the client
2211 * has asked to resume a session, but the server couldn't, then a
2212 * full handshake will be performed.
2213 *
2214 * The non-fatal errors such as %GNUTLS_E_AGAIN and
2215 * %GNUTLS_E_INTERRUPTED interrupt the handshake procedure, which
2216 * should be later be resumed. Call this function again, until it
2217 * returns 0; cf. gnutls_record_get_direction() and
2218 * gnutls_error_is_fatal().
2219 *
2220 * If this function is called by a server after a rehandshake request
2221 * then %GNUTLS_E_GOT_APPLICATION_DATA or
2222 * %GNUTLS_E_WARNING_ALERT_RECEIVED may be returned. Note that these
2223 * are non fatal errors, only in the specific case of a rehandshake.
2224 * Their meaning is that the client rejected the rehandshake request.
2225 *
2226 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
2227 *
2228 **/
2229int
2230gnutls_handshake (gnutls_session_t session)
2231{
2232 int ret;
2233
2234 if ((ret = _gnutls_handshake_hash_init (session)) < 0)
2235 {
2236 gnutls_assert ();
2237 return ret;
2238 }
2239
2240 if (session->security_parameters.entity == GNUTLS_CLIENT)
2241 {
2242 ret = _gnutls_handshake_client (session);
2243 }
2244 else
2245 {
2246 ret = _gnutls_handshake_server (session);
2247 }
2248 if (ret < 0)
2249 {
2250 /* In the case of a rehandshake abort
2251 * we should reset the handshake's internal state.
2252 */
2253 if (_gnutls_abort_handshake (session, ret) == 0)
2254 STATE = STATE0;
2255
2256 return ret;
2257 }
2258
2259 ret = _gnutls_handshake_common (session);
2260
2261 if (ret < 0)
2262 {
2263 if (_gnutls_abort_handshake (session, ret) == 0)
2264 STATE = STATE0;
2265
2266 return ret;
2267 }
2268
2269 STATE = STATE0;
2270
2271 _gnutls_handshake_io_buffer_clear (session);
2272 _gnutls_handshake_internal_state_clear (session);
2273
2274 return 0;
2275}
2276
2277#define IMED_RET( str, ret) do { \
2278 if (ret < 0) { \
2279 if (gnutls_error_is_fatal(ret)==0) return ret; \
2280 gnutls_assert(); \
2281 ERR( str, ret); \
2282 _gnutls_handshake_hash_buffers_clear(session); \
2283 return ret; \
2284 } } while (0)
2285
2286
2287
2288/*
2289 * _gnutls_handshake_client
2290 * This function performs the client side of the handshake of the TLS/SSL protocol.
2291 */
2292int
2293_gnutls_handshake_client (gnutls_session_t session)
2294{
2295 int ret = 0;
2296
2297#ifdef HANDSHAKE_DEBUG
2298 char buf[64];
2299
2300 if (session->internals.resumed_security_parameters.session_id_size > 0)
2301 _gnutls_handshake_log ("HSK[%x]: Ask to resume: %s\n", session,
2302 _gnutls_bin2hex (session->internals.
2303 resumed_security_parameters.
2304 session_id,
2305 session->internals.
2306 resumed_security_parameters.
2307 session_id_size, buf,
2308 sizeof (buf)));
2309#endif
2310
2311 switch (STATE)
2312 {
2313 case STATE0:
2314 case STATE1:
2315 ret = _gnutls_send_hello (session, AGAIN (STATE1));
2316 STATE = STATE1;
2317 IMED_RET ("send hello", ret);
2318
2319 case STATE2:
2320 /* receive the server hello */
2321 ret =
2322 _gnutls_recv_handshake (session, NULL, NULL,
2323 GNUTLS_HANDSHAKE_SERVER_HELLO,
2324 MANDATORY_PACKET);
2325 STATE = STATE2;
2326 IMED_RET ("recv hello", ret);
2327
2328 case STATE70:
2329 if (session->security_parameters.extensions.do_recv_supplemental)
2330 {
2331 ret = _gnutls_recv_supplemental (session);
2332 STATE = STATE70;
2333 IMED_RET ("recv supplemental", ret);
2334 }
2335
2336 case STATE3:
2337 /* RECV CERTIFICATE */
2338 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2339 ret = _gnutls_recv_server_certificate (session);
2340 STATE = STATE3;
2341 IMED_RET ("recv server certificate", ret);
2342
2343 case STATE4:
2344 /* receive the server key exchange */
2345 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2346 ret = _gnutls_recv_server_kx_message (session);
2347 STATE = STATE4;
2348 IMED_RET ("recv server kx message", ret);
2349
2350 case STATE5:
2351 /* receive the server certificate request - if any
2352 */
2353
2354 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2355 ret = _gnutls_recv_server_certificate_request (session);
2356 STATE = STATE5;
2357 IMED_RET ("recv server certificate request message", ret);
2358
2359 case STATE6:
2360 /* receive the server hello done */
2361 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2362 ret =
2363 _gnutls_recv_handshake (session, NULL, NULL,
2364 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
2365 MANDATORY_PACKET);
2366 STATE = STATE6;
2367 IMED_RET ("recv server hello done", ret);
2368
2369 case STATE71:
2370 if (session->security_parameters.extensions.do_send_supplemental)
2371 {
2372 ret = _gnutls_send_supplemental (session, AGAIN (STATE71));
2373 STATE = STATE71;
2374 IMED_RET ("send supplemental", ret);
2375 }
2376
2377 case STATE7:
2378 /* send our certificate - if any and if requested
2379 */
2380 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2381 ret = _gnutls_send_client_certificate (session, AGAIN (STATE7));
2382 STATE = STATE7;
2383 IMED_RET ("send client certificate", ret);
2384
2385 case STATE8:
2386 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2387 ret = _gnutls_send_client_kx_message (session, AGAIN (STATE8));
2388 STATE = STATE8;
2389 IMED_RET ("send client kx", ret);
2390
2391 case STATE9:
2392 /* send client certificate verify */
2393 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2394 ret =
2395 _gnutls_send_client_certificate_verify (session, AGAIN (STATE9));
2396 STATE = STATE9;
2397 IMED_RET ("send client certificate verify", ret);
2398
2399 STATE = STATE0;
2400 default:
2401 break;
2402 }
2403
2404
2405 return 0;
2406}
2407
2408/* This function sends the final handshake packets and initializes connection
2409 */
2410static int
2411_gnutls_send_handshake_final (gnutls_session_t session, int init)
2412{
2413 int ret = 0;
2414
2415 /* Send the CHANGE CIPHER SPEC PACKET */
2416
2417 switch (STATE)
2418 {
2419 case STATE0:
2420 case STATE20:
2421 ret = _gnutls_send_change_cipher_spec (session, AGAIN (STATE20));
2422 STATE = STATE20;
2423 if (ret < 0)
2424 {
2425 ERR ("send ChangeCipherSpec", ret);
2426 gnutls_assert ();
2427 return ret;
2428 }
2429
2430 /* Initialize the connection session (start encryption) - in case of client
2431 */
2432 if (init == TRUE)
2433 {
2434 ret = _gnutls_connection_state_init (session);
2435 if (ret < 0)
2436 {
2437 gnutls_assert ();
2438 return ret;
2439 }
2440 }
2441
2442 ret = _gnutls_write_connection_state_init (session);
2443 if (ret < 0)
2444 {
2445 gnutls_assert ();
2446 return ret;
2447 }
2448
2449 case STATE21:
2450 /* send the finished message */
2451 ret = _gnutls_send_finished (session, AGAIN (STATE21));
2452 STATE = STATE21;
2453 if (ret < 0)
2454 {
2455 ERR ("send Finished", ret);
2456 gnutls_assert ();
2457 return ret;
2458 }
2459
2460 STATE = STATE0;
2461 default:
2462 break;
2463 }
2464
2465 return 0;
2466}
2467
2468/* This function receives the final handshake packets
2469 * And executes the appropriate function to initialize the
2470 * read session.
2471 */
2472static int
2473_gnutls_recv_handshake_final (gnutls_session_t session, int init)
2474{
2475 int ret = 0;
2476 uint8_t ch;
2477
2478 switch (STATE)
2479 {
2480 case STATE0:
2481 case STATE30:
2482 ret = _gnutls_recv_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, &ch, 1);
2483 STATE = STATE30;
2484 if (ret <= 0)
2485 {
2486 ERR ("recv ChangeCipherSpec", ret);
2487 gnutls_assert ();
2488 return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
2489 }
2490
2491 /* Initialize the connection session (start encryption) - in case of server */
2492 if (init == TRUE)
2493 {
2494 ret = _gnutls_connection_state_init (session);
2495 if (ret < 0)
2496 {
2497 gnutls_assert ();
2498 return ret;
2499 }
2500 }
2501
2502 ret = _gnutls_read_connection_state_init (session);
2503 if (ret < 0)
2504 {
2505 gnutls_assert ();
2506 return ret;
2507 }
2508
2509 case STATE31:
2510 ret = _gnutls_recv_finished (session);
2511 STATE = STATE31;
2512 if (ret < 0)
2513 {
2514 ERR ("recv finished", ret);
2515 gnutls_assert ();
2516 return ret;
2517 }
2518 STATE = STATE0;
2519 default:
2520 break;
2521 }
2522
2523
2524 return 0;
2525}
2526
2527 /*
2528 * _gnutls_handshake_server
2529 * This function does the server stuff of the handshake protocol.
2530 */
2531
2532int
2533_gnutls_handshake_server (gnutls_session_t session)
2534{
2535 int ret = 0;
2536
2537 switch (STATE)
2538 {
2539 case STATE0:
2540 case STATE1:
2541 ret =
2542 _gnutls_recv_handshake (session, NULL, NULL,
2543 GNUTLS_HANDSHAKE_CLIENT_HELLO,
2544 MANDATORY_PACKET);
2545 STATE = STATE1;
2546 IMED_RET ("recv hello", ret);
2547
2548 case STATE2:
2549 ret = _gnutls_send_hello (session, AGAIN (STATE2));
2550 STATE = STATE2;
2551 IMED_RET ("send hello", ret);
2552
2553 case STATE70:
2554 if (session->security_parameters.extensions.do_send_supplemental)
2555 {
2556 ret = _gnutls_send_supplemental (session, AGAIN (STATE70));
2557 STATE = STATE70;
2558 IMED_RET ("send supplemental data", ret);
2559 }
2560
2561 /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
2562 case STATE3:
2563 /* NOTE: these should not be send if we are resuming */
2564
2565 if (session->internals.resumed == RESUME_FALSE)
2566 ret = _gnutls_send_server_certificate (session, AGAIN (STATE3));
2567 STATE = STATE3;
2568 IMED_RET ("send server certificate", ret);
2569
2570 case STATE4:
2571 /* send server key exchange (A) */
2572 if (session->internals.resumed == RESUME_FALSE)
2573 ret = _gnutls_send_server_kx_message (session, AGAIN (STATE4));
2574 STATE = STATE4;
2575 IMED_RET ("send server kx", ret);
2576
2577 case STATE5:
2578 /* Send certificate request - if requested to */
2579 if (session->internals.resumed == RESUME_FALSE)
2580 ret =
2581 _gnutls_send_server_certificate_request (session, AGAIN (STATE5));
2582 STATE = STATE5;
2583 IMED_RET ("send server cert request", ret);
2584
2585 case STATE6:
2586 /* send the server hello done */
2587 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2588 ret =
2589 _gnutls_send_empty_handshake (session,
2590 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
2591 AGAIN (STATE6));
2592 STATE = STATE6;
2593 IMED_RET ("send server hello done", ret);
2594
2595 case STATE71:
2596 if (session->security_parameters.extensions.do_recv_supplemental)
2597 {
2598 ret = _gnutls_recv_supplemental (session);
2599 STATE = STATE71;
2600 IMED_RET ("recv client supplemental", ret);
2601 }
2602
2603 /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */
2604 case STATE7:
2605 /* receive the client certificate message */
2606 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2607 ret = _gnutls_recv_client_certificate (session);
2608 STATE = STATE7;
2609 IMED_RET ("recv client certificate", ret);
2610
2611 case STATE8:
2612 /* receive the client key exchange message */
2613 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2614 ret = _gnutls_recv_client_kx_message (session);
2615 STATE = STATE8;
2616 IMED_RET ("recv client kx", ret);
2617
2618 case STATE9:
2619 /* receive the client certificate verify message */
2620 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2621 ret = _gnutls_recv_client_certificate_verify_message (session);
2622 STATE = STATE9;
2623 IMED_RET ("recv client certificate verify", ret);
2624
2625 STATE = STATE0; /* finished thus clear session */
2626 default:
2627 break;
2628 }
2629
2630 return 0;
2631}
2632
2633int
2634_gnutls_handshake_common (gnutls_session_t session)
2635{
2636 int ret = 0;
2637
2638 /* send and recv the change cipher spec and finished messages */
2639 if ((session->internals.resumed == RESUME_TRUE
2640 && session->security_parameters.entity == GNUTLS_CLIENT)
2641 || (session->internals.resumed == RESUME_FALSE
2642 && session->security_parameters.entity == GNUTLS_SERVER))
2643 {
2644 /* if we are a client resuming - or we are a server not resuming */
2645
2646 ret = _gnutls_recv_handshake_final (session, TRUE);
2647 IMED_RET ("recv handshake final", ret);
2648
2649 ret = _gnutls_send_handshake_final (session, FALSE);
2650 IMED_RET ("send handshake final", ret);
2651 }
2652 else
2653 { /* if we are a client not resuming - or we are a server resuming */
2654
2655 ret = _gnutls_send_handshake_final (session, TRUE);
2656 IMED_RET ("send handshake final 2", ret);
2657
2658 ret = _gnutls_recv_handshake_final (session, FALSE);
2659 IMED_RET ("recv handshake final 2", ret);
2660 }
2661
2662 if (session->security_parameters.entity == GNUTLS_SERVER)
2663 {
2664 /* in order to support session resuming */
2665 _gnutls_server_register_current_session (session);
2666 }
2667
2668 /* clear handshake buffer */
2669 _gnutls_handshake_hash_buffers_clear (session);
2670 return ret;
2671
2672}
2673
2674int
2675_gnutls_generate_session_id (opaque * session_id, uint8_t * len)
2676{
2677 *len = TLS_MAX_SESSION_ID_SIZE;
2678
2679 if (gc_nonce (session_id, *len) != GC_OK)
2680 {
2681 gnutls_assert ();
2682 return GNUTLS_E_RANDOM_FAILED;
2683 }
2684
2685 return 0;
2686}
2687
2688int
2689_gnutls_recv_hello_request (gnutls_session_t session, void *data,
2690 uint32_t data_size)
2691{
2692 uint8_t type;
2693
2694 if (session->security_parameters.entity == GNUTLS_SERVER)
2695 {
2696 gnutls_assert ();
2697 return GNUTLS_E_UNEXPECTED_PACKET;
2698 }
2699 if (data_size < 1)
2700 {
2701 gnutls_assert ();
2702 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
2703 }
2704 type = ((uint8_t *) data)[0];
2705 if (type == GNUTLS_HANDSHAKE_HELLO_REQUEST)
2706 return GNUTLS_E_REHANDSHAKE;
2707 else
2708 {
2709 gnutls_assert ();
2710 return GNUTLS_E_UNEXPECTED_PACKET;
2711 }
2712}
2713
2714/* Returns 1 if the given KX has not the corresponding parameters
2715 * (DH or RSA) set up. Otherwise returns 0.
2716 */
2717inline static int
2718check_server_params (gnutls_session_t session,
2719 gnutls_kx_algorithm_t kx,
2720 gnutls_kx_algorithm_t * alg, int alg_size)
2721{
2722 int cred_type;
2723 gnutls_dh_params_t dh_params = NULL;
2724 gnutls_rsa_params_t rsa_params = NULL;
2725 int j;
2726
2727 cred_type = _gnutls_map_kx_get_cred (kx, 1);
2728
2729 /* Read the Diffie Hellman parameters, if any.
2730 */
2731 if (cred_type == GNUTLS_CRD_CERTIFICATE)
2732 {
2733 int delete;
2734 gnutls_certificate_credentials_t x509_cred =
2735 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
2736 cred_type, NULL);
2737
2738 if (x509_cred != NULL)
2739 {
2740 dh_params =
2741 _gnutls_get_dh_params (x509_cred->dh_params,
2742 x509_cred->params_func, session);
2743 rsa_params =
2744 _gnutls_certificate_get_rsa_params (x509_cred->rsa_params,
2745 x509_cred->params_func,
2746 session);
2747 }
2748
2749 /* Check also if the certificate supports the
2750 * KX method.
2751 */
2752 delete = 1;
2753 for (j = 0; j < alg_size; j++)
2754 {
2755 if (alg[j] == kx)
2756 {
2757 delete = 0;
2758 break;
2759 }
2760 }
2761
2762 if (delete == 1)
2763 return 1;
2764
2765#ifdef ENABLE_ANON
2766 }
2767 else if (cred_type == GNUTLS_CRD_ANON)
2768 {
2769 gnutls_anon_server_credentials_t anon_cred =
2770 (gnutls_anon_server_credentials_t) _gnutls_get_cred (session->key,
2771 cred_type, NULL);
2772
2773 if (anon_cred != NULL)
2774 {
2775 dh_params =
2776 _gnutls_get_dh_params (anon_cred->dh_params,
2777 anon_cred->params_func, session);
2778 }
2779#endif
2780#ifdef ENABLE_PSK
2781 }
2782 else if (cred_type == GNUTLS_CRD_PSK)
2783 {
2784 gnutls_psk_server_credentials_t psk_cred =
2785 (gnutls_psk_server_credentials_t) _gnutls_get_cred (session->key,
2786 cred_type, NULL);
2787
2788 if (psk_cred != NULL)
2789 {
2790 dh_params =
2791 _gnutls_get_dh_params (psk_cred->dh_params, psk_cred->params_func,
2792 session);
2793 }
2794#endif
2795 }
2796 else
2797 return 0; /* no need for params */
2798
2799
2800 /* If the key exchange method needs RSA or DH params,
2801 * but they are not set then remove it.
2802 */
2803 if (_gnutls_kx_needs_rsa_params (kx) != 0)
2804 {
2805 /* needs rsa params. */
2806 if (_gnutls_rsa_params_to_mpi (rsa_params) == NULL)
2807 {
2808 gnutls_assert ();
2809 return 1;
2810 }
2811 }
2812
2813 if (_gnutls_kx_needs_dh_params (kx) != 0)
2814 {
2815 /* needs DH params. */
2816 if (_gnutls_dh_params_to_mpi (dh_params) == NULL)
2817 {
2818 gnutls_assert ();
2819 return 1;
2820 }
2821 }
2822
2823 return 0;
2824}
2825
2826/* This function will remove algorithms that are not supported by
2827 * the requested authentication method. We remove an algorithm if
2828 * we have a certificate with keyUsage bits set.
2829 *
2830 * This does a more high level check than gnutls_supported_ciphersuites(),
2831 * by checking certificates etc.
2832 */
2833int
2834_gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
2835 cipher_suite_st ** cipherSuites,
2836 int numCipherSuites,
2837 gnutls_pk_algorithm_t requested_pk_algo)
2838{
2839
2840 int ret = 0;
2841 cipher_suite_st *newSuite, cs;
2842 int newSuiteSize = 0, i;
2843 gnutls_certificate_credentials_t cert_cred;
2844 gnutls_kx_algorithm_t kx;
2845 int server = session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
2846 gnutls_kx_algorithm_t *alg = NULL;
2847 int alg_size = 0;
2848
2849 /* if we should use a specific certificate,
2850 * we should remove all algorithms that are not supported
2851 * by that certificate and are on the same authentication
2852 * method (CERTIFICATE).
2853 */
2854
2855 cert_cred =
2856 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
2857 GNUTLS_CRD_CERTIFICATE,
2858 NULL);
2859
2860 /* If there are certificate credentials, find an appropriate certificate
2861 * or disable them;
2862 */
2863 if (session->security_parameters.entity == GNUTLS_SERVER
2864 && cert_cred != NULL)
2865 {
2866 ret = _gnutls_server_select_cert (session, requested_pk_algo);
2867 if (ret < 0)
2868 {
2869 gnutls_assert ();
2870 _gnutls_x509_log ("Could not find an appropriate certificate: %s\n",
2871 gnutls_strerror (ret));
2872 cert_cred = NULL;
2873 }
2874 }
2875
2876 /* get all the key exchange algorithms that are
2877 * supported by the X509 certificate parameters.
2878 */
2879 if ((ret =
2880 _gnutls_selected_cert_supported_kx (session, &alg, &alg_size)) < 0)
2881 {
2882 gnutls_assert ();
2883 return ret;
2884 }
2885
2886 newSuite = gnutls_malloc (numCipherSuites * sizeof (cipher_suite_st));
2887 if (newSuite == NULL)
2888 {
2889 gnutls_assert ();
2890 gnutls_free (alg);
2891 return GNUTLS_E_MEMORY_ERROR;
2892 }
2893
2894 /* now removes ciphersuites based on the KX algorithm
2895 */
2896 for (i = 0; i < numCipherSuites; i++)
2897 {
2898 int delete = 0;
2899
2900 /* finds the key exchange algorithm in
2901 * the ciphersuite
2902 */
2903 kx = _gnutls_cipher_suite_get_kx_algo (&(*cipherSuites)[i]);
2904
2905 /* if it is defined but had no credentials
2906 */
2907 if (_gnutls_get_kx_cred (session, kx, NULL) == NULL)
2908 {
2909 delete = 1;
2910 }
2911 else
2912 {
2913 delete = 0;
2914
2915 if (server)
2916 delete = check_server_params (session, kx, alg, alg_size);
2917 }
2918
2919 /* These two SRP kx's are marked to require a CRD_CERTIFICATE,
2920 (see cred_mappings in gnutls_algorithms.c), but it also
2921 requires a SRP credential. Don't use SRP kx unless we have a
2922 SRP credential too. */
2923 if (kx == GNUTLS_KX_SRP_RSA || kx == GNUTLS_KX_SRP_DSS)
2924 {
2925 if (!_gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL))
2926 delete = 1;
2927 }
2928
2929 memcpy (&cs.suite, &(*cipherSuites)[i].suite, 2);
2930
2931 if (delete == 0)
2932 {
2933
2934 _gnutls_handshake_log ("HSK[%x]: Keeping ciphersuite: %s\n",
2935 session,
2936 _gnutls_cipher_suite_get_name (&cs));
2937
2938 memcpy (newSuite[newSuiteSize].suite, (*cipherSuites)[i].suite, 2);
2939 newSuiteSize++;
2940 }
2941 else
2942 {
2943 _gnutls_handshake_log ("HSK[%x]: Removing ciphersuite: %s\n",
2944 session,
2945 _gnutls_cipher_suite_get_name (&cs));
2946
2947 }
2948 }
2949
2950 gnutls_free (alg);
2951 gnutls_free (*cipherSuites);
2952 *cipherSuites = newSuite;
2953
2954 ret = newSuiteSize;
2955
2956 return ret;
2957
2958}
2959
2960/**
2961 * gnutls_handshake_set_max_packet_length - This function will set the maximum length of a handshake message
2962 * @session: is a #gnutls_session_t structure.
2963 * @max: is the maximum number.
2964 *
2965 * This function will set the maximum size of a handshake message.
2966 * Handshake messages over this size are rejected. The default value
2967 * is 16kb which is large enough. Set this to 0 if you do not want to
2968 * set an upper limit.
2969 *
2970 **/
2971void
2972gnutls_handshake_set_max_packet_length (gnutls_session_t session, size_t max)
2973{
2974 session->internals.max_handshake_data_buffer_size = max;
2975}
2976
2977void
2978_gnutls_set_adv_version (gnutls_session_t session, gnutls_protocol_t ver)
2979{
2980 set_adv_version (session, _gnutls_version_get_major (ver),
2981 _gnutls_version_get_minor (ver));
2982}
2983
2984gnutls_protocol_t
2985_gnutls_get_adv_version (gnutls_session_t session)
2986{
2987 return _gnutls_version_get (_gnutls_get_adv_version_major (session),
2988 _gnutls_get_adv_version_minor (session));
2989}
2990
2991/**
2992 * gnutls_handshake_get_last_in - Returns the last handshake message received.
2993 * @session: is a #gnutls_session_t structure.
2994 *
2995 * This function is only useful to check where the last performed
2996 * handshake failed. If the previous handshake succeed or was not
2997 * performed at all then no meaningful value will be returned.
2998 *
2999 * Check %gnutls_handshake_description_t in gnutls.h for the
3000 * available handshake descriptions.
3001 *
3002 * Returns: the last handshake message type received, a
3003 * %gnutls_handshake_description_t.
3004 **/
3005gnutls_handshake_description_t
3006gnutls_handshake_get_last_in (gnutls_session_t session)
3007{
3008 return session->internals.last_handshake_in;
3009}
3010
3011/**
3012 * gnutls_handshake_get_last_out - Returns the last handshake message sent.
3013 * @session: is a #gnutls_session_t structure.
3014 *
3015 * This function is only useful to check where the last performed
3016 * handshake failed. If the previous handshake succeed or was not
3017 * performed at all then no meaningful value will be returned.
3018 *
3019 * Check %gnutls_handshake_description_t in gnutls.h for the
3020 * available handshake descriptions.
3021 *
3022 * Returns: the last handshake message type sent, a
3023 * %gnutls_handshake_description_t.
3024 **/
3025gnutls_handshake_description_t
3026gnutls_handshake_get_last_out (gnutls_session_t session)
3027{
3028 return session->internals.last_handshake_out;
3029}
diff --git a/src/daemon/https/tls/gnutls_handshake.h b/src/daemon/https/tls/gnutls_handshake.h
new file mode 100644
index 00000000..5cff279a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_handshake.h
@@ -0,0 +1,60 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25typedef enum Optional
26{ OPTIONAL_PACKET, MANDATORY_PACKET } Optional;
27
28int _gnutls_send_handshake (gnutls_session_t session, void *i_data,
29 uint32_t i_datasize,
30 gnutls_handshake_description_t type);
31int _gnutls_recv_hello_request (gnutls_session_t session, void *data,
32 uint32_t data_size);
33int _gnutls_send_hello (gnutls_session_t session, int again);
34int _gnutls_recv_hello (gnutls_session_t session, opaque * data, int datalen);
35int _gnutls_recv_handshake (gnutls_session_t session, uint8_t **, int *,
36 gnutls_handshake_description_t,
37 Optional optional);
38int _gnutls_generate_session_id (opaque * session_id, uint8_t * len);
39int _gnutls_handshake_common (gnutls_session_t session);
40int _gnutls_handshake_client (gnutls_session_t session);
41int _gnutls_handshake_server (gnutls_session_t session);
42void _gnutls_set_server_random (gnutls_session_t session, uint8_t * rnd);
43void _gnutls_set_client_random (gnutls_session_t session, uint8_t * rnd);
44int _gnutls_tls_create_random (opaque * dst);
45int _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
46 cipher_suite_st ** cipherSuites,
47 int numCipherSuites,
48 gnutls_pk_algorithm_t);
49int _gnutls_find_pk_algos_in_ciphersuites (opaque * data, int datalen);
50int _gnutls_server_select_suite (gnutls_session_t session, opaque * data,
51 int datalen);
52
53int _gnutls_negotiate_version( gnutls_session_t session, gnutls_protocol_t adv_version);
54int _gnutls_user_hello_func( gnutls_session, gnutls_protocol_t adv_version);
55
56#define STATE session->internals.handshake_state
57/* This returns true if we have got there
58 * before (and not finished due to an interrupt).
59 */
60#define AGAIN(target) STATE==target?1:0
diff --git a/src/daemon/https/tls/gnutls_hash_int.c b/src/daemon/https/tls/gnutls_hash_int.c
new file mode 100644
index 00000000..2574f213
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_hash_int.c
@@ -0,0 +1,446 @@
1/*
2 * Copyright (C) 2000, 2001, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file handles all the internal functions that cope with hashes
26 * and HMACs.
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_hash_int.h>
31#include <gnutls_errors.h>
32
33static inline Gc_hash
34_gnutls_mac2gc (gnutls_mac_algorithm_t mac)
35{
36 switch (mac)
37 {
38 case GNUTLS_MAC_NULL:
39 return -1;
40 break;
41 case GNUTLS_MAC_SHA1:
42 return GC_SHA1;
43 break;
44 case GNUTLS_MAC_SHA256:
45 return GC_SHA256;
46 break;
47 case GNUTLS_MAC_MD5:
48 return GC_MD5;
49 break;
50 default:
51 gnutls_assert ();
52 return -1;
53 }
54 return -1;
55}
56
57GNUTLS_HASH_HANDLE
58_gnutls_hash_init (gnutls_mac_algorithm_t algorithm)
59{
60 mac_hd_t ret;
61 int result;
62
63 ret = gnutls_malloc (sizeof (mac_hd_st));
64 if (ret == NULL)
65 {
66 gnutls_assert ();
67 return GNUTLS_HASH_FAILED;
68 }
69
70 ret->algorithm = algorithm;
71
72 result = gc_hash_open (_gnutls_mac2gc (algorithm), 0, &ret->handle);
73 if (result)
74 {
75 gnutls_assert ();
76 gnutls_free (ret);
77 ret = GNUTLS_HASH_FAILED;
78 }
79
80 return ret;
81}
82
83int
84_gnutls_hash_get_algo_len (gnutls_mac_algorithm_t algorithm)
85{
86 int ret;
87
88 ret = gc_hash_digest_length (_gnutls_mac2gc (algorithm));
89
90 return ret;
91
92}
93
94int
95_gnutls_hash (GNUTLS_HASH_HANDLE handle, const void *text, size_t textlen)
96{
97 if (textlen > 0)
98 gc_hash_write (handle->handle, textlen, text);
99 return 0;
100}
101
102GNUTLS_HASH_HANDLE
103_gnutls_hash_copy (GNUTLS_HASH_HANDLE handle)
104{
105 GNUTLS_HASH_HANDLE ret;
106 int result;
107
108 ret = gnutls_malloc (sizeof (mac_hd_st));
109
110 if (ret == NULL)
111 return GNUTLS_HASH_FAILED;
112
113 ret->algorithm = handle->algorithm;
114 ret->key = NULL; /* it's a hash anyway */
115 ret->keysize = 0;
116
117 result = gc_hash_clone (handle->handle, &ret->handle);
118
119 if (result)
120 {
121 gnutls_free (ret);
122 return GNUTLS_HASH_FAILED;
123 }
124
125 return ret;
126}
127
128void
129_gnutls_hash_deinit (GNUTLS_HASH_HANDLE handle, void *digest)
130{
131 const opaque *mac;
132 int maclen;
133
134 maclen = _gnutls_hash_get_algo_len (handle->algorithm);
135
136 mac = gc_hash_read (handle->handle);
137 if (digest != NULL)
138 memcpy (digest, mac, maclen);
139
140 gc_hash_close (handle->handle);
141
142 gnutls_free (handle);
143}
144
145
146mac_hd_t
147_gnutls_hmac_init (gnutls_mac_algorithm_t algorithm,
148 const void *key, int keylen)
149{
150 mac_hd_t ret;
151 int result;
152
153 ret = gnutls_malloc (sizeof (mac_hd_st));
154 if (ret == NULL)
155 return GNUTLS_MAC_FAILED;
156
157 result = gc_hash_open (_gnutls_mac2gc (algorithm), GC_HMAC, &ret->handle);
158 if (result)
159 {
160 gnutls_free (ret);
161 return GNUTLS_MAC_FAILED;
162 }
163
164 gc_hash_hmac_setkey (ret->handle, keylen, key);
165
166 ret->algorithm = algorithm;
167 ret->key = key;
168 ret->keysize = keylen;
169
170 return ret;
171}
172
173void
174_gnutls_hmac_deinit (mac_hd_t handle, void *digest)
175{
176 const opaque *mac;
177 int maclen;
178
179 maclen = _gnutls_hash_get_algo_len (handle->algorithm);
180
181 mac = gc_hash_read (handle->handle);
182
183 if (digest != NULL)
184 memcpy (digest, mac, maclen);
185
186 gc_hash_close (handle->handle);
187
188 gnutls_free (handle);
189}
190
191inline static int
192get_padsize (gnutls_mac_algorithm_t algorithm)
193{
194 switch (algorithm)
195 {
196 case GNUTLS_MAC_MD5:
197 return 48;
198 case GNUTLS_MAC_SHA1:
199 return 40;
200 default:
201 return 0;
202 }
203}
204
205mac_hd_t
206_gnutls_mac_init_ssl3 (gnutls_mac_algorithm_t algorithm, void *key,
207 int keylen)
208{
209 mac_hd_t ret;
210 opaque ipad[48];
211 int padsize;
212
213 padsize = get_padsize (algorithm);
214 if (padsize == 0)
215 {
216 gnutls_assert ();
217 return GNUTLS_MAC_FAILED;
218 }
219
220 memset (ipad, 0x36, padsize);
221
222 ret = _gnutls_hash_init (algorithm);
223 if (ret != GNUTLS_HASH_FAILED)
224 {
225 ret->key = key;
226 ret->keysize = keylen;
227
228 if (keylen > 0)
229 _gnutls_hash (ret, key, keylen);
230 _gnutls_hash (ret, ipad, padsize);
231 }
232
233 return ret;
234}
235
236void
237_gnutls_mac_deinit_ssl3 (mac_hd_t handle, void *digest)
238{
239 opaque ret[MAX_HASH_SIZE];
240 mac_hd_t td;
241 opaque opad[48];
242 int padsize;
243 int block;
244
245 padsize = get_padsize (handle->algorithm);
246 if (padsize == 0)
247 {
248 gnutls_assert ();
249 return;
250 }
251
252 memset (opad, 0x5C, padsize);
253
254 td = _gnutls_hash_init (handle->algorithm);
255 if (td != GNUTLS_MAC_FAILED)
256 {
257 if (handle->keysize > 0)
258 _gnutls_hash (td, handle->key, handle->keysize);
259
260 _gnutls_hash (td, opad, padsize);
261 block = _gnutls_hmac_get_algo_len (handle->algorithm);
262 _gnutls_hash_deinit (handle, ret); /* get the previous hash */
263 _gnutls_hash (td, ret, block);
264
265 _gnutls_hash_deinit (td, digest);
266 }
267}
268
269void
270_gnutls_mac_deinit_ssl3_handshake (mac_hd_t handle,
271 void *digest, opaque * key,
272 uint32_t key_size)
273{
274 opaque ret[MAX_HASH_SIZE];
275 mac_hd_t td;
276 opaque opad[48];
277 opaque ipad[48];
278 int padsize;
279 int block;
280
281 padsize = get_padsize (handle->algorithm);
282 if (padsize == 0)
283 {
284 gnutls_assert ();
285 return;
286 }
287
288 memset (opad, 0x5C, padsize);
289 memset (ipad, 0x36, padsize);
290
291 td = _gnutls_hash_init (handle->algorithm);
292 if (td != GNUTLS_HASH_FAILED)
293 {
294 if (key_size > 0)
295 _gnutls_hash (td, key, key_size);
296
297 _gnutls_hash (td, opad, padsize);
298 block = _gnutls_hmac_get_algo_len (handle->algorithm);
299
300 if (key_size > 0)
301 _gnutls_hash (handle, key, key_size);
302 _gnutls_hash (handle, ipad, padsize);
303 _gnutls_hash_deinit (handle, ret); /* get the previous hash */
304
305 _gnutls_hash (td, ret, block);
306
307 _gnutls_hash_deinit (td, digest);
308 }
309}
310
311static int
312ssl3_sha (int i, opaque * secret, int secret_len,
313 opaque * rnd, int rnd_len, void *digest)
314{
315 int j;
316 opaque text1[26];
317
318 GNUTLS_HASH_HANDLE td;
319
320 for (j = 0; j < i + 1; j++)
321 {
322 text1[j] = 65 + i; /* A==65 */
323 }
324
325 td = _gnutls_hash_init (GNUTLS_MAC_SHA1);
326 if (td == NULL)
327 {
328 gnutls_assert ();
329 return GNUTLS_E_HASH_FAILED;
330 }
331
332 _gnutls_hash (td, text1, i + 1);
333 _gnutls_hash (td, secret, secret_len);
334 _gnutls_hash (td, rnd, rnd_len);
335
336 _gnutls_hash_deinit (td, digest);
337 return 0;
338}
339
340static int
341ssl3_md5 (int i, opaque * secret, int secret_len,
342 opaque * rnd, int rnd_len, void *digest)
343{
344 opaque tmp[MAX_HASH_SIZE];
345 mac_hd_t td;
346 int ret;
347
348 td = _gnutls_hash_init (GNUTLS_MAC_MD5);
349 if (td == NULL)
350 {
351 gnutls_assert ();
352 return GNUTLS_E_HASH_FAILED;
353 }
354
355 _gnutls_hash (td, secret, secret_len);
356
357 ret = ssl3_sha (i, secret, secret_len, rnd, rnd_len, tmp);
358 if (ret < 0)
359 {
360 gnutls_assert ();
361 _gnutls_hash_deinit (td, digest);
362 return ret;
363 }
364
365 _gnutls_hash (td, tmp, _gnutls_hash_get_algo_len (GNUTLS_MAC_SHA1));
366
367 _gnutls_hash_deinit (td, digest);
368 return 0;
369}
370
371int
372_gnutls_ssl3_hash_md5 (void *first, int first_len,
373 void *second, int second_len, int ret_len,
374 opaque * ret)
375{
376 opaque digest[MAX_HASH_SIZE];
377 mac_hd_t td;
378 int block = _gnutls_hash_get_algo_len (GNUTLS_MAC_MD5);
379
380 td = _gnutls_hash_init (GNUTLS_MAC_MD5);
381 if (td == NULL)
382 {
383 gnutls_assert ();
384 return GNUTLS_E_HASH_FAILED;
385 }
386
387 _gnutls_hash (td, first, first_len);
388 _gnutls_hash (td, second, second_len);
389
390 _gnutls_hash_deinit (td, digest);
391
392 if (ret_len > block)
393 {
394 gnutls_assert ();
395 return GNUTLS_E_INTERNAL_ERROR;
396 }
397
398 memcpy (ret, digest, ret_len);
399
400 return 0;
401
402}
403
404int
405_gnutls_ssl3_generate_random (void *secret, int secret_len,
406 void *rnd, int rnd_len,
407 int ret_bytes, opaque * ret)
408{
409 int i = 0, copy, output_bytes;
410 opaque digest[MAX_HASH_SIZE];
411 int block = _gnutls_hash_get_algo_len (GNUTLS_MAC_MD5);
412 int result, times;
413
414 output_bytes = 0;
415 do
416 {
417 output_bytes += block;
418 }
419 while (output_bytes < ret_bytes);
420
421 times = output_bytes / block;
422
423 for (i = 0; i < times; i++)
424 {
425
426 result = ssl3_md5 (i, secret, secret_len, rnd, rnd_len, digest);
427 if (result < 0)
428 {
429 gnutls_assert ();
430 return result;
431 }
432
433 if ((1 + i) * block < ret_bytes)
434 {
435 copy = block;
436 }
437 else
438 {
439 copy = ret_bytes - (i) * block;
440 }
441
442 memcpy (&ret[i * block], digest, copy);
443 }
444
445 return 0;
446}
diff --git a/src/daemon/https/tls/gnutls_hash_int.h b/src/daemon/https/tls/gnutls_hash_int.h
new file mode 100644
index 00000000..3e1b75e6
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_hash_int.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_HASH_INT_H
26# define GNUTLS_HASH_INT_H
27
28#include <gnutls_int.h>
29
30/* for message digests */
31
32typedef struct
33{
34 gc_hash_handle handle;
35 gnutls_mac_algorithm_t algorithm;
36 const void *key;
37 int keysize;
38} mac_hd_st;
39typedef mac_hd_st *mac_hd_t;
40typedef mac_hd_t GNUTLS_HASH_HANDLE;
41
42#define GNUTLS_HASH_FAILED NULL
43#define GNUTLS_MAC_FAILED NULL
44
45mac_hd_t _gnutls_hmac_init (gnutls_mac_algorithm_t algorithm,
46 const void *key, int keylen);
47#define _gnutls_hmac_get_algo_len _gnutls_hash_get_algo_len
48#define _gnutls_hmac _gnutls_hash
49void _gnutls_hmac_deinit (mac_hd_t handle, void *digest);
50
51mac_hd_t _gnutls_mac_init_ssl3 (gnutls_mac_algorithm_t algorithm, void *key,
52 int keylen);
53void _gnutls_mac_deinit_ssl3 (mac_hd_t handle, void *digest);
54
55GNUTLS_HASH_HANDLE _gnutls_hash_init (gnutls_mac_algorithm_t algorithm);
56int _gnutls_hash_get_algo_len (gnutls_mac_algorithm_t algorithm);
57int _gnutls_hash (GNUTLS_HASH_HANDLE handle, const void *text,
58 size_t textlen);
59void _gnutls_hash_deinit (GNUTLS_HASH_HANDLE handle, void *digest);
60
61int _gnutls_ssl3_generate_random (void *secret, int secret_len,
62 void *rnd, int random_len, int bytes,
63 opaque * ret);
64int _gnutls_ssl3_hash_md5 (void *first, int first_len, void *second,
65 int second_len, int ret_len, opaque * ret);
66
67void _gnutls_mac_deinit_ssl3_handshake (mac_hd_t handle, void *digest,
68 opaque * key, uint32_t key_size);
69
70GNUTLS_HASH_HANDLE _gnutls_hash_copy (GNUTLS_HASH_HANDLE handle);
71
72#endif /* GNUTLS_HASH_INT_H */
diff --git a/src/daemon/https/tls/gnutls_int.h b/src/daemon/https/tls/gnutls_int.h
new file mode 100644
index 00000000..9c54262e
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_int.h
@@ -0,0 +1,679 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_INT_H
26
27#define GNUTLS_INT_H
28
29#include <defines.h>
30
31#include <gnutls.h>
32#include <extra.h>
33#include <gnutls_mem.h>
34
35/* FIXME: delete this once opencdk has reentrant keyring functions
36 */
37#define KEYRING_HACK
38
39#define MAX32 4294967295
40#define MAX24 16777215
41#define MAX16 65535
42
43/* The size of a handshake message should not
44 * be larger than this value.
45 */
46#define MAX_HANDSHAKE_PACKET_SIZE 48*1024
47
48#define TLS_RANDOM_SIZE 32
49#define TLS_MAX_SESSION_ID_SIZE 32
50#define TLS_MASTER_SIZE 48
51
52/* The maximum digest size of hash algorithms.
53 */
54#define MAX_HASH_SIZE 64
55
56#define MAX_LOG_SIZE 1024 /* maximum size of log message */
57#define MAX_SRP_USERNAME 128
58#define MAX_SERVER_NAME_SIZE 128
59
60/* we can receive up to MAX_EXT_TYPES extensions.
61 */
62#define MAX_EXT_TYPES 64
63
64/* The initial size of the receive
65 * buffer size. This will grow if larger
66 * packets are received.
67 */
68#define INITIAL_RECV_BUFFER_SIZE 256
69
70/* the default for TCP */
71#define DEFAULT_LOWAT 1
72
73/* expire time for resuming sessions */
74#define DEFAULT_EXPIRE_TIME 3600
75
76/* the maximum size of encrypted packets */
77#define DEFAULT_MAX_RECORD_SIZE 16384
78#define RECORD_HEADER_SIZE 5
79#define MAX_RECORD_SEND_SIZE (size_t)session->security_parameters.max_record_send_size
80#define MAX_RECORD_RECV_SIZE (size_t)session->security_parameters.max_record_recv_size
81#define MAX_PAD_SIZE 255
82#define EXTRA_COMP_SIZE 2048
83#define MAX_RECORD_OVERHEAD MAX_PAD_SIZE+EXTRA_COMP_SIZE
84#define MAX_RECV_SIZE MAX_RECORD_OVERHEAD+MAX_RECORD_RECV_SIZE+RECORD_HEADER_SIZE
85
86#define HANDSHAKE_HEADER_SIZE 4
87
88/* defaults for verification functions
89 */
90#define DEFAULT_VERIFY_DEPTH 32
91#define DEFAULT_VERIFY_BITS 16*1024
92
93#define DECR_LEN(len, x) do { len-=x; if (len<0) {gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;} } while (0)
94#define DECR_LENGTH_RET(len, x, RET) do { len-=x; if (len<0) {gnutls_assert(); return RET;} } while (0)
95#define DECR_LENGTH_COM(len, x, COM) do { len-=x; if (len<0) {gnutls_assert(); COM;} } while (0)
96
97#define HASH2MAC(x) ((gnutls_mac_algorithm_t)x)
98
99// TODO rm
100/* Additional cast to bring void* to a type castable to int. */
101#define GNUTLS_POINTER_TO_INT_CAST (long)
102
103#define GNUTLS_POINTER_TO_INT(_) ((int) GNUTLS_POINTER_TO_INT_CAST (_))
104#define GNUTLS_INT_TO_POINTER(_) ((void*) GNUTLS_POINTER_TO_INT_CAST (_))
105
106typedef unsigned char opaque;
107typedef struct
108 {
109 opaque pint[3];
110 } uint24;
111
112#include <gnutls_mpi.h>
113
114typedef enum change_cipher_spec_t
115 {
116 GNUTLS_TYPE_CHANGE_CIPHER_SPEC = 1
117 } change_cipher_spec_t;
118
119typedef enum handshake_state_t
120 {
121 STATE0 = 0, STATE1, STATE2,
122 STATE3, STATE4, STATE5,
123 STATE6, STATE7, STATE8, STATE9, STATE20 = 20, STATE21,
124 STATE30 = 30, STATE31, STATE50 = 50, STATE60 = 60, STATE61, STATE62,
125 STATE70, STATE71
126 } handshake_state_t;
127
128#include <gnutls_buffer.h>
129
130/* This is the maximum number of algorithms (ciphers or macs etc).
131 * keep it synced with GNUTLS_MAX_ALGORITHM_NUM in gnutls.h
132 */
133#define MAX_ALGOS 16
134
135#define MAX_CIPHERSUITES 256
136
137typedef enum extensions_t
138 { GNUTLS_EXTENSION_SERVER_NAME = 0,
139 GNUTLS_EXTENSION_MAX_RECORD_SIZE = 1,
140 GNUTLS_EXTENSION_CERT_TYPE = 9,
141#ifdef ENABLE_OPRFI
142 GNUTLS_EXTENSION_OPAQUE_PRF_INPUT = ENABLE_OPRFI,
143#endif
144 GNUTLS_EXTENSION_SRP = 12,
145 GNUTLS_EXTENSION_INNER_APPLICATION = 37703
146 } extensions_t;
147
148typedef enum
149 { CIPHER_STREAM, CIPHER_BLOCK} cipher_type_t;
150
151typedef enum valid_session_t
152 { VALID_TRUE, VALID_FALSE} valid_session_t;
153typedef enum resumable_session_t
154 { RESUME_TRUE,
155 RESUME_FALSE
156 } resumable_session_t;
157
158/* Record Protocol */
159typedef enum content_type_t
160 {
161 GNUTLS_CHANGE_CIPHER_SPEC = 20, GNUTLS_ALERT,
162 GNUTLS_HANDSHAKE, GNUTLS_APPLICATION_DATA,
163 GNUTLS_INNER_APPLICATION = 24
164 } content_type_t;
165
166#define GNUTLS_PK_ANY (gnutls_pk_algorithm_t)-1
167#define GNUTLS_PK_NONE (gnutls_pk_algorithm_t)-2
168
169/* STATE (stop) */
170
171typedef void (*LOG_FUNC)(int,
172 const char *);
173
174/* Store & Retrieve functions defines: */
175typedef struct auth_cred_st
176 {
177 gnutls_credentials_type_t algorithm;
178
179 /* the type of credentials depends on algorithm
180 */
181 void *credentials;
182 struct auth_cred_st *next;
183 } auth_cred_st;
184
185struct gnutls_key_st
186 {
187 /* For DH KX */
188 gnutls_datum_t key;
189 mpi_t KEY;
190 mpi_t client_Y;
191 mpi_t client_g;
192 mpi_t client_p;
193 mpi_t dh_secret;
194 /* for SRP */
195 mpi_t A;
196 mpi_t B;
197 mpi_t u;
198 mpi_t b;
199 mpi_t a;
200 mpi_t x;
201 /* RSA: e, m
202 */
203 mpi_t rsa[2];
204
205 /* this is used to hold the peers authentication data
206 */
207 /* auth_info_t structures SHOULD NOT contain malloced
208 * elements. Check gnutls_session_pack.c, and gnutls_auth.c.
209 * Rememember that this should be calloced!
210 */
211 void *auth_info;
212 gnutls_credentials_type_t auth_info_type;
213 int auth_info_size; /* needed in order to store to db for restoring
214 */
215 uint8_t crypt_algo;
216
217 auth_cred_st *cred; /* used to specify keys/certificates etc */
218
219 int certificate_requested;
220 /* some ciphersuites use this
221 * to provide client authentication.
222 * 1 if client auth was requested
223 * by the peer, 0 otherwise
224 *** In case of a server this
225 * holds 1 if we should wait
226 * for a client certificate verify
227 */
228 };
229typedef struct gnutls_key_st *gnutls_key_st;
230
231/* STATE (cont) */
232#include <gnutls_hash_int.h>
233#include <gnutls_cipher_int.h>
234#include <gnutls_compress_int.h>
235#include <gnutls_cert.h>
236
237typedef struct
238 {
239 uint8_t suite[2];
240 } cipher_suite_st;
241
242/* This structure holds parameters got from TLS extension
243 * mechanism. (some extensions may hold parameters in auth_info_t
244 * structures also - see SRP).
245 */
246typedef struct
247 {
248 opaque name[MAX_SERVER_NAME_SIZE];
249 unsigned name_length;
250 gnutls_server_name_type_t type;
251 } server_name_st;
252
253#define MAX_SERVER_NAME_EXTENSIONS 3
254typedef struct
255 {
256 server_name_st server_names[MAX_SERVER_NAME_EXTENSIONS];
257 /* limit server_name extensions */
258 unsigned server_names_size;
259
260 opaque srp_username[MAX_SRP_USERNAME + 1];
261
262 /* TLS/IA data. */
263 int gnutls_ia_enable, gnutls_ia_peer_enable;
264 int gnutls_ia_allowskip, gnutls_ia_peer_allowskip;
265
266 /* Used by extensions that enable supplemental data. */
267 int do_recv_supplemental, do_send_supplemental;
268
269 /* Opaque PRF input. */
270 gnutls_oprfi_callback_func oprfi_cb;
271 void *oprfi_userdata;
272 opaque *oprfi_client;
273 uint16_t oprfi_client_len;
274 opaque *oprfi_server;
275 uint16_t oprfi_server_len;
276 } tls_ext_st;
277
278/* This flag indicates for an extension whether
279 * it is useful to application level or TLS level only.
280 * This is used to parse the application level extensions
281 * before the user_hello callback is called.
282 */
283typedef enum tls_ext_parse_type_t
284 {
285 EXTENSION_ANY,
286 EXTENSION_APPLICATION,
287 EXTENSION_TLS
288 } tls_ext_parse_type_t;
289
290/* auth_info_t structures now MAY contain malloced
291 * elements.
292 */
293
294/* This structure and auth_info_t, are stored in the resume database,
295 * and are restored, in case of resume.
296 * Holds all the required parameters to resume the current
297 * session.
298 */
299
300/* if you add anything in Security_Parameters struct, then
301 * also modify CPY_COMMON in gnutls_constate.c
302 */
303
304/* Note that the security parameters structure is set up after the
305 * handshake has finished. The only value you may depend on while
306 * the handshake is in progress is the cipher suite value.
307 */
308typedef struct
309 {
310 gnutls_connection_end_t entity;
311 gnutls_kx_algorithm_t kx_algorithm;
312 /* we've got separate write/read bulk/macs because
313 * there is a time in handshake where the peer has
314 * null cipher and we don't
315 */
316 gnutls_cipher_algorithm_t read_bulk_cipher_algorithm;
317 gnutls_mac_algorithm_t read_mac_algorithm;
318 gnutls_compression_method_t read_compression_algorithm;
319
320 gnutls_cipher_algorithm_t write_bulk_cipher_algorithm;
321 gnutls_mac_algorithm_t write_mac_algorithm;
322 gnutls_compression_method_t write_compression_algorithm;
323
324 /* this is the ciphersuite we are going to use
325 * moved here from internals in order to be restored
326 * on resume;
327 */
328 cipher_suite_st current_cipher_suite;
329 opaque master_secret[TLS_MASTER_SIZE];
330 opaque client_random[TLS_RANDOM_SIZE];
331 opaque server_random[TLS_RANDOM_SIZE];
332 opaque session_id[TLS_MAX_SESSION_ID_SIZE];
333 uint8_t session_id_size;
334 time_t timestamp;
335 tls_ext_st extensions;
336
337 /* The send size is the one requested by the programmer.
338 * The recv size is the one negotiated with the peer.
339 */
340 uint16_t max_record_send_size;
341 uint16_t max_record_recv_size;
342 /* holds the negotiated certificate type */
343 gnutls_certificate_type_t cert_type;
344 gnutls_protocol_t version; /* moved here */
345 /* For TLS/IA. XXX: Move to IA credential? */
346 opaque inner_secret[TLS_MASTER_SIZE];
347 } security_parameters_st;
348
349/* This structure holds the generated keys
350 */
351typedef struct
352 {
353 gnutls_datum_t server_write_mac_secret;
354 gnutls_datum_t client_write_mac_secret;
355 gnutls_datum_t server_write_IV;
356 gnutls_datum_t client_write_IV;
357 gnutls_datum_t server_write_key;
358 gnutls_datum_t client_write_key;
359 int generated_keys; /* zero if keys have not
360 * been generated. Non zero
361 * otherwise.
362 */
363 } cipher_specs_st;
364
365typedef struct
366 {
367 cipher_hd_t write_cipher_state;
368 cipher_hd_t read_cipher_state;
369 comp_hd_t read_compression_state;
370 comp_hd_t write_compression_state;
371 gnutls_datum_t read_mac_secret;
372 gnutls_datum_t write_mac_secret;
373 uint64 read_sequence_number;
374 uint64 write_sequence_number;
375 } conn_stat_st;
376
377typedef struct
378 {
379 unsigned int priority[MAX_ALGOS];
380 unsigned int algorithms;
381 } priority_st;
382
383/* For the external api */
384struct gnutls_priority_st
385 {
386 priority_st cipher;
387 priority_st mac;
388 priority_st kx;
389 priority_st compression;
390 priority_st protocol;
391 priority_st cert_type;
392
393 /* to disable record padding */
394 int no_padding;
395 };
396
397/* DH and RSA parameters types.
398 */
399typedef struct gnutls_dh_params_int
400 {
401 /* [0] is the prime, [1] is the generator.
402 */
403 mpi_t params[2];
404 } dh_params_st;
405
406typedef struct
407 {
408 gnutls_dh_params_t dh_params;
409 int free_dh_params;
410 gnutls_rsa_params_t rsa_params;
411 int free_rsa_params;
412 } internal_params_st;
413
414typedef struct
415 {
416 opaque header[HANDSHAKE_HEADER_SIZE];
417 /* this holds the number of bytes in the handshake_header[] */
418 size_t header_size;
419 /* this holds the length of the handshake packet */
420 size_t packet_length;
421 gnutls_handshake_description_t recv_type;
422 } handshake_header_buffer_st;
423
424typedef struct
425 {
426 gnutls_buffer application_data_buffer; /* holds data to be delivered to application layer */
427 gnutls_buffer handshake_hash_buffer; /* used to keep the last received handshake
428 * message */
429 mac_hd_t handshake_mac_handle_sha; /* hash of the handshake messages */
430 mac_hd_t handshake_mac_handle_md5; /* hash of the handshake messages */
431
432 gnutls_buffer handshake_data_buffer; /* this is a buffer that holds the current handshake message */
433 gnutls_buffer ia_data_buffer; /* holds inner application data (TLS/IA) */
434 resumable_session_t resumable; /* TRUE or FALSE - if we can resume that session */
435 handshake_state_t handshake_state; /* holds
436 * a number which indicates where
437 * the handshake procedure has been
438 * interrupted. If it is 0 then
439 * no interruption has happened.
440 */
441
442 valid_session_t valid_connection; /* true or FALSE - if this session is valid */
443
444 int may_not_read; /* if it's 0 then we can read/write, otherwise it's forbiden to read/write
445 */
446 int may_not_write;
447 int read_eof; /* non-zero if we have received a closure alert. */
448
449 int last_alert; /* last alert received */
450
451 /* The last handshake messages sent or received.
452 */
453 int last_handshake_in;
454 int last_handshake_out;
455
456 /* this is the compression method we are going to use */
457 gnutls_compression_method_t compression_method;
458
459 /* priorities */
460 struct gnutls_priority_st priorities;
461
462 /* resumed session */
463 resumable_session_t resumed; /* RESUME_TRUE or FALSE - if we are resuming a session */
464 security_parameters_st resumed_security_parameters;
465
466 /* sockets internals */
467 int lowat;
468
469 /* These buffers are used in the handshake
470 * protocol only. freed using _gnutls_handshake_io_buffer_clear();
471 */
472 gnutls_buffer handshake_send_buffer;
473 size_t handshake_send_buffer_prev_size;
474 content_type_t handshake_send_buffer_type;
475 gnutls_handshake_description_t handshake_send_buffer_htype;
476 content_type_t handshake_recv_buffer_type;
477 gnutls_handshake_description_t handshake_recv_buffer_htype;
478 gnutls_buffer handshake_recv_buffer;
479
480 /* this buffer holds a record packet -mostly used for
481 * non blocking IO.
482 */
483 gnutls_buffer record_recv_buffer;
484 gnutls_buffer record_send_buffer; /* holds cached data
485 * for the gnutls_io_write_buffered()
486 * function.
487 */
488 size_t record_send_buffer_prev_size; /* holds the
489 * data written in the previous runs.
490 */
491 size_t record_send_buffer_user_size; /* holds the
492 * size of the user specified data to
493 * send.
494 */
495
496 /* 0 if no peeked data was kept, 1 otherwise.
497 */
498 int have_peeked_data;
499
500 int expire_time; /* after expire_time seconds this session will expire */
501 struct mod_auth_st_int *auth_struct; /* used in handshake packets and KX algorithms */
502 int v2_hello; /* 0 if the client hello is v3+.
503 * non-zero if we got a v2 hello.
504 */
505 /* keeps the headers of the handshake packet
506 */
507 handshake_header_buffer_st handshake_header_buffer;
508
509 /* this is the highest version available
510 * to the peer. (advertized version).
511 * This is obtained by the Handshake Client Hello
512 * message. (some implementations read the Record version)
513 */
514 uint8_t adv_version_major;
515 uint8_t adv_version_minor;
516
517 /* if this is non zero a certificate request message
518 * will be sent to the client. - only if the ciphersuite
519 * supports it.
520 */
521 int send_cert_req;
522
523 /* bits to use for DHE and DHA
524 * use _gnutls_dh_get_prime_bits() and gnutls_dh_set_prime_bits()
525 * to access it.
526 */
527 uint16_t dh_prime_bits;
528
529 size_t max_handshake_data_buffer_size;
530
531 /* PUSH & PULL functions.
532 */
533 gnutls_pull_func _gnutls_pull_func;
534 gnutls_push_func _gnutls_push_func;
535 /* Holds the first argument of PUSH and PULL
536 * functions;
537 */
538 gnutls_transport_ptr_t transport_recv_ptr;
539 gnutls_transport_ptr_t transport_send_ptr;
540
541 /* STORE & RETRIEVE functions. Only used if other
542 * backend than gdbm is used.
543 */
544 gnutls_db_store_func db_store_func;
545 gnutls_db_retr_func db_retrieve_func;
546 gnutls_db_remove_func db_remove_func;
547 void *db_ptr;
548
549 /* post client hello callback (server side only)
550 */
551 gnutls_handshake_post_client_hello_func user_hello_func;
552
553 /* Holds the record size requested by the
554 * user.
555 */
556 uint16_t proposed_record_size;
557
558 /* holds the selected certificate and key.
559 * use _gnutls_selected_certs_deinit() and _gnutls_selected_certs_set()
560 * to change them.
561 */
562 gnutls_cert *selected_cert_list;
563 int selected_cert_list_length;
564 gnutls_privkey *selected_key;
565 int selected_need_free;
566
567 /* holds the extensions we sent to the peer
568 * (in case of a client)
569 */
570 uint16_t extensions_sent[MAX_EXT_TYPES];
571 uint16_t extensions_sent_size;
572
573 /* is 0 if we are to send the whole PGP key, or non zero
574 * if the fingerprint is to be sent.
575 */
576 int pgp_fingerprint;
577
578 /* This holds the default version that our first
579 * record packet will have. */
580 opaque default_record_version[2];
581
582 int cbc_protection_hack;
583
584 void *user_ptr;
585
586 int enable_private; /* non zero to
587 * enable cipher suites
588 * which have 0xFF status.
589 */
590
591 /* Holds 0 if the last called function was interrupted while
592 * receiving, and non zero otherwise.
593 */
594 int direction;
595
596 /* This callback will be used (if set) to receive an
597 * openpgp key. (if the peer sends a fingerprint)
598 */
599 gnutls_openpgp_recv_key_func openpgp_recv_key_func;
600
601 /* If non zero the server will not advertize the CA's he
602 * trusts (do not send an RDN sequence).
603 */
604 int ignore_rdn_sequence;
605
606 /* This is used to set an arbitary version in the RSA
607 * PMS secret. Can be used by clients to test whether the
608 * server checks that version. (** only used in gnutls-cli-debug)
609 */
610 opaque rsa_pms_version[2];
611
612 char *srp_username;
613 char *srp_password;
614
615 /* Here we cache the DH or RSA parameters got from the
616 * credentials structure, or from a callback. That is to
617 * minimize external calls.
618 */
619 internal_params_st params;
620
621 /* This buffer is used by the record recv functions,
622 * as a temporary store buffer.
623 */
624 gnutls_datum_t recv_buffer;
625
626 /* To avoid using global variables, and especially on Windows where
627 * the application may use a different errno variable than GnuTLS,
628 * it is possible to use gnutls_transport_set_errno to set a
629 * session-specific errno variable in the user-replaceable push/pull
630 * functions. This value is used by the send/recv functions. (The
631 * strange name of this variable is because 'errno' is typically
632 * #define'd.)
633 */
634 int errnum;
635
636 /* Function used to perform public-key signing operation during
637 handshake. Used by gnutls_sig.c:_gnutls_tls_sign(), see also
638 gnutls_sign_callback_set(). */
639 gnutls_sign_func sign_func;
640 void *sign_func_userdata;
641
642 /* If you add anything here, check _gnutls_handshake_internal_state_clear().
643 */
644 } internals_st;
645
646struct gnutls_session_int
647 {
648 security_parameters_st security_parameters;
649 cipher_specs_st cipher_specs;
650 conn_stat_st connection_state;
651 internals_st internals;
652 gnutls_key_st key;
653 };
654
655/* functions
656 */
657void _gnutls_set_current_version(gnutls_session_t session,
658 gnutls_protocol_t version);
659
660void _gnutls_free_auth_info(gnutls_session_t session);
661
662/* These two macros return the advertized TLS version of
663 * the peer.
664 */
665#define _gnutls_get_adv_version_major( session) \
666 session->internals.adv_version_major
667
668#define _gnutls_get_adv_version_minor( session) \
669 session->internals.adv_version_minor
670
671#define set_adv_version( session, major, minor) \
672 session->internals.adv_version_major = major; \
673 session->internals.adv_version_minor = minor
674
675void _gnutls_set_adv_version(gnutls_session_t,
676 gnutls_protocol_t);
677gnutls_protocol_t _gnutls_get_adv_version(gnutls_session_t);
678
679#endif /* GNUTLS_INT_H */
diff --git a/src/daemon/https/tls/gnutls_kx.c b/src/daemon/https/tls/gnutls_kx.c
new file mode 100644
index 00000000..5e7f0d4d
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_kx.c
@@ -0,0 +1,773 @@
1/*
2 * Copyright (C) 2000, 2001, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains functions which are wrappers for the key exchange
26 * part of TLS. They are called by the handshake functions (gnutls_handshake)
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_handshake.h"
31#include "gnutls_kx.h"
32#include "gnutls_dh.h"
33#include "gnutls_errors.h"
34#include "gnutls_algorithms.h"
35#include "debug.h"
36#include "gnutls_mpi.h"
37#include <gnutls_state.h>
38#include <gnutls_datum.h>
39#include <gnutls_rsa_export.h>
40
41/* This file contains important thing for the TLS handshake procedure.
42 */
43
44#define MASTER_SECRET "master secret"
45static int generate_normal_master (gnutls_session_t session, int);
46
47int
48_gnutls_generate_master (gnutls_session_t session, int keep_premaster)
49{
50 if (session->internals.resumed == RESUME_FALSE)
51 return generate_normal_master (session, keep_premaster);
52 return 0;
53}
54
55/* here we generate the TLS Master secret.
56 */
57#define PREMASTER session->key->key
58static int
59generate_normal_master (gnutls_session_t session, int keep_premaster)
60{
61 int ret = 0;
62 char buf[512];
63
64 _gnutls_hard_log ("INT: PREMASTER SECRET[%d]: %s\n", PREMASTER.size,
65 _gnutls_bin2hex (PREMASTER.data, PREMASTER.size, buf,
66 sizeof (buf)));
67 _gnutls_hard_log ("INT: CLIENT RANDOM[%d]: %s\n", 32,
68 _gnutls_bin2hex (session->security_parameters.
69 client_random, 32, buf, sizeof (buf)));
70 _gnutls_hard_log ("INT: SERVER RANDOM[%d]: %s\n", 32,
71 _gnutls_bin2hex (session->security_parameters.
72 server_random, 32, buf, sizeof (buf)));
73
74 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
75 {
76 opaque rnd[2 * TLS_RANDOM_SIZE + 1];
77
78 memcpy (rnd, session->security_parameters.client_random,
79 TLS_RANDOM_SIZE);
80 memcpy (&rnd[TLS_RANDOM_SIZE],
81 session->security_parameters.server_random, TLS_RANDOM_SIZE);
82
83 ret =
84 _gnutls_ssl3_generate_random (PREMASTER.data, PREMASTER.size,
85 rnd, 2 * TLS_RANDOM_SIZE,
86 TLS_MASTER_SIZE,
87 session->security_parameters.
88 master_secret);
89
90 }
91 else if (session->security_parameters.extensions.oprfi_client_len > 0 &&
92 session->security_parameters.extensions.oprfi_server_len > 0)
93 {
94 opaque *rnd;
95 size_t rndlen = 2 * TLS_RANDOM_SIZE;
96
97 rndlen += session->security_parameters.extensions.oprfi_client_len;
98 rndlen += session->security_parameters.extensions.oprfi_server_len;
99
100 rnd = gnutls_malloc (rndlen + 1);
101 if (!rnd)
102 {
103 gnutls_assert ();
104 return GNUTLS_E_MEMORY_ERROR;
105 }
106
107 _gnutls_hard_log ("INT: CLIENT OPRFI[%d]: %s\n",
108 session->security_parameters.
109 extensions.oprfi_server_len,
110 _gnutls_bin2hex (session->security_parameters.
111 extensions.oprfi_client,
112 session->security_parameters.
113 extensions.oprfi_client_len,
114 buf, sizeof (buf)));
115 _gnutls_hard_log ("INT: SERVER OPRFI[%d]: %s\n",
116 session->security_parameters.
117 extensions.oprfi_server_len,
118 _gnutls_bin2hex (session->security_parameters.
119 extensions.oprfi_server,
120 session->security_parameters.
121 extensions.oprfi_server_len,
122 buf, sizeof (buf)));
123
124 memcpy (rnd, session->security_parameters.client_random,
125 TLS_RANDOM_SIZE);
126 memcpy (rnd + TLS_RANDOM_SIZE,
127 session->security_parameters.extensions.oprfi_client,
128 session->security_parameters.extensions.oprfi_client_len);
129 memcpy (rnd + TLS_RANDOM_SIZE +
130 session->security_parameters.extensions.oprfi_client_len,
131 session->security_parameters.server_random, TLS_RANDOM_SIZE);
132 memcpy (rnd + TLS_RANDOM_SIZE +
133 session->security_parameters.extensions.oprfi_client_len +
134 TLS_RANDOM_SIZE,
135 session->security_parameters.extensions.oprfi_server,
136 session->security_parameters.extensions.oprfi_server_len);
137
138 ret = _gnutls_PRF (session, PREMASTER.data, PREMASTER.size,
139 MASTER_SECRET, strlen (MASTER_SECRET),
140 rnd, rndlen, TLS_MASTER_SIZE,
141 session->security_parameters.master_secret);
142
143 gnutls_free (rnd);
144 }
145 else
146 {
147 opaque rnd[2 * TLS_RANDOM_SIZE + 1];
148
149 memcpy (rnd, session->security_parameters.client_random,
150 TLS_RANDOM_SIZE);
151 memcpy (&rnd[TLS_RANDOM_SIZE],
152 session->security_parameters.server_random, TLS_RANDOM_SIZE);
153
154 ret =
155 _gnutls_PRF (session, PREMASTER.data, PREMASTER.size,
156 MASTER_SECRET, strlen (MASTER_SECRET),
157 rnd, 2 * TLS_RANDOM_SIZE, TLS_MASTER_SIZE,
158 session->security_parameters.master_secret);
159 }
160
161 /* TLS/IA inner secret is derived from the master secret. */
162 memcpy (session->security_parameters.inner_secret,
163 session->security_parameters.master_secret, TLS_MASTER_SIZE);
164
165 if (!keep_premaster)
166 _gnutls_free_datum (&PREMASTER);
167
168 if (ret < 0)
169 return ret;
170
171 _gnutls_hard_log ("INT: MASTER SECRET: %s\n",
172 _gnutls_bin2hex (session->security_parameters.
173 master_secret, TLS_MASTER_SIZE, buf,
174 sizeof (buf)));
175
176 return ret;
177}
178
179
180/* This is called when we want to receive the key exchange message of the
181 * server. It does nothing if this type of message is not required
182 * by the selected ciphersuite.
183 */
184int
185_gnutls_send_server_kx_message (gnutls_session_t session, int again)
186{
187 uint8_t *data = NULL;
188 int data_size = 0;
189 int ret = 0;
190
191 if (session->internals.auth_struct->gnutls_generate_server_kx == NULL)
192 return 0;
193
194 data = NULL;
195 data_size = 0;
196
197 if (again == 0)
198 {
199 data_size =
200 session->internals.auth_struct->
201 gnutls_generate_server_kx (session, &data);
202
203 if (data_size == GNUTLS_E_INT_RET_0)
204 {
205 gnutls_assert ();
206 return 0;
207 }
208
209 if (data_size < 0)
210 {
211 gnutls_assert ();
212 return data_size;
213 }
214 }
215
216 ret =
217 _gnutls_send_handshake (session, data, data_size,
218 GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE);
219 gnutls_free (data);
220
221 if (ret < 0)
222 {
223 gnutls_assert ();
224 return ret;
225 }
226 return data_size;
227}
228
229/* This function sends a certificate request message to the
230 * client.
231 */
232int
233_gnutls_send_server_certificate_request (gnutls_session_t session, int again)
234{
235 uint8_t *data = NULL;
236 int data_size = 0;
237 int ret = 0;
238
239 if (session->internals.auth_struct->
240 gnutls_generate_server_certificate_request == NULL)
241 return 0;
242
243 if (session->internals.send_cert_req <= 0)
244 return 0;
245
246 data = NULL;
247 data_size = 0;
248
249 if (again == 0)
250 {
251 data_size =
252 session->internals.auth_struct->
253 gnutls_generate_server_certificate_request (session, &data);
254
255 if (data_size < 0)
256 {
257 gnutls_assert ();
258 return data_size;
259 }
260 }
261 ret =
262 _gnutls_send_handshake (session, data, data_size,
263 GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST);
264 gnutls_free (data);
265
266 if (ret < 0)
267 {
268 gnutls_assert ();
269 return ret;
270 }
271 return data_size;
272}
273
274
275/* This is the function for the client to send the key
276 * exchange message
277 */
278int
279_gnutls_send_client_kx_message (gnutls_session_t session, int again)
280{
281 uint8_t *data;
282 int data_size;
283 int ret = 0;
284
285 if (session->internals.auth_struct->gnutls_generate_client_kx == NULL)
286 return 0;
287
288
289 data = NULL;
290 data_size = 0;
291
292 if (again == 0)
293 {
294 data_size =
295 session->internals.auth_struct->
296 gnutls_generate_client_kx (session, &data);
297 if (data_size < 0)
298 {
299 gnutls_assert ();
300 return data_size;
301 }
302 }
303 ret =
304 _gnutls_send_handshake (session, data, data_size,
305 GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE);
306 gnutls_free (data);
307
308 if (ret < 0)
309 {
310 gnutls_assert ();
311 return ret;
312 }
313
314 return ret;
315}
316
317
318/* This is the function for the client to send the certificate
319 * verify message
320 */
321int
322_gnutls_send_client_certificate_verify (gnutls_session_t session, int again)
323{
324 uint8_t *data;
325 int ret = 0;
326 int data_size;
327
328 /* This is a packet that is only sent by the client
329 */
330 if (session->security_parameters.entity == GNUTLS_SERVER)
331 return 0;
332
333 /* if certificate verify is not needed just exit
334 */
335 if (session->key->certificate_requested == 0)
336 return 0;
337
338 if (session->internals.auth_struct->gnutls_generate_client_cert_vrfy ==
339 NULL)
340 {
341 gnutls_assert ();
342 return 0; /* this algorithm does not support cli_cert_vrfy
343 */
344 }
345
346 data = NULL;
347 data_size = 0;
348
349 if (again == 0)
350 {
351 data_size =
352 session->internals.auth_struct->
353 gnutls_generate_client_cert_vrfy (session, &data);
354 if (data_size < 0)
355 {
356 gnutls_assert ();
357 return data_size;
358 }
359 if (data_size == 0)
360 return 0;
361
362 }
363 ret =
364 _gnutls_send_handshake (session, data,
365 data_size, GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY);
366 gnutls_free (data);
367
368 return ret;
369}
370
371
372int
373_gnutls_recv_server_kx_message (gnutls_session_t session)
374{
375 uint8_t *data = NULL;
376 int datasize;
377 int ret = 0;
378
379 if (session->internals.auth_struct->gnutls_process_server_kx != NULL)
380 {
381
382 /* EXCEPTION FOR RSA_EXPORT cipher suite
383 */
384 if (_gnutls_session_is_export (session) != 0 &&
385 _gnutls_peers_cert_less_512 (session) != 0)
386 {
387 gnutls_assert ();
388 return 0;
389 }
390
391 ret =
392 _gnutls_recv_handshake (session, &data,
393 &datasize,
394 GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE,
395 MANDATORY_PACKET);
396 if (ret < 0)
397 {
398 gnutls_assert ();
399 return ret;
400 }
401
402 ret =
403 session->internals.auth_struct->
404 gnutls_process_server_kx (session, data, datasize);
405 gnutls_free (data);
406
407 if (ret < 0)
408 {
409 gnutls_assert ();
410 return ret;
411 }
412
413 }
414 return ret;
415}
416
417int
418_gnutls_recv_server_certificate_request (gnutls_session_t session)
419{
420 uint8_t *data;
421 int datasize;
422 int ret = 0;
423
424 if (session->internals.auth_struct->
425 gnutls_process_server_certificate_request != NULL)
426 {
427
428 ret =
429 _gnutls_recv_handshake (session, &data,
430 &datasize,
431 GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST,
432 OPTIONAL_PACKET);
433 if (ret < 0)
434 return ret;
435
436 if (ret == 0 && datasize == 0)
437 return 0; /* ignored */
438
439 ret =
440 session->internals.auth_struct->
441 gnutls_process_server_certificate_request (session, data, datasize);
442 gnutls_free (data);
443 if (ret < 0)
444 return ret;
445
446 }
447 return ret;
448}
449
450int
451_gnutls_recv_client_kx_message (gnutls_session_t session)
452{
453 uint8_t *data;
454 int datasize;
455 int ret = 0;
456
457
458 /* Do key exchange only if the algorithm permits it */
459 if (session->internals.auth_struct->gnutls_process_client_kx != NULL)
460 {
461
462 ret =
463 _gnutls_recv_handshake (session, &data,
464 &datasize,
465 GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE,
466 MANDATORY_PACKET);
467 if (ret < 0)
468 return ret;
469
470 ret =
471 session->internals.auth_struct->
472 gnutls_process_client_kx (session, data, datasize);
473 gnutls_free (data);
474 if (ret < 0)
475 return ret;
476
477 }
478
479 return ret;
480}
481
482
483/* This is called when we want send our certificate
484 */
485int
486_gnutls_send_client_certificate (gnutls_session_t session, int again)
487{
488 uint8_t *data = NULL;
489 int data_size = 0;
490 int ret = 0;
491
492
493 if (session->key->certificate_requested == 0)
494 return 0;
495
496 if (session->internals.auth_struct->
497 gnutls_generate_client_certificate == NULL)
498 return 0;
499
500 data = NULL;
501 data_size = 0;
502
503 if (again == 0)
504 {
505 if (gnutls_protocol_get_version (session) != GNUTLS_SSL3 ||
506 session->internals.selected_cert_list_length > 0)
507 {
508 /* TLS 1.0 or SSL 3.0 with a valid certificate
509 */
510 data_size =
511 session->internals.auth_struct->
512 gnutls_generate_client_certificate (session, &data);
513
514 if (data_size < 0)
515 {
516 gnutls_assert ();
517 return data_size;
518 }
519 }
520 }
521
522 /* In the SSL 3.0 protocol we need to send a
523 * no certificate alert instead of an
524 * empty certificate.
525 */
526 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3 &&
527 session->internals.selected_cert_list_length == 0)
528 {
529 ret =
530 gnutls_alert_send (session, GNUTLS_AL_WARNING,
531 GNUTLS_A_SSL3_NO_CERTIFICATE);
532
533 }
534 else
535 { /* TLS 1.0 or SSL 3.0 with a valid certificate
536 */
537 ret =
538 _gnutls_send_handshake (session, data, data_size,
539 GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
540 gnutls_free (data);
541 }
542
543 if (ret < 0)
544 {
545 gnutls_assert ();
546 return ret;
547 }
548
549 return data_size;
550}
551
552
553/* This is called when we want send our certificate
554 */
555int
556_gnutls_send_server_certificate (gnutls_session_t session, int again)
557{
558 uint8_t *data = NULL;
559 int data_size = 0;
560 int ret = 0;
561
562
563 if (session->internals.auth_struct->
564 gnutls_generate_server_certificate == NULL)
565 return 0;
566
567 data = NULL;
568 data_size = 0;
569
570 if (again == 0)
571 {
572 data_size =
573 session->internals.auth_struct->
574 gnutls_generate_server_certificate (session, &data);
575
576 if (data_size < 0)
577 {
578 gnutls_assert ();
579 return data_size;
580 }
581 }
582 ret =
583 _gnutls_send_handshake (session, data, data_size,
584 GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
585 gnutls_free (data);
586
587 if (ret < 0)
588 {
589 gnutls_assert ();
590 return ret;
591 }
592
593 return data_size;
594}
595
596
597int
598_gnutls_recv_client_certificate (gnutls_session_t session)
599{
600 int datasize;
601 opaque *data;
602 int ret = 0;
603 int optional;
604
605 if (session->internals.auth_struct->
606 gnutls_process_client_certificate != NULL)
607 {
608
609 /* if we have not requested a certificate then just return
610 */
611 if (session->internals.send_cert_req == 0)
612 {
613 return 0;
614 }
615
616 if (session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
617 optional = MANDATORY_PACKET;
618 else
619 optional = OPTIONAL_PACKET;
620
621 ret =
622 _gnutls_recv_handshake (session, &data,
623 &datasize,
624 GNUTLS_HANDSHAKE_CERTIFICATE_PKT, optional);
625
626 if (ret < 0)
627 {
628 /* Handle the case of old SSL3 clients who send
629 * a warning alert instead of an empty certificate to indicate
630 * no certificate.
631 */
632 if (optional == OPTIONAL_PACKET &&
633 ret == GNUTLS_E_WARNING_ALERT_RECEIVED &&
634 gnutls_protocol_get_version (session) == GNUTLS_SSL3 &&
635 gnutls_alert_get (session) == GNUTLS_A_SSL3_NO_CERTIFICATE)
636 {
637
638 /* SSL3 does not send an empty certificate,
639 * but this alert. So we just ignore it.
640 */
641 gnutls_assert ();
642 return 0;
643 }
644
645 /* certificate was required
646 */
647 if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED
648 || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
649 && optional == MANDATORY_PACKET)
650 {
651 gnutls_assert ();
652 return GNUTLS_E_NO_CERTIFICATE_FOUND;
653 }
654
655 return ret;
656 }
657
658 if (ret == 0 && datasize == 0 && optional == OPTIONAL_PACKET)
659 {
660 /* Client has not sent the certificate message.
661 * well I'm not sure we should accept this
662 * behaviour.
663 */
664 gnutls_assert ();
665 return 0;
666 }
667 ret =
668 session->internals.auth_struct->
669 gnutls_process_client_certificate (session, data, datasize);
670
671 gnutls_free (data);
672 if (ret < 0 && ret != GNUTLS_E_NO_CERTIFICATE_FOUND)
673 {
674 gnutls_assert ();
675 return ret;
676 }
677
678 /* ok we should expect a certificate verify message now
679 */
680 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND && optional == OPTIONAL_PACKET)
681 ret = 0;
682 else
683 session->key->certificate_requested = 1;
684
685 }
686
687 return ret;
688}
689
690int
691_gnutls_recv_server_certificate (gnutls_session_t session)
692{
693 int datasize;
694 opaque *data;
695 int ret = 0;
696
697 if (session->internals.auth_struct->
698 gnutls_process_server_certificate != NULL)
699 {
700
701 ret =
702 _gnutls_recv_handshake (session, &data,
703 &datasize,
704 GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
705 MANDATORY_PACKET);
706 if (ret < 0)
707 {
708 gnutls_assert ();
709 return ret;
710 }
711
712 ret =
713 session->internals.auth_struct->
714 gnutls_process_server_certificate (session, data, datasize);
715 gnutls_free (data);
716 if (ret < 0)
717 {
718 gnutls_assert ();
719 return ret;
720 }
721 }
722
723 return ret;
724}
725
726
727/* Recv the client certificate verify. This packet may not
728 * arrive if the peer did not send us a certificate.
729 */
730int
731_gnutls_recv_client_certificate_verify_message (gnutls_session_t session)
732{
733 uint8_t *data;
734 int datasize;
735 int ret = 0;
736
737
738 if (session->internals.auth_struct->gnutls_process_client_cert_vrfy != NULL)
739 {
740
741 if (session->internals.send_cert_req == 0 ||
742 session->key->certificate_requested == 0)
743 {
744 return 0;
745 }
746
747 ret =
748 _gnutls_recv_handshake (session, &data,
749 &datasize,
750 GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY,
751 OPTIONAL_PACKET);
752 if (ret < 0)
753 return ret;
754
755 if (ret == 0 && datasize == 0
756 && session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
757 {
758 /* certificate was required */
759 gnutls_assert ();
760 return GNUTLS_E_NO_CERTIFICATE_FOUND;
761 }
762
763 ret =
764 session->internals.auth_struct->
765 gnutls_process_client_cert_vrfy (session, data, datasize);
766 gnutls_free (data);
767 if (ret < 0)
768 return ret;
769
770 }
771
772 return ret;
773}
diff --git a/src/daemon/https/tls/gnutls_kx.h b/src/daemon/https/tls/gnutls_kx.h
new file mode 100644
index 00000000..45ba68bd
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_kx.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_send_server_kx_message (gnutls_session_t session, int again);
26int _gnutls_send_client_kx_message (gnutls_session_t session, int again);
27int _gnutls_recv_server_kx_message (gnutls_session_t session);
28int _gnutls_recv_client_kx_message (gnutls_session_t session);
29int _gnutls_send_client_certificate_verify (gnutls_session_t session,
30 int again);
31int _gnutls_send_server_certificate (gnutls_session_t session, int again);
32int _gnutls_generate_master (gnutls_session_t session, int keep_premaster);
33int _gnutls_recv_client_certificate (gnutls_session_t session);
34int _gnutls_recv_server_certificate (gnutls_session_t session);
35int _gnutls_send_client_certificate (gnutls_session_t session, int again);
36int _gnutls_recv_server_certificate_request (gnutls_session_t session);
37int _gnutls_send_server_certificate_request (gnutls_session_t session,
38 int again);
39int _gnutls_recv_client_certificate_verify_message (gnutls_session_t session);
diff --git a/src/daemon/https/tls/gnutls_mem.c b/src/daemon/https/tls/gnutls_mem.c
new file mode 100644
index 00000000..91a6fa3c
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_mem.c
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_num.h>
28
29gnutls_alloc_function gnutls_secure_malloc = malloc;
30gnutls_alloc_function gnutls_malloc = malloc;
31gnutls_free_function gnutls_free = free;
32gnutls_realloc_function gnutls_realloc = realloc;
33
34void *(*gnutls_calloc) (size_t, size_t) = calloc;
35char *(*gnutls_strdup) (const char *) = _gnutls_strdup;
36
37int
38_gnutls_is_secure_mem_null (const void *ign)
39{
40 return 0;
41}
42
43int (*_gnutls_is_secure_memory) (const void *) = _gnutls_is_secure_mem_null;
44
45
46void *
47_gnutls_calloc (size_t nmemb, size_t size)
48{
49 void *ret;
50 size *= nmemb;
51 ret = gnutls_malloc (size);
52 if (ret != NULL)
53 memset (ret, 0, size);
54 return ret;
55}
56
57svoid *
58gnutls_secure_calloc (size_t nmemb, size_t size)
59{
60 svoid *ret;
61 size *= nmemb;
62 ret = gnutls_secure_malloc (size);
63 if (ret != NULL)
64 memset (ret, 0, size);
65 return ret;
66}
67
68/* This realloc will free ptr in case realloc
69 * fails.
70 */
71void *
72gnutls_realloc_fast (void *ptr, size_t size)
73{
74 void *ret;
75
76 if (size == 0)
77 return ptr;
78
79 ret = gnutls_realloc (ptr, size);
80 if (ret == NULL)
81 {
82 gnutls_free (ptr);
83 }
84
85 return ret;
86}
87
88char *
89_gnutls_strdup (const char *str)
90{
91 size_t siz = strlen (str) + 1;
92 char *ret;
93
94 ret = gnutls_malloc (siz);
95 if (ret != NULL)
96 memcpy (ret, str, siz);
97 return ret;
98}
99
100
101#if 0
102/* don't use them. They are included for documentation.
103 */
104
105/**
106 * gnutls_malloc - Allocates and returns data
107 *
108 * This function will allocate 's' bytes data, and
109 * return a pointer to memory. This function is supposed
110 * to be used by callbacks.
111 *
112 * The allocation function used is the one set by gnutls_global_set_mem_functions().
113 *
114 **/
115void *
116gnutls_malloc (size_t s)
117{
118}
119
120/**
121 * gnutls_free - Returns a free() like function
122 * @d: pointer to memory
123 *
124 * This function will free data pointed by ptr.
125 *
126 * The deallocation function used is the one set by gnutls_global_set_mem_functions().
127 *
128 **/
129void
130gnutls_free (void *ptr)
131{
132}
133
134#endif
diff --git a/src/daemon/https/tls/gnutls_mem.h b/src/daemon/https/tls/gnutls_mem.h
new file mode 100644
index 00000000..f76081e5
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_mem.h
@@ -0,0 +1,70 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_MEM_H
26# define GNUTLS_MEM_H
27
28#ifdef USE_DMALLOC
29# include <dmalloc.h>
30#endif
31
32typedef void svoid; /* for functions that allocate using gnutls_secure_malloc */
33
34/* Use gnutls_afree() when calling alloca, or
35 * memory leaks may occur in systems which do not
36 * support alloca.
37 */
38#ifdef USE_EFENCE
39# define gnutls_alloca gnutls_malloc
40# define gnutls_afree gnutls_free
41#endif
42
43#ifdef HAVE_ALLOCA
44# ifdef HAVE_ALLOCA_H
45# include <alloca.h>
46# endif
47# ifndef gnutls_alloca
48# define gnutls_alloca alloca
49# define gnutls_afree(x)
50# endif
51#else
52# ifndef gnutls_alloca
53# define gnutls_alloca gnutls_malloc
54# define gnutls_afree gnutls_free
55# endif
56#endif /* HAVE_ALLOCA */
57
58extern int (*_gnutls_is_secure_memory) (const void *);
59
60/* this realloc function will return ptr if size==0, and
61 * will free the ptr if the new allocation failed.
62 */
63void *gnutls_realloc_fast (void *ptr, size_t size);
64
65svoid *gnutls_secure_calloc (size_t nmemb, size_t size);
66
67void *_gnutls_calloc (size_t nmemb, size_t size);
68char *_gnutls_strdup (const char *);
69
70#endif /* GNUTLS_MEM_H */
diff --git a/src/daemon/https/tls/gnutls_mpi.c b/src/daemon/https/tls/gnutls_mpi.c
new file mode 100644
index 00000000..0d807a18
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_mpi.c
@@ -0,0 +1,285 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Here lie everything that has to do with large numbers, libgcrypt and
26 * other stuff that didn't fit anywhere else.
27 */
28
29#include <gnutls_int.h>
30#include <libtasn1.h>
31#include <gnutls_errors.h>
32#include <gnutls_num.h>
33
34/* Functions that refer to the libgcrypt library.
35 */
36
37void
38_gnutls_mpi_release (mpi_t * x)
39{
40 if (*x == NULL)
41 return;
42 gcry_mpi_release (*x);
43 *x = NULL;
44}
45
46/* returns zero on success
47 */
48int
49_gnutls_mpi_scan (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes)
50{
51 int ret;
52
53 ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, buffer, *nbytes, nbytes);
54 if (ret)
55 return GNUTLS_E_MPI_SCAN_FAILED;
56
57 return 0;
58}
59
60/* returns zero on success. Fails if the number is zero.
61 */
62int
63_gnutls_mpi_scan_nz (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes)
64{
65 int ret;
66
67 ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, buffer, *nbytes, nbytes);
68 if (ret)
69 return GNUTLS_E_MPI_SCAN_FAILED;
70
71 /* MPIs with 0 bits are illegal
72 */
73 if (_gnutls_mpi_get_nbits (*ret_mpi) == 0)
74 {
75 _gnutls_mpi_release (ret_mpi);
76 return GNUTLS_E_MPI_SCAN_FAILED;
77 }
78
79 return 0;
80}
81
82int
83_gnutls_mpi_scan_pgp (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes)
84{
85 int ret;
86 ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_PGP, buffer, *nbytes, nbytes);
87 if (ret)
88 return GNUTLS_E_MPI_SCAN_FAILED;
89
90 /* MPIs with 0 bits are illegal
91 */
92 if (_gnutls_mpi_get_nbits (*ret_mpi) == 0)
93 {
94 _gnutls_mpi_release (ret_mpi);
95 return GNUTLS_E_MPI_SCAN_FAILED;
96 }
97
98 return 0;
99}
100
101int
102_gnutls_mpi_print (void *buffer, size_t * nbytes, const mpi_t a)
103{
104 int ret;
105
106 if (nbytes == NULL || a == NULL)
107 return GNUTLS_E_INVALID_REQUEST;
108
109 ret = gcry_mpi_print (GCRYMPI_FMT_USG, buffer, *nbytes, nbytes, a);
110 if (!ret)
111 return 0;
112
113 return GNUTLS_E_MPI_PRINT_FAILED;
114}
115
116/* Always has the first bit zero */
117int
118_gnutls_mpi_print_lz (void *buffer, size_t * nbytes, const mpi_t a)
119{
120 int ret;
121
122 if (nbytes == NULL || a == NULL)
123 return GNUTLS_E_INVALID_REQUEST;
124
125 ret = gcry_mpi_print (GCRYMPI_FMT_STD, buffer, *nbytes, nbytes, a);
126 if (!ret)
127 return 0;
128
129 return GNUTLS_E_MPI_PRINT_FAILED;
130}
131
132/* Always has the first bit zero */
133int
134_gnutls_mpi_dprint_lz (gnutls_datum_t * dest, const mpi_t a)
135{
136 int ret;
137 opaque *buf = NULL;
138 size_t bytes = 0;
139
140 if (dest == NULL || a == NULL)
141 return GNUTLS_E_INVALID_REQUEST;
142
143 gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &bytes, a);
144
145 if (bytes != 0)
146 buf = gnutls_malloc (bytes);
147 if (buf == NULL)
148 return GNUTLS_E_MEMORY_ERROR;
149
150 ret = gcry_mpi_print (GCRYMPI_FMT_STD, buf, bytes, &bytes, a);
151 if (!ret)
152 {
153 dest->data = buf;
154 dest->size = bytes;
155 return 0;
156 }
157
158 gnutls_free (buf);
159 return GNUTLS_E_MPI_PRINT_FAILED;
160}
161
162int
163_gnutls_mpi_dprint (gnutls_datum_t * dest, const mpi_t a)
164{
165 int ret;
166 opaque *buf = NULL;
167 size_t bytes = 0;
168
169 if (dest == NULL || a == NULL)
170 return GNUTLS_E_INVALID_REQUEST;
171
172 gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &bytes, a);
173
174 if (bytes != 0)
175 buf = gnutls_malloc (bytes);
176 if (buf == NULL)
177 return GNUTLS_E_MEMORY_ERROR;
178
179 ret = gcry_mpi_print (GCRYMPI_FMT_USG, buf, bytes, &bytes, a);
180 if (!ret)
181 {
182 dest->data = buf;
183 dest->size = bytes;
184 return 0;
185 }
186
187 gnutls_free (buf);
188 return GNUTLS_E_MPI_PRINT_FAILED;
189}
190
191
192/* this function reads an integer
193 * from asn1 structs. Combines the read and mpi_scan
194 * steps.
195 */
196int
197_gnutls_x509_read_int (ASN1_TYPE node, const char *value, mpi_t * ret_mpi)
198{
199 int result;
200 size_t s_len;
201 opaque *tmpstr = NULL;
202 int tmpstr_size;
203
204 tmpstr_size = 0;
205 result = asn1_read_value (node, value, NULL, &tmpstr_size);
206 if (result != ASN1_MEM_ERROR)
207 {
208 gnutls_assert ();
209 return _gnutls_asn2err (result);
210 }
211
212 tmpstr = gnutls_alloca (tmpstr_size);
213 if (tmpstr == NULL)
214 {
215 gnutls_assert ();
216 return GNUTLS_E_MEMORY_ERROR;
217 }
218
219 result = asn1_read_value (node, value, tmpstr, &tmpstr_size);
220 if (result != ASN1_SUCCESS)
221 {
222 gnutls_assert ();
223 gnutls_afree (tmpstr);
224 return _gnutls_asn2err (result);
225 }
226
227 s_len = tmpstr_size;
228 if (_gnutls_mpi_scan (ret_mpi, tmpstr, &s_len) != 0)
229 {
230 gnutls_assert ();
231 gnutls_afree (tmpstr);
232 return GNUTLS_E_MPI_SCAN_FAILED;
233 }
234
235 gnutls_afree (tmpstr);
236
237 return 0;
238}
239
240/* Writes the specified integer into the specified node.
241 */
242int
243_gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi, int lz)
244{
245 opaque *tmpstr;
246 size_t s_len;
247 int result;
248
249 s_len = 0;
250 if (lz)
251 result = _gnutls_mpi_print_lz (NULL, &s_len, mpi);
252 else
253 result = _gnutls_mpi_print (NULL, &s_len, mpi);
254
255 tmpstr = gnutls_alloca (s_len);
256 if (tmpstr == NULL)
257 {
258 gnutls_assert ();
259 return GNUTLS_E_MEMORY_ERROR;
260 }
261
262 if (lz)
263 result = _gnutls_mpi_print_lz (tmpstr, &s_len, mpi);
264 else
265 result = _gnutls_mpi_print (tmpstr, &s_len, mpi);
266
267 if (result != 0)
268 {
269 gnutls_assert ();
270 gnutls_afree (tmpstr);
271 return GNUTLS_E_MPI_PRINT_FAILED;
272 }
273
274 result = asn1_write_value (node, value, tmpstr, s_len);
275
276 gnutls_afree (tmpstr);
277
278 if (result != ASN1_SUCCESS)
279 {
280 gnutls_assert ();
281 return _gnutls_asn2err (result);
282 }
283
284 return 0;
285}
diff --git a/src/daemon/https/tls/gnutls_mpi.h b/src/daemon/https/tls/gnutls_mpi.h
new file mode 100644
index 00000000..de2a6f20
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_mpi.h
@@ -0,0 +1,78 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_MPI_H
26# define GNUTLS_MPI_H
27
28# include <gnutls_int.h>
29# include <gcrypt.h>
30# include <libtasn1.h>
31/* lgl */
32# include "gc.h"
33
34typedef gcry_mpi_t mpi_t;
35
36#define _gnutls_mpi_cmp gcry_mpi_cmp
37#define _gnutls_mpi_cmp_ui gcry_mpi_cmp_ui
38#define _gnutls_mpi_mod gcry_mpi_mod
39#define _gnutls_mpi_new gcry_mpi_new
40#define _gnutls_mpi_snew gcry_mpi_snew
41#define _gnutls_mpi_copy gcry_mpi_copy
42#define _gnutls_mpi_set_ui gcry_mpi_set_ui
43#define _gnutls_mpi_set gcry_mpi_set
44#define _gnutls_mpi_randomize gcry_mpi_randomize
45#define _gnutls_mpi_get_nbits gcry_mpi_get_nbits
46#define _gnutls_mpi_powm gcry_mpi_powm
47#define _gnutls_mpi_invm gcry_mpi_invm
48#define _gnutls_mpi_addm gcry_mpi_addm
49#define _gnutls_mpi_subm gcry_mpi_subm
50#define _gnutls_mpi_sub_ui gcry_mpi_sub_ui
51#define _gnutls_mpi_mulm gcry_mpi_mulm
52#define _gnutls_mpi_mul gcry_mpi_mul
53#define _gnutls_mpi_add gcry_mpi_add
54#define _gnutls_mpi_add_ui gcry_mpi_add_ui
55#define _gnutls_mpi_sub_ui gcry_mpi_sub_ui
56#define _gnutls_mpi_mul_ui gcry_mpi_mul_ui
57#define _gnutls_prime_check gcry_prime_check
58#define _gnutls_mpi_div gcry_mpi_div
59
60#define _gnutls_mpi_alloc_like(x) _gnutls_mpi_new(_gnutls_mpi_get_nbits(x))
61#define _gnutls_mpi_salloc_like(x) _gnutls_mpi_snew(_gnutls_mpi_get_nbits(x))
62
63void _gnutls_mpi_release (mpi_t * x);
64
65int _gnutls_mpi_scan_nz (mpi_t * ret_mpi, const opaque * buffer,
66 size_t * nbytes);
67int _gnutls_mpi_scan (mpi_t * ret_mpi, const opaque * buffer,
68 size_t * nbytes);
69int _gnutls_mpi_scan_pgp (mpi_t * ret_mpi, const opaque * buffer,
70 size_t * nbytes);
71
72int _gnutls_mpi_print (void *buffer, size_t * nbytes, const mpi_t a);
73int _gnutls_mpi_print_lz (void *buffer, size_t * nbytes, const mpi_t a);
74
75int _gnutls_mpi_dprint_lz (gnutls_datum_t * dest, const mpi_t a);
76int _gnutls_mpi_dprint (gnutls_datum_t * dest, const mpi_t a);
77
78#endif
diff --git a/src/daemon/https/tls/gnutls_num.c b/src/daemon/https/tls/gnutls_num.c
new file mode 100644
index 00000000..474cb73b
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_num.c
@@ -0,0 +1,192 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains the functions needed for 64 bit integer support in
26 * TLS, and functions which ease the access to TLS vectors (data of given size).
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_num.h>
31#include <gnutls_errors.h>
32
33/* This function will add one to uint64 x.
34 * Returns 0 on success, or -1 if the uint64 max limit
35 * has been reached.
36 */
37int
38_gnutls_uint64pp (uint64 * x)
39{
40 register int i, y = 0;
41
42 for (i = 7; i >= 0; i--)
43 {
44 y = 0;
45 if (x->i[i] == 0xff)
46 {
47 x->i[i] = 0;
48 y = 1;
49 }
50 else
51 x->i[i]++;
52
53 if (y == 0)
54 break;
55 }
56 if (y != 0)
57 return -1; /* over 64 bits! WOW */
58
59 return 0;
60}
61
62uint32_t
63_gnutls_uint24touint32 (uint24 num)
64{
65 uint32_t ret = 0;
66
67 ((uint8_t *) & ret)[1] = num.pint[0];
68 ((uint8_t *) & ret)[2] = num.pint[1];
69 ((uint8_t *) & ret)[3] = num.pint[2];
70 return ret;
71}
72
73uint24
74_gnutls_uint32touint24 (uint32_t num)
75{
76 uint24 ret;
77
78 ret.pint[0] = ((uint8_t *) & num)[1];
79 ret.pint[1] = ((uint8_t *) & num)[2];
80 ret.pint[2] = ((uint8_t *) & num)[3];
81 return ret;
82
83}
84
85/* data should be at least 3 bytes */
86uint32_t
87_gnutls_read_uint24 (const opaque * data)
88{
89 uint32_t res;
90 uint24 num;
91
92 num.pint[0] = data[0];
93 num.pint[1] = data[1];
94 num.pint[2] = data[2];
95
96 res = _gnutls_uint24touint32 (num);
97#ifndef WORDS_BIGENDIAN
98 res = byteswap32 (res);
99#endif
100 return res;
101}
102
103void
104_gnutls_write_uint24 (uint32_t num, opaque * data)
105{
106 uint24 tmp;
107
108#ifndef WORDS_BIGENDIAN
109 num = byteswap32 (num);
110#endif
111 tmp = _gnutls_uint32touint24 (num);
112
113 data[0] = tmp.pint[0];
114 data[1] = tmp.pint[1];
115 data[2] = tmp.pint[2];
116}
117
118uint32_t
119_gnutls_read_uint32 (const opaque * data)
120{
121 uint32_t res;
122
123 memcpy (&res, data, sizeof (uint32_t));
124#ifndef WORDS_BIGENDIAN
125 res = byteswap32 (res);
126#endif
127 return res;
128}
129
130void
131_gnutls_write_uint32 (uint32_t num, opaque * data)
132{
133
134#ifndef WORDS_BIGENDIAN
135 num = byteswap32 (num);
136#endif
137 memcpy (data, &num, sizeof (uint32_t));
138}
139
140uint16_t
141_gnutls_read_uint16 (const opaque * data)
142{
143 uint16_t res;
144 memcpy (&res, data, sizeof (uint16_t));
145#ifndef WORDS_BIGENDIAN
146 res = byteswap16 (res);
147#endif
148 return res;
149}
150
151void
152_gnutls_write_uint16 (uint16_t num, opaque * data)
153{
154
155#ifndef WORDS_BIGENDIAN
156 num = byteswap16 (num);
157#endif
158 memcpy (data, &num, sizeof (uint16_t));
159}
160
161uint32_t
162_gnutls_conv_uint32 (uint32_t data)
163{
164#ifndef WORDS_BIGENDIAN
165 return byteswap32 (data);
166#else
167 return data;
168#endif
169}
170
171uint16_t
172_gnutls_conv_uint16 (uint16_t data)
173{
174#ifndef WORDS_BIGENDIAN
175 return byteswap16 (data);
176#else
177 return data;
178#endif
179}
180
181uint32_t
182_gnutls_uint64touint32 (const uint64 * num)
183{
184 uint32_t ret;
185
186 memcpy (&ret, &num->i[4], 4);
187#ifndef WORDS_BIGENDIAN
188 ret = byteswap32 (ret);
189#endif
190
191 return ret;
192}
diff --git a/src/daemon/https/tls/gnutls_num.h b/src/daemon/https/tls/gnutls_num.h
new file mode 100644
index 00000000..3ab226ae
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_num.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26
27#define rotl32(x,n) (((x) << ((uint16_t)(n))) | ((x) >> (32 - (uint16_t)(n))))
28#define rotr32(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (32 - (uint16_t)(n))))
29#define rotl16(x,n) (((x) << ((uint16_t)(n))) | ((x) >> (16 - (uint16_t)(n))))
30#define rotr16(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (16 - (uint16_t)(n))))
31
32#define byteswap16(x) ((rotl16(x, 8) & 0x00ff) | (rotr16(x, 8) & 0xff00))
33#define byteswap32(x) ((rotl32(x, 8) & 0x00ff00ffUL) | (rotr32(x, 8) & 0xff00ff00UL))
34
35uint32_t _gnutls_uint24touint32 (uint24 num);
36uint24 _gnutls_uint32touint24 (uint32_t num);
37uint32_t _gnutls_read_uint32 (const opaque * data);
38uint16_t _gnutls_read_uint16 (const opaque * data);
39uint32_t _gnutls_conv_uint32 (uint32_t data);
40uint16_t _gnutls_conv_uint16 (uint16_t data);
41uint32_t _gnutls_read_uint24 (const opaque * data);
42void _gnutls_write_uint24 (uint32_t num, opaque * data);
43void _gnutls_write_uint32 (uint32_t num, opaque * data);
44void _gnutls_write_uint16 (uint16_t num, opaque * data);
45uint32_t _gnutls_uint64touint32 (const uint64 *);
46
47int _gnutls_uint64pp (uint64 *);
48# define _gnutls_uint64zero(x) x.i[0] = x.i[1] = x.i[2] = x.i[3] = x.i[4] = x.i[5] = x.i[6] = x.i[7] = 0
49# define UINT64DATA(x) x.i
diff --git a/src/daemon/https/tls/gnutls_pk.c b/src/daemon/https/tls/gnutls_pk.c
new file mode 100644
index 00000000..cfec9463
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_pk.c
@@ -0,0 +1,915 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains the functions needed for RSA/DSA public key
26 * encryption and signatures.
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_mpi.h>
31#include <gnutls_pk.h>
32#include <gnutls_errors.h>
33#include <gnutls_datum.h>
34#include <gnutls_global.h>
35#include <gnutls_num.h>
36#include "debug.h"
37#include <gc.h>
38
39/* x509 */
40#include "common.h"
41#include "mpi.h"
42
43static int _gnutls_pk_encrypt (int algo, mpi_t * resarr, mpi_t data,
44 mpi_t * pkey, int pkey_len);
45static int _gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash,
46 mpi_t * pkey, int);
47static int _gnutls_pk_verify (int algo, mpi_t hash, mpi_t * data,
48 mpi_t * pkey, int);
49static int _gnutls_pk_decrypt (int algo, mpi_t * resarr, mpi_t data,
50 mpi_t * pkey, int);
51
52
53/* Do PKCS-1 RSA encryption.
54 * params is modulus, public exp.
55 */
56int
57_gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
58 const gnutls_datum_t * plaintext,
59 mpi_t * params, unsigned params_len,
60 unsigned btype)
61{
62 unsigned int i, pad;
63 int ret;
64 mpi_t m, res;
65 opaque *edata, *ps;
66 size_t k, psize;
67 size_t mod_bits;
68
69 mod_bits = _gnutls_mpi_get_nbits (params[0]);
70 k = mod_bits / 8;
71 if (mod_bits % 8 != 0)
72 k++;
73
74 if (plaintext->size > k - 11)
75 {
76 gnutls_assert ();
77 return GNUTLS_E_PK_ENCRYPTION_FAILED;
78 }
79
80 edata = gnutls_alloca (k);
81 if (edata == NULL)
82 {
83 gnutls_assert ();
84 return GNUTLS_E_MEMORY_ERROR;
85 }
86
87 /* EB = 00||BT||PS||00||D
88 * (use block type 'btype')
89 */
90
91 edata[0] = 0;
92 edata[1] = btype;
93 psize = k - 3 - plaintext->size;
94
95 ps = &edata[2];
96 switch (btype)
97 {
98 case 2:
99 /* using public key */
100 if (params_len < RSA_PUBLIC_PARAMS)
101 {
102 gnutls_assert ();
103 gnutls_afree (edata);
104 return GNUTLS_E_INTERNAL_ERROR;
105 }
106
107 if (gc_pseudo_random (ps, psize) != GC_OK)
108 {
109 gnutls_assert ();
110 gnutls_afree (edata);
111 return GNUTLS_E_RANDOM_FAILED;
112 }
113 for (i = 0; i < psize; i++)
114 while (ps[i] == 0)
115 {
116 if (gc_pseudo_random (&ps[i], 1) != GC_OK)
117 {
118 gnutls_assert ();
119 gnutls_afree (edata);
120 return GNUTLS_E_RANDOM_FAILED;
121 }
122 }
123 break;
124 case 1:
125 /* using private key */
126
127 if (params_len < RSA_PRIVATE_PARAMS)
128 {
129 gnutls_assert ();
130 gnutls_afree (edata);
131 return GNUTLS_E_INTERNAL_ERROR;
132 }
133
134 for (i = 0; i < psize; i++)
135 ps[i] = 0xff;
136 break;
137 default:
138 gnutls_assert ();
139 gnutls_afree (edata);
140 return GNUTLS_E_INTERNAL_ERROR;
141 }
142
143 ps[psize] = 0;
144 memcpy (&ps[psize + 1], plaintext->data, plaintext->size);
145
146 if (_gnutls_mpi_scan_nz (&m, edata, &k) != 0)
147 {
148 gnutls_assert ();
149 gnutls_afree (edata);
150 return GNUTLS_E_MPI_SCAN_FAILED;
151 }
152 gnutls_afree (edata);
153
154 if (btype == 2) /* encrypt */
155 ret = _gnutls_pk_encrypt (GCRY_PK_RSA, &res, m, params, params_len);
156 else /* sign */
157 ret = _gnutls_pk_sign (GCRY_PK_RSA, &res, m, params, params_len);
158
159 _gnutls_mpi_release (&m);
160
161 if (ret < 0)
162 {
163 gnutls_assert ();
164 return ret;
165 }
166
167 _gnutls_mpi_print (NULL, &psize, res);
168
169 if (psize < k)
170 {
171 /* padding psize */
172 pad = k - psize;
173 psize = k;
174 }
175 else if (psize == k)
176 {
177 pad = 0;
178 }
179 else
180 { /* psize > k !!! */
181 /* This is an impossible situation */
182 gnutls_assert ();
183 _gnutls_mpi_release (&res);
184 return GNUTLS_E_INTERNAL_ERROR;
185 }
186
187 ciphertext->data = gnutls_malloc (psize);
188 if (ciphertext->data == NULL)
189 {
190 gnutls_assert ();
191 _gnutls_mpi_release (&res);
192 return GNUTLS_E_MEMORY_ERROR;
193 }
194 _gnutls_mpi_print (&ciphertext->data[pad], &psize, res);
195 for (i = 0; i < pad; i++)
196 ciphertext->data[i] = 0;
197
198 ciphertext->size = k;
199
200 _gnutls_mpi_release (&res);
201
202 return 0;
203}
204
205
206/* Do PKCS-1 RSA decryption.
207 * params is modulus, public exp., private key
208 * Can decrypt block type 1 and type 2 packets.
209 */
210int
211_gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
212 const gnutls_datum_t * ciphertext,
213 mpi_t * params, unsigned params_len,
214 unsigned btype)
215{
216 unsigned k, i;
217 int ret;
218 mpi_t c, res;
219 opaque *edata;
220 size_t esize, mod_bits;
221
222 mod_bits = _gnutls_mpi_get_nbits (params[0]);
223 k = mod_bits / 8;
224 if (mod_bits % 8 != 0)
225 k++;
226
227 esize = ciphertext->size;
228
229 if (esize != k)
230 {
231 gnutls_assert ();
232 return GNUTLS_E_PK_DECRYPTION_FAILED;
233 }
234
235 if (_gnutls_mpi_scan_nz (&c, ciphertext->data, &esize) != 0)
236 {
237 gnutls_assert ();
238 return GNUTLS_E_MPI_SCAN_FAILED;
239 }
240
241 /* we can use btype to see if the private key is
242 * available.
243 */
244 if (btype == 2)
245 ret = _gnutls_pk_decrypt (GCRY_PK_RSA, &res, c, params, params_len);
246 else
247 {
248 ret = _gnutls_pk_encrypt (GCRY_PK_RSA, &res, c, params, params_len);
249 }
250 _gnutls_mpi_release (&c);
251
252 if (ret < 0)
253 {
254 gnutls_assert ();
255 return ret;
256 }
257
258 _gnutls_mpi_print (NULL, &esize, res);
259 edata = gnutls_alloca (esize + 1);
260 if (edata == NULL)
261 {
262 gnutls_assert ();
263 _gnutls_mpi_release (&res);
264 return GNUTLS_E_MEMORY_ERROR;
265 }
266 _gnutls_mpi_print (&edata[1], &esize, res);
267
268 _gnutls_mpi_release (&res);
269
270 /* EB = 00||BT||PS||00||D
271 * (use block type 'btype')
272 *
273 * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
274 * avoid attacks similar to the one described by Bleichenbacher in:
275 * "Chosen Ciphertext Attacks against Protocols Based on RSA
276 * Encryption Standard PKCS #1".
277 */
278
279
280 edata[0] = 0;
281 esize++;
282
283 if (edata[0] != 0 || edata[1] != btype)
284 {
285 gnutls_assert ();
286 gnutls_afree (edata);
287 return GNUTLS_E_DECRYPTION_FAILED;
288 }
289
290 ret = GNUTLS_E_DECRYPTION_FAILED;
291 switch (btype)
292 {
293 case 2:
294 for (i = 2; i < esize; i++)
295 {
296 if (edata[i] == 0)
297 {
298 ret = 0;
299 break;
300 }
301 }
302 break;
303 case 1:
304 for (i = 2; i < esize; i++)
305 {
306 if (edata[i] == 0 && i > 2)
307 {
308 ret = 0;
309 break;
310 }
311 if (edata[i] != 0xff)
312 {
313 _gnutls_handshake_log ("PKCS #1 padding error");
314 /* PKCS #1 padding error. Don't use
315 GNUTLS_E_PKCS1_WRONG_PAD here. */
316 break;
317 }
318 }
319 break;
320 default:
321 gnutls_assert ();
322 gnutls_afree (edata);
323 break;
324 }
325 i++;
326
327 if (ret < 0)
328 {
329 gnutls_assert ();
330 gnutls_afree (edata);
331 return GNUTLS_E_DECRYPTION_FAILED;
332 }
333
334 if (_gnutls_sset_datum (plaintext, &edata[i], esize - i) < 0)
335 {
336 gnutls_assert ();
337 gnutls_afree (edata);
338 return GNUTLS_E_MEMORY_ERROR;
339 }
340
341 gnutls_afree (edata);
342
343 return 0;
344}
345
346
347int
348_gnutls_rsa_verify (const gnutls_datum_t * vdata,
349 const gnutls_datum_t * ciphertext, mpi_t * params,
350 int params_len, int btype)
351{
352
353 gnutls_datum_t plain;
354 int ret;
355
356 /* decrypt signature */
357 if ((ret =
358 _gnutls_pkcs1_rsa_decrypt (&plain, ciphertext, params, params_len,
359 btype)) < 0)
360 {
361 gnutls_assert ();
362 return ret;
363 }
364
365 if (plain.size != vdata->size)
366 {
367 gnutls_assert ();
368 _gnutls_free_datum (&plain);
369 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
370 }
371
372 if (memcmp (plain.data, vdata->data, plain.size) != 0)
373 {
374 gnutls_assert ();
375 _gnutls_free_datum (&plain);
376 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
377 }
378
379 _gnutls_free_datum (&plain);
380
381 return 0; /* ok */
382}
383
384/* encodes the Dss-Sig-Value structure
385 */
386static int
387encode_ber_rs (gnutls_datum_t * sig_value, mpi_t r, mpi_t s)
388{
389 ASN1_TYPE sig;
390 int result, tot_len;
391
392 if ((result =
393 asn1_create_element (_gnutls_get_gnutls_asn (),
394 "GNUTLS.DSASignatureValue",
395 &sig)) != ASN1_SUCCESS)
396 {
397 gnutls_assert ();
398 return _gnutls_asn2err (result);
399 }
400
401 result = _gnutls_x509_write_int (sig, "r", r, 1);
402 if (result < 0)
403 {
404 gnutls_assert ();
405 asn1_delete_structure (&sig);
406 return result;
407 }
408
409 result = _gnutls_x509_write_int (sig, "s", s, 1);
410 if (result < 0)
411 {
412 gnutls_assert ();
413 asn1_delete_structure (&sig);
414 return result;
415 }
416
417 tot_len = 0;
418
419 result = _gnutls_x509_der_encode (sig, "", sig_value, 0);
420
421 asn1_delete_structure (&sig);
422
423 if (result < 0)
424 {
425 gnutls_assert ();
426 return result;
427 }
428
429 return 0;
430}
431
432
433/* Do DSA signature calculation. params is p, q, g, y, x in that order.
434 */
435int
436_gnutls_dsa_sign (gnutls_datum_t * signature,
437 const gnutls_datum_t * hash, mpi_t * params,
438 unsigned params_len)
439{
440 mpi_t rs[2], mdata;
441 int ret;
442 size_t k;
443
444 k = hash->size;
445 if (k < 20)
446 { /* SHA1 or better only */
447 gnutls_assert ();
448 return GNUTLS_E_PK_SIGN_FAILED;
449 }
450
451 if (_gnutls_mpi_scan_nz (&mdata, hash->data, &k) != 0)
452 {
453 gnutls_assert ();
454 return GNUTLS_E_MPI_SCAN_FAILED;
455 }
456
457 ret = _gnutls_pk_sign (GCRY_PK_DSA, rs, mdata, params, params_len);
458 /* rs[0], rs[1] now hold r,s */
459 _gnutls_mpi_release (&mdata);
460
461 if (ret < 0)
462 {
463 gnutls_assert ();
464 return ret;
465 }
466
467 ret = encode_ber_rs (signature, rs[0], rs[1]);
468
469 /* free r,s */
470 _gnutls_mpi_release (&rs[0]);
471 _gnutls_mpi_release (&rs[1]);
472
473 if (ret != 0)
474 {
475 gnutls_assert ();
476 return GNUTLS_E_MEMORY_ERROR;
477 }
478
479 return 0;
480}
481
482/* decodes the Dss-Sig-Value structure
483 */
484static int
485decode_ber_rs (const gnutls_datum_t * sig_value, mpi_t * r, mpi_t * s)
486{
487 ASN1_TYPE sig;
488 int result;
489
490 if ((result =
491 asn1_create_element (_gnutls_get_gnutls_asn (),
492 "GNUTLS.DSASignatureValue",
493 &sig)) != ASN1_SUCCESS)
494 {
495 gnutls_assert ();
496 return _gnutls_asn2err (result);
497 }
498
499 result = asn1_der_decoding (&sig, sig_value->data, sig_value->size, NULL);
500 if (result != ASN1_SUCCESS)
501 {
502 gnutls_assert ();
503 asn1_delete_structure (&sig);
504 return _gnutls_asn2err (result);
505 }
506
507 result = _gnutls_x509_read_int (sig, "r", r);
508 if (result < 0)
509 {
510 gnutls_assert ();
511 asn1_delete_structure (&sig);
512 return result;
513 }
514
515 result = _gnutls_x509_read_int (sig, "s", s);
516 if (result < 0)
517 {
518 gnutls_assert ();
519 _gnutls_mpi_release (s);
520 asn1_delete_structure (&sig);
521 return result;
522 }
523
524 asn1_delete_structure (&sig);
525
526 return 0;
527}
528
529/* params is p, q, g, y in that order
530 */
531int
532_gnutls_dsa_verify (const gnutls_datum_t * vdata,
533 const gnutls_datum_t * sig_value, mpi_t * params,
534 int params_len)
535{
536
537 mpi_t mdata;
538 int ret;
539 size_t k;
540 mpi_t rs[2];
541
542 if (vdata->size != 20)
543 { /* sha-1 only */
544 gnutls_assert ();
545 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
546 }
547
548 if (decode_ber_rs (sig_value, &rs[0], &rs[1]) != 0)
549 {
550 gnutls_assert ();
551 return GNUTLS_E_MPI_SCAN_FAILED;
552 }
553
554 k = vdata->size;
555 if (_gnutls_mpi_scan_nz (&mdata, vdata->data, &k) != 0)
556 {
557 gnutls_assert ();
558 _gnutls_mpi_release (&rs[0]);
559 _gnutls_mpi_release (&rs[1]);
560 return GNUTLS_E_MPI_SCAN_FAILED;
561 }
562
563 /* decrypt signature */
564 ret = _gnutls_pk_verify (GCRY_PK_DSA, mdata, rs, params, params_len);
565 _gnutls_mpi_release (&mdata);
566 _gnutls_mpi_release (&rs[0]);
567 _gnutls_mpi_release (&rs[1]);
568
569 if (ret < 0)
570 {
571 gnutls_assert ();
572 return ret;
573 }
574
575 return 0; /* ok */
576}
577
578
579/* this is taken from gnupg
580 */
581
582/****************
583 * Emulate our old PK interface here - sometime in the future we might
584 * change the internal design to directly fit to libgcrypt.
585 */
586static int
587_gnutls_pk_encrypt (int algo, mpi_t * resarr, mpi_t data,
588 mpi_t * pkey, int pkey_len)
589{
590 gcry_sexp_t s_ciph, s_data, s_pkey;
591 int rc = -1;
592
593 /* make a sexp from pkey */
594 switch (algo)
595 {
596 case GCRY_PK_RSA:
597 if (pkey_len >= 2)
598 rc = gcry_sexp_build (&s_pkey, NULL,
599 "(public-key(rsa(n%m)(e%m)))",
600 pkey[0], pkey[1]);
601 break;
602
603 default:
604 gnutls_assert ();
605 return GNUTLS_E_INTERNAL_ERROR;
606 }
607
608 if (rc != 0)
609 {
610 gnutls_assert ();
611 return GNUTLS_E_INTERNAL_ERROR;
612 }
613
614 /* put the data into a simple list */
615 if (gcry_sexp_build (&s_data, NULL, "%m", data))
616 {
617 gnutls_assert ();
618 gcry_sexp_release (s_pkey);
619 return GNUTLS_E_INTERNAL_ERROR;
620 }
621
622 /* pass it to libgcrypt */
623 rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
624 gcry_sexp_release (s_data);
625 gcry_sexp_release (s_pkey);
626
627 if (rc != 0)
628 {
629 gnutls_assert ();
630 return GNUTLS_E_PK_ENCRYPTION_FAILED;
631
632 }
633 else
634 { /* add better error handling or make gnupg use S-Exp directly */
635 gcry_sexp_t list = gcry_sexp_find_token (s_ciph, "a", 0);
636 if (list == NULL)
637 {
638 gnutls_assert ();
639 gcry_sexp_release (s_ciph);
640 return GNUTLS_E_INTERNAL_ERROR;
641 }
642
643 resarr[0] = gcry_sexp_nth_mpi (list, 1, 0);
644 gcry_sexp_release (list);
645
646 if (resarr[0] == NULL)
647 {
648 gnutls_assert ();
649 gcry_sexp_release (s_ciph);
650 return GNUTLS_E_INTERNAL_ERROR;
651 }
652 }
653
654 gcry_sexp_release (s_ciph);
655 return rc;
656}
657
658static int
659_gnutls_pk_decrypt (int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey,
660 int pkey_len)
661{
662 gcry_sexp_t s_plain, s_data, s_pkey;
663 int rc = -1;
664
665 /* make a sexp from pkey */
666 switch (algo)
667 {
668 case GCRY_PK_RSA:
669 if (pkey_len >= 6)
670 rc = gcry_sexp_build (&s_pkey, NULL,
671 "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
672 pkey[0], pkey[1], pkey[2], pkey[3],
673 pkey[4], pkey[5]);
674 break;
675
676 default:
677 gnutls_assert ();
678 return GNUTLS_E_INTERNAL_ERROR;
679 }
680
681 if (rc != 0)
682 {
683 gnutls_assert ();
684 return GNUTLS_E_INTERNAL_ERROR;
685 }
686
687 /* put the data into a simple list */
688 if (gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data))
689 {
690 gnutls_assert ();
691 gcry_sexp_release (s_pkey);
692 return GNUTLS_E_INTERNAL_ERROR;
693 }
694
695 /* pass it to libgcrypt */
696 rc = gcry_pk_decrypt (&s_plain, s_data, s_pkey);
697 gcry_sexp_release (s_data);
698 gcry_sexp_release (s_pkey);
699
700 if (rc != 0)
701 {
702 gnutls_assert ();
703 return GNUTLS_E_PK_DECRYPTION_FAILED;
704
705 }
706 else
707 { /* add better error handling or make gnupg use S-Exp directly */
708 resarr[0] = gcry_sexp_nth_mpi (s_plain, 0, 0);
709
710 if (resarr[0] == NULL)
711 {
712 gnutls_assert ();
713 gcry_sexp_release (s_plain);
714 return GNUTLS_E_INTERNAL_ERROR;
715 }
716 }
717
718 gcry_sexp_release (s_plain);
719 return rc;
720}
721
722
723/* in case of DSA puts into data, r,s
724 */
725static int
726_gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash, mpi_t * pkey,
727 int pkey_len)
728{
729 gcry_sexp_t s_hash, s_key, s_sig;
730 int rc = -1;
731
732 /* make a sexp from pkey */
733 switch (algo)
734 {
735 case GCRY_PK_DSA:
736 if (pkey_len >= 5)
737 rc = gcry_sexp_build (&s_key, NULL,
738 "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
739 pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]);
740 else
741 {
742 gnutls_assert ();
743 }
744
745 break;
746 case GCRY_PK_RSA:
747 if (pkey_len >= 6)
748 rc = gcry_sexp_build (&s_key, NULL,
749 "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
750 pkey[0], pkey[1], pkey[2], pkey[3],
751 pkey[4], pkey[5]);
752 else
753 {
754 gnutls_assert ();
755 }
756 break;
757
758 default:
759 gnutls_assert ();
760 return GNUTLS_E_INTERNAL_ERROR;
761 }
762
763 if (rc != 0)
764 {
765 gnutls_assert ();
766 return GNUTLS_E_INTERNAL_ERROR;
767 }
768
769 /* put the data into a simple list */
770 if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
771 {
772 gnutls_assert ();
773 return GNUTLS_E_INTERNAL_ERROR;
774 }
775
776 /* pass it to libgcrypt */
777 rc = gcry_pk_sign (&s_sig, s_hash, s_key);
778 gcry_sexp_release (s_hash);
779 gcry_sexp_release (s_key);
780
781 if (rc != 0)
782 {
783 gnutls_assert ();
784 return GNUTLS_E_PK_SIGN_FAILED;
785
786 }
787 else
788 {
789 gcry_sexp_t list;
790
791 if (algo == GCRY_PK_DSA)
792 {
793 list = gcry_sexp_find_token (s_sig, "r", 0);
794 if (list == NULL)
795 {
796 gnutls_assert ();
797 gcry_sexp_release (s_sig);
798 return GNUTLS_E_INTERNAL_ERROR;
799 }
800
801 data[0] = gcry_sexp_nth_mpi (list, 1, 0);
802 gcry_sexp_release (list);
803
804 list = gcry_sexp_find_token (s_sig, "s", 0);
805 if (list == NULL)
806 {
807 gnutls_assert ();
808 gcry_sexp_release (s_sig);
809 return GNUTLS_E_INTERNAL_ERROR;
810 }
811
812 data[1] = gcry_sexp_nth_mpi (list, 1, 0);
813 gcry_sexp_release (list);
814 }
815 else
816 { /* GCRY_PK_RSA */
817 list = gcry_sexp_find_token (s_sig, "s", 0);
818 if (list == NULL)
819 {
820 gnutls_assert ();
821 gcry_sexp_release (s_sig);
822 return GNUTLS_E_INTERNAL_ERROR;
823 }
824
825 data[0] = gcry_sexp_nth_mpi (list, 1, 0);
826 gcry_sexp_release (list);
827 }
828 }
829
830 gcry_sexp_release (s_sig);
831 return 0;
832}
833
834
835static int
836_gnutls_pk_verify (int algo, mpi_t hash, mpi_t * data,
837 mpi_t * pkey, int pkey_len)
838{
839 gcry_sexp_t s_sig, s_hash, s_pkey;
840 int rc = -1;
841
842 /* make a sexp from pkey */
843 switch (algo)
844 {
845 case GCRY_PK_DSA:
846 if (pkey_len >= 4)
847 rc = gcry_sexp_build (&s_pkey, NULL,
848 "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
849 pkey[0], pkey[1], pkey[2], pkey[3]);
850 break;
851 case GCRY_PK_RSA:
852 if (pkey_len >= 2)
853 rc = gcry_sexp_build (&s_pkey, NULL,
854 "(public-key(rsa(n%m)(e%m)))",
855 pkey[0], pkey[1]);
856 break;
857
858 default:
859 gnutls_assert ();
860 return GNUTLS_E_INTERNAL_ERROR;
861 }
862
863 if (rc != 0)
864 {
865 gnutls_assert ();
866 return GNUTLS_E_INTERNAL_ERROR;
867 }
868
869 /* put the data into a simple list */
870 if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
871 {
872 gnutls_assert ();
873 gcry_sexp_release (s_pkey);
874 return GNUTLS_E_INTERNAL_ERROR;
875 }
876
877 switch (algo)
878 {
879 case GCRY_PK_DSA:
880 rc = gcry_sexp_build (&s_sig, NULL,
881 "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]);
882 break;
883 case GCRY_PK_RSA:
884 rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%m)))", data[0]);
885 break;
886
887 default:
888 gnutls_assert ();
889 gcry_sexp_release (s_pkey);
890 gcry_sexp_release (s_hash);
891 return GNUTLS_E_INTERNAL_ERROR;
892 }
893
894 if (rc != 0)
895 {
896 gnutls_assert ();
897 gcry_sexp_release (s_pkey);
898 gcry_sexp_release (s_hash);
899 return GNUTLS_E_INTERNAL_ERROR;
900 }
901
902 rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
903
904 gcry_sexp_release (s_sig);
905 gcry_sexp_release (s_hash);
906 gcry_sexp_release (s_pkey);
907
908 if (rc != 0)
909 {
910 gnutls_assert ();
911 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
912 }
913
914 return 0;
915}
diff --git a/src/daemon/https/tls/gnutls_pk.h b/src/daemon/https/tls/gnutls_pk.h
new file mode 100644
index 00000000..e6f37b0e
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_pk.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_PK_H
26# define GNUTLS_PK_H
27
28int _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
29 const gnutls_datum_t * plaintext,
30 mpi_t * params, unsigned params_len,
31 unsigned btype);
32int _gnutls_dsa_sign (gnutls_datum_t * signature,
33 const gnutls_datum_t * plaintext, mpi_t * params,
34 unsigned params_len);
35int _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
36 const gnutls_datum_t * ciphertext,
37 mpi_t * params, unsigned params_len,
38 unsigned btype);
39int _gnutls_rsa_verify (const gnutls_datum_t * vdata,
40 const gnutls_datum_t * ciphertext, mpi_t * params,
41 int params_len, int btype);
42int _gnutls_dsa_verify (const gnutls_datum_t * vdata,
43 const gnutls_datum_t * sig_value, mpi_t * params,
44 int params_len);
45
46#endif /* GNUTLS_PK_H */
diff --git a/src/daemon/https/tls/gnutls_priority.c b/src/daemon/https/tls/gnutls_priority.c
new file mode 100644
index 00000000..69019191
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_priority.c
@@ -0,0 +1,497 @@
1/*
2 * Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Here lies the code of the gnutls_*_set_priority() functions.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_algorithms.h"
30#include "gnutls_errors.h"
31#include <gnutls_num.h>
32
33#define MAX_ELEMENTS 48
34
35static void break_comma_list (char *etag,
36 char **broken_etag,
37 int *elements, int max_elements, char sep);
38
39/**
40 * gnutls_cipher_set_priority - Sets the priority on the ciphers supported by gnutls.
41 * @session: is a #gnutls_session_t structure.
42 * @list: is a 0 terminated list of gnutls_cipher_algorithm_t elements.
43 *
44 * Sets the priority on the ciphers supported by gnutls.
45 * Priority is higher for elements specified before others.
46 * After specifying the ciphers you want, you must append a 0.
47 * Note that the priority is set on the client. The server does
48 * not use the algorithm's priority except for disabling
49 * algorithms that were not specified.
50 *
51 * Returns 0 on success.
52 *
53 **/
54int
55gnutls_cipher_set_priority (gnutls_session_t session, const int *list)
56{
57 int num = 0, i;
58
59 while (list[num] != 0)
60 num++;
61 if (num > MAX_ALGOS)
62 num = MAX_ALGOS;
63 session->internals.priorities.cipher.algorithms = num;
64
65 for (i = 0; i < num; i++)
66 {
67 session->internals.priorities.cipher.priority[i] = list[i];
68 }
69
70 return 0;
71}
72
73inline static int
74_set_priority (priority_st * st, const int *list)
75{
76 int num = 0, i;
77
78 while (list[num] != 0)
79 num++;
80 if (num > MAX_ALGOS)
81 num = MAX_ALGOS;
82 st->algorithms = num;
83
84 for (i = 0; i < num; i++)
85 {
86 st->priority[i] = list[i];
87 }
88
89 return 0;
90
91}
92
93/**
94 * gnutls_kx_set_priority - Sets the priority on the key exchange algorithms supported by gnutls.
95 * @session: is a #gnutls_session_t structure.
96 * @list: is a 0 terminated list of gnutls_kx_algorithm_t elements.
97 *
98 * Sets the priority on the key exchange algorithms supported by gnutls.
99 * Priority is higher for elements specified before others.
100 * After specifying the algorithms you want, you must append a 0.
101 * Note that the priority is set on the client. The server does
102 * not use the algorithm's priority except for disabling
103 * algorithms that were not specified.
104 *
105 * Returns 0 on success.
106 *
107 **/
108int
109gnutls_kx_set_priority (gnutls_session_t session, const int *list)
110{
111 return _set_priority (&session->internals.priorities.kx, list);
112}
113
114/**
115 * gnutls_mac_set_priority - Sets the priority on the mac algorithms supported by gnutls.
116 * @session: is a #gnutls_session_t structure.
117 * @list: is a 0 terminated list of gnutls_mac_algorithm_t elements.
118 *
119 * Sets the priority on the mac algorithms supported by gnutls.
120 * Priority is higher for elements specified before others.
121 * After specifying the algorithms you want, you must append a 0.
122 * Note that the priority is set on the client. The server does
123 * not use the algorithm's priority except for disabling
124 * algorithms that were not specified.
125 *
126 * Returns 0 on success.
127 *
128 **/
129int
130gnutls_mac_set_priority (gnutls_session_t session, const int *list)
131{
132 return _set_priority (&session->internals.priorities.mac, list);
133}
134
135/**
136 * gnutls_compression_set_priority - Sets the priority on the compression algorithms supported by gnutls.
137 * @session: is a #gnutls_session_t structure.
138 * @list: is a 0 terminated list of gnutls_compression_method_t elements.
139 *
140 * Sets the priority on the compression algorithms supported by gnutls.
141 * Priority is higher for elements specified before others.
142 * After specifying the algorithms you want, you must append a 0.
143 * Note that the priority is set on the client. The server does
144 * not use the algorithm's priority except for disabling
145 * algorithms that were not specified.
146 *
147 * TLS 1.0 does not define any compression algorithms except
148 * NULL. Other compression algorithms are to be considered
149 * as gnutls extensions.
150 *
151 * Returns 0 on success.
152 *
153 **/
154int
155gnutls_compression_set_priority (gnutls_session_t session, const int *list)
156{
157 return _set_priority (&session->internals.priorities.compression, list);
158}
159
160/**
161 * gnutls_protocol_set_priority - Sets the priority on the protocol versions supported by gnutls.
162 * @session: is a #gnutls_session_t structure.
163 * @list: is a 0 terminated list of gnutls_protocol_t elements.
164 *
165 * Sets the priority on the protocol versions supported by gnutls.
166 * This function actually enables or disables protocols. Newer protocol
167 * versions always have highest priority.
168 *
169 * Returns 0 on success.
170 *
171 **/
172int
173gnutls_protocol_set_priority (gnutls_session_t session, const int *list)
174{
175 int ret;
176
177 ret = _set_priority (&session->internals.priorities.protocol, list);
178
179 /* set the current version to the first in the chain.
180 * This will be overridden later.
181 */
182 if (list)
183 _gnutls_set_current_version (session, list[0]);
184
185 return ret;
186}
187
188/**
189 * gnutls_certificate_type_set_priority - Sets the priority on the certificate types supported by gnutls.
190 * @session: is a #gnutls_session_t structure.
191 * @list: is a 0 terminated list of gnutls_certificate_type_t elements.
192 *
193 * Sets the priority on the certificate types supported by gnutls.
194 * Priority is higher for elements specified before others.
195 * After specifying the types you want, you must append a 0.
196 * Note that the certificate type priority is set on the client.
197 * The server does not use the cert type priority except for disabling
198 * types that were not specified.
199 *
200 * Returns 0 on success.
201 *
202 **/
203int
204gnutls_certificate_type_set_priority (gnutls_session_t session,
205 const int *list)
206{
207#ifdef ENABLE_OPENPGP
208 return _set_priority (&session->internals.priorities.cert_type, list);
209
210#else
211
212 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
213
214#endif
215}
216
217static const int protocol_priority[] = { GNUTLS_TLS1_1,
218 GNUTLS_TLS1_0,
219 0
220};
221
222static const int cipher_priority_secure256[] = { GNUTLS_CIPHER_AES_256_CBC,
223 0
224};
225
226static const int kx_priority_secure[] = { GNUTLS_KX_RSA,
227 0
228};
229
230static const int mac_priority_secure[] = { GNUTLS_MAC_SHA1,
231 0
232};
233
234static int cert_type_priority[] = { GNUTLS_CRT_X509,
235 0
236};
237
238static const int comp_priority[] = { GNUTLS_COMP_NULL,
239 0
240};
241
242typedef void (rmadd_func) (priority_st * priority_list, int alg);
243
244/**
245 * gnutls_priority_set - Sets priorities for the cipher suites supported by gnutls.
246 * @session: is a #gnutls_session_t structure.
247 * @priority: is a #gnutls_priority_t structure.
248 *
249 * Sets the priorities to use on the ciphers, key exchange methods,
250 * macs and compression methods.
251 *
252 * On success 0 is returned.
253 *
254 **/
255int
256gnutls_priority_set (gnutls_session_t session, gnutls_priority_t priority)
257{
258 if (priority == NULL)
259 {
260 gnutls_assert ();
261 return GNUTLS_E_NO_CIPHER_SUITES;
262 }
263
264 memcpy (&session->internals.priorities, priority,
265 sizeof (struct gnutls_priority_st));
266
267 return 0;
268}
269
270/**
271 * gnutls_priority_init - Sets priorities for the cipher suites supported by gnutls.
272 * @priority_cache: is a #gnutls_prioritity_t structure.
273 * @priorities: is a string describing priorities
274 * @err_pos: In case of an error this will have the position in the string the error occured
275 *
276 * Sets priorities for the ciphers, key exchange methods, macs and
277 * compression methods. This is to avoid using the
278 * gnutls_*_priority() functions.
279 *
280 * The #priorities option allows you to specify a semi-colon
281 * separated list of the cipher priorities to enable.
282 *
283 * Unless the first keyword is "NONE" the defaults are:
284 * Protocols: TLS1.1, TLS1.0, and SSL3.0.
285 * Compression: NULL.
286 * Certificate types: X.509, OpenPGP.
287 *
288 * You can also use predefined sets of ciphersuites: "PERFORMANCE"
289 * all the "secure" ciphersuites are enabled, limited to 128 bit
290 * ciphers and sorted by terms of speed performance.
291 *
292 * "NORMAL" option enables all "secure" ciphersuites. The 256-bit ciphers
293 * are included as a fallback only. The ciphers are sorted by security margin.
294 *
295 * "SECURE128" flag enables all "secure" ciphersuites with ciphers up to
296 * 128 bits, sorted by security margin.
297 *
298 * "SECURE256" flag enables all "secure" ciphersuites including the 256 bit
299 * ciphers, sorted by security margin.
300 *
301 * "EXPORT" all the ciphersuites are enabled, including the
302 * low-security 40 bit ciphers.
303 *
304 * "NONE" nothing is enabled. This disables even protocols and
305 * compression methods.
306 *
307 * Special keywords:
308 * '!' or '-' appended with an algorithm will remove this algorithm.
309 * '+' appended with an algorithm will add this algorithm.
310 * '%COMPAT' will enable compatibility features for a server.
311 *
312 * To avoid collisions in order to specify a compression algorithm in
313 * this string you have to prefix it with "COMP-", protocol versions
314 * with "VERS-" and certificate types with "CTYPE-". All other
315 * algorithms don't need a prefix.
316 *
317 * For key exchange algorithms when in NORMAL or SECURE levels the
318 * perfect forward secrecy algorithms take precendence of the other
319 * protocols. In all cases all the supported key exchange algorithms
320 * are enabled (except for the RSA-EXPORT which is only enabled in
321 * EXPORT level).
322 *
323 * Note that although one can select very long key sizes (such as 256 bits)
324 * for symmetric algorithms, to actually increase security the public key
325 * algorithms have to use longer key sizes as well.
326 *
327 * Examples: "NORMAL:!AES-128-CBC",
328 * "EXPORT:!VERS-TLS1.0:+COMP-DEFLATE:+CTYPE-OPENPGP",
329 * "NONE:+VERS-TLS1.0:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL", "NORMAL",
330 * "NORMAL:%COMPAT".
331 *
332 * Returns: On syntax error GNUTLS_E_INVALID_REQUEST is returned and
333 * 0 on success.
334 **/
335int
336gnutls_priority_init (gnutls_priority_t * priority_cache,
337 const char *priorities, const char **err_pos)
338{
339 int broken_list_size, i, j;
340 char *darg;
341 int algo;
342
343 *priority_cache = gnutls_calloc (1, sizeof (struct gnutls_priority_st));
344 if (*priority_cache == NULL)
345 {
346 gnutls_assert ();
347 return GNUTLS_E_MEMORY_ERROR;
348 }
349
350 /* set mode to "SECURE256" */
351 _set_priority (&(*priority_cache)->protocol, protocol_priority);
352 _set_priority (&(*priority_cache)->cipher, cipher_priority_secure256);
353 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
354 _set_priority (&(*priority_cache)->mac, mac_priority_secure);
355 _set_priority (&(*priority_cache)->cert_type, cert_type_priority);
356 _set_priority (&(*priority_cache)->compression, comp_priority);
357 (*priority_cache)->no_padding = 0;
358
359 return 0;
360}
361
362/**
363 * gnutls_priority_deinit - Deinitialize the priorities cache for the cipher suites supported by gnutls.
364 * @priority_cache: is a #gnutls_prioritity_t structure.
365 *
366 * Deinitializes the priority cache.
367 *
368 **/
369void
370gnutls_priority_deinit (gnutls_priority_t priority_cache)
371{
372 gnutls_free (priority_cache);
373}
374
375/**
376 * gnutls_priority_set_direct - Sets priorities for the cipher suites supported by gnutls.
377 * @session: is a #gnutls_session_t structure.
378 * @priorities: is a string describing priorities
379 * @err_pos: In case of an error this will have the position in the string the error occured
380 *
381 * Sets the priorities to use on the ciphers, key exchange methods,
382 * macs and compression methods. This function avoids keeping a
383 * priority cache and is used to directly set string priorities to a
384 * TLS session. For documentation check the gnutls_priority_init().
385 *
386 * On syntax error GNUTLS_E_INVALID_REQUEST is returned and 0 on success.
387 *
388 **/
389int
390gnutls_priority_set_direct (gnutls_session_t session,
391 const char *priorities, const char **err_pos)
392{
393 gnutls_priority_t prio;
394 int ret;
395
396 ret = gnutls_priority_init (&prio, priorities, err_pos);
397 if (ret < 0)
398 {
399 gnutls_assert ();
400 return ret;
401 }
402
403 ret = gnutls_priority_set (session, prio);
404 if (ret < 0)
405 {
406 gnutls_assert ();
407 return ret;
408 }
409
410 gnutls_priority_deinit (prio);
411
412 return 0;
413}
414
415/* Breaks a list of "xxx", "yyy", to a character array, of
416 * MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified.
417 */
418static void
419break_comma_list (char *etag,
420 char **broken_etag,
421 int *elements, int max_elements, char sep)
422{
423 char *p = etag;
424 if (sep == 0)
425 sep = ',';
426
427 *elements = 0;
428
429 do
430 {
431 broken_etag[*elements] = p;
432
433 (*elements)++;
434
435 p = strchr (p, sep);
436 if (p)
437 {
438 *p = 0;
439 p++; /* move to next entry and skip white
440 * space.
441 */
442 while (*p == ' ')
443 p++;
444 }
445 }
446 while (p != NULL && *elements < max_elements);
447}
448
449/**
450 * gnutls_set_default_priority - Sets some default priority on the cipher suites supported by gnutls.
451 * @session: is a #gnutls_session_t structure.
452 *
453 * Sets some default priority on the ciphers, key exchange methods,
454 * macs and compression methods.
455 *
456 * This is the same as calling:
457 *
458 * gnutls_priority_set_direct (session, "NORMAL", NULL);
459 *
460 * This function is kept around for backwards compatibility, but
461 * because of its wide use it is still fully supported. If you wish
462 * to allow users to provide a string that specify which ciphers to
463 * use (which is recommended), you should use
464 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
465 *
466 * Returns 0 on success.
467 **/
468int
469gnutls_set_default_priority (gnutls_session_t session)
470{
471 return gnutls_priority_set_direct (session, "NORMAL", NULL);
472}
473
474/**
475 * gnutls_set_default_export_priority - Sets some default priority on the cipher suites supported by gnutls.
476 * @session: is a #gnutls_session_t structure.
477 *
478 * Sets some default priority on the ciphers, key exchange methods, macs
479 * and compression methods. This function also includes weak algorithms.
480 *
481 * This is the same as calling:
482 *
483 * gnutls_priority_set_direct (session, "EXPORT", NULL);
484 *
485 * This function is kept around for backwards compatibility, but
486 * because of its wide use it is still fully supported. If you wish
487 * to allow users to provide a string that specify which ciphers to
488 * use (which is recommended), you should use
489 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
490 *
491 * Returns 0 on success.
492 **/
493int
494gnutls_set_default_export_priority (gnutls_session_t session)
495{
496 return gnutls_priority_set_direct (session, "EXPORT", NULL);
497}
diff --git a/src/daemon/https/tls/gnutls_record.c b/src/daemon/https/tls/gnutls_record.c
new file mode 100644
index 00000000..cacbdecc
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_record.c
@@ -0,0 +1,1204 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Functions that are record layer specific, are included in this file.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_errors.h"
30#include "debug.h"
31#include "gnutls_compress.h"
32#include "gnutls_cipher.h"
33#include "gnutls_buffers.h"
34#include "gnutls_handshake.h"
35#include "gnutls_hash_int.h"
36#include "gnutls_cipher_int.h"
37#include "gnutls_algorithms.h"
38#include "gnutls_db.h"
39#include "gnutls_auth_int.h"
40#include "gnutls_num.h"
41#include "gnutls_record.h"
42#include "gnutls_datum.h"
43#include "ext_max_record.h"
44#include <gnutls_state.h>
45#include <gnutls_dh.h>
46
47/**
48 * gnutls_protocol_get_version - Returns the version of the currently used protocol
49 * @session: is a #gnutls_session_t structure.
50 *
51 * Returns: the version of the currently used protocol.
52 **/
53gnutls_protocol_t gnutls_protocol_get_version(gnutls_session_t session)
54{
55 return session->security_parameters.version;
56}
57
58void _gnutls_set_current_version(gnutls_session_t session,
59 gnutls_protocol_t version)
60{
61 session->security_parameters.version = version;
62}
63
64/**
65 * gnutls_transport_set_lowat - Used to set the lowat value in order for select to check for pending data.
66 * @session: is a #gnutls_session_t structure.
67 * @num: is the low water value.
68 *
69 * Used to set the lowat value in order for select to check if there
70 * are pending data to socket buffer. Used only if you have changed
71 * the default low water value (default is 1). Normally you will not
72 * need that function. This function is only useful if using
73 * berkeley style sockets. Otherwise it must be called and set lowat
74 * to zero.
75 **/
76void gnutls_transport_set_lowat(gnutls_session_t session,
77 int num)
78{
79 session->internals.lowat = num;
80}
81
82/**
83 * gnutls_record_disable_padding - Used to disabled padding in TLS 1.0 and above
84 * @session: is a #gnutls_session_t structure.
85 *
86 * Used to disabled padding in TLS 1.0 and above. Normally you do
87 * not need to use this function, but there are buggy clients that
88 * complain if a server pads the encrypted data. This of course will
89 * disable protection against statistical attacks on the data.
90 *
91 * Normally only servers that require maximum compatibility with everything
92 * out there, need to call this function.
93 **/
94void gnutls_record_disable_padding(gnutls_session_t session)
95{
96 session->internals.priorities.no_padding = 1;
97}
98
99/**
100 * gnutls_transport_set_ptr - Used to set first argument of the transport functions
101 * @session: is a #gnutls_session_t structure.
102 * @ptr: is the value.
103 *
104 * Used to set the first argument of the transport function (like
105 * PUSH and PULL). In berkeley style sockets this function will set
106 * the connection handle.
107 **/
108void gnutls_transport_set_ptr(gnutls_session_t session,
109 gnutls_transport_ptr_t ptr)
110{
111 session->internals.transport_recv_ptr = ptr;
112 session->internals.transport_send_ptr = ptr;
113}
114
115/**
116 * gnutls_transport_set_ptr2 - Used to set first argument of the transport functions
117 * @session: is a #gnutls_session_t structure.
118 * @recv_ptr: is the value for the pull function
119 * @send_ptr: is the value for the push function
120 *
121 * Used to set the first argument of the transport function (like
122 * PUSH and PULL). In berkeley style sockets this function will set
123 * the connection handle. With this function you can use two
124 * different pointers for receiving and sending.
125 **/
126void gnutls_transport_set_ptr2(gnutls_session_t session,
127 gnutls_transport_ptr_t recv_ptr,
128 gnutls_transport_ptr_t send_ptr)
129{
130 session->internals.transport_send_ptr = send_ptr;
131 session->internals.transport_recv_ptr = recv_ptr;
132}
133
134/**
135 * gnutls_transport_get_ptr - Used to return the first argument of the transport functions
136 * @session: is a #gnutls_session_t structure.
137 *
138 * Used to get the first argument of the transport function (like
139 * PUSH and PULL). This must have been set using
140 * gnutls_transport_set_ptr().
141 *
142 * Returns: first argument of the transport function.
143 **/
144gnutls_transport_ptr_t gnutls_transport_get_ptr(gnutls_session_t session)
145{
146 return session->internals.transport_recv_ptr;
147}
148
149/**
150 * gnutls_transport_get_ptr2 - Used to return the first argument of the transport functions
151 * @session: is a #gnutls_session_t structure.
152 * @recv_ptr: will hold the value for the pull function
153 * @send_ptr: will hold the value for the push function
154 *
155 * Used to get the arguments of the transport functions (like PUSH
156 * and PULL). These should have been set using
157 * gnutls_transport_set_ptr2().
158 **/
159void gnutls_transport_get_ptr2(gnutls_session_t session,
160 gnutls_transport_ptr_t * recv_ptr,
161 gnutls_transport_ptr_t * send_ptr)
162{
163
164 *recv_ptr = session->internals.transport_recv_ptr;
165 *send_ptr = session->internals.transport_send_ptr;
166}
167
168/**
169 * gnutls_bye - This function terminates the current TLS/SSL connection.
170 * @session: is a #gnutls_session_t structure.
171 * @how: is an integer
172 *
173 * Terminates the current TLS/SSL connection. The connection should
174 * have been initiated using gnutls_handshake(). @how should be one
175 * of %GNUTLS_SHUT_RDWR, %GNUTLS_SHUT_WR.
176 *
177 * In case of %GNUTLS_SHUT_RDWR then the TLS connection gets
178 * terminated and further receives and sends will be disallowed. If
179 * the return value is zero you may continue using the connection.
180 * %GNUTLS_SHUT_RDWR actually sends an alert containing a close
181 * request and waits for the peer to reply with the same message.
182 *
183 * In case of %GNUTLS_SHUT_WR then the TLS connection gets terminated
184 * and further sends will be disallowed. In order to reuse the
185 * connection you should wait for an EOF from the peer.
186 * %GNUTLS_SHUT_WR sends an alert containing a close request.
187 *
188 * Note that not all implementations will properly terminate a TLS
189 * connection. Some of them, usually for performance reasons, will
190 * terminate only the underlying transport layer, thus causing a
191 * transmission error to the peer. This error cannot be
192 * distinguished from a malicious party prematurely terminating the
193 * session, thus this behavior is not recommended.
194 *
195 * This function may also return %GNUTLS_E_AGAIN or
196 * %GNUTLS_E_INTERRUPTED; cf. gnutls_record_get_direction().
197 *
198 * Returns: %GNUTLS_E_SUCCESS on success, or an error code, see
199 * function documentation for entire semantics.
200 **/
201int gnutls_bye(gnutls_session_t session,
202 gnutls_close_request_t how)
203{
204 int ret = 0;
205
206 switch (STATE)
207 {
208 case STATE0:
209 case STATE60:
210 ret = _gnutls_io_write_flush(session);
211 STATE = STATE60;
212 if (ret < 0)
213 {
214 gnutls_assert ();
215 return ret;
216 }
217
218 case STATE61:
219 ret = gnutls_alert_send(session, GNUTLS_AL_WARNING, GNUTLS_A_CLOSE_NOTIFY);
220 STATE = STATE61;
221 if (ret < 0)
222 {
223 gnutls_assert ();
224 return ret;
225 }
226
227 case STATE62:
228 STATE = STATE62;
229 if (how == GNUTLS_SHUT_RDWR)
230 {
231 do
232 {
233 _gnutls_io_clear_peeked_data(session);
234 ret = _gnutls_recv_int(session, GNUTLS_ALERT, -1, NULL, 0);
235 } while (ret == GNUTLS_E_GOT_APPLICATION_DATA);
236
237 if (ret >= 0)
238 session->internals.may_not_read = 1;
239
240 if (ret < 0)
241 {
242 gnutls_assert ();
243 return ret;
244 }
245 }
246 STATE = STATE62;
247
248 break;
249 default:
250 gnutls_assert ()
251 ;
252 return GNUTLS_E_INTERNAL_ERROR;
253 }
254
255 STATE = STATE0;
256
257 session->internals.may_not_write = 1;
258 return 0;
259}
260
261inline static void session_invalidate(gnutls_session_t session)
262{
263 session->internals.valid_connection = VALID_FALSE;
264}
265
266inline static void session_unresumable(gnutls_session_t session)
267{
268 session->internals.resumable = RESUME_FALSE;
269}
270
271/* returns 0 if session is valid
272 */
273inline static int session_is_valid(gnutls_session_t session)
274{
275 if (session->internals.valid_connection == VALID_FALSE)
276 return GNUTLS_E_INVALID_SESSION;
277
278 return 0;
279}
280
281/* Copies the record version into the headers. The
282 * version must have 2 bytes at least.
283 */
284inline static void copy_record_version(gnutls_session_t session,
285 gnutls_handshake_description_t htype,
286 opaque version[2])
287{
288 gnutls_protocol_t lver;
289
290 if (htype != GNUTLS_HANDSHAKE_CLIENT_HELLO
291 || session->internals.default_record_version[0] == 0)
292 {
293 lver = gnutls_protocol_get_version(session);
294
295 version[0] = _gnutls_version_get_major(lver);
296 version[1] = _gnutls_version_get_minor(lver);
297 }
298 else
299 {
300 version[0] = session->internals.default_record_version[0];
301 version[1] = session->internals.default_record_version[1];
302 }
303}
304
305/* This function behaves exactly like write(). The only difference is
306 * that it accepts, the gnutls_session_t and the content_type_t of data to
307 * send (if called by the user the Content is specific)
308 * It is intended to transfer data, under the current session.
309 *
310 * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
311 * This makes the function much easier to read, and more error resistant
312 * (there were cases were the old function could mess everything up).
313 * --nmav
314 *
315 * This function may accept a NULL pointer for data, and 0 for size, if
316 * and only if the previous send was interrupted for some reason.
317 *
318 */
319ssize_t _gnutls_send_int(gnutls_session_t session,
320 content_type_t type,
321 gnutls_handshake_description_t htype,
322 const void *_data,
323 size_t sizeofdata)
324{
325 uint8_t *cipher;
326 int cipher_size;
327 int retval, ret;
328 int data2send_size;
329 uint8_t headers[5];
330 const uint8_t *data = _data;
331
332 /* Do not allow null pointer if the send buffer is empty.
333 * If the previous send was interrupted then a null pointer is
334 * ok, and means to resume.
335 */
336 if (session->internals.record_send_buffer.length == 0 && (sizeofdata == 0
337 && _data == NULL))
338 {
339 gnutls_assert ();
340 return GNUTLS_E_INVALID_REQUEST;
341 }
342
343 if (type != GNUTLS_ALERT) /* alert messages are sent anyway */
344 if (session_is_valid(session) || session->internals.may_not_write != 0)
345 {
346 gnutls_assert ();
347 return GNUTLS_E_INVALID_SESSION;
348 }
349
350 headers[0] = type;
351
352 /* Use the default record version, if it is
353 * set.
354 */
355 copy_record_version(session, htype, &headers[1]);
356
357 _gnutls_record_log
358 ("REC[%x]: Sending Packet[%d] %s(%d) with length: %d\n", session,
359 (int) _gnutls_uint64touint32 (&session->connection_state.
360 write_sequence_number),
361 _gnutls_packet2str (type), type, sizeofdata);
362
363 if (sizeofdata > MAX_RECORD_SEND_SIZE)
364 data2send_size = MAX_RECORD_SEND_SIZE;
365 else
366 data2send_size = sizeofdata;
367
368 /* Only encrypt if we don't have data to send
369 * from the previous run. - probably interrupted.
370 */
371 if (session->internals.record_send_buffer.length > 0)
372 {
373 ret = _gnutls_io_write_flush(session);
374 if (ret > 0)
375 cipher_size = ret;
376 else
377 cipher_size = 0;
378
379 cipher = NULL;
380
381 retval = session->internals.record_send_buffer_user_size;
382 }
383 else
384 {
385 /* now proceed to packet encryption
386 */
387 cipher_size = data2send_size + MAX_RECORD_OVERHEAD;cipher = gnutls_malloc (cipher_size);
388 if (cipher == NULL)
389 {
390 gnutls_assert ();
391 return GNUTLS_E_MEMORY_ERROR;
392 }
393
394 cipher_size =
395 _gnutls_encrypt (session, headers, RECORD_HEADER_SIZE, data,
396 data2send_size, cipher, cipher_size, type,
397 (session->internals.priorities.no_padding ==
398 0) ? 1 : 0);
399 if (cipher_size <= 0)
400 {
401 gnutls_assert ();
402 if (cipher_size == 0)
403 cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
404 gnutls_free (cipher);
405 return cipher_size; /* error */
406 }
407
408 retval = data2send_size;
409 session->internals.record_send_buffer_user_size = data2send_size;
410
411 /* increase sequence number
412 */
413 if (_gnutls_uint64pp
414 (&session->connection_state.write_sequence_number) != 0)
415 {
416 session_invalidate (session);
417 gnutls_assert ();
418 gnutls_free (cipher);
419 return GNUTLS_E_RECORD_LIMIT_REACHED;
420 }
421
422 ret = _gnutls_io_write_buffered (session, cipher, cipher_size);
423 gnutls_free (cipher);
424 }
425
426 if (ret != cipher_size)
427 {
428 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
429 {
430 /* If we have sent any data then just return
431 * the error value. Do not invalidate the session.
432 */
433 gnutls_assert ();
434 return ret;
435 }
436
437 if (ret> 0)
438 {
439 gnutls_assert ();
440 ret = GNUTLS_E_INTERNAL_ERROR;
441 }
442 session_unresumable (session);
443 session->internals.may_not_write = 1;
444 gnutls_assert ();
445 return ret;
446 }
447
448 session->internals.record_send_buffer_user_size = 0;
449
450 _gnutls_record_log ("REC[%x]: Sent Packet[%d] %s(%d) with length: %d\n",
451 session,
452 (int) _gnutls_uint64touint32 (&session->
453 connection_state.
454 write_sequence_number),
455 _gnutls_packet2str (type), type, cipher_size);
456
457 return retval;
458}
459
460/* This function is to be called if the handshake was successfully
461 * completed. This sends a Change Cipher Spec packet to the peer.
462 */
463ssize_t _gnutls_send_change_cipher_spec(gnutls_session_t session,
464 int again)
465{
466 static const opaque data[1] =
467 {
468 GNUTLS_TYPE_CHANGE_CIPHER_SPEC };
469
470 _gnutls_handshake_log ("REC[%x]: Sent ChangeCipherSpec\n", session);
471
472 if (again == 0)
473 return _gnutls_send_int(session, GNUTLS_CHANGE_CIPHER_SPEC, -1, data, 1);
474 else
475 {
476 return _gnutls_io_write_flush(session);
477 }
478}
479
480inline static int check_recv_type(content_type_t recv_type)
481{
482 switch (recv_type)
483 {
484 case GNUTLS_CHANGE_CIPHER_SPEC:
485 case GNUTLS_ALERT:
486 case GNUTLS_HANDSHAKE:
487 case GNUTLS_APPLICATION_DATA:
488 case GNUTLS_INNER_APPLICATION:
489 return 0;
490 default:
491 gnutls_assert ()
492 ;
493 return GNUTLS_A_UNEXPECTED_MESSAGE;
494 }
495
496}
497
498/* Checks if there are pending data in the record buffers. If there are
499 * then it copies the data.
500 */
501static int check_buffers(gnutls_session_t session,
502 content_type_t type,
503 opaque * data,
504 int sizeofdata)
505{
506 if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE || type
507 == GNUTLS_INNER_APPLICATION) && _gnutls_record_buffer_get_size(type,
508 session)
509 > 0)
510 {
511 int ret, ret2;
512 ret = _gnutls_record_buffer_get(type, session, data, sizeofdata);
513 if (ret < 0)
514 {
515 gnutls_assert ();
516 return ret;
517 }
518
519 /* if the buffer just got empty */
520 if (_gnutls_record_buffer_get_size(type, session) == 0)
521 {
522 if ((ret2 = _gnutls_io_clear_peeked_data(session)) < 0)
523 {
524 gnutls_assert ();
525 return ret2;
526 }
527 }
528
529 return ret;
530 }
531
532 return 0;
533}
534
535/* Checks the record headers and returns the length, version and
536 * content type.
537 */
538static int record_check_headers(gnutls_session_t session,
539 uint8_t headers[RECORD_HEADER_SIZE],
540 content_type_t type,
541 gnutls_handshake_description_t htype,
542 /*output */content_type_t * recv_type,
543 opaque version[2],
544 uint16_t * length,
545 uint16_t * header_size)
546{
547
548 /* Read the first two bytes to determine if this is a
549 * version 2 message
550 */
551
552 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO && type == GNUTLS_HANDSHAKE
553 && headers[0] > 127)
554 {
555
556 /* if msb set and expecting handshake message
557 * it should be SSL 2 hello
558 */
559 version[0] = 3; /* assume SSL 3.0 */
560 version[1] = 0;
561
562 *length = (((headers[0] & 0x7f) << 8)) | headers[1];
563
564 /* SSL 2.0 headers */
565 *header_size = 2;
566 *recv_type = GNUTLS_HANDSHAKE; /* we accept only v2 client hello
567 */
568
569 /* in order to assist the handshake protocol.
570 * V2 compatibility is a mess.
571 */
572 session->internals.v2_hello = *length;
573
574 _gnutls_record_log ("REC[%x]: V2 packet received. Length: %d\n",
575 session, *length);
576
577 }
578 else
579 {
580 /* version 3.x */
581 *recv_type = headers[0];
582 version[0] = headers[1];
583 version[1] = headers[2];
584
585 /* No DECR_LEN, since headers has enough size.
586 */
587 *length = _gnutls_read_uint16(&headers[3]);
588 }
589
590 return 0;
591}
592
593/* Here we check if the advertized version is the one we
594 * negotiated in the handshake.
595 */
596inline static int record_check_version(gnutls_session_t session,
597 gnutls_handshake_description_t htype,
598 opaque version[2])
599{
600 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO)
601 {
602 /* Reject hello packets with major version higher than 3.
603 */
604 if (version[0] > 3)
605 {
606 gnutls_assert ();
607 _gnutls_record_log
608 ("REC[%x]: INVALID VERSION PACKET: (%d) %d.%d\n", session,
609 htype, version[0], version[1]);
610 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
611 }
612 }
613 else if (htype != GNUTLS_HANDSHAKE_SERVER_HELLO
614 && gnutls_protocol_get_version(session)
615 != _gnutls_version_get(version[0], version[1]))
616 {
617 /* Reject record packets that have a different version than the
618 * one negotiated. Note that this version is not protected by any
619 * mac. I don't really think that this check serves any purpose.
620 */
621 gnutls_assert ();
622 _gnutls_record_log ("REC[%x]: INVALID VERSION PACKET: (%d) %d.%d\n",
623 session, htype, version[0], version[1]);
624
625 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
626 }
627
628 return 0;
629}
630
631/* This function will check if the received record type is
632 * the one we actually expect.
633 */
634static int record_check_type(gnutls_session_t session,
635 content_type_t recv_type,
636 content_type_t type,
637 gnutls_handshake_description_t htype,
638 opaque * data,
639 int data_size)
640{
641
642 int ret;
643
644 if ((recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type
645 == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
646 {
647 _gnutls_record_buffer_put(type, session, (void *) data, data_size);
648 }
649 else
650 {
651 switch (recv_type)
652 {
653 case GNUTLS_ALERT:
654
655 _gnutls_record_log
656 ("REC[%x]: Alert[%d|%d] - %s - was received\n", session,
657 data[0], data[1], gnutls_alert_get_name ((int) data[1]));
658
659 session->internals.last_alert = data[1];
660
661 /* if close notify is received and
662 * the alert is not fatal
663 */
664 if (data[1] == GNUTLS_A_CLOSE_NOTIFY && data[0] != GNUTLS_AL_FATAL)
665 {
666 /* If we have been expecting for an alert do
667 */
668 session->internals.read_eof = 1;
669 return GNUTLS_E_INT_RET_0; /* EOF */
670 }
671 else
672 {
673
674 /* if the alert is FATAL or WARNING
675 * return the apropriate message
676 */
677
678 gnutls_assert ();
679 ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
680 if (data[0] == GNUTLS_AL_FATAL)
681 {
682 session_unresumable(session);
683 session_invalidate(session);
684 ret = GNUTLS_E_FATAL_ALERT_RECEIVED;
685 }
686
687 return ret;
688 }
689 break;
690
691 case GNUTLS_CHANGE_CIPHER_SPEC:
692 /* this packet is now handled in the recv_int()
693 * function
694 */
695 gnutls_assert ()
696 ;
697
698 return GNUTLS_E_UNEXPECTED_PACKET;
699
700 case GNUTLS_APPLICATION_DATA:
701 /* even if data is unexpected put it into the buffer */
702 if ((ret = _gnutls_record_buffer_put(recv_type, session, (void *) data,
703 data_size)) < 0)
704 {
705 gnutls_assert ();
706 return ret;
707 }
708
709 /* the got_application data is only returned
710 * if expecting client hello (for rehandshake
711 * reasons). Otherwise it is an unexpected packet
712 */
713 if (type == GNUTLS_ALERT || (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
714 && type == GNUTLS_HANDSHAKE))
715 return GNUTLS_E_GOT_APPLICATION_DATA;
716 else
717 {
718 gnutls_assert ();
719 return GNUTLS_E_UNEXPECTED_PACKET;
720 }
721
722 break;
723 case GNUTLS_HANDSHAKE:
724 /* This is legal if HELLO_REQUEST is received - and we are a client.
725 * If we are a server, a client may initiate a renegotiation at any time.
726 */
727 if (session->security_parameters.entity == GNUTLS_SERVER)
728 {
729 gnutls_assert ();
730 return GNUTLS_E_REHANDSHAKE;
731 }
732
733 /* If we are already in a handshake then a Hello
734 * Request is illegal. But here we don't really care
735 * since this message will never make it up here.
736 */
737
738 /* So we accept it */
739 return _gnutls_recv_hello_request(session, data, data_size);
740
741 break;
742 case GNUTLS_INNER_APPLICATION:
743 /* even if data is unexpected put it into the buffer */
744 if ((ret = _gnutls_record_buffer_put(recv_type, session, (void *) data,
745 data_size)) < 0)
746 {
747 gnutls_assert ();
748 return ret;
749 }
750 gnutls_assert ()
751 ;
752 return GNUTLS_E_UNEXPECTED_PACKET;
753 break;
754 default:
755
756 _gnutls_record_log
757 ("REC[%x]: Received Unknown packet %d expecting %d\n",
758 session, recv_type, type);
759
760 gnutls_assert ()
761 ;
762 return GNUTLS_E_INTERNAL_ERROR;
763 }
764 }
765
766 return 0;
767
768}
769
770/* This function will return the internal (per session) temporary
771 * recv buffer. If the buffer was not initialized before it will
772 * also initialize it.
773 */
774inline static int get_temp_recv_buffer(gnutls_session_t session,
775 gnutls_datum_t * tmp)
776{
777 size_t max_record_size;
778
779 if (gnutls_compression_get(session) != GNUTLS_COMP_NULL)
780 max_record_size = MAX_RECORD_RECV_SIZE + EXTRA_COMP_SIZE;
781 else
782 max_record_size = MAX_RECORD_RECV_SIZE;
783
784 /* We allocate MAX_RECORD_RECV_SIZE length
785 * because we cannot predict the output data by the record
786 * packet length (due to compression).
787 */
788
789 if (max_record_size > session->internals.recv_buffer.size
790 || session->internals.recv_buffer.data == NULL)
791 {
792
793 /* Initialize the internal buffer.
794 */
795 session->internals.recv_buffer.data
796 = gnutls_realloc(session->internals.recv_buffer.data, max_record_size);
797
798 if (session->internals.recv_buffer.data == NULL)
799 {
800 gnutls_assert ();
801 return GNUTLS_E_MEMORY_ERROR;
802 }
803
804 session->internals.recv_buffer.size = max_record_size;
805 }
806
807 tmp->data = session->internals.recv_buffer.data;
808 tmp->size = session->internals.recv_buffer.size;
809
810 return 0;
811}
812
813#define MAX_EMPTY_PACKETS_SEQUENCE 4
814
815/* This function behaves exactly like read(). The only difference is
816 * that it accepts the gnutls_session_t and the content_type_t of data to
817 * receive (if called by the user the Content is Userdata only)
818 * It is intended to receive data, under the current session.
819 *
820 * The gnutls_handshake_description_t was introduced to support SSL V2.0 client hellos.
821 */
822ssize_t _gnutls_recv_int(gnutls_session_t session,
823 content_type_t type,
824 gnutls_handshake_description_t htype,
825 opaque * data,
826 size_t sizeofdata)
827{
828 gnutls_datum_t tmp;
829 int decrypted_length;
830 opaque version[2];
831 uint8_t *headers;
832 content_type_t recv_type;
833 uint16_t length;
834 uint8_t *ciphertext;
835 uint8_t *recv_data;
836 int ret, ret2;
837 uint16_t header_size;
838 int empty_packet = 0;
839
840 if (type != GNUTLS_ALERT && (sizeofdata == 0 || data == NULL))
841 {
842 return GNUTLS_E_INVALID_REQUEST;
843 }
844
845 begin:
846
847 if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE)
848 {
849 gnutls_assert ();
850 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
851 }
852
853 if (session->internals.read_eof != 0)
854 {
855 /* if we have already read an EOF
856 */
857 return 0;
858 }
859 else if (session_is_valid(session) != 0 || session->internals.may_not_read
860 != 0)
861 {
862 gnutls_assert ();
863 return GNUTLS_E_INVALID_SESSION;
864 }
865
866 /* If we have enough data in the cache do not bother receiving
867 * a new packet. (in order to flush the cache)
868 */
869 ret = check_buffers(session, type, data, sizeofdata);
870 if (ret != 0)
871 return ret;
872
873 /* default headers for TLS 1.0
874 */
875 header_size = RECORD_HEADER_SIZE;
876
877 if ((ret = _gnutls_io_read_buffered(session, &headers, header_size, -1))
878 != header_size)
879 {
880 if (ret < 0 && gnutls_error_is_fatal(ret) == 0)
881 return ret;
882
883 session_invalidate(session);
884 if (type == GNUTLS_ALERT)
885 {
886 gnutls_assert ();
887 return 0; /* we were expecting close notify */
888 }
889 session_unresumable(session);
890 gnutls_assert ();
891 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
892 }
893
894 if ((ret = record_check_headers(session, headers, type, htype, &recv_type,
895 version, &length, &header_size)) < 0)
896 {
897 gnutls_assert ();
898 return ret;
899 }
900
901 /* Here we check if the Type of the received packet is
902 * ok.
903 */
904 if ((ret = check_recv_type(recv_type)) < 0)
905 {
906 gnutls_assert ();
907 return ret;
908 }
909
910 /* Here we check if the advertized version is the one we
911 * negotiated in the handshake.
912 */
913 if ((ret = record_check_version(session, htype, version)) < 0)
914 {
915 gnutls_assert ();
916 session_invalidate(session);
917 return ret;
918 }
919
920 _gnutls_record_log
921 ("REC[%x]: Expected Packet[%d] %s(%d) with length: %d\n", session,
922 (int) _gnutls_uint64touint32 (&session->connection_state.
923 read_sequence_number),
924 _gnutls_packet2str (type), type, sizeofdata);
925 _gnutls_record_log
926 ("REC[%x]: Received Packet[%d] %s(%d) with length: %d\n", session,
927 (int) _gnutls_uint64touint32 (&session->connection_state.
928 read_sequence_number),
929 _gnutls_packet2str (recv_type), recv_type, length);
930
931 if (length > MAX_RECV_SIZE)
932 {
933 _gnutls_record_log
934 ("REC[%x]: FATAL ERROR: Received packet with length: %d\n",
935 session, length);
936
937 session_unresumable(session);
938 session_invalidate(session);
939 gnutls_assert ();
940 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
941 }
942
943 /* check if we have that data into buffer.
944 */
945 if ((ret = _gnutls_io_read_buffered(session, &recv_data,
946 header_size + length, recv_type))
947 != header_size + length)
948 {
949 if (ret < 0 && gnutls_error_is_fatal(ret) == 0)
950 return ret;
951
952 session_unresumable(session);
953 session_invalidate(session);
954 gnutls_assert ();
955 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
956 }
957
958 /* ok now we are sure that we can read all the data - so
959 * move on !
960 */
961 _gnutls_io_clear_read_buffer(session);
962 ciphertext = &recv_data[header_size];
963
964 ret = get_temp_recv_buffer(session, &tmp);
965 if (ret < 0)
966 {
967 gnutls_assert ();
968 return ret;
969 }
970
971 /* decrypt the data we got.
972 */
973 ret = _gnutls_decrypt(session, ciphertext, length, tmp.data, tmp.size,
974 recv_type);
975 if (ret < 0)
976 {
977 session_unresumable(session);
978 session_invalidate(session);
979 gnutls_assert ();
980 return ret;
981 }
982 decrypted_length = ret;
983
984 /* Check if this is a CHANGE_CIPHER_SPEC
985 */
986 if (type == GNUTLS_CHANGE_CIPHER_SPEC && recv_type
987 == GNUTLS_CHANGE_CIPHER_SPEC)
988 {
989
990 _gnutls_record_log
991 ("REC[%x]: ChangeCipherSpec Packet was received\n", session);
992
993 if ((size_t) ret != sizeofdata)
994 { /* sizeofdata should be 1 */
995 gnutls_assert ();
996 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
997 }
998 memcpy(data, tmp.data, sizeofdata);
999
1000 return ret;
1001 }
1002
1003 _gnutls_record_log
1004 ("REC[%x]: Decrypted Packet[%d] %s(%d) with length: %d\n", session,
1005 (int) _gnutls_uint64touint32 (&session->connection_state.
1006 read_sequence_number),
1007 _gnutls_packet2str (recv_type), recv_type, decrypted_length);
1008
1009 /* increase sequence number
1010 */
1011 if (_gnutls_uint64pp(&session->connection_state.read_sequence_number) != 0)
1012 {
1013 session_invalidate(session);
1014 gnutls_assert ();
1015 return GNUTLS_E_RECORD_LIMIT_REACHED;
1016 }
1017
1018 ret = record_check_type(session, recv_type, type, htype, tmp.data,
1019 decrypted_length);
1020 if (ret < 0)
1021 {
1022 if (ret == GNUTLS_E_INT_RET_0)
1023 return 0;
1024 gnutls_assert ();
1025 return ret;
1026 }
1027
1028 /* Get Application data from buffer
1029 */
1030 if ((recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type
1031 == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
1032 {
1033
1034 ret = _gnutls_record_buffer_get(type, session, data, sizeofdata);
1035 if (ret < 0)
1036 {
1037 gnutls_assert ();
1038 return ret;
1039 }
1040
1041 /* if the buffer just got empty
1042 */
1043 if (_gnutls_record_buffer_get_size(type, session) == 0)
1044 {
1045 if ((ret2 = _gnutls_io_clear_peeked_data(session)) < 0)
1046 {
1047 gnutls_assert ();
1048 return ret2;
1049 }
1050 }
1051 }
1052 else
1053 {
1054 gnutls_assert ();
1055 return GNUTLS_E_UNEXPECTED_PACKET;
1056 /* we didn't get what we wanted to
1057 */
1058 }
1059
1060 /* (originally for) TLS 1.0 CBC protection.
1061 * Actually this code is called if we just received
1062 * an empty packet. An empty TLS packet is usually
1063 * sent to protect some vulnerabilities in the CBC mode.
1064 * In that case we go to the beginning and start reading
1065 * the next packet.
1066 */
1067 if (ret == 0)
1068 {
1069 empty_packet++;
1070 goto begin;
1071 }
1072
1073 return ret;
1074}
1075
1076/**
1077 * gnutls_record_send - sends to the peer the specified data
1078 * @session: is a #gnutls_session_t structure.
1079 * @data: contains the data to send
1080 * @sizeofdata: is the length of the data
1081 *
1082 * This function has the similar semantics with send(). The only
1083 * difference is that is accepts a GNUTLS session, and uses different
1084 * error codes.
1085 *
1086 * Note that if the send buffer is full, send() will block this
1087 * function. See the send() documentation for full information. You
1088 * can replace the default push function by using
1089 * gnutls_transport_set_ptr2() with a call to send() with a
1090 * MSG_DONTWAIT flag if blocking is a problem.
1091 *
1092 * If the EINTR is returned by the internal push function (the
1093 * default is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
1094 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1095 * call this function again, with the same parameters; alternatively
1096 * you could provide a %NULL pointer for data, and 0 for
1097 * size. cf. gnutls_record_get_direction().
1098 *
1099 * Returns: the number of bytes sent, or a negative error code. The
1100 * number of bytes sent might be less than @sizeofdata. The maximum
1101 * number of bytes this function can send in a single call depends on
1102 * the negotiated maximum record size.
1103 **/
1104ssize_t gnutls_record_send(gnutls_session_t session,
1105 const void *data,
1106 size_t sizeofdata)
1107{
1108 return _gnutls_send_int(session, GNUTLS_APPLICATION_DATA, -1, data,
1109 sizeofdata);
1110}
1111
1112/**
1113 * gnutls_record_recv - reads data from the TLS record protocol
1114 * @session: is a #gnutls_session_t structure.
1115 * @data: the buffer that the data will be read into
1116 * @sizeofdata: the number of requested bytes
1117 *
1118 * This function has the similar semantics with recv(). The only
1119 * difference is that is accepts a GNUTLS session, and uses different
1120 * error codes.
1121 *
1122 * In the special case that a server requests a renegotiation, the
1123 * client may receive an error code of %GNUTLS_E_REHANDSHAKE. This
1124 * message may be simply ignored, replied with an alert containing
1125 * NO_RENEGOTIATION, or replied with a new handshake, depending on
1126 * the client's will.
1127 *
1128 * If %EINTR is returned by the internal push function (the default
1129 * is recv()) then %GNUTLS_E_INTERRUPTED will be returned. If
1130 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1131 * call this function again to get the data. See also
1132 * gnutls_record_get_direction().
1133 *
1134 * A server may also receive %GNUTLS_E_REHANDSHAKE when a client has
1135 * initiated a handshake. In that case the server can only initiate a
1136 * handshake or terminate the connection.
1137 *
1138 * Returns: the number of bytes received and zero on EOF. A negative
1139 * error code is returned in case of an error. The number of bytes
1140 * received might be less than @sizeofdata.
1141 **/
1142ssize_t gnutls_record_recv(gnutls_session_t session,
1143 void *data,
1144 size_t sizeofdata)
1145{
1146 return _gnutls_recv_int(session, GNUTLS_APPLICATION_DATA, -1, data,
1147 sizeofdata);
1148}
1149
1150/**
1151 * gnutls_record_get_max_size - returns the maximum record size
1152 * @session: is a #gnutls_session_t structure.
1153 *
1154 * This function returns the maximum record packet size in this
1155 * connection. The maximum record size is negotiated by the client
1156 * after the first handshake message.
1157 **/
1158size_t gnutls_record_get_max_size(gnutls_session_t session)
1159{
1160 /* Recv will hold the negotiated max record size
1161 * always.
1162 */
1163 return session->security_parameters.max_record_recv_size;
1164}
1165
1166/**
1167 * gnutls_record_set_max_size - sets the maximum record size
1168 * @session: is a #gnutls_session_t structure.
1169 * @size: is the new size
1170 *
1171 * This function sets the maximum record packet size in this
1172 * connection. This property can only be set to clients. The server
1173 * may choose not to accept the requested size.
1174 *
1175 * Acceptable values are 512(=2^9), 1024(=2^10), 2048(=2^11) and
1176 * 4096(=2^12). Returns 0 on success. The requested record size does
1177 * get in effect immediately only while sending data. The receive
1178 * part will take effect after a successful handshake.
1179 *
1180 * This function uses a TLS extension called 'max record size'. Not
1181 * all TLS implementations use or even understand this extension.
1182 **/
1183ssize_t gnutls_record_set_max_size(gnutls_session_t session,
1184 size_t size)
1185{
1186 ssize_t new_size;
1187
1188 if (session->security_parameters.entity == GNUTLS_SERVER)
1189 return GNUTLS_E_INVALID_REQUEST;
1190
1191 new_size = _gnutls_mre_record2num(size);
1192
1193 if (new_size < 0)
1194 {
1195 gnutls_assert ();
1196 return new_size;
1197 }
1198
1199 session->security_parameters.max_record_send_size = size;
1200
1201 session->internals.proposed_record_size = size;
1202
1203 return 0;
1204}
diff --git a/src/daemon/https/tls/gnutls_record.h b/src/daemon/https/tls/gnutls_record.h
new file mode 100644
index 00000000..5595f32a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_record.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25ssize_t _gnutls_send_int (gnutls_session_t session, content_type_t type,
26 gnutls_handshake_description_t htype,
27 const void *data, size_t sizeofdata);
28ssize_t _gnutls_recv_int (gnutls_session_t session, content_type_t type,
29 gnutls_handshake_description_t, opaque * data,
30 size_t sizeofdata);
31ssize_t _gnutls_send_change_cipher_spec (gnutls_session_t session, int again);
32void gnutls_transport_set_lowat (gnutls_session_t session, int num);
diff --git a/src/daemon/https/tls/gnutls_rsa_export.c b/src/daemon/https/tls/gnutls_rsa_export.c
new file mode 100644
index 00000000..66fad085
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_rsa_export.c
@@ -0,0 +1,361 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains code for RSA temporary keys. These keys are
26 * only used in export cipher suites.
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_errors.h>
31#include <gnutls_datum.h>
32#include <gnutls_rsa_export.h>
33#include "debug.h"
34/* x509 */
35#include "x509.h"
36#include "privkey.h"
37
38/* This function takes a number of bits and returns a supported
39 * number of bits. Ie a number of bits that we have a prime in the
40 * dh_primes structure.
41 */
42
43#define MAX_SUPPORTED_BITS 512
44
45/* returns e and m, depends on the requested bits.
46 * We only support limited key sizes.
47 */
48const mpi_t *
49_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t rsa_params)
50{
51 if (rsa_params == NULL)
52 {
53 return NULL;
54 }
55
56 return rsa_params->params;
57
58}
59
60/* resarr will contain: modulus(0), public exponent(1), private exponent(2),
61 * prime1 - p (3), prime2 - q(4), u (5).
62 */
63int
64_gnutls_rsa_generate_params (mpi_t * resarr, int *resarr_len, int bits)
65{
66
67 int ret;
68 gcry_sexp_t parms, key, list;
69
70 ret = gcry_sexp_build (&parms, NULL, "(genkey(rsa(nbits %d)))", bits);
71 if (ret != 0)
72 {
73 gnutls_assert ();
74 return GNUTLS_E_INTERNAL_ERROR;
75 }
76
77 /* generate the RSA key */
78 ret = gcry_pk_genkey (&key, parms);
79 gcry_sexp_release (parms);
80
81 if (ret != 0)
82 {
83 gnutls_assert ();
84 return GNUTLS_E_INTERNAL_ERROR;
85 }
86
87 list = gcry_sexp_find_token (key, "n", 0);
88 if (list == NULL)
89 {
90 gnutls_assert ();
91 gcry_sexp_release (key);
92 return GNUTLS_E_INTERNAL_ERROR;
93 }
94
95 resarr[0] = gcry_sexp_nth_mpi (list, 1, 0);
96 gcry_sexp_release (list);
97
98 list = gcry_sexp_find_token (key, "e", 0);
99 if (list == NULL)
100 {
101 gnutls_assert ();
102 gcry_sexp_release (key);
103 return GNUTLS_E_INTERNAL_ERROR;
104 }
105
106 resarr[1] = gcry_sexp_nth_mpi (list, 1, 0);
107 gcry_sexp_release (list);
108
109 list = gcry_sexp_find_token (key, "d", 0);
110 if (list == NULL)
111 {
112 gnutls_assert ();
113 gcry_sexp_release (key);
114 return GNUTLS_E_INTERNAL_ERROR;
115 }
116
117 resarr[2] = gcry_sexp_nth_mpi (list, 1, 0);
118 gcry_sexp_release (list);
119
120 list = gcry_sexp_find_token (key, "p", 0);
121 if (list == NULL)
122 {
123 gnutls_assert ();
124 gcry_sexp_release (key);
125 return GNUTLS_E_INTERNAL_ERROR;
126 }
127
128 resarr[3] = gcry_sexp_nth_mpi (list, 1, 0);
129 gcry_sexp_release (list);
130
131
132 list = gcry_sexp_find_token (key, "q", 0);
133 if (list == NULL)
134 {
135 gnutls_assert ();
136 gcry_sexp_release (key);
137 return GNUTLS_E_INTERNAL_ERROR;
138 }
139
140 resarr[4] = gcry_sexp_nth_mpi (list, 1, 0);
141 gcry_sexp_release (list);
142
143
144 list = gcry_sexp_find_token (key, "u", 0);
145 if (list == NULL)
146 {
147 gnutls_assert ();
148 gcry_sexp_release (key);
149 return GNUTLS_E_INTERNAL_ERROR;
150 }
151
152 resarr[5] = gcry_sexp_nth_mpi (list, 1, 0);
153 gcry_sexp_release (list);
154
155 gcry_sexp_release (key);
156
157 _gnutls_dump_mpi ("n: ", resarr[0]);
158 _gnutls_dump_mpi ("e: ", resarr[1]);
159 _gnutls_dump_mpi ("d: ", resarr[2]);
160 _gnutls_dump_mpi ("p: ", resarr[3]);
161 _gnutls_dump_mpi ("q: ", resarr[4]);
162 _gnutls_dump_mpi ("u: ", resarr[5]);
163
164 *resarr_len = 6;
165
166 return 0;
167
168}
169
170
171/**
172 * gnutls_rsa_params_import_raw - This function will replace the old RSA parameters
173 * @rsa_params: Is a structure will hold the parameters
174 * @m: holds the modulus
175 * @e: holds the public exponent
176 * @d: holds the private exponent
177 * @p: holds the first prime (p)
178 * @q: holds the second prime (q)
179 * @u: holds the coefficient
180 *
181 * This function will replace the parameters in the given structure.
182 * The new parameters should be stored in the appropriate gnutls_datum.
183 *
184 **/
185int
186gnutls_rsa_params_import_raw (gnutls_rsa_params_t rsa_params,
187 const gnutls_datum_t * m,
188 const gnutls_datum_t * e,
189 const gnutls_datum_t * d,
190 const gnutls_datum_t * p,
191 const gnutls_datum_t * q,
192 const gnutls_datum_t * u)
193{
194 return gnutls_x509_privkey_import_rsa_raw (rsa_params, m, e, d, p, q, u);
195}
196
197/**
198 * gnutls_rsa_params_init - This function will initialize the temporary RSA parameters
199 * @rsa_params: Is a structure that will hold the parameters
200 *
201 * This function will initialize the temporary RSA parameters structure.
202 *
203 **/
204int
205gnutls_rsa_params_init (gnutls_rsa_params_t * rsa_params)
206{
207 int ret;
208
209 ret = gnutls_x509_privkey_init (rsa_params);
210 if (ret < 0)
211 {
212 gnutls_assert ();
213 return ret;
214 }
215
216 (*rsa_params)->crippled = 1;
217
218 return 0;
219}
220
221/**
222 * gnutls_rsa_params_deinit - This function will deinitialize the RSA parameters
223 * @rsa_params: Is a structure that holds the parameters
224 *
225 * This function will deinitialize the RSA parameters structure.
226 *
227 **/
228void
229gnutls_rsa_params_deinit (gnutls_rsa_params_t rsa_params)
230{
231 gnutls_x509_privkey_deinit (rsa_params);
232}
233
234/**
235 * gnutls_rsa_params_cpy - This function will copy an RSA parameters structure
236 * @dst: Is the destination structure, which should be initialized.
237 * @src: Is the source structure
238 *
239 * This function will copy the RSA parameters structure from source
240 * to destination.
241 *
242 **/
243int
244gnutls_rsa_params_cpy (gnutls_rsa_params_t dst, gnutls_rsa_params_t src)
245{
246 return gnutls_x509_privkey_cpy (dst, src);
247}
248
249/**
250 * gnutls_rsa_params_generate2 - This function will generate temporary RSA parameters
251 * @params: The structure where the parameters will be stored
252 * @bits: is the prime's number of bits
253 *
254 * This function will generate new temporary RSA parameters for use in
255 * RSA-EXPORT ciphersuites. This function is normally slow.
256 *
257 * Note that if the parameters are to be used in export cipher suites the
258 * bits value should be 512 or less.
259 * Also note that the generation of new RSA parameters is only useful
260 * to servers. Clients use the parameters sent by the server, thus it's
261 * no use calling this in client side.
262 *
263 **/
264int
265gnutls_rsa_params_generate2 (gnutls_rsa_params_t params, unsigned int bits)
266{
267 return gnutls_x509_privkey_generate (params, GNUTLS_PK_RSA, bits, 0);
268}
269
270/**
271 * gnutls_rsa_params_import_pkcs1 - This function will import RSA params from a pkcs1 structure
272 * @params: A structure where the parameters will be copied to
273 * @pkcs1_params: should contain a PKCS1 RSAPublicKey structure PEM or DER encoded
274 * @format: the format of params. PEM or DER.
275 *
276 * This function will extract the RSAPublicKey found in a PKCS1 formatted
277 * structure.
278 *
279 * If the structure is PEM encoded, it should have a header
280 * of "BEGIN RSA PRIVATE KEY".
281 *
282 * In case of failure a negative value will be returned, and
283 * 0 on success.
284 *
285 **/
286int
287gnutls_rsa_params_import_pkcs1 (gnutls_rsa_params_t params,
288 const gnutls_datum_t * pkcs1_params,
289 gnutls_x509_crt_fmt_t format)
290{
291 return gnutls_x509_privkey_import (params, pkcs1_params, format);
292}
293
294
295/**
296 * gnutls_rsa_params_export_pkcs1 - This function will export RSA params to a pkcs1 structure
297 * @params: Holds the RSA parameters
298 * @format: the format of output params. One of PEM or DER.
299 * @params_data: will contain a PKCS1 RSAPublicKey structure PEM or DER encoded
300 * @params_data_size: holds the size of params_data (and will be replaced by the actual size of parameters)
301 *
302 * This function will export the given RSA parameters to a PKCS1
303 * RSAPublicKey structure. If the buffer provided is not long enough to
304 * hold the output, then GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
305 *
306 * If the structure is PEM encoded, it will have a header
307 * of "BEGIN RSA PRIVATE KEY".
308 *
309 * In case of failure a negative value will be returned, and
310 * 0 on success.
311 *
312 **/
313int
314gnutls_rsa_params_export_pkcs1 (gnutls_rsa_params_t params,
315 gnutls_x509_crt_fmt_t format,
316 unsigned char *params_data,
317 size_t * params_data_size)
318{
319 return gnutls_x509_privkey_export (params, format,
320 params_data, params_data_size);
321}
322
323
324/**
325 * gnutls_rsa_params_export_raw - This function will export the RSA parameters
326 * @params: a structure that holds the rsa parameters
327 * @m: will hold the modulus
328 * @e: will hold the public exponent
329 * @d: will hold the private exponent
330 * @p: will hold the first prime (p)
331 * @q: will hold the second prime (q)
332 * @u: will hold the coefficient
333 * @bits: if non null will hold the prime's number of bits
334 *
335 * This function will export the RSA parameters found in the given
336 * structure. The new parameters will be allocated using
337 * gnutls_malloc() and will be stored in the appropriate datum.
338 *
339 **/
340int
341gnutls_rsa_params_export_raw (gnutls_rsa_params_t params,
342 gnutls_datum_t * m, gnutls_datum_t * e,
343 gnutls_datum_t * d, gnutls_datum_t * p,
344 gnutls_datum_t * q, gnutls_datum_t * u,
345 unsigned int *bits)
346{
347 int ret;
348
349 ret = gnutls_x509_privkey_export_rsa_raw (params, m, e, d, p, q, u);
350 if (ret < 0)
351 {
352 gnutls_assert ();
353 return ret;
354 }
355
356 if (bits)
357 *bits = _gnutls_mpi_get_nbits (params->params[3]);
358
359 return 0;
360
361}
diff --git a/src/daemon/https/tls/gnutls_rsa_export.h b/src/daemon/https/tls/gnutls_rsa_export.h
new file mode 100644
index 00000000..b39e5e93
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_rsa_export.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25const mpi_t *_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t);
26int _gnutls_peers_cert_less_512 (gnutls_session_t session);
27int _gnutls_rsa_generate_params (mpi_t * resarr, int *resarr_len, int bits);
diff --git a/src/daemon/https/tls/gnutls_session.c b/src/daemon/https/tls/gnutls_session.c
new file mode 100644
index 00000000..541cc699
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_session.c
@@ -0,0 +1,199 @@
1/*
2 * Copyright (C) 2000, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24#include "gnutls_int.h"
25#include "gnutls_errors.h"
26#include "debug.h"
27#include <gnutls_session_pack.h>
28#include <gnutls_datum.h>
29
30/**
31 * gnutls_session_get_data - Returns all session parameters.
32 * @session: is a #gnutls_session_t structure.
33 * @session_data: is a pointer to space to hold the session.
34 * @session_data_size: is the session_data's size, or it will be set by the function.
35 *
36 * Returns all session parameters, in order to support resuming.
37 * The client should call this, and keep the returned session, if he wants to
38 * resume that current version later by calling gnutls_session_set_data()
39 * This function must be called after a successful handshake.
40 *
41 * Resuming sessions is really useful and speedups connections after a succesful one.
42 **/
43int
44gnutls_session_get_data (gnutls_session_t session,
45 void *session_data, size_t * session_data_size)
46{
47
48 gnutls_datum_t psession;
49 int ret;
50
51 if (session->internals.resumable == RESUME_FALSE)
52 return GNUTLS_E_INVALID_SESSION;
53
54 psession.data = session_data;
55
56 ret = _gnutls_session_pack (session, &psession);
57 if (ret < 0)
58 {
59 gnutls_assert ();
60 return ret;
61 }
62 *session_data_size = psession.size;
63
64 if (psession.size > *session_data_size)
65 {
66 ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
67 goto error;
68 }
69
70 if (session_data != NULL)
71 memcpy (session_data, psession.data, psession.size);
72
73 ret = 0;
74
75error:
76 _gnutls_free_datum (&psession);
77 return ret;
78}
79
80/**
81 * gnutls_session_get_data2 - Returns all session parameters.
82 * @session: is a #gnutls_session_t structure.
83 * @session_data: is a pointer to a datum that will hold the session.
84 *
85 * Returns all session parameters, in order to support resuming.
86 * The client should call this, and keep the returned session, if he wants to
87 * resume that current version later by calling gnutls_session_set_data()
88 * This function must be called after a successful handshake. The returned
89 * datum must be freed with gnutls_free().
90 *
91 * Resuming sessions is really useful and speedups connections after a succesful one.
92 **/
93int
94gnutls_session_get_data2 (gnutls_session_t session, gnutls_datum_t * data)
95{
96
97 int ret;
98
99 if (data == NULL)
100 {
101 return GNUTLS_E_INVALID_REQUEST;
102 }
103
104 if (session->internals.resumable == RESUME_FALSE)
105 return GNUTLS_E_INVALID_SESSION;
106
107 ret = _gnutls_session_pack (session, data);
108 if (ret < 0)
109 {
110 gnutls_assert ();
111 return ret;
112 }
113
114 return 0;
115}
116
117
118/**
119 * gnutls_session_get_id - Returns session id.
120 * @session: is a #gnutls_session_t structure.
121 * @session_id: is a pointer to space to hold the session id.
122 * @session_id_size: is the session id's size, or it will be set by the function.
123 *
124 * Returns the current session id. This can be used if you want to check if
125 * the next session you tried to resume was actually resumed.
126 * This is because resumed sessions have the same sessionID with the
127 * original session.
128 *
129 * Session id is some data set by the server, that identify the current session.
130 * In TLS 1.0 and SSL 3.0 session id is always less than 32 bytes.
131 *
132 * Returns zero on success.
133 **/
134int
135gnutls_session_get_id (gnutls_session_t session,
136 void *session_id, size_t * session_id_size)
137{
138 size_t given_session_id_size = *session_id_size;
139
140 *session_id_size = session->security_parameters.session_id_size;
141
142 /* just return the session size */
143 if (session_id == NULL)
144 {
145 return 0;
146 }
147
148 if (given_session_id_size < session->security_parameters.session_id_size)
149 {
150 return GNUTLS_E_SHORT_MEMORY_BUFFER;
151 }
152
153 memcpy (session_id, &session->security_parameters.session_id,
154 *session_id_size);
155
156 return 0;
157}
158
159/**
160 * gnutls_session_set_data - Sets all session parameters
161 * @session: is a #gnutls_session_t structure.
162 * @session_data: is a pointer to space to hold the session.
163 * @session_data_size: is the session's size
164 *
165 * Sets all session parameters, in order to resume a previously established
166 * session. The session data given must be the one returned by gnutls_session_get_data().
167 * This function should be called before gnutls_handshake().
168 *
169 * Keep in mind that session resuming is advisory. The server may
170 * choose not to resume the session, thus a full handshake will be
171 * performed.
172 *
173 * Returns a negative value on error.
174 *
175 **/
176int
177gnutls_session_set_data (gnutls_session_t session,
178 const void *session_data, size_t session_data_size)
179{
180 int ret;
181 gnutls_datum_t psession;
182
183 psession.data = (opaque *) session_data;
184 psession.size = session_data_size;
185
186 if (session_data == NULL || session_data_size == 0)
187 {
188 gnutls_assert ();
189 return GNUTLS_E_INVALID_REQUEST;
190 }
191 ret = _gnutls_session_unpack (session, &psession);
192 if (ret < 0)
193 {
194 gnutls_assert ();
195 return ret;
196 }
197
198 return 0;
199}
diff --git a/src/daemon/https/tls/gnutls_session.h b/src/daemon/https/tls/gnutls_session.h
new file mode 100644
index 00000000..dae99edc
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_session.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
diff --git a/src/daemon/https/tls/gnutls_session_pack.c b/src/daemon/https/tls/gnutls_session_pack.c
new file mode 100644
index 00000000..f18fe97a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_session_pack.c
@@ -0,0 +1,1204 @@
1/*
2 * Copyright (C) 2000, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Contains functions that are supposed to pack and unpack session data,
26 * before and after they are sent to the database backend.
27 */
28
29#include <gnutls_int.h>
30#ifdef ENABLE_SRP
31# include <auth_srp.h>
32#endif
33#ifdef ENABLE_PSK
34# include <auth_psk.h>
35#endif
36#include <auth_anon.h>
37#include <auth_cert.h>
38#include <gnutls_errors.h>
39#include <gnutls_auth_int.h>
40#include <gnutls_session_pack.h>
41#include <gnutls_datum.h>
42#include <gnutls_num.h>
43
44#define PACK_HEADER_SIZE 1
45#define MAX_SEC_PARAMS 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)+165
46static int pack_certificate_auth_info (gnutls_session_t,
47 gnutls_datum_t * packed_session);
48static int unpack_certificate_auth_info (gnutls_session_t,
49 const gnutls_datum_t *
50 packed_session);
51
52static int unpack_srp_auth_info (gnutls_session_t session,
53 const gnutls_datum_t * packed_session);
54static int pack_srp_auth_info (gnutls_session_t session,
55 gnutls_datum_t * packed_session);
56
57static int unpack_psk_auth_info (gnutls_session_t session,
58 const gnutls_datum_t * packed_session);
59static int pack_psk_auth_info (gnutls_session_t session,
60 gnutls_datum_t * packed_session);
61
62static int unpack_anon_auth_info (gnutls_session_t session,
63 const gnutls_datum_t * packed_session);
64static int pack_anon_auth_info (gnutls_session_t session,
65 gnutls_datum_t * packed_session);
66
67static int unpack_security_parameters (gnutls_session_t session,
68 const gnutls_datum_t * packed_session);
69static int pack_security_parameters (gnutls_session_t session,
70 gnutls_datum_t * packed_session);
71
72
73/* Since auth_info structures contain malloced data, this function
74 * is required in order to pack these structures in a vector in
75 * order to store them to the DB.
76 *
77 * packed_session will contain the session data.
78 *
79 * The data will be in a platform independent format.
80 */
81int
82_gnutls_session_pack (gnutls_session_t session,
83 gnutls_datum_t * packed_session)
84{
85 int ret;
86
87 if (packed_session == NULL)
88 {
89 gnutls_assert ();
90 return GNUTLS_E_INTERNAL_ERROR;
91 }
92
93
94 switch (gnutls_auth_get_type (session))
95 {
96#ifdef ENABLE_SRP
97 case GNUTLS_CRD_SRP:
98 ret = pack_srp_auth_info (session, packed_session);
99 if (ret < 0)
100 {
101 gnutls_assert ();
102 return ret;
103 }
104 break;
105#endif
106#ifdef ENABLE_PSK
107 case GNUTLS_CRD_PSK:
108 ret = pack_psk_auth_info (session, packed_session);
109 if (ret < 0)
110 {
111 gnutls_assert ();
112 return ret;
113 }
114 break;
115#endif
116#ifdef ENABLE_ANON
117 case GNUTLS_CRD_ANON:
118 ret = pack_anon_auth_info (session, packed_session);
119 if (ret < 0)
120 {
121 gnutls_assert ();
122 return ret;
123 }
124 break;
125#endif
126 case GNUTLS_CRD_CERTIFICATE:
127 ret = pack_certificate_auth_info (session, packed_session);
128 if (ret < 0)
129 {
130 gnutls_assert ();
131 return ret;
132 }
133 break;
134 default:
135 return GNUTLS_E_INTERNAL_ERROR;
136
137 }
138
139 /* Auth_info structures copied. Now copy security_parameters_st.
140 * packed_session must have allocated space for the security parameters.
141 */
142 ret = pack_security_parameters (session, packed_session);
143 if (ret < 0)
144 {
145 gnutls_assert ();
146 _gnutls_free_datum (packed_session);
147 return ret;
148 }
149
150 return 0;
151}
152
153
154/* Load session data from a buffer.
155 */
156int
157_gnutls_session_unpack (gnutls_session_t session,
158 const gnutls_datum_t * packed_session)
159{
160 int ret;
161
162 if (packed_session == NULL || packed_session->size == 0)
163 {
164 gnutls_assert ();
165 return GNUTLS_E_INTERNAL_ERROR;
166 }
167
168 if (_gnutls_get_auth_info (session) != NULL)
169 {
170 _gnutls_free_auth_info (session);
171 }
172
173 switch (packed_session->data[0])
174 {
175#ifdef ENABLE_SRP
176 case GNUTLS_CRD_SRP:
177 ret = unpack_srp_auth_info (session, packed_session);
178 if (ret < 0)
179 {
180 gnutls_assert ();
181 return ret;
182 }
183 break;
184#endif
185#ifdef ENABLE_PSK
186 case GNUTLS_CRD_PSK:
187 ret = unpack_psk_auth_info (session, packed_session);
188 if (ret < 0)
189 {
190 gnutls_assert ();
191 return ret;
192 }
193 break;
194#endif
195#ifdef ENABLE_ANON
196 case GNUTLS_CRD_ANON:
197 ret = unpack_anon_auth_info (session, packed_session);
198 if (ret < 0)
199 {
200 gnutls_assert ();
201 return ret;
202 }
203 break;
204#endif
205 case GNUTLS_CRD_CERTIFICATE:
206 ret = unpack_certificate_auth_info (session, packed_session);
207 if (ret < 0)
208 {
209 gnutls_assert ();
210 return ret;
211 }
212 break;
213 default:
214 gnutls_assert ();
215 return GNUTLS_E_INTERNAL_ERROR;
216
217 }
218
219 /* Auth_info structures copied. Now copy security_parameters_st.
220 * packed_session must have allocated space for the security parameters.
221 */
222 ret = unpack_security_parameters (session, packed_session);
223 if (ret < 0)
224 {
225 gnutls_assert ();
226 return ret;
227 }
228
229 return 0;
230}
231
232
233/* Format:
234 * 1 byte the credentials type
235 * 4 bytes the size of the whole structure
236 * DH stuff
237 * 2 bytes the size of secret key in bits
238 * 4 bytes the size of the prime
239 * x bytes the prime
240 * 4 bytes the size of the generator
241 * x bytes the generator
242 * 4 bytes the size of the public key
243 * x bytes the public key
244 * RSA stuff
245 * 4 bytes the size of the modulus
246 * x bytes the modulus
247 * 4 bytes the size of the exponent
248 * x bytes the exponent
249 * CERTIFICATES
250 * 4 bytes the length of the certificate list
251 * 4 bytes the size of first certificate
252 * x bytes the certificate
253 * and so on...
254 */
255static int
256pack_certificate_auth_info (gnutls_session_t session,
257 gnutls_datum_t * packed_session)
258{
259 unsigned int pos = 0, i;
260 int cert_size, pack_size;
261 cert_auth_info_t info = _gnutls_get_auth_info (session);
262
263 if (info)
264 {
265 cert_size = 4;
266
267 for (i = 0; i < info->ncerts; i++)
268 cert_size += 4 + info->raw_certificate_list[i].size;
269
270 pack_size = 2 + 4 + info->dh.prime.size +
271 4 + info->dh.generator.size + 4 + info->dh.public_key.size +
272 4 + info->rsa_export.modulus.size +
273 4 + info->rsa_export.exponent.size + cert_size;
274 }
275 else
276 pack_size = 0;
277
278 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
279
280 /* calculate the size and allocate the data.
281 */
282 packed_session->data =
283 gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
284
285 if (packed_session->data == NULL)
286 {
287 gnutls_assert ();
288 return GNUTLS_E_MEMORY_ERROR;
289 }
290
291 packed_session->data[0] = GNUTLS_CRD_CERTIFICATE;
292 _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
293 pos += 4 + PACK_HEADER_SIZE;
294
295
296 if (pack_size > 0)
297 {
298
299 _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
300 pos += 2;
301
302 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
303 pos += 4 + info->dh.prime.size;
304 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
305 pos += 4 + info->dh.generator.size;
306 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
307 pos += 4 + info->dh.public_key.size;
308
309 _gnutls_write_datum32 (&packed_session->data[pos],
310 info->rsa_export.modulus);
311 pos += 4 + info->rsa_export.modulus.size;
312 _gnutls_write_datum32 (&packed_session->data[pos],
313 info->rsa_export.exponent);
314 pos += 4 + info->rsa_export.exponent.size;
315
316 _gnutls_write_uint32 (info->ncerts, &packed_session->data[pos]);
317 pos += 4;
318
319 for (i = 0; i < info->ncerts; i++)
320 {
321 _gnutls_write_datum32 (&packed_session->data[pos],
322 info->raw_certificate_list[i]);
323 pos += sizeof (uint32_t) + info->raw_certificate_list[i].size;
324 }
325 }
326
327 return 0;
328}
329
330
331/* Upack certificate info.
332 */
333static int
334unpack_certificate_auth_info (gnutls_session_t session,
335 const gnutls_datum_t * packed_session)
336{
337 int pos = 0, size, ret;
338 unsigned int i = 0, j;
339 size_t pack_size;
340 cert_auth_info_t info;
341
342 if (packed_session->data[0] != GNUTLS_CRD_CERTIFICATE)
343 {
344 gnutls_assert ();
345 return GNUTLS_E_INVALID_REQUEST;
346 }
347
348 pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
349 pos += PACK_HEADER_SIZE + 4;
350
351 if (pack_size == 0)
352 return 0; /* nothing to be done */
353
354 /* a simple check for integrity */
355 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
356 {
357 gnutls_assert ();
358 return GNUTLS_E_INVALID_REQUEST;
359 }
360
361 /* client and server have the same auth_info here
362 */
363 ret =
364 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
365 sizeof (cert_auth_info_st), 1);
366 if (ret < 0)
367 {
368 gnutls_assert ();
369 return ret;
370 }
371
372 info = _gnutls_get_auth_info (session);
373 if (info == NULL)
374 {
375 gnutls_assert ();
376 return GNUTLS_E_INTERNAL_ERROR;
377 }
378
379 info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
380 pos += 2;
381
382 size = _gnutls_read_uint32 (&packed_session->data[pos]);
383 pos += 4;
384 ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
385 if (ret < 0)
386 {
387 gnutls_assert ();
388 goto error;
389 }
390 pos += size;
391
392 size = _gnutls_read_uint32 (&packed_session->data[pos]);
393 pos += 4;
394 ret =
395 _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
396 if (ret < 0)
397 {
398 gnutls_assert ();
399 goto error;
400 }
401 pos += size;
402
403 size = _gnutls_read_uint32 (&packed_session->data[pos]);
404 pos += 4;
405 ret =
406 _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
407 size);
408 if (ret < 0)
409 {
410 gnutls_assert ();
411 goto error;
412 }
413 pos += size;
414
415 size = _gnutls_read_uint32 (&packed_session->data[pos]);
416 pos += 4;
417 ret =
418 _gnutls_set_datum (&info->rsa_export.modulus,
419 &packed_session->data[pos], size);
420 if (ret < 0)
421 {
422 gnutls_assert ();
423 goto error;
424 }
425 pos += size;
426
427 size = _gnutls_read_uint32 (&packed_session->data[pos]);
428 pos += 4;
429 ret =
430 _gnutls_set_datum (&info->rsa_export.exponent,
431 &packed_session->data[pos], size);
432 if (ret < 0)
433 {
434 gnutls_assert ();
435 goto error;
436 }
437 pos += size;
438
439 info->ncerts = _gnutls_read_uint32 (&packed_session->data[pos]);
440 pos += 4;
441
442 if (info->ncerts > 0)
443 {
444 info->raw_certificate_list =
445 gnutls_calloc (1, sizeof (gnutls_datum_t) * info->ncerts);
446 if (info->raw_certificate_list == NULL)
447 {
448 gnutls_assert ();
449 ret = GNUTLS_E_MEMORY_ERROR;
450 goto error;
451 }
452 }
453
454 for (i = 0; i < info->ncerts; i++)
455 {
456 size = _gnutls_read_uint32 (&packed_session->data[pos]);
457 pos += sizeof (uint32_t);
458
459 ret =
460 _gnutls_set_datum (&info->raw_certificate_list[i],
461 &packed_session->data[pos], size);
462 pos += size;
463
464 if (ret < 0)
465 {
466 gnutls_assert ();
467 goto error;
468 }
469 }
470
471
472 return 0;
473
474error:
475 _gnutls_free_datum (&info->dh.prime);
476 _gnutls_free_datum (&info->dh.generator);
477 _gnutls_free_datum (&info->dh.public_key);
478
479 _gnutls_free_datum (&info->rsa_export.modulus);
480 _gnutls_free_datum (&info->rsa_export.exponent);
481
482 for (j = 0; j < i; j++)
483 _gnutls_free_datum (&info->raw_certificate_list[j]);
484
485 gnutls_free (info->raw_certificate_list);
486
487 return ret;
488
489}
490
491#ifdef ENABLE_SRP
492/* Packs the SRP session authentication data.
493 */
494
495/* Format:
496 * 1 byte the credentials type
497 * 4 bytes the size of the SRP username (x)
498 * x bytes the SRP username
499 */
500static int
501pack_srp_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
502{
503 srp_server_auth_info_t info = _gnutls_get_auth_info (session);
504 int pack_size;
505
506 if (info && info->username)
507 pack_size = strlen (info->username) + 1; /* include the terminating null */
508 else
509 pack_size = 0;
510
511 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
512
513 /* calculate the size and allocate the data.
514 */
515 packed_session->data =
516 gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
517
518 if (packed_session->data == NULL)
519 {
520 gnutls_assert ();
521 return GNUTLS_E_MEMORY_ERROR;
522 }
523
524 packed_session->data[0] = GNUTLS_CRD_SRP;
525 _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
526
527 if (pack_size > 0)
528 memcpy (&packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
529 info->username, pack_size + 1);
530
531 return 0;
532}
533
534
535static int
536unpack_srp_auth_info (gnutls_session_t session,
537 const gnutls_datum_t * packed_session)
538{
539 size_t username_size;
540 int ret;
541 srp_server_auth_info_t info;
542
543 if (packed_session->data[0] != GNUTLS_CRD_SRP)
544 {
545 gnutls_assert ();
546 return GNUTLS_E_INVALID_REQUEST;
547 }
548
549 username_size =
550 _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
551
552 if (username_size == 0)
553 return 0; /* nothing to be done */
554
555 /* a simple check for integrity */
556 if (username_size + 4 + PACK_HEADER_SIZE > packed_session->size)
557 {
558 gnutls_assert ();
559 return GNUTLS_E_INVALID_REQUEST;
560 }
561
562 ret =
563 _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
564 sizeof (srp_server_auth_info_st), 1);
565 if (ret < 0)
566 {
567 gnutls_assert ();
568 return ret;
569 }
570
571 info = _gnutls_get_auth_info (session);
572 if (info == NULL)
573 {
574 gnutls_assert ();
575 return GNUTLS_E_INTERNAL_ERROR;
576 }
577
578 memcpy (info->username,
579 &packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
580 username_size);
581
582 return 0;
583}
584#endif
585
586
587#ifdef ENABLE_ANON
588/* Packs the ANON session authentication data.
589 */
590
591/* Format:
592 * 1 byte the credentials type
593 * 4 bytes the size of the whole structure
594 * 2 bytes the size of secret key in bits
595 * 4 bytes the size of the prime
596 * x bytes the prime
597 * 4 bytes the size of the generator
598 * x bytes the generator
599 * 4 bytes the size of the public key
600 * x bytes the public key
601 */
602static int
603pack_anon_auth_info (gnutls_session_t session,
604 gnutls_datum_t * packed_session)
605{
606 anon_auth_info_t info = _gnutls_get_auth_info (session);
607 int pos = 0;
608 size_t pack_size;
609
610 if (info)
611 pack_size = 2 + 4 * 3 + info->dh.prime.size +
612 info->dh.generator.size + info->dh.public_key.size;
613 else
614 pack_size = 0;
615
616 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
617
618 /* calculate the size and allocate the data.
619 */
620 packed_session->data =
621 gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
622
623 if (packed_session->data == NULL)
624 {
625 gnutls_assert ();
626 return GNUTLS_E_MEMORY_ERROR;
627 }
628
629 packed_session->data[0] = GNUTLS_CRD_ANON;
630 _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
631 pos += 4 + PACK_HEADER_SIZE;
632
633 if (pack_size > 0)
634 {
635 _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
636 pos += 2;
637
638 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
639 pos += 4 + info->dh.prime.size;
640 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
641 pos += 4 + info->dh.generator.size;
642 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
643 pos += 4 + info->dh.public_key.size;
644
645 }
646
647 return 0;
648}
649
650
651static int
652unpack_anon_auth_info (gnutls_session_t session,
653 const gnutls_datum_t * packed_session)
654{
655 size_t pack_size;
656 int pos = 0, size, ret;
657 anon_auth_info_t info;
658
659 if (packed_session->data[0] != GNUTLS_CRD_ANON)
660 {
661 gnutls_assert ();
662 return GNUTLS_E_INVALID_REQUEST;
663 }
664
665 pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
666 pos += PACK_HEADER_SIZE + 4;
667
668
669 if (pack_size == 0)
670 return 0; /* nothing to be done */
671
672 /* a simple check for integrity */
673 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
674 {
675 gnutls_assert ();
676 return GNUTLS_E_INVALID_REQUEST;
677 }
678
679 /* client and serer have the same auth_info here
680 */
681 ret =
682 _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
683 sizeof (anon_auth_info_st), 1);
684 if (ret < 0)
685 {
686 gnutls_assert ();
687 return ret;
688 }
689
690 info = _gnutls_get_auth_info (session);
691 if (info == NULL)
692 {
693 gnutls_assert ();
694 return GNUTLS_E_INTERNAL_ERROR;
695 }
696
697 info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
698 pos += 2;
699
700 size = _gnutls_read_uint32 (&packed_session->data[pos]);
701 pos += 4;
702 ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
703 if (ret < 0)
704 {
705 gnutls_assert ();
706 goto error;
707 }
708 pos += size;
709
710 size = _gnutls_read_uint32 (&packed_session->data[pos]);
711 pos += 4;
712 ret =
713 _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
714 if (ret < 0)
715 {
716 gnutls_assert ();
717 goto error;
718 }
719 pos += size;
720
721 size = _gnutls_read_uint32 (&packed_session->data[pos]);
722 pos += 4;
723 ret =
724 _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
725 size);
726 if (ret < 0)
727 {
728 gnutls_assert ();
729 goto error;
730 }
731 pos += size;
732
733 return 0;
734
735error:
736 _gnutls_free_datum (&info->dh.prime);
737 _gnutls_free_datum (&info->dh.generator);
738 _gnutls_free_datum (&info->dh.public_key);
739 return ret;
740}
741#endif /* ANON */
742
743#ifdef ENABLE_PSK
744/* Packs the PSK session authentication data.
745 */
746
747/* Format:
748 * 1 byte the credentials type
749 * 4 bytes the size of the whole structure
750 * 4 bytes the size of the PSK username (x)
751 * x bytes the PSK username
752 * 2 bytes the size of secret key in bits
753 * 4 bytes the size of the prime
754 * x bytes the prime
755 * 4 bytes the size of the generator
756 * x bytes the generator
757 * 4 bytes the size of the public key
758 * x bytes the public key
759 */
760static int
761pack_psk_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
762{
763 psk_auth_info_t info;
764 int pack_size, username_size = 0, pos;
765
766 info = _gnutls_get_auth_info (session);
767
768 if (info)
769 {
770 username_size = strlen (info->username) + 1; /* include the terminating null */
771 pack_size = username_size +
772 2 + 4 * 3 + info->dh.prime.size + info->dh.generator.size +
773 info->dh.public_key.size;
774 }
775 else
776 pack_size = 0;
777
778 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
779
780 /* calculate the size and allocate the data.
781 */
782 packed_session->data =
783 gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
784
785 if (packed_session->data == NULL)
786 {
787 gnutls_assert ();
788 return GNUTLS_E_MEMORY_ERROR;
789 }
790
791 pos = 0;
792
793 packed_session->data[pos] = GNUTLS_CRD_PSK;
794 pos++;
795
796 _gnutls_write_uint32 (pack_size, &packed_session->data[pos]);
797 pos += 4;
798
799
800 if (pack_size > 0)
801 {
802 _gnutls_write_uint32 (username_size, &packed_session->data[pos]);
803 pos += 4;
804
805 memcpy (&packed_session->data[pos], info->username, username_size);
806 pos += username_size;
807
808 _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
809 pos += 2;
810
811 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
812 pos += 4 + info->dh.prime.size;
813 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
814 pos += 4 + info->dh.generator.size;
815 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
816 pos += 4 + info->dh.public_key.size;
817
818 }
819
820
821 return 0;
822}
823
824static int
825unpack_psk_auth_info (gnutls_session_t session,
826 const gnutls_datum_t * packed_session)
827{
828 size_t username_size;
829 size_t pack_size;
830 int pos = 0, size, ret;
831 psk_auth_info_t info;
832
833 if (packed_session->data[0] != GNUTLS_CRD_PSK)
834 {
835 gnutls_assert ();
836 return GNUTLS_E_INVALID_REQUEST;
837 }
838
839 pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
840 pos += PACK_HEADER_SIZE + 4;
841
842
843 if (pack_size == 0)
844 return 0; /* nothing to be done */
845
846 /* a simple check for integrity */
847 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
848 {
849 gnutls_assert ();
850 return GNUTLS_E_INVALID_REQUEST;
851 }
852
853 /* client and serer have the same auth_info here
854 */
855 ret =
856 _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
857 sizeof (psk_auth_info_st), 1);
858 if (ret < 0)
859 {
860 gnutls_assert ();
861 return ret;
862 }
863
864 info = _gnutls_get_auth_info (session);
865 if (info == NULL)
866 {
867 gnutls_assert ();
868 return GNUTLS_E_INTERNAL_ERROR;
869 }
870
871 username_size = _gnutls_read_uint32 (&packed_session->data[pos]);
872 pos += 4;
873
874 memcpy (info->username, &packed_session->data[pos], username_size);
875 pos += username_size;
876
877 info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
878 pos += 2;
879
880 size = _gnutls_read_uint32 (&packed_session->data[pos]);
881 pos += 4;
882 ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
883 if (ret < 0)
884 {
885 gnutls_assert ();
886 goto error;
887 }
888 pos += size;
889
890 size = _gnutls_read_uint32 (&packed_session->data[pos]);
891 pos += 4;
892 ret =
893 _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
894 if (ret < 0)
895 {
896 gnutls_assert ();
897 goto error;
898 }
899 pos += size;
900
901 size = _gnutls_read_uint32 (&packed_session->data[pos]);
902 pos += 4;
903 ret =
904 _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
905 size);
906 if (ret < 0)
907 {
908 gnutls_assert ();
909 goto error;
910 }
911 pos += size;
912
913 return 0;
914
915error:
916 _gnutls_free_datum (&info->dh.prime);
917 _gnutls_free_datum (&info->dh.generator);
918 _gnutls_free_datum (&info->dh.public_key);
919 return ret;
920}
921#endif
922
923
924/* Packs the security parameters.
925 */
926
927/* Format:
928 * 4 bytes the total security data size
929 * 1 byte the entity type (client/server)
930 * 1 byte the key exchange algorithm used
931 * 1 byte the read cipher algorithm
932 * 1 byte the read mac algorithm
933 * 1 byte the read compression algorithm
934 *
935 * 1 byte the write cipher algorithm
936 * 1 byte the write mac algorithm
937 * 1 byte the write compression algorithm
938 *
939 * 1 byte the certificate type
940 * 1 byte the protocol version
941 *
942 * 2 bytes the cipher suite
943 *
944 * 48 bytes the master secret
945 *
946 * 32 bytes the client random
947 * 32 bytes the server random
948 *
949 * 1 byte the session ID size
950 * x bytes the session ID (32 bytes max)
951 *
952 * 4 bytes a timestamp
953 * -------------------
954 * MAX: 165 bytes
955 *
956 * EXTENSIONS:
957 * 2 bytes the record send size
958 * 2 bytes the record recv size
959 *
960 * 1 byte the SRP username size
961 * x bytes the SRP username (MAX_SRP_USERNAME)
962 *
963 * 2 bytes the number of server name extensions (up to MAX_SERVER_NAME_EXTENSIONS)
964 * 1 byte the first name type
965 * 2 bytes the size of the first name
966 * x bytes the first name (MAX_SERVER_NAME_SIZE)
967 * and so on...
968 *
969 * --------------------
970 * MAX: 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)
971 */
972static int
973pack_security_parameters (gnutls_session_t session,
974 gnutls_datum_t * packed_session)
975{
976 int pos = 0;
977 size_t len, init, i;
978
979 /* move after the auth info stuff.
980 */
981 init =
982 _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
983 PACK_HEADER_SIZE;
984
985 pos = init + 4; /* make some space to write later the size */
986
987 packed_session->data[pos++] = session->security_parameters.entity;
988 packed_session->data[pos++] = session->security_parameters.kx_algorithm;
989 packed_session->data[pos++] =
990 session->security_parameters.read_bulk_cipher_algorithm;
991 packed_session->data[pos++] =
992 session->security_parameters.read_mac_algorithm;
993 packed_session->data[pos++] =
994 session->security_parameters.read_compression_algorithm;
995 packed_session->data[pos++] =
996 session->security_parameters.write_bulk_cipher_algorithm;
997 packed_session->data[pos++] =
998 session->security_parameters.write_mac_algorithm;
999 packed_session->data[pos++] =
1000 session->security_parameters.write_compression_algorithm;
1001 packed_session->data[pos++] =
1002 session->security_parameters.current_cipher_suite.suite[0];
1003 packed_session->data[pos++] =
1004 session->security_parameters.current_cipher_suite.suite[1];
1005
1006 packed_session->data[pos++] = session->security_parameters.cert_type;
1007 packed_session->data[pos++] = session->security_parameters.version;
1008
1009 memcpy (&packed_session->data[pos],
1010 session->security_parameters.master_secret, TLS_MASTER_SIZE);
1011 pos += TLS_MASTER_SIZE;
1012
1013 memcpy (&packed_session->data[pos],
1014 session->security_parameters.client_random, TLS_RANDOM_SIZE);
1015 pos += TLS_RANDOM_SIZE;
1016 memcpy (&packed_session->data[pos],
1017 session->security_parameters.server_random, TLS_RANDOM_SIZE);
1018 pos += TLS_RANDOM_SIZE;
1019
1020 packed_session->data[pos++] = session->security_parameters.session_id_size;
1021 memcpy (&packed_session->data[pos], session->security_parameters.session_id,
1022 session->security_parameters.session_id_size);
1023 pos += session->security_parameters.session_id_size;
1024
1025 _gnutls_write_uint32 (session->security_parameters.timestamp,
1026 &packed_session->data[pos]);
1027 pos += 4;
1028
1029 /* Extensions */
1030 _gnutls_write_uint16 (session->security_parameters.max_record_send_size,
1031 &packed_session->data[pos]);
1032 pos += 2;
1033
1034 _gnutls_write_uint16 (session->security_parameters.max_record_recv_size,
1035 &packed_session->data[pos]);
1036 pos += 2;
1037
1038 /* SRP */
1039 len =
1040 strlen ((char *) session->security_parameters.extensions.srp_username);
1041 packed_session->data[pos++] = len;
1042 memcpy (&packed_session->data[pos],
1043 session->security_parameters.extensions.srp_username, len);
1044 pos += len;
1045
1046 _gnutls_write_uint16 (session->security_parameters.extensions.
1047 server_names_size, &packed_session->data[pos]);
1048 pos += 2;
1049
1050 for (i = 0; i < session->security_parameters.extensions.server_names_size;
1051 i++)
1052 {
1053 packed_session->data[pos++] =
1054 session->security_parameters.extensions.server_names[i].type;
1055 _gnutls_write_uint16 (session->security_parameters.extensions.
1056 server_names[i].name_length,
1057 &packed_session->data[pos]);
1058 pos += 2;
1059
1060 memcpy (&packed_session->data[pos],
1061 session->security_parameters.extensions.server_names[i].name,
1062 session->security_parameters.extensions.server_names[i].
1063 name_length);
1064 pos +=
1065 session->security_parameters.extensions.server_names[i].name_length;
1066 }
1067
1068 /* write the total size */
1069 _gnutls_write_uint32 (pos - init - 4, &packed_session->data[init]);
1070 packed_session->size += pos - init;
1071
1072 return 0;
1073}
1074
1075
1076static int
1077unpack_security_parameters (gnutls_session_t session,
1078 const gnutls_datum_t * packed_session)
1079{
1080 size_t pack_size, init, i;
1081 int pos = 0, len;
1082 time_t timestamp = time (0);
1083
1084
1085 /* skip the auth info stuff */
1086 init =
1087 _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
1088 PACK_HEADER_SIZE;
1089
1090 pos = init;
1091
1092 pack_size = _gnutls_read_uint32 (&packed_session->data[pos]);
1093 pos += 4;
1094
1095
1096 if (pack_size == 0)
1097 return GNUTLS_E_INVALID_REQUEST;
1098
1099 /* a simple check for integrity */
1100 if (pack_size > MAX_SEC_PARAMS)
1101 {
1102 gnutls_assert ();
1103 return GNUTLS_E_INVALID_REQUEST;
1104 }
1105
1106 session->internals.resumed_security_parameters.entity =
1107 packed_session->data[pos++];
1108 session->internals.resumed_security_parameters.kx_algorithm =
1109 packed_session->data[pos++];
1110 session->internals.resumed_security_parameters.read_bulk_cipher_algorithm =
1111 packed_session->data[pos++];
1112 session->internals.resumed_security_parameters.read_mac_algorithm =
1113 packed_session->data[pos++];
1114 session->internals.resumed_security_parameters.read_compression_algorithm =
1115 packed_session->data[pos++];
1116 session->internals.resumed_security_parameters.write_bulk_cipher_algorithm =
1117 packed_session->data[pos++];
1118 session->internals.resumed_security_parameters.write_mac_algorithm =
1119 packed_session->data[pos++];
1120 session->internals.resumed_security_parameters.write_compression_algorithm =
1121 packed_session->data[pos++];
1122 session->internals.resumed_security_parameters.current_cipher_suite.
1123 suite[0] = packed_session->data[pos++];
1124 session->internals.resumed_security_parameters.current_cipher_suite.
1125 suite[1] = packed_session->data[pos++];
1126
1127 session->internals.resumed_security_parameters.cert_type =
1128 packed_session->data[pos++];
1129 session->internals.resumed_security_parameters.version =
1130 packed_session->data[pos++];
1131
1132 memcpy (session->internals.resumed_security_parameters.master_secret,
1133 &packed_session->data[pos], TLS_MASTER_SIZE);
1134 pos += TLS_MASTER_SIZE;
1135
1136 memcpy (session->internals.resumed_security_parameters.client_random,
1137 &packed_session->data[pos], TLS_RANDOM_SIZE);
1138 pos += TLS_RANDOM_SIZE;
1139 memcpy (session->internals.resumed_security_parameters.server_random,
1140 &packed_session->data[pos], TLS_RANDOM_SIZE);
1141 pos += TLS_RANDOM_SIZE;
1142
1143 session->internals.resumed_security_parameters.session_id_size =
1144 packed_session->data[pos++];
1145 memcpy (session->internals.resumed_security_parameters.session_id,
1146 &packed_session->data[pos],
1147 session->internals.resumed_security_parameters.session_id_size);
1148 pos += session->internals.resumed_security_parameters.session_id_size;
1149
1150 session->internals.resumed_security_parameters.timestamp =
1151 _gnutls_read_uint32 (&packed_session->data[pos]);
1152 pos += 4;
1153
1154 if (timestamp - session->internals.resumed_security_parameters.timestamp >
1155 session->internals.expire_time
1156 || session->internals.resumed_security_parameters.timestamp > timestamp)
1157 {
1158 gnutls_assert ();
1159 return GNUTLS_E_EXPIRED;
1160 }
1161
1162 /* Extensions */
1163 session->internals.resumed_security_parameters.max_record_send_size =
1164 _gnutls_read_uint16 (&packed_session->data[pos]);
1165 pos += 2;
1166
1167 session->internals.resumed_security_parameters.max_record_recv_size =
1168 _gnutls_read_uint16 (&packed_session->data[pos]);
1169 pos += 2;
1170
1171
1172 /* SRP */
1173 len = packed_session->data[pos++]; /* srp username length */
1174 memcpy (session->internals.resumed_security_parameters.extensions.
1175 srp_username, &packed_session->data[pos], len);
1176 session->internals.resumed_security_parameters.extensions.
1177 srp_username[len] = 0;
1178 pos += len;
1179
1180 session->internals.resumed_security_parameters.extensions.
1181 server_names_size = _gnutls_read_uint16 (&packed_session->data[pos]);
1182 pos += 2;
1183 for (i = 0;
1184 i <
1185 session->internals.resumed_security_parameters.extensions.
1186 server_names_size; i++)
1187 {
1188 session->internals.resumed_security_parameters.extensions.
1189 server_names[i].type = packed_session->data[pos++];
1190 session->internals.resumed_security_parameters.extensions.
1191 server_names[i].name_length =
1192 _gnutls_read_uint16 (&packed_session->data[pos]);
1193 pos += 2;
1194
1195 memcpy (session->internals.resumed_security_parameters.extensions.
1196 server_names[i].name, &packed_session->data[pos],
1197 session->internals.resumed_security_parameters.extensions.
1198 server_names[i].name_length);
1199 pos +=
1200 session->internals.resumed_security_parameters.extensions.
1201 server_names[i].name_length;
1202 }
1203 return 0;
1204}
diff --git a/src/daemon/https/tls/gnutls_session_pack.h b/src/daemon/https/tls/gnutls_session_pack.h
new file mode 100644
index 00000000..93dd32de
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_session_pack.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_session_pack (gnutls_session_t session,
26 gnutls_datum_t * packed_session);
27int _gnutls_session_unpack (gnutls_session_t session,
28 const gnutls_datum_t * packed_session);
diff --git a/src/daemon/https/tls/gnutls_sig.c b/src/daemon/https/tls/gnutls_sig.c
new file mode 100644
index 00000000..0456438f
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_sig.c
@@ -0,0 +1,473 @@
1/*
2 * Copyright (C) 2001, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <x509_b64.h>
28#include <auth_cert.h>
29#include <gnutls_cert.h>
30#include <libtasn1.h>
31#include <gnutls_datum.h>
32#include <gnutls_mpi.h>
33#include <gnutls_global.h>
34#include <gnutls_pk.h>
35#include <debug.h>
36#include <gnutls_buffers.h>
37#include <gnutls_sig.h>
38#include <gnutls_kx.h>
39
40static int _gnutls_tls_sign (gnutls_session_t session,
41 gnutls_cert * cert,
42 gnutls_privkey * pkey,
43 const gnutls_datum_t * hash_concat,
44 gnutls_datum_t * signature);
45
46/* Generates a signature of all the previous sent packets in the
47 * handshake procedure. (20040227: now it works for SSL 3.0 as well)
48 */
49int
50_gnutls_tls_sign_hdata (gnutls_session_t session,
51 gnutls_cert * cert,
52 gnutls_privkey * pkey, gnutls_datum_t * signature)
53{
54 gnutls_datum_t dconcat;
55 int ret;
56 opaque concat[36];
57 mac_hd_t td_md5;
58 mac_hd_t td_sha;
59 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
60
61 td_sha = _gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
62 if (td_sha == NULL)
63 {
64 gnutls_assert ();
65 return GNUTLS_E_HASH_FAILED;
66 }
67
68 if (ver == GNUTLS_SSL3)
69 {
70 ret = _gnutls_generate_master (session, 1);
71 if (ret < 0)
72 {
73 gnutls_assert ();
74 return ret;
75 }
76
77 _gnutls_mac_deinit_ssl3_handshake (td_sha, &concat[16],
78 session->security_parameters.
79 master_secret, TLS_MASTER_SIZE);
80 }
81 else
82 _gnutls_hash_deinit (td_sha, &concat[16]);
83
84 switch (cert->subject_pk_algorithm)
85 {
86 case GNUTLS_PK_RSA:
87 td_md5 =
88 _gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
89 if (td_md5 == NULL)
90 {
91 gnutls_assert ();
92 return GNUTLS_E_HASH_FAILED;
93 }
94
95 if (ver == GNUTLS_SSL3)
96 _gnutls_mac_deinit_ssl3_handshake (td_md5, concat,
97 session->security_parameters.
98 master_secret, TLS_MASTER_SIZE);
99 else
100 _gnutls_hash_deinit (td_md5, concat);
101
102 dconcat.data = concat;
103 dconcat.size = 36;
104 break;
105 default:
106 gnutls_assert ();
107 return GNUTLS_E_INTERNAL_ERROR;
108 }
109 ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
110 if (ret < 0)
111 {
112 gnutls_assert ();
113 }
114
115 return ret;
116}
117
118/* Generates a signature of all the random data and the parameters.
119 * Used in DHE_* ciphersuites.
120 */
121int
122_gnutls_tls_sign_params (gnutls_session_t session,
123 gnutls_cert * cert,
124 gnutls_privkey * pkey,
125 gnutls_datum_t * params, gnutls_datum_t * signature)
126{
127 gnutls_datum_t dconcat;
128 int ret;
129 mac_hd_t td_sha;
130 opaque concat[36];
131 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
132
133 td_sha = _gnutls_hash_init (GNUTLS_MAC_SHA1);
134 if (td_sha == NULL)
135 {
136 gnutls_assert ();
137 return GNUTLS_E_HASH_FAILED;
138 }
139
140 _gnutls_hash (td_sha, session->security_parameters.client_random,
141 TLS_RANDOM_SIZE);
142 _gnutls_hash (td_sha, session->security_parameters.server_random,
143 TLS_RANDOM_SIZE);
144 _gnutls_hash (td_sha, params->data, params->size);
145
146 switch (cert->subject_pk_algorithm)
147 {
148 case GNUTLS_PK_RSA:
149 if (ver < GNUTLS_TLS1_2)
150 {
151 mac_hd_t td_md5 = _gnutls_hash_init (GNUTLS_MAC_MD5);
152 if (td_md5 == NULL)
153 {
154 gnutls_assert ();
155 return GNUTLS_E_HASH_FAILED;
156 }
157
158 _gnutls_hash (td_md5, session->security_parameters.client_random,
159 TLS_RANDOM_SIZE);
160 _gnutls_hash (td_md5, session->security_parameters.server_random,
161 TLS_RANDOM_SIZE);
162 _gnutls_hash (td_md5, params->data, params->size);
163
164 _gnutls_hash_deinit (td_md5, concat);
165 _gnutls_hash_deinit (td_sha, &concat[16]);
166
167 dconcat.size = 36;
168 }
169 else
170 {
171#if 1
172 /* Use NULL parameters. */
173 memcpy (concat,
174 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
175 15);
176 _gnutls_hash_deinit (td_sha, &concat[15]);
177 dconcat.size = 35;
178#else
179 /* No parameters field. */
180 memcpy (concat,
181 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
182 _gnutls_hash_deinit (td_sha, &concat[13]);
183 dconcat.size = 33;
184#endif
185 }
186 dconcat.data = concat;
187 break;
188 default:
189 gnutls_assert ();
190 _gnutls_hash_deinit (td_sha, NULL);
191 return GNUTLS_E_INTERNAL_ERROR;
192 }
193 ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
194 if (ret < 0)
195 {
196 gnutls_assert ();
197 }
198
199 return ret;
200
201}
202
203/* This will create a PKCS1 or DSA signature, using the given parameters, and the
204 * given data. The output will be allocated and be put in signature.
205 */
206int
207_gnutls_sign (gnutls_pk_algorithm_t algo,
208 mpi_t * params,
209 int params_size,
210 const gnutls_datum_t * data, gnutls_datum_t * signature)
211{
212 int ret;
213
214 switch (algo)
215 {
216 case GNUTLS_PK_RSA:
217 /* encrypt */
218 if ((ret =
219 _gnutls_pkcs1_rsa_encrypt (signature, data, params, params_size,
220 1)) < 0)
221 {
222 gnutls_assert ();
223 return ret;
224 }
225
226 break;
227 default:
228 gnutls_assert ();
229 return GNUTLS_E_INTERNAL_ERROR;
230 break;
231 }
232
233 return 0;
234}
235
236/* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
237 * Cert is the certificate of the corresponding private key. It is only checked if
238 * it supports signing.
239 */
240static int
241_gnutls_tls_sign (gnutls_session_t session,
242 gnutls_cert * cert,
243 gnutls_privkey * pkey,
244 const gnutls_datum_t * hash_concat,
245 gnutls_datum_t * signature)
246{
247
248 /* If our certificate supports signing
249 */
250
251 if (cert != NULL)
252 if (cert->key_usage != 0)
253 if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
254 {
255 gnutls_assert ();
256 return GNUTLS_E_KEY_USAGE_VIOLATION;
257 }
258
259 /* External signing. */
260 if (!pkey || pkey->params_size == 0)
261 {
262 if (!session->internals.sign_func)
263 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
264
265 return (*session->internals.sign_func) (session,
266 session->internals.
267 sign_func_userdata,
268 cert->cert_type, &cert->raw,
269 hash_concat, signature);
270 }
271
272 return _gnutls_sign (pkey->pk_algorithm, pkey->params, pkey->params_size,
273 hash_concat, signature);
274}
275
276static int
277_gnutls_verify_sig (gnutls_cert * cert,
278 const gnutls_datum_t * hash_concat,
279 gnutls_datum_t * signature, size_t sha1pos)
280{
281 int ret;
282 gnutls_datum_t vdata;
283
284 if (cert->version == 0 || cert == NULL)
285 { /* this is the only way to check
286 * if it is initialized
287 */
288 gnutls_assert ();
289 return GNUTLS_E_CERTIFICATE_ERROR;
290 }
291
292 /* If the certificate supports signing continue.
293 */
294 if (cert != NULL)
295 if (cert->key_usage != 0)
296 if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
297 {
298 gnutls_assert ();
299 return GNUTLS_E_KEY_USAGE_VIOLATION;
300 }
301
302 switch (cert->subject_pk_algorithm)
303 {
304 case GNUTLS_PK_RSA:
305
306 vdata.data = hash_concat->data;
307 vdata.size = hash_concat->size;
308
309 /* verify signature */
310 if ((ret = _gnutls_rsa_verify (&vdata, signature, cert->params,
311 cert->params_size, 1)) < 0)
312 {
313 gnutls_assert ();
314 return ret;
315 }
316
317 break;
318 default:
319 gnutls_assert ();
320 return GNUTLS_E_INTERNAL_ERROR;
321 }
322
323 return 0;
324}
325
326/* Verifies a TLS signature (like the one in the client certificate
327 * verify message).
328 */
329int
330_gnutls_verify_sig_hdata (gnutls_session_t session,
331 gnutls_cert * cert, gnutls_datum_t * signature)
332{
333 int ret;
334 opaque concat[36];
335 mac_hd_t td_md5;
336 mac_hd_t td_sha;
337 gnutls_datum_t dconcat;
338 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
339
340 td_md5 = _gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
341 if (td_md5 == NULL)
342 {
343 gnutls_assert ();
344 return GNUTLS_E_HASH_FAILED;
345 }
346
347 td_sha = _gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
348 if (td_sha == NULL)
349 {
350 gnutls_assert ();
351 _gnutls_hash_deinit (td_md5, NULL);
352 return GNUTLS_E_HASH_FAILED;
353 }
354
355 if (ver == GNUTLS_SSL3)
356 {
357 ret = _gnutls_generate_master (session, 1);
358 if (ret < 0)
359 {
360 gnutls_assert ();
361 return ret;
362 }
363
364 _gnutls_mac_deinit_ssl3_handshake (td_md5, concat,
365 session->security_parameters.
366 master_secret, TLS_MASTER_SIZE);
367 _gnutls_mac_deinit_ssl3_handshake (td_sha, &concat[16],
368 session->security_parameters.
369 master_secret, TLS_MASTER_SIZE);
370 }
371 else
372 {
373 _gnutls_hash_deinit (td_md5, concat);
374 _gnutls_hash_deinit (td_sha, &concat[16]);
375 }
376
377 dconcat.data = concat;
378 dconcat.size = 20 + 16; /* md5+ sha */
379
380 ret = _gnutls_verify_sig (cert, &dconcat, signature, 16);
381 if (ret < 0)
382 {
383 gnutls_assert ();
384 return ret;
385 }
386
387 return ret;
388
389}
390
391/* Generates a signature of all the random data and the parameters.
392 * Used in DHE_* ciphersuites.
393 */
394int
395_gnutls_verify_sig_params (gnutls_session_t session,
396 gnutls_cert * cert,
397 const gnutls_datum_t * params,
398 gnutls_datum_t * signature)
399{
400 gnutls_datum_t dconcat;
401 int ret;
402 mac_hd_t td_md5 = NULL;
403 mac_hd_t td_sha;
404 opaque concat[36];
405 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
406
407 if (ver < GNUTLS_TLS1_2)
408 {
409 td_md5 = _gnutls_hash_init (GNUTLS_MAC_MD5);
410 if (td_md5 == NULL)
411 {
412 gnutls_assert ();
413 return GNUTLS_E_HASH_FAILED;
414 }
415
416 _gnutls_hash (td_md5, session->security_parameters.client_random,
417 TLS_RANDOM_SIZE);
418 _gnutls_hash (td_md5, session->security_parameters.server_random,
419 TLS_RANDOM_SIZE);
420 _gnutls_hash (td_md5, params->data, params->size);
421 }
422
423 td_sha = _gnutls_hash_init (GNUTLS_MAC_SHA1);
424 if (td_sha == NULL)
425 {
426 gnutls_assert ();
427 if (td_md5)
428 _gnutls_hash_deinit (td_md5, NULL);
429 return GNUTLS_E_HASH_FAILED;
430 }
431
432 _gnutls_hash (td_sha, session->security_parameters.client_random,
433 TLS_RANDOM_SIZE);
434 _gnutls_hash (td_sha, session->security_parameters.server_random,
435 TLS_RANDOM_SIZE);
436 _gnutls_hash (td_sha, params->data, params->size);
437
438 if (ver < GNUTLS_TLS1_2)
439 {
440 _gnutls_hash_deinit (td_md5, concat);
441 _gnutls_hash_deinit (td_sha, &concat[16]);
442 dconcat.size = 36;
443 }
444 else
445 {
446#if 1
447 /* Use NULL parameters. */
448 memcpy (concat,
449 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
450 15);
451 _gnutls_hash_deinit (td_sha, &concat[15]);
452 dconcat.size = 35;
453#else
454 /* No parameters field. */
455 memcpy (concat,
456 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
457 _gnutls_hash_deinit (td_sha, &concat[13]);
458 dconcat.size = 33;
459#endif
460 }
461
462 dconcat.data = concat;
463
464 ret = _gnutls_verify_sig (cert, &dconcat, signature, dconcat.size - 20);
465 if (ret < 0)
466 {
467 gnutls_assert ();
468 return ret;
469 }
470
471 return ret;
472
473}
diff --git a/src/daemon/https/tls/gnutls_sig.h b/src/daemon/https/tls/gnutls_sig.h
new file mode 100644
index 00000000..4d770716
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_sig.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_SIG_H
26# define GNUTLS_SIG_H
27
28int _gnutls_tls_sign_hdata (gnutls_session_t session,
29 gnutls_cert * cert,
30 gnutls_privkey * pkey,
31 gnutls_datum_t * signature);
32
33int _gnutls_tls_sign_params (gnutls_session_t session,
34 gnutls_cert * cert,
35 gnutls_privkey * pkey,
36 gnutls_datum_t * params,
37 gnutls_datum_t * signature);
38
39int _gnutls_verify_sig_hdata (gnutls_session_t session,
40 gnutls_cert * cert, gnutls_datum_t * signature);
41
42int _gnutls_verify_sig_params (gnutls_session_t session,
43 gnutls_cert * cert,
44 const gnutls_datum_t * params,
45 gnutls_datum_t * signature);
46
47int _gnutls_sign (gnutls_pk_algorithm_t algo,
48 mpi_t * params, int params_size,
49 const gnutls_datum_t * data, gnutls_datum_t * signature);
50
51#endif
diff --git a/src/daemon/https/tls/gnutls_state.c b/src/daemon/https/tls/gnutls_state.c
new file mode 100644
index 00000000..ccc865a1
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_state.c
@@ -0,0 +1,1219 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Functions to manipulate the session (gnutls_int.h), and some other stuff
26 * are included here. The file's name is traditionally gnutls_state even if the
27 * state has been renamed to session.
28 */
29
30#include <gnutls_int.h>
31#include <gnutls_errors.h>
32#include <gnutls_auth_int.h>
33#include <gnutls_num.h>
34#include <gnutls_datum.h>
35#include <gnutls_db.h>
36#include <gnutls_record.h>
37#include <gnutls_handshake.h>
38#include <gnutls_dh.h>
39#include <gnutls_buffers.h>
40#include <gnutls_state.h>
41#include <auth_cert.h>
42#include <auth_anon.h>
43#include <gnutls_algorithms.h>
44#include <gnutls_rsa_export.h>
45
46void
47_gnutls_session_cert_type_set (gnutls_session_t session,
48 gnutls_certificate_type_t ct)
49{
50 session->security_parameters.cert_type = ct;
51}
52
53/**
54 * gnutls_cipher_get - Returns the currently used cipher.
55 * @session: is a #gnutls_session_t structure.
56 *
57 * Returns: the currently used cipher.
58 **/
59gnutls_cipher_algorithm_t
60gnutls_cipher_get (gnutls_session_t session)
61{
62 return session->security_parameters.read_bulk_cipher_algorithm;
63}
64
65/**
66 * gnutls_certificate_type_get - Returns the currently used certificate type.
67 * @session: is a #gnutls_session_t structure.
68 *
69 * The certificate type is by default X.509, unless it is negotiated
70 * as a TLS extension.
71 *
72 * Returns: the currently used %gnutls_certificate_type_t certificate
73 * type.
74 **/
75gnutls_certificate_type_t
76gnutls_certificate_type_get (gnutls_session_t session)
77{
78 return session->security_parameters.cert_type;
79}
80
81/**
82 * gnutls_kx_get - Returns the key exchange algorithm.
83 * @session: is a #gnutls_session_t structure.
84 *
85 * Returns: the key exchange algorithm used in the last handshake.
86 **/
87gnutls_kx_algorithm_t
88gnutls_kx_get (gnutls_session_t session)
89{
90 return session->security_parameters.kx_algorithm;
91}
92
93/**
94 * gnutls_mac_get - Returns the currently used mac algorithm.
95 * @session: is a #gnutls_session_t structure.
96 *
97 * Returns: the currently used mac algorithm.
98 **/
99gnutls_mac_algorithm_t
100gnutls_mac_get (gnutls_session_t session)
101{
102 return session->security_parameters.read_mac_algorithm;
103}
104
105/**
106 * gnutls_compression_get - Returns the currently used compression algorithm.
107 * @session: is a #gnutls_session_t structure.
108 *
109 * Returns: the currently used compression method.
110 **/
111gnutls_compression_method_t
112gnutls_compression_get (gnutls_session_t session)
113{
114 return session->security_parameters.read_compression_algorithm;
115}
116
117/* Check if the given certificate type is supported.
118 * This means that it is enabled by the priority functions,
119 * and a matching certificate exists.
120 */
121int
122_gnutls_session_cert_type_supported (gnutls_session_t session,
123 gnutls_certificate_type_t cert_type)
124{
125 unsigned i;
126 unsigned cert_found = 0;
127 gnutls_certificate_credentials_t cred;
128
129 if (session->security_parameters.entity == GNUTLS_SERVER)
130 {
131 cred
132 = (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
133 GNUTLS_CRD_CERTIFICATE,
134 NULL);
135
136 if (cred == NULL)
137 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
138
139 if (cred->server_get_cert_callback == NULL)
140 {
141 for (i = 0; i < cred->ncerts; i++)
142 {
143 if (cred->cert_list[i][0].cert_type == cert_type)
144 {
145 cert_found = 1;
146 break;
147 }
148 }
149
150 if (cert_found == 0)
151 /* no certificate is of that type.
152 */
153 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
154 }
155 }
156
157 if (session->internals.priorities.cert_type.algorithms == 0 && cert_type
158 == DEFAULT_CERT_TYPE)
159 return 0;
160
161 for (i = 0; i < session->internals.priorities.cert_type.algorithms; i++)
162 {
163 if (session->internals.priorities.cert_type.priority[i] == cert_type)
164 {
165 return 0; /* ok */
166 }
167 }
168
169 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
170}
171
172/* this function deinitializes all the internal parameters stored
173 * in a session struct.
174 */
175inline static void
176deinit_internal_params (gnutls_session_t session)
177{
178 if (session->internals.params.free_dh_params)
179 gnutls_dh_params_deinit (session->internals.params.dh_params);
180
181 if (session->internals.params.free_rsa_params)
182 gnutls_rsa_params_deinit (session->internals.params.rsa_params);
183
184 memset (&session->internals.params, 0, sizeof (session->internals.params));
185}
186
187/* This function will clear all the variables in internals
188 * structure within the session, which depend on the current handshake.
189 * This is used to allow further handshakes.
190 */
191void
192_gnutls_handshake_internal_state_clear (gnutls_session_t session)
193{
194 session->internals.extensions_sent_size = 0;
195
196 /* by default no selected certificate */
197 session->internals.proposed_record_size = DEFAULT_MAX_RECORD_SIZE;
198 session->internals.adv_version_major = 0;
199 session->internals.adv_version_minor = 0;
200 session->internals.v2_hello = 0;
201 memset (&session->internals.handshake_header_buffer, 0,
202 sizeof (handshake_header_buffer_st));
203 session->internals.adv_version_minor = 0;
204 session->internals.adv_version_minor = 0;
205 session->internals.direction = 0;
206
207 /* use out of band data for the last
208 * handshake messages received.
209 */
210 session->internals.last_handshake_in = -1;
211 session->internals.last_handshake_out = -1;
212
213 session->internals.resumable = RESUME_TRUE;
214 _gnutls_free_datum (&session->internals.recv_buffer);
215
216 deinit_internal_params (session);
217
218}
219
220#define MIN_DH_BITS 727
221/**
222 * gnutls_init - This function initializes the session to null (null encryption etc...).
223 * @con_end: indicate if this session is to be used for server or client.
224 * @session: is a pointer to a #gnutls_session_t structure.
225 *
226 * This function initializes the current session to null. Every
227 * session must be initialized before use, so internal structures can
228 * be allocated. This function allocates structures which can only
229 * be free'd by calling gnutls_deinit(). Returns zero on success.
230 *
231 * @con_end can be one of %GNUTLS_CLIENT and %GNUTLS_SERVER.
232 *
233 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
234 **/
235
236// TODO rm redundent pointer ref
237int
238gnutls_init (gnutls_session_t * session, gnutls_connection_end_t con_end)
239{
240 *session = gnutls_calloc (1, sizeof (struct gnutls_session_int));
241 if (*session == NULL)
242 return GNUTLS_E_MEMORY_ERROR;
243
244 (*session)->security_parameters.entity = con_end;
245
246 /* the default certificate type for TLS */
247 (*session)->security_parameters.cert_type = DEFAULT_CERT_TYPE;
248
249 /* Set the defaults for initial handshake */
250 (*session)->security_parameters.read_bulk_cipher_algorithm =
251 (*session)->security_parameters.write_bulk_cipher_algorithm =
252 GNUTLS_CIPHER_NULL;
253
254 (*session)->security_parameters.read_mac_algorithm =
255 (*session)->security_parameters.write_mac_algorithm = GNUTLS_MAC_NULL;
256
257 (*session)->security_parameters.read_compression_algorithm
258 = GNUTLS_COMP_NULL;
259 (*session)->security_parameters.write_compression_algorithm
260 = GNUTLS_COMP_NULL;
261
262 (*session)->internals.enable_private = 0;
263
264 /* Initialize buffers */
265 _gnutls_buffer_init (&(*session)->internals.application_data_buffer);
266 _gnutls_buffer_init (&(*session)->internals.handshake_data_buffer);
267 _gnutls_buffer_init (&(*session)->internals.handshake_hash_buffer);
268 _gnutls_buffer_init (&(*session)->internals.ia_data_buffer);
269
270 _gnutls_buffer_init (&(*session)->internals.record_send_buffer);
271 _gnutls_buffer_init (&(*session)->internals.record_recv_buffer);
272
273 _gnutls_buffer_init (&(*session)->internals.handshake_send_buffer);
274 _gnutls_buffer_init (&(*session)->internals.handshake_recv_buffer);
275
276 (*session)->key = gnutls_calloc (1, sizeof (struct gnutls_key_st));
277 if ((*session)->key == NULL)
278 {
279 cleanup_session:gnutls_free (*session);
280 *session = NULL;
281 return GNUTLS_E_MEMORY_ERROR;
282 }
283
284 (*session)->internals.expire_time = DEFAULT_EXPIRE_TIME; /* one hour default */
285
286 gnutls_dh_set_prime_bits ((*session), MIN_DH_BITS);
287
288 gnutls_transport_set_lowat ((*session), DEFAULT_LOWAT); /* the default for tcp */
289
290 gnutls_handshake_set_max_packet_length ((*session),
291 MAX_HANDSHAKE_PACKET_SIZE);
292
293 /* Allocate a minimum size for recv_data
294 * This is allocated in order to avoid small messages, making
295 * the receive procedure slow.
296 */
297 (*session)->internals.record_recv_buffer.data
298 = gnutls_malloc (INITIAL_RECV_BUFFER_SIZE);
299 if ((*session)->internals.record_recv_buffer.data == NULL)
300 {
301 gnutls_free ((*session)->key);
302 goto cleanup_session;
303 }
304
305 /* set the socket pointers to -1; */
306 (*session)->internals.transport_recv_ptr = (gnutls_transport_ptr_t) - 1;
307 (*session)->internals.transport_send_ptr = (gnutls_transport_ptr_t) - 1;
308
309 /* set the default maximum record size for TLS
310 */
311 (*session)->security_parameters.max_record_recv_size
312 = DEFAULT_MAX_RECORD_SIZE;
313 (*session)->security_parameters.max_record_send_size
314 = DEFAULT_MAX_RECORD_SIZE;
315
316 /* everything else not initialized here is initialized
317 * as NULL or 0. This is why calloc is used.
318 */
319
320 _gnutls_handshake_internal_state_clear (*session);
321
322 return 0;
323}
324
325/* returns RESUME_FALSE or RESUME_TRUE.
326 */
327int
328_gnutls_session_is_resumable (gnutls_session_t session)
329{
330 return session->internals.resumable;
331}
332
333/**
334 * gnutls_deinit - This function clears all buffers associated with a session
335 * @session: is a #gnutls_session_t structure.
336 *
337 * This function clears all buffers associated with the @session.
338 * This function will also remove session data from the session
339 * database if the session was terminated abnormally.
340 **/
341void
342gnutls_deinit (gnutls_session_t session)
343{
344
345 if (session == NULL)
346 return;
347
348 /* remove auth info firstly */
349 _gnutls_free_auth_info (session);
350
351 _gnutls_handshake_internal_state_clear (session);
352 _gnutls_handshake_io_buffer_clear (session);
353
354 _gnutls_free_datum (&session->connection_state.read_mac_secret);
355 _gnutls_free_datum (&session->connection_state.write_mac_secret);
356
357 _gnutls_buffer_clear (&session->internals.ia_data_buffer);
358 _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
359 _gnutls_buffer_clear (&session->internals.handshake_data_buffer);
360 _gnutls_buffer_clear (&session->internals.application_data_buffer);
361 _gnutls_buffer_clear (&session->internals.record_recv_buffer);
362 _gnutls_buffer_clear (&session->internals.record_send_buffer);
363
364 gnutls_credentials_clear (session);
365 _gnutls_selected_certs_deinit (session);
366
367 if (session->connection_state.read_cipher_state != NULL)
368 _gnutls_cipher_deinit (session->connection_state.read_cipher_state);
369 if (session->connection_state.write_cipher_state != NULL)
370 _gnutls_cipher_deinit (session->connection_state.write_cipher_state);
371
372 if (session->connection_state.read_compression_state != NULL)
373 _gnutls_comp_deinit (session->connection_state.read_compression_state, 1);
374 if (session->connection_state.write_compression_state != NULL)
375 _gnutls_comp_deinit (session->connection_state.
376 write_compression_state, 0);
377
378 _gnutls_free_datum (&session->cipher_specs.server_write_mac_secret);
379 _gnutls_free_datum (&session->cipher_specs.client_write_mac_secret);
380 _gnutls_free_datum (&session->cipher_specs.server_write_IV);
381 _gnutls_free_datum (&session->cipher_specs.client_write_IV);
382 _gnutls_free_datum (&session->cipher_specs.server_write_key);
383 _gnutls_free_datum (&session->cipher_specs.client_write_key);
384
385 if (session->key != NULL)
386 {
387 _gnutls_mpi_release (&session->key->KEY);
388 _gnutls_mpi_release (&session->key->client_Y);
389 _gnutls_mpi_release (&session->key->client_p);
390 _gnutls_mpi_release (&session->key->client_g);
391
392 _gnutls_mpi_release (&session->key->u);
393 _gnutls_mpi_release (&session->key->a);
394 _gnutls_mpi_release (&session->key->x);
395 _gnutls_mpi_release (&session->key->A);
396 _gnutls_mpi_release (&session->key->B);
397 _gnutls_mpi_release (&session->key->b);
398
399 /* RSA */
400 _gnutls_mpi_release (&session->key->rsa[0]);
401 _gnutls_mpi_release (&session->key->rsa[1]);
402
403 _gnutls_mpi_release (&session->key->dh_secret);
404 gnutls_free (session->key);
405
406 session->key = NULL;
407 }
408
409 gnutls_free (session->internals.srp_username);
410
411 if (session->internals.srp_password)
412 {
413 memset (session->internals.srp_password, 0,
414 strlen (session->internals.srp_password));
415 gnutls_free (session->internals.srp_password);
416 }
417
418 memset (session, 0, sizeof (struct gnutls_session_int));
419 gnutls_free (session);
420}
421
422/* Returns the minimum prime bits that are acceptable.
423 */
424int
425_gnutls_dh_get_allowed_prime_bits (gnutls_session_t session)
426{
427 return session->internals.dh_prime_bits;
428}
429
430int
431_gnutls_dh_set_peer_public (gnutls_session_t session, mpi_t public)
432{
433 dh_info_st *dh;
434 int ret;
435
436 switch (gnutls_auth_get_type (session))
437 {
438 case GNUTLS_CRD_ANON:
439 {
440 anon_auth_info_t info;
441 info = _gnutls_get_auth_info (session);
442 if (info == NULL)
443 return GNUTLS_E_INTERNAL_ERROR;
444
445 dh = &info->dh;
446 break;
447 }
448 case GNUTLS_CRD_CERTIFICATE:
449 {
450 cert_auth_info_t info;
451
452 info = _gnutls_get_auth_info (session);
453 if (info == NULL)
454 return GNUTLS_E_INTERNAL_ERROR;
455
456 dh = &info->dh;
457 break;
458 }
459 default:
460 gnutls_assert ();
461 return GNUTLS_E_INTERNAL_ERROR;
462 }
463
464 ret = _gnutls_mpi_dprint_lz (&dh->public_key, public);
465 if (ret < 0)
466 {
467 gnutls_assert ();
468 return ret;
469 }
470
471 return 0;
472}
473
474int
475_gnutls_dh_set_secret_bits (gnutls_session_t session, unsigned bits)
476{
477 switch (gnutls_auth_get_type (session))
478 {
479 case GNUTLS_CRD_ANON:
480 {
481 anon_auth_info_t info;
482 info = _gnutls_get_auth_info (session);
483 if (info == NULL)
484 return GNUTLS_E_INTERNAL_ERROR;
485 info->dh.secret_bits = bits;
486 break;
487 }
488 case GNUTLS_CRD_CERTIFICATE:
489 {
490 cert_auth_info_t info;
491
492 info = _gnutls_get_auth_info (session);
493 if (info == NULL)
494 return GNUTLS_E_INTERNAL_ERROR;
495
496 info->dh.secret_bits = bits;
497 break;
498 default:
499 gnutls_assert ();
500 return GNUTLS_E_INTERNAL_ERROR;
501 }
502 }
503
504 return 0;
505}
506
507/* This function will set in the auth info structure the
508 * RSA exponent and the modulus.
509 */
510int
511_gnutls_rsa_export_set_pubkey (gnutls_session_t session,
512 mpi_t exponent, mpi_t modulus)
513{
514 cert_auth_info_t info;
515 int ret;
516
517 info = _gnutls_get_auth_info (session);
518 if (info == NULL)
519 return GNUTLS_E_INTERNAL_ERROR;
520
521 ret = _gnutls_mpi_dprint_lz (&info->rsa_export.modulus, modulus);
522 if (ret < 0)
523 {
524 gnutls_assert ();
525 return ret;
526 }
527
528 ret = _gnutls_mpi_dprint_lz (&info->rsa_export.exponent, exponent);
529 if (ret < 0)
530 {
531 gnutls_assert ();
532 _gnutls_free_datum (&info->rsa_export.modulus);
533 return ret;
534 }
535
536 return 0;
537}
538
539/* Sets the prime and the generator in the auth info structure.
540 */
541int
542_gnutls_dh_set_group (gnutls_session_t session, mpi_t gen, mpi_t prime)
543{
544 dh_info_st *dh;
545 int ret;
546
547 switch (gnutls_auth_get_type (session))
548 {
549 case GNUTLS_CRD_ANON:
550 {
551 anon_auth_info_t info;
552 info = _gnutls_get_auth_info (session);
553 if (info == NULL)
554 return GNUTLS_E_INTERNAL_ERROR;
555
556 dh = &info->dh;
557 break;
558 }
559 case GNUTLS_CRD_CERTIFICATE:
560 {
561 cert_auth_info_t info;
562
563 info = _gnutls_get_auth_info (session);
564 if (info == NULL)
565 return GNUTLS_E_INTERNAL_ERROR;
566
567 dh = &info->dh;
568 break;
569 }
570 default:
571 gnutls_assert ();
572 return GNUTLS_E_INTERNAL_ERROR;
573 }
574
575 /* prime
576 */
577 ret = _gnutls_mpi_dprint_lz (&dh->prime, prime);
578 if (ret < 0)
579 {
580 gnutls_assert ();
581 return ret;
582 }
583
584 /* generator
585 */
586 ret = _gnutls_mpi_dprint_lz (&dh->generator, gen);
587 if (ret < 0)
588 {
589 gnutls_assert ();
590 _gnutls_free_datum (&dh->prime);
591 return ret;
592 }
593
594 return 0;
595}
596
597/**
598 * gnutls_openpgp_send_cert - This function will order gnutls to send the openpgp fingerprint instead of the key
599 * @session: is a pointer to a #gnutls_session_t structure.
600 * @status: is one of GNUTLS_OPENPGP_CERT, or GNUTLS_OPENPGP_CERT_FINGERPRINT
601 *
602 * This function will order gnutls to send the key fingerprint
603 * instead of the key in the initial handshake procedure. This should
604 * be used with care and only when there is indication or knowledge
605 * that the server can obtain the client's key.
606 **/
607void
608gnutls_openpgp_send_cert (gnutls_session_t session,
609 gnutls_openpgp_crt_status_t status)
610{
611 session->internals.pgp_fingerprint = status;
612}
613
614/**
615 * gnutls_certificate_send_x509_rdn_sequence - This function will order gnutls to send or not the x.509 rdn sequence
616 * @session: is a pointer to a #gnutls_session_t structure.
617 * @status: is 0 or 1
618 *
619 * If status is non zero, this function will order gnutls not to send
620 * the rdnSequence in the certificate request message. That is the
621 * server will not advertize it's trusted CAs to the peer. If status
622 * is zero then the default behaviour will take effect, which is to
623 * advertize the server's trusted CAs.
624 *
625 * This function has no effect in clients, and in authentication
626 * methods other than certificate with X.509 certificates.
627 **/
628void
629gnutls_certificate_send_x509_rdn_sequence (gnutls_session_t session,
630 int status)
631{
632 session->internals.ignore_rdn_sequence = status;
633}
634
635int
636_gnutls_openpgp_send_fingerprint (gnutls_session_t session)
637{
638 return session->internals.pgp_fingerprint;
639}
640
641/*-
642 * _gnutls_record_set_default_version - Used to set the default version for the first record packet
643 * @session: is a #gnutls_session_t structure.
644 * @major: is a tls major version
645 * @minor: is a tls minor version
646 *
647 * This function sets the default version that we will use in the first
648 * record packet (client hello). This function is only useful to people
649 * that know TLS internals and want to debug other implementations.
650 *
651 -*/
652void
653_gnutls_record_set_default_version (gnutls_session_t session,
654 unsigned char major, unsigned char minor)
655{
656 session->internals.default_record_version[0] = major;
657 session->internals.default_record_version[1] = minor;
658}
659
660/**
661 * gnutls_handshake_set_private_extensions - Used to enable the private cipher suites
662 * @session: is a #gnutls_session_t structure.
663 * @allow: is an integer (0 or 1)
664 *
665 * This function will enable or disable the use of private cipher
666 * suites (the ones that start with 0xFF). By default or if @allow
667 * is 0 then these cipher suites will not be advertized nor used.
668 *
669 * Unless this function is called with the option to allow (1), then
670 * no compression algorithms, like LZO. That is because these
671 * algorithms are not yet defined in any RFC or even internet draft.
672 *
673 * Enabling the private ciphersuites when talking to other than
674 * gnutls servers and clients may cause interoperability problems.
675 **/
676void
677gnutls_handshake_set_private_extensions (gnutls_session_t session, int allow)
678{
679 session->internals.enable_private = allow;
680}
681
682inline static int
683_gnutls_cal_PRF_A (gnutls_mac_algorithm_t algorithm,
684 const void *secret,
685 int secret_size,
686 const void *seed, int seed_size, void *result)
687{
688 mac_hd_t td1;
689
690 td1 = _gnutls_hmac_init (algorithm, secret, secret_size);
691 if (td1 == GNUTLS_MAC_FAILED)
692 {
693 gnutls_assert ();
694 return GNUTLS_E_INTERNAL_ERROR;
695 }
696
697 _gnutls_hmac (td1, seed, seed_size);
698 _gnutls_hmac_deinit (td1, result);
699
700 return 0;
701}
702
703#define MAX_SEED_SIZE 200
704
705/* Produces "total_bytes" bytes using the hash algorithm specified.
706 * (used in the PRF function)
707 */
708static int
709_gnutls_P_hash (gnutls_mac_algorithm_t algorithm,
710 const opaque * secret,
711 int secret_size,
712 const opaque * seed,
713 int seed_size, int total_bytes, opaque * ret)
714{
715
716 mac_hd_t td2;
717 int i, times, how, blocksize, A_size;
718 opaque final[20], Atmp[MAX_SEED_SIZE];
719 int output_bytes, result;
720
721 if (seed_size > MAX_SEED_SIZE || total_bytes <= 0)
722 {
723 gnutls_assert ();
724 return GNUTLS_E_INTERNAL_ERROR;
725 }
726
727 blocksize = _gnutls_hmac_get_algo_len (algorithm);
728
729 output_bytes = 0;
730 do
731 {
732 output_bytes += blocksize;
733 }
734 while (output_bytes < total_bytes);
735
736 /* calculate A(0) */
737
738 memcpy (Atmp, seed, seed_size);
739 A_size = seed_size;
740
741 times = output_bytes / blocksize;
742
743 for (i = 0; i < times; i++)
744 {
745 td2 = _gnutls_hmac_init (algorithm, secret, secret_size);
746 if (td2 == GNUTLS_MAC_FAILED)
747 {
748 gnutls_assert ();
749 return GNUTLS_E_INTERNAL_ERROR;
750 }
751
752 /* here we calculate A(i+1) */
753 if ((result = _gnutls_cal_PRF_A (algorithm, secret, secret_size, Atmp,
754 A_size, Atmp)) < 0)
755 {
756 gnutls_assert ();
757 _gnutls_hmac_deinit (td2, final);
758 return result;
759 }
760
761 A_size = blocksize;
762
763 _gnutls_hmac (td2, Atmp, A_size);
764 _gnutls_hmac (td2, seed, seed_size);
765 _gnutls_hmac_deinit (td2, final);
766
767 if ((1 + i) * blocksize < total_bytes)
768 {
769 how = blocksize;
770 }
771 else
772 {
773 how = total_bytes - (i) * blocksize;
774 }
775
776 if (how > 0)
777 {
778 memcpy (&ret[i * blocksize], final, how);
779 }
780 }
781
782 return 0;
783}
784
785/* Xor's two buffers and puts the output in the first one.
786 */
787inline static void
788_gnutls_xor (opaque * o1, opaque * o2, int length)
789{
790 int i;
791 for (i = 0; i < length; i++)
792 {
793 o1[i] ^= o2[i];
794 }
795}
796
797#define MAX_PRF_BYTES 200
798
799/* The PRF function expands a given secret
800 * needed by the TLS specification. ret must have a least total_bytes
801 * available.
802 */
803int
804_gnutls_PRF (gnutls_session_t session,
805 const opaque * secret,
806 int secret_size,
807 const char *label,
808 int label_size,
809 const opaque * seed, int seed_size, int total_bytes, void *ret)
810{
811 int l_s, s_seed_size;
812 const opaque *s1, *s2;
813 opaque s_seed[MAX_SEED_SIZE];
814 opaque o1[MAX_PRF_BYTES], o2[MAX_PRF_BYTES];
815 int result;
816 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
817
818 if (total_bytes > MAX_PRF_BYTES)
819 {
820 gnutls_assert ();
821 return GNUTLS_E_INTERNAL_ERROR;
822 }
823 /* label+seed = s_seed */
824 s_seed_size = seed_size + label_size;
825
826 if (s_seed_size > MAX_SEED_SIZE)
827 {
828 gnutls_assert ();
829 return GNUTLS_E_INTERNAL_ERROR;
830 }
831
832 memcpy (s_seed, label, label_size);
833 memcpy (&s_seed[label_size], seed, seed_size);
834
835 if (ver >= GNUTLS_TLS1_2)
836 {
837 result = _gnutls_P_hash (GNUTLS_MAC_SHA1, secret, secret_size, s_seed,
838 s_seed_size, total_bytes, ret);
839 if (result < 0)
840 {
841 gnutls_assert ();
842 return result;
843 }
844 }
845 else
846 {
847 l_s = secret_size / 2;
848
849 s1 = &secret[0];
850 s2 = &secret[l_s];
851
852 if (secret_size % 2 != 0)
853 {
854 l_s++;
855 }
856
857 result = _gnutls_P_hash (GNUTLS_MAC_MD5, s1, l_s, s_seed, s_seed_size,
858 total_bytes, o1);
859 if (result < 0)
860 {
861 gnutls_assert ();
862 return result;
863 }
864
865 result = _gnutls_P_hash (GNUTLS_MAC_SHA1, s2, l_s, s_seed, s_seed_size,
866 total_bytes, o2);
867 if (result < 0)
868 {
869 gnutls_assert ();
870 return result;
871 }
872
873 _gnutls_xor (o1, o2, total_bytes);
874
875 memcpy (ret, o1, total_bytes);
876 }
877
878 return 0; /* ok */
879
880}
881
882/**
883 * gnutls_prf_raw - access the TLS PRF directly
884 * @session: is a #gnutls_session_t structure.
885 * @label_size: length of the @label variable.
886 * @label: label used in PRF computation, typically a short string.
887 * @seed_size: length of the @seed variable.
888 * @seed: optional extra data to seed the PRF with.
889 * @outsize: size of pre-allocated output buffer to hold the output.
890 * @out: pre-allocate buffer to hold the generated data.
891 *
892 * Apply the TLS Pseudo-Random-Function (PRF) using the master secret
893 * on some data.
894 *
895 * The @label variable usually contain a string denoting the purpose
896 * for the generated data. The @seed usually contain data such as the
897 * client and server random, perhaps together with some additional
898 * data that is added to guarantee uniqueness of the output for a
899 * particular purpose.
900 *
901 * Because the output is not guaranteed to be unique for a particular
902 * session unless @seed include the client random and server random
903 * fields (the PRF would output the same data on another connection
904 * resumed from the first one), it is not recommended to use this
905 * function directly. The gnutls_prf() function seed the PRF with the
906 * client and server random fields directly, and is recommended if you
907 * want to generate pseudo random data unique for each session.
908 *
909 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
910 **/
911int
912gnutls_prf_raw (gnutls_session_t session,
913 size_t label_size,
914 const char *label,
915 size_t seed_size, const char *seed, size_t outsize, char *out)
916{
917 int ret;
918
919 ret = _gnutls_PRF (session, session->security_parameters.master_secret,
920 TLS_MASTER_SIZE, label, label_size, (opaque *) seed,
921 seed_size, outsize, out);
922
923 return ret;
924}
925
926/**
927 * gnutls_prf - derive pseudo-random data using the TLS PRF
928 * @session: is a #gnutls_session_t structure.
929 * @label_size: length of the @label variable.
930 * @label: label used in PRF computation, typically a short string.
931 * @server_random_first: non-0 if server random field should be first in seed
932 * @extra_size: length of the @extra variable.
933 * @extra: optional extra data to seed the PRF with.
934 * @outsize: size of pre-allocated output buffer to hold the output.
935 * @out: pre-allocate buffer to hold the generated data.
936 *
937 * Apply the TLS Pseudo-Random-Function (PRF) using the master secret
938 * on some data, seeded with the client and server random fields.
939 *
940 * The @label variable usually contain a string denoting the purpose
941 * for the generated data. The @server_random_first indicate whether
942 * the client random field or the server random field should be first
943 * in the seed. Non-0 indicate that the server random field is first,
944 * 0 that the client random field is first.
945 *
946 * The @extra variable can be used to add more data to the seed, after
947 * the random variables. It can be used to tie make sure the
948 * generated output is strongly connected to some additional data
949 * (e.g., a string used in user authentication).
950 *
951 * The output is placed in *@OUT, which must be pre-allocated.
952 *
953 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
954 **/
955int
956gnutls_prf (gnutls_session_t session,
957 size_t label_size,
958 const char *label,
959 int server_random_first,
960 size_t extra_size, const char *extra, size_t outsize, char *out)
961{
962 int ret;
963 opaque *seed;
964 size_t seedsize = 2 * TLS_RANDOM_SIZE + extra_size;
965
966 seed = gnutls_malloc (seedsize);
967 if (!seed)
968 {
969 gnutls_assert ();
970 return GNUTLS_E_MEMORY_ERROR;
971 }
972
973 memcpy (seed,
974 server_random_first ? session->security_parameters.server_random
975 : session->security_parameters.client_random, TLS_RANDOM_SIZE);
976 memcpy (seed + TLS_RANDOM_SIZE,
977 server_random_first ? session->security_parameters.client_random
978 : session->security_parameters.server_random, TLS_RANDOM_SIZE);
979
980 memcpy (seed + 2 * TLS_RANDOM_SIZE, extra, extra_size);
981
982 ret = _gnutls_PRF (session, session->security_parameters.master_secret,
983 TLS_MASTER_SIZE, label, label_size, seed, seedsize,
984 outsize, out);
985
986 gnutls_free (seed);
987
988 return ret;
989}
990
991/**
992 * gnutls_session_get_client_random - get the session's client random value
993 * @session: is a #gnutls_session_t structure.
994 *
995 * Return a pointer to the 32-byte client random field used in the
996 * session. The pointer must not be modified or deallocated.
997 *
998 * If a client random value has not yet been established, the output
999 * will be garbage; in particular, a %NULL return value should not be
1000 * expected.
1001 *
1002 * Returns: pointer to client random data.
1003 **/
1004const void *
1005gnutls_session_get_client_random (gnutls_session_t session)
1006{
1007 return (char *) session->security_parameters.client_random;
1008}
1009
1010/**
1011 * gnutls_session_get_server_random - get the session's server random value
1012 * @session: is a #gnutls_session_t structure.
1013 *
1014 * Return a pointer to the 32-byte server random field used in the
1015 * session. The pointer must not be modified or deallocated.
1016 *
1017 * If a server random value has not yet been established, the output
1018 * will be garbage; in particular, a %NULL return value should not be
1019 * expected.
1020 *
1021 * Returns: pointer to server random data.
1022 **/
1023const void *
1024gnutls_session_get_server_random (gnutls_session_t session)
1025{
1026 return (char *) session->security_parameters.server_random;
1027}
1028
1029/**
1030 * gnutls_session_get_master_secret - get the session's master secret value
1031 * @session: is a #gnutls_session_t structure.
1032 *
1033 * Return a pointer to the 48-byte master secret in the session. The
1034 * pointer must not be modified or deallocated.
1035 *
1036 * If a master secret value has not yet been established, the output
1037 * will be garbage; in particular, a %NULL return value should not be
1038 * expected.
1039 *
1040 * Consider using gnutls_prf() rather than extracting the master
1041 * secret and use it to derive further data.
1042 *
1043 * Returns: pointer to master secret data.
1044 **/
1045const void *
1046gnutls_session_get_master_secret (gnutls_session_t session)
1047{
1048 return (char *) session->security_parameters.master_secret;
1049}
1050
1051/**
1052 * gnutls_session_is_resumed - Used to check whether this session is a resumed one
1053 * @session: is a #gnutls_session_t structure.
1054 *
1055 * Returns: non zero if this session is resumed, or a zero if this is
1056 * a new session.
1057 **/
1058int
1059gnutls_session_is_resumed (gnutls_session_t session)
1060{
1061 if (session->security_parameters.entity == GNUTLS_CLIENT)
1062 {
1063 if (session->security_parameters.session_id_size > 0
1064 && session->security_parameters.session_id_size
1065 == session->internals.resumed_security_parameters.session_id_size
1066 && memcmp (session->security_parameters.session_id,
1067 session->internals.resumed_security_parameters.
1068 session_id, session->security_parameters.session_id_size)
1069 == 0)
1070 return 1;
1071 }
1072 else
1073 {
1074 if (session->internals.resumed == RESUME_TRUE)
1075 return 1;
1076 }
1077
1078 return 0;
1079}
1080
1081/*-
1082 * _gnutls_session_is_export - Used to check whether this session is of export grade
1083 * @session: is a #gnutls_session_t structure.
1084 *
1085 * This function will return non zero if this session is of export grade.
1086 *
1087 -*/
1088int
1089_gnutls_session_is_export (gnutls_session_t session)
1090{
1091 gnutls_cipher_algorithm_t cipher;
1092
1093 cipher =
1094 _gnutls_cipher_suite_get_cipher_algo (&session->security_parameters.
1095 current_cipher_suite);
1096
1097 if (_gnutls_cipher_get_export_flag (cipher) != 0)
1098 return 1;
1099
1100 return 0;
1101}
1102
1103/**
1104 * gnutls_session_get_ptr - Used to get the user pointer from the session structure
1105 * @session: is a #gnutls_session_t structure.
1106 *
1107 * Returns: the user given pointer from the session structure. This
1108 * is the pointer set with gnutls_session_set_ptr().
1109 **/
1110void *
1111gnutls_session_get_ptr (gnutls_session_t session)
1112{
1113 return session->internals.user_ptr;
1114}
1115
1116/**
1117 * gnutls_session_set_ptr - Used to set the user pointer to the session structure
1118 * @session: is a #gnutls_session_t structure.
1119 * @ptr: is the user pointer
1120 *
1121 * This function will set (associate) the user given pointer to the
1122 * session structure. This is pointer can be accessed with
1123 * gnutls_session_get_ptr().
1124 **/
1125void
1126gnutls_session_set_ptr (gnutls_session_t session, void *ptr)
1127{
1128 session->internals.user_ptr = ptr;
1129}
1130
1131/**
1132 * gnutls_record_get_direction - This function will return the direction of the last interrupted function call
1133 * @session: is a #gnutls_session_t structure.
1134 *
1135 * This function provides information about the internals of the
1136 * record protocol and is only useful if a prior gnutls function call
1137 * (e.g. gnutls_handshake()) was interrupted for some reason, that
1138 * is, if a function returned %GNUTLS_E_INTERRUPTED or
1139 * %GNUTLS_E_AGAIN. In such a case, you might want to call select()
1140 * or poll() before calling the interrupted gnutls function again.
1141 * To tell you whether a file descriptor should be selected for
1142 * either reading or writing, gnutls_record_get_direction() returns 0
1143 * if the interrupted function was trying to read data, and 1 if it
1144 * was trying to write data.
1145 *
1146 * Returns: 0 if trying to read data, 1 if trying to write data.
1147 **/
1148int
1149gnutls_record_get_direction (gnutls_session_t session)
1150{
1151 return session->internals.direction;
1152}
1153
1154/*-
1155 * _gnutls_rsa_pms_set_version - Sets a version to be used at the RSA PMS
1156 * @session: is a #gnutls_session_t structure.
1157 * @major: is the major version to use
1158 * @minor: is the minor version to use
1159 *
1160 * This function will set the given version number to be used at the
1161 * RSA PMS secret. This is only useful to clients, which want to
1162 * test server's capabilities.
1163 *
1164 -*/
1165void
1166_gnutls_rsa_pms_set_version (gnutls_session_t session,
1167 unsigned char major, unsigned char minor)
1168{
1169 session->internals.rsa_pms_version[0] = major;
1170 session->internals.rsa_pms_version[1] = minor;
1171}
1172
1173/**
1174 * gnutls_handshake_set_post_client_hello_function - This function will a callback to be called after the client hello is received
1175 * @res: is a gnutls_anon_server_credentials_t structure
1176 * @func: is the function to be called
1177 *
1178 * This function will set a callback to be called after the client
1179 * hello has been received (callback valid in server side only). This
1180 * allows the server to adjust settings based on received extensions.
1181 *
1182 * Those settings could be ciphersuites, requesting certificate, or
1183 * anything else except for version negotiation (this is done before
1184 * the hello message is parsed).
1185 *
1186 * This callback must return 0 on success or a gnutls error code to
1187 * terminate the handshake.
1188 *
1189 * NOTE: You should not use this function to terminate the handshake
1190 * based on client input unless you know what you are doing. Before
1191 * the handshake is finished there is no way to know if there is a
1192 * man-in-the-middle attack being performed.
1193 *
1194 **/
1195void
1196gnutls_handshake_set_post_client_hello_function (gnutls_session_t session,
1197 gnutls_handshake_post_client_hello_func
1198 func)
1199{
1200 session->internals.user_hello_func = func;
1201}
1202
1203/**
1204 * gnutls_session_enable_compatibility_mode - Used to disable certain features in TLS in order to honour compatibility
1205 * @session: is a #gnutls_session_t structure.
1206 *
1207 * This function can be used to disable certain (security) features
1208 * in TLS in order to maintain maximum compatibility with buggy
1209 * clients. It is equivalent to calling:
1210 * gnutls_record_disable_padding()
1211 *
1212 * Normally only servers that require maximum compatibility with
1213 * everything out there, need to call this function.
1214 **/
1215void
1216gnutls_session_enable_compatibility_mode (gnutls_session_t session)
1217{
1218 gnutls_record_disable_padding (session);
1219}
diff --git a/src/daemon/https/tls/gnutls_state.h b/src/daemon/https/tls/gnutls_state.h
new file mode 100644
index 00000000..7a920ee4
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_state.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_STATE_H
26# define GNUTLS_STATE_H
27
28#include <gnutls_int.h>
29
30void _gnutls_session_cert_type_set (gnutls_session_t session,
31 gnutls_certificate_type_t);
32gnutls_kx_algorithm_t gnutls_kx_get (gnutls_session_t session);
33gnutls_cipher_algorithm_t gnutls_cipher_get (gnutls_session_t session);
34gnutls_certificate_type_t gnutls_certificate_type_get (gnutls_session_t);
35
36#include <gnutls_auth_int.h>
37
38#define CHECK_AUTH(auth, ret) if (gnutls_auth_get_type(session) != auth) { \
39 gnutls_assert(); \
40 return ret; \
41 }
42
43#endif
44
45int _gnutls_session_cert_type_supported (gnutls_session_t,
46 gnutls_certificate_type_t);
47
48int _gnutls_dh_set_secret_bits (gnutls_session_t session, unsigned bits);
49
50int _gnutls_dh_set_peer_public (gnutls_session_t session, mpi_t public);
51int _gnutls_dh_set_group (gnutls_session_t session, mpi_t gen, mpi_t prime);
52
53int _gnutls_dh_get_allowed_prime_bits (gnutls_session_t session);
54void _gnutls_handshake_internal_state_clear (gnutls_session_t);
55
56int _gnutls_rsa_export_set_pubkey (gnutls_session_t session,
57 mpi_t exponent, mpi_t modulus);
58
59int _gnutls_session_is_resumable (gnutls_session_t session);
60int _gnutls_session_is_export (gnutls_session_t session);
61
62int _gnutls_openpgp_send_fingerprint (gnutls_session_t session);
63
64int _gnutls_PRF (gnutls_session_t session,
65 const opaque * secret, int secret_size,
66 const char *label, int label_size,
67 const opaque * seed, int seed_size,
68 int total_bytes, void *ret);
69
70int gnutls_init (gnutls_session_t * session, gnutls_connection_end_t con_end);
71
72#define DEFAULT_CERT_TYPE GNUTLS_CRT_X509
diff --git a/src/daemon/https/tls/gnutls_str.c b/src/daemon/https/tls/gnutls_str.c
new file mode 100644
index 00000000..0ccf8445
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_str.c
@@ -0,0 +1,312 @@
1/*
2 * Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_num.h>
28#include <gnutls_str.h>
29
30/* These function are like strcat, strcpy. They only
31 * do bound checking (they shouldn't cause buffer overruns),
32 * and they always produce null terminated strings.
33 *
34 * They should be used only with null terminated strings.
35 */
36void _gnutls_str_cat(char *dest,
37 size_t dest_tot_size,
38 const char *src)
39{
40 size_t str_size = strlen(src);
41 size_t dest_size = strlen(dest);
42
43 if (dest_tot_size - dest_size > str_size)
44 {
45 strcat(dest, src);
46 }
47 else
48 {
49 if (dest_tot_size - dest_size > 0)
50 {
51 strncat(dest, src, (dest_tot_size - dest_size) - 1);
52 dest[dest_tot_size - 1] = 0;
53 }
54 }
55}
56
57void _gnutls_str_cpy(char *dest,
58 size_t dest_tot_size,
59 const char *src)
60{
61 size_t str_size = strlen(src);
62
63 if (dest_tot_size > str_size)
64 {
65 strcpy(dest, src);
66 }
67 else
68 {
69 if (dest_tot_size > 0)
70 {
71 strncpy(dest, src, (dest_tot_size) - 1);
72 dest[dest_tot_size - 1] = 0;
73 }
74 }
75}
76
77void _gnutls_mem_cpy(char *dest,
78 size_t dest_tot_size,
79 const char *src,
80 size_t src_size)
81{
82
83 if (dest_tot_size >= src_size)
84 {
85 memcpy(dest, src, src_size);
86 }
87 else
88 {
89 if (dest_tot_size > 0)
90 {
91 memcpy(dest, src, dest_tot_size);
92 }
93 }
94}
95
96void _gnutls_string_init(gnutls_string * str,
97 gnutls_alloc_function alloc_func,
98 gnutls_realloc_function realloc_func,
99 gnutls_free_function free_func)
100{
101 str->data = NULL;
102 str->max_length = 0;
103 str->length = 0;
104
105 str->alloc_func = alloc_func;
106 str->free_func = free_func;
107 str->realloc_func = realloc_func;
108}
109
110void _gnutls_string_clear(gnutls_string * str)
111{
112 if (str == NULL || str->data == NULL)
113 return;
114 str->free_func(str->data);
115
116 str->data = NULL;
117 str->max_length = 0;
118 str->length = 0;
119}
120
121/* This one does not copy the string.
122 */
123gnutls_datum_t _gnutls_string2datum(gnutls_string * str)
124{
125 gnutls_datum_t ret;
126
127 ret.data = str->data;
128 ret.size = str->length;
129
130 return ret;
131}
132
133#define MIN_CHUNK 256
134
135int _gnutls_string_copy_str(gnutls_string * dest,
136 const char *src)
137{
138 size_t src_len = strlen(src);
139 size_t max;
140 if (dest->max_length >= src_len)
141 {
142 memcpy(dest->data, src, src_len);
143 dest->length = src_len;
144
145 return src_len;
146 }
147 else
148 {
149 max = (src_len > MIN_CHUNK) ? src_len : MIN_CHUNK;
150 dest->data = dest->realloc_func(dest->data, max);
151 if (dest->data == NULL)
152 {
153 gnutls_assert ();
154 return GNUTLS_E_MEMORY_ERROR;
155 }
156 dest->max_length = MAX (MIN_CHUNK, src_len);
157
158 memcpy(dest->data, src, src_len);
159 dest->length = src_len;
160
161 return src_len;
162 }
163}
164
165int _gnutls_string_append_str(gnutls_string * dest,
166 const char *src)
167{
168 size_t src_len = strlen(src);
169 size_t tot_len = src_len + dest->length;
170
171 if (dest->max_length >= tot_len)
172 {
173 memcpy(&dest->data[dest->length], src, src_len);
174 dest->length = tot_len;
175
176 return tot_len;
177 }
178 else
179 {
180 size_t new_len=
181 MAX (src_len, MIN_CHUNK) + MAX (dest->max_length, MIN_CHUNK);
182
183 dest->data = dest->realloc_func(dest->data, new_len);
184 if (dest->data == NULL)
185 {
186 gnutls_assert ();
187 return GNUTLS_E_MEMORY_ERROR;
188 }
189 dest->max_length = new_len;
190
191 memcpy(&dest->data[dest->length], src, src_len);
192 dest->length = tot_len;
193
194 return tot_len;
195 }
196}
197
198int _gnutls_string_append_data(gnutls_string * dest,
199 const void *data,
200 size_t data_size)
201{
202 size_t tot_len = data_size + dest->length;
203
204 if (dest->max_length >= tot_len)
205 {
206 memcpy(&dest->data[dest->length], data, data_size);
207 dest->length = tot_len;
208
209 return tot_len;
210 }
211 else
212 {
213 size_t new_len=
214 MAX (data_size, MIN_CHUNK) + MAX (dest->max_length, MIN_CHUNK);
215
216 dest->data = dest->realloc_func(dest->data, new_len);
217 if (dest->data == NULL)
218 {
219 gnutls_assert ();
220 return GNUTLS_E_MEMORY_ERROR;
221 }
222 dest->max_length = new_len;
223
224 memcpy(&dest->data[dest->length], data, data_size);
225 dest->length = tot_len;
226
227 return tot_len;
228 }
229}
230
231int _gnutls_string_append_printf(gnutls_string * dest,
232 const char *fmt,
233 ...)
234{
235 va_list args;
236 int len;
237 char *str;
238
239 va_start(args, fmt);
240 len = vasprintf(&str, fmt, args);
241 va_end(args);
242
243 if (len < 0 || !str)
244 return -1;
245
246 len = _gnutls_string_append_str(dest, str);
247
248 free(str);
249
250 return len;
251}
252
253/* Converts the given string (old) to hex. A buffer must be provided
254 * to hold the new hex string. The new string will be null terminated.
255 * If the buffer does not have enough space to hold the string, a
256 * truncated hex string is returned (always null terminated).
257 */
258char * _gnutls_bin2hex(const void *_old,
259 size_t oldlen,
260 char *buffer,
261 size_t buffer_size)
262{
263 unsigned int i, j;
264 const opaque *old = _old;
265
266 for (i = j = 0; i < oldlen && j + 2 < buffer_size; j += 2)
267 {
268 sprintf(&buffer[j], "%.2x", old[i]);
269 i++;
270 }
271 buffer[j] = '\0';
272
273 return buffer;
274}
275
276/* just a hex2bin function.
277 */
278int _gnutls_hex2bin(const opaque * hex_data,
279 int hex_size,
280 opaque * bin_data,
281 size_t * bin_size)
282{
283 int i, j;
284 opaque hex2_data[3];
285 unsigned long val;
286
287 /* FIXME: we don't handle whitespace.
288 */
289 hex_size /= 2;
290
291 if (*bin_size < (size_t) hex_size)
292 {
293 gnutls_assert ();
294 return GNUTLS_E_SHORT_MEMORY_BUFFER;
295 }
296
297 for (i = j = 0; j < hex_size; i += 2, j++)
298 {
299 hex2_data[0] = hex_data[i];
300 hex2_data[1] = hex_data[i + 1];
301 hex2_data[2] = 0;
302 val = strtoul((char *) hex2_data, NULL, 16);
303 if (val == ULONG_MAX)
304 {
305 gnutls_assert ();
306 return GNUTLS_E_SRP_PWD_PARSING_ERROR;
307 }
308 bin_data[j] = val;
309 }
310
311 return 0;
312}
diff --git a/src/daemon/https/tls/gnutls_str.h b/src/daemon/https/tls/gnutls_str.h
new file mode 100644
index 00000000..c805d70f
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_str.h
@@ -0,0 +1,67 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#ifndef GNUTLS_STR_H
26# define GNUTLS_STR_H
27
28#include <gnutls_int.h>
29
30#define MAX(X,Y) ((X) > (Y) ? (X) : (Y));
31
32void _gnutls_str_cpy (char *dest, size_t dest_tot_size, const char *src);
33void _gnutls_mem_cpy (char *dest, size_t dest_tot_size, const char *src,
34 size_t src_size);
35void _gnutls_str_cat (char *dest, size_t dest_tot_size, const char *src);
36
37typedef struct
38{
39 opaque * data;
40 size_t max_length;
41 size_t length;
42 gnutls_realloc_function realloc_func;
43 gnutls_alloc_function alloc_func;
44 gnutls_free_function free_func;
45} gnutls_string;
46
47void _gnutls_string_init (gnutls_string *, gnutls_alloc_function,
48 gnutls_realloc_function, gnutls_free_function);
49void _gnutls_string_clear (gnutls_string *);
50
51/* Beware, do not clear the string, after calling this
52 * function
53 */
54gnutls_datum_t _gnutls_string2datum (gnutls_string * str);
55
56int _gnutls_string_copy_str (gnutls_string * dest, const char *src);
57int _gnutls_string_append_str (gnutls_string *, const char *str);
58int _gnutls_string_append_data (gnutls_string *, const void *data,
59 size_t data_size);
60int _gnutls_string_append_printf (gnutls_string * dest, const char *fmt, ...);
61
62char *_gnutls_bin2hex (const void *old, size_t oldlen, char *buffer,
63 size_t buffer_size);
64int _gnutls_hex2bin (const opaque * hex_data, int hex_size, opaque * bin_data,
65 size_t * bin_size);
66
67#endif
diff --git a/src/daemon/https/tls/gnutls_supplemental.c b/src/daemon/https/tls/gnutls_supplemental.c
new file mode 100644
index 00000000..a47b9aaa
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_supplemental.c
@@ -0,0 +1,207 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains support functions for 'TLS Handshake Message for
26 * Supplemental Data' (RFC 4680).
27 *
28 * The idea here is simple. gnutls_handshake() in gnuts_handshake.c
29 * will call _gnutls_gen_supplemental and _gnutls_parse_supplemental
30 * when some extension requested that supplemental data be sent or
31 * received. Extension request this by setting the flags
32 * do_recv_supplemental or do_send_supplemental in the session.
33 *
34 * The functions in this file iterate through the _gnutls_supplemental
35 * array, and calls the send/recv functions for each respective data
36 * type.
37 *
38 * The receive function of each data type is responsible for decoding
39 * its own data. If the extension did not expect to receive
40 * supplemental data, it should return GNUTLS_E_UNEXPECTED_PACKET.
41 * Otherwise, it just parse the data as normal.
42 *
43 * The send function needs to append the 2-byte data format type, and
44 * append the 2-byte length of its data, and the data. If it doesn't
45 * want to send any data, it is fine to return without doing anything.
46 */
47
48#include "gnutls_int.h"
49#include "gnutls_supplemental.h"
50#include "gnutls_errors.h"
51#include "gnutls_num.h"
52
53typedef int (*supp_recv_func) (gnutls_session_t session,
54 const opaque * data, size_t data_size);
55typedef int (*supp_send_func) (gnutls_session_t session, gnutls_buffer * buf);
56
57typedef struct
58{
59 const char *name;
60 gnutls_supplemental_data_format_type_t type;
61 supp_recv_func supp_recv_func;
62 supp_send_func supp_send_func;
63} gnutls_supplemental_entry;
64
65gnutls_supplemental_entry _gnutls_supplemental[] = {
66 {0, 0, 0, 0}
67};
68
69const char *
70gnutls_supplemental_get_name (gnutls_supplemental_data_format_type_t type)
71{
72 gnutls_supplemental_entry *p;
73
74 for (p = _gnutls_supplemental; p->name != NULL; p++)
75 if (p->type == type)
76 return p->name;
77
78 return NULL;
79}
80
81static supp_recv_func
82get_supp_func_recv (gnutls_supplemental_data_format_type_t type)
83{
84 gnutls_supplemental_entry *p;
85
86 for (p = _gnutls_supplemental; p->name != NULL; p++)
87 if (p->type == type)
88 return p->supp_recv_func;
89
90 return NULL;
91}
92
93int
94_gnutls_gen_supplemental (gnutls_session_t session, gnutls_buffer * buf)
95{
96 gnutls_supplemental_entry *p;
97 int ret;
98
99 /* Make room for 3 byte length field. */
100 ret = _gnutls_buffer_append (buf, "\0\0\0", 3);
101 if (ret < 0)
102 {
103 gnutls_assert ();
104 return ret;
105 }
106
107 for (p = _gnutls_supplemental; p->name; p++)
108 {
109 supp_send_func supp_send = p->supp_send_func;
110 size_t sizepos = buf->length;
111 int ret;
112
113 /* Make room for supplement type and length byte length field. */
114 ret = _gnutls_buffer_append (buf, "\0\0\0\0", 4);
115 if (ret < 0)
116 {
117 gnutls_assert ();
118 return ret;
119 }
120
121 ret = supp_send (session, buf);
122 if (ret < 0)
123 {
124 gnutls_assert ();
125 return ret;
126 }
127
128 /* If data were added, store type+length, otherwise reset. */
129 if (buf->length > sizepos + 4)
130 {
131 buf->data[sizepos] = 0;
132 buf->data[sizepos + 1] = p->type;
133 buf->data[sizepos + 2] = ((buf->length - sizepos - 4) >> 8) & 0xFF;
134 buf->data[sizepos + 3] = (buf->length - sizepos - 4) & 0xFF;
135 }
136 else
137 buf->length -= 4;
138 }
139
140 buf->data[0] = ((buf->length - 3) >> 16) & 0xFF;
141 buf->data[1] = ((buf->length - 3) >> 8) & 0xFF;
142 buf->data[2] = (buf->length - 3) & 0xFF;
143
144 _gnutls_debug_log ("EXT[%x]: Sending %d bytes of supplemental data\n",
145 session, buf->length);
146
147 return buf->length;
148}
149
150int
151_gnutls_parse_supplemental (gnutls_session_t session,
152 const uint8_t * data, int datalen)
153{
154 const opaque *p = data;
155 ssize_t dsize = datalen;
156 size_t total_size;
157
158 DECR_LEN (dsize, 3);
159 total_size = _gnutls_read_uint24 (p);
160 p += 3;
161
162 if (dsize != total_size)
163 {
164 gnutls_assert ();
165 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
166 }
167
168 do
169 {
170 uint16_t supp_data_type;
171 uint16_t supp_data_length;
172 supp_recv_func recv_func;
173
174 DECR_LEN (dsize, 2);
175 supp_data_type = _gnutls_read_uint16 (p);
176 p += 2;
177
178 DECR_LEN (dsize, 2);
179 supp_data_length = _gnutls_read_uint16 (p);
180 p += 2;
181
182 _gnutls_debug_log ("EXT[%x]: Got supplemental type=%02x length=%d\n",
183 session, supp_data_type, supp_data_length);
184
185 recv_func = get_supp_func_recv (supp_data_type);
186 if (recv_func)
187 {
188 int ret = recv_func (session, p, supp_data_length);
189 if (ret < 0)
190 {
191 gnutls_assert ();
192 return ret;
193 }
194 }
195 else
196 {
197 gnutls_assert ();
198 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
199 }
200
201 DECR_LEN (dsize, supp_data_length);
202 p += supp_data_length;
203 }
204 while (dsize > 0);
205
206 return 0;
207}
diff --git a/src/daemon/https/tls/gnutls_supplemental.h b/src/daemon/https/tls/gnutls_supplemental.h
new file mode 100644
index 00000000..0b9c1207
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_supplemental.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26
27int _gnutls_parse_supplemental (gnutls_session_t session,
28 const uint8_t *data,
29 int data_size);
30int _gnutls_gen_supplemental (gnutls_session_t session,
31 gnutls_buffer *buf);
diff --git a/src/daemon/https/tls/gnutls_ui.c b/src/daemon/https/tls/gnutls_ui.c
new file mode 100644
index 00000000..49ed2e96
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_ui.c
@@ -0,0 +1,627 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This file contains certificate authentication functions to be exported in the
26 * API and did not fit elsewhere.
27 */
28
29#include <gnutls_int.h>
30#include <auth_anon.h>
31#include <auth_cert.h>
32#include <gnutls_errors.h>
33#include <gnutls_auth_int.h>
34#include <gnutls_state.h>
35#include <gnutls_datum.h>
36
37/* ANON & DHE */
38
39/**
40 * gnutls_dh_set_prime_bits - Used to set the bits for a DH ciphersuite
41 * @session: is a #gnutls_session_t structure.
42 * @bits: is the number of bits
43 *
44 * This function sets the number of bits, for use in an
45 * Diffie Hellman key exchange. This is used both in DH ephemeral and
46 * DH anonymous cipher suites. This will set the
47 * minimum size of the prime that will be used for the handshake.
48 *
49 * In the client side it sets the minimum accepted number of bits.
50 * If a server sends a prime with less bits than that
51 * GNUTLS_E_DH_PRIME_UNACCEPTABLE will be returned by the
52 * handshake.
53 *
54 **/
55void
56gnutls_dh_set_prime_bits (gnutls_session_t session, unsigned int bits)
57{
58 session->internals.dh_prime_bits = bits;
59}
60
61/**
62 * gnutls_dh_get_group - This function returns the group of the DH authentication
63 * @session: is a gnutls session
64 * @raw_gen: will hold the generator.
65 * @raw_prime: will hold the prime.
66 *
67 * This function will return the group parameters used in the last Diffie Hellman
68 * authentication with the peer. These are the prime and the generator used.
69 * This function should be used for both anonymous and ephemeral diffie Hellman.
70 * The output parameters must be freed with gnutls_free().
71 *
72 * Returns a negative value in case of an error.
73 *
74 **/
75int
76gnutls_dh_get_group (gnutls_session_t session,
77 gnutls_datum_t * raw_gen, gnutls_datum_t * raw_prime)
78{
79 dh_info_st *dh;
80 int ret;
81 anon_auth_info_t anon_info;
82 cert_auth_info_t cert_info;
83
84 switch (gnutls_auth_get_type (session))
85 {
86 case GNUTLS_CRD_ANON:
87 anon_info = _gnutls_get_auth_info (session);
88 if (anon_info == NULL)
89 return GNUTLS_E_INTERNAL_ERROR;
90 dh = &anon_info->dh;
91 break;
92 case GNUTLS_CRD_CERTIFICATE:
93 cert_info = _gnutls_get_auth_info (session);
94 if (cert_info == NULL)
95 return GNUTLS_E_INTERNAL_ERROR;
96 dh = &cert_info->dh;
97 break;
98 default:
99 gnutls_assert ();
100 return GNUTLS_E_INVALID_REQUEST;
101 }
102
103 ret = _gnutls_set_datum (raw_prime, dh->prime.data, dh->prime.size);
104 if (ret < 0)
105 {
106 gnutls_assert ();
107 return ret;
108 }
109
110 ret = _gnutls_set_datum (raw_gen, dh->generator.data, dh->generator.size);
111 if (ret < 0)
112 {
113 gnutls_assert ();
114 _gnutls_free_datum (raw_prime);
115 return ret;
116 }
117
118 return 0;
119}
120
121/**
122 * gnutls_dh_get_pubkey - This function returns the peer's public key used in DH authentication
123 * @session: is a gnutls session
124 * @raw_key: will hold the public key.
125 *
126 * This function will return the peer's public key used in the last Diffie Hellman authentication.
127 * This function should be used for both anonymous and ephemeral diffie Hellman.
128 * The output parameters must be freed with gnutls_free().
129 *
130 * Returns a negative value in case of an error.
131 *
132 **/
133int
134gnutls_dh_get_pubkey (gnutls_session_t session, gnutls_datum_t * raw_key)
135{
136 dh_info_st *dh;
137 anon_auth_info_t anon_info;
138 cert_auth_info_t cert_info;
139 cert_auth_info_t psk_info;
140
141 switch (gnutls_auth_get_type (session))
142 {
143 case GNUTLS_CRD_ANON:
144 {
145 anon_info = _gnutls_get_auth_info (session);
146 if (anon_info == NULL)
147 return GNUTLS_E_INTERNAL_ERROR;
148 dh = &anon_info->dh;
149 break;
150 }
151 case GNUTLS_CRD_PSK:
152 {
153 psk_info = _gnutls_get_auth_info (session);
154 if (psk_info == NULL)
155 return GNUTLS_E_INTERNAL_ERROR;
156 dh = &psk_info->dh;
157 break;
158 }
159 case GNUTLS_CRD_CERTIFICATE:
160 {
161
162 cert_info = _gnutls_get_auth_info (session);
163 if (cert_info == NULL)
164 return GNUTLS_E_INTERNAL_ERROR;
165 dh = &cert_info->dh;
166 break;
167 }
168 default:
169 gnutls_assert ();
170 return GNUTLS_E_INVALID_REQUEST;
171 }
172
173 return _gnutls_set_datum (raw_key, dh->public_key.data,
174 dh->public_key.size);
175}
176
177/**
178 * gnutls_rsa_export_get_pubkey - This function returns the peer's public key used in RSA-EXPORT authentication
179 * @session: is a gnutls session
180 * @exponent: will hold the exponent.
181 * @modulus: will hold the modulus.
182 *
183 * This function will return the peer's public key exponent and
184 * modulus used in the last RSA-EXPORT authentication. The output
185 * parameters must be freed with gnutls_free().
186 *
187 * Returns a negative value in case of an error.
188 *
189 **/
190int
191gnutls_rsa_export_get_pubkey (gnutls_session_t session,
192 gnutls_datum_t * exponent,
193 gnutls_datum_t * modulus)
194{
195 cert_auth_info_t info;
196 int ret;
197
198 if (gnutls_auth_get_type (session) == GNUTLS_CRD_CERTIFICATE)
199 {
200 info = _gnutls_get_auth_info (session);
201 if (info == NULL)
202 return GNUTLS_E_INTERNAL_ERROR;
203
204 ret = _gnutls_set_datum (modulus, info->rsa_export.modulus.data,
205 info->rsa_export.modulus.size);
206 if (ret < 0)
207 {
208 gnutls_assert ();
209 return ret;
210 }
211
212 ret = _gnutls_set_datum (exponent, info->rsa_export.exponent.data,
213 info->rsa_export.exponent.size);
214 if (ret < 0)
215 {
216 gnutls_assert ();
217 _gnutls_free_datum (modulus);
218 return ret;
219 }
220
221 return 0;
222 }
223
224 return GNUTLS_E_INVALID_REQUEST;
225}
226
227/**
228 * gnutls_dh_get_secret_bits - This function returns the bits used in DH authentication
229 * @session: is a gnutls session
230 *
231 * This function will return the bits used in the last Diffie Hellman authentication
232 * with the peer. Should be used for both anonymous and ephemeral diffie Hellman.
233 * Returns a negative value in case of an error.
234 *
235 **/
236int
237gnutls_dh_get_secret_bits (gnutls_session_t session)
238{
239 switch (gnutls_auth_get_type (session))
240 {
241 case GNUTLS_CRD_ANON:
242 {
243 anon_auth_info_t info;
244
245 info = _gnutls_get_auth_info (session);
246 if (info == NULL)
247 return GNUTLS_E_INTERNAL_ERROR;
248 return info->dh.secret_bits;
249 }
250 case GNUTLS_CRD_CERTIFICATE:
251 {
252 cert_auth_info_t info;
253
254 info = _gnutls_get_auth_info (session);
255 if (info == NULL)
256 return GNUTLS_E_INTERNAL_ERROR;
257
258 return info->dh.secret_bits;
259 }
260 default:
261 gnutls_assert ();
262 return GNUTLS_E_INVALID_REQUEST;
263 }
264}
265
266/**
267 * gnutls_dh_get_prime_bits - This function returns the bits used in DH authentication
268 * @session: is a gnutls session
269 *
270 * This function will return the bits of the prime used in the last Diffie Hellman authentication
271 * with the peer. Should be used for both anonymous and ephemeral diffie Hellman.
272 * Returns a negative value in case of an error.
273 *
274 **/
275int
276gnutls_dh_get_prime_bits (gnutls_session_t session)
277{
278 dh_info_st *dh;
279
280 switch (gnutls_auth_get_type (session))
281 {
282 case GNUTLS_CRD_ANON:
283 {
284 anon_auth_info_t info;
285
286 info = _gnutls_get_auth_info (session);
287 if (info == NULL)
288 return GNUTLS_E_INTERNAL_ERROR;
289 dh = &info->dh;
290 break;
291 }
292 case GNUTLS_CRD_CERTIFICATE:
293 {
294 cert_auth_info_t info;
295
296 info = _gnutls_get_auth_info (session);
297 if (info == NULL)
298 return GNUTLS_E_INTERNAL_ERROR;
299
300 dh = &info->dh;
301 break;
302 }
303 default:
304 gnutls_assert ();
305 return GNUTLS_E_INVALID_REQUEST;
306 }
307
308 return (dh->prime.size) * 8;
309
310}
311
312/**
313 * gnutls_rsa_export_get_modulus_bits - This function returns the bits used in RSA-export key exchange
314 * @session: is a gnutls session
315 *
316 * This function will return the bits used in the last RSA-EXPORT key exchange
317 * with the peer.
318 * Returns a negative value in case of an error.
319 *
320 **/
321int
322gnutls_rsa_export_get_modulus_bits (gnutls_session_t session)
323{
324 cert_auth_info_t info;
325
326 info = _gnutls_get_auth_info (session);
327 if (info == NULL)
328 return GNUTLS_E_INTERNAL_ERROR;
329
330 return info->rsa_export.modulus.size * 8;
331}
332
333/**
334 * gnutls_dh_get_peers_public_bits - This function returns the bits used in DH authentication
335 * @session: is a gnutls session
336 *
337 * This function will return the bits used in the last Diffie Hellman authentication
338 * with the peer. Should be used for both anonymous and ephemeral diffie Hellman.
339 * Returns a negative value in case of an error.
340 *
341 **/
342int
343gnutls_dh_get_peers_public_bits (gnutls_session_t session)
344{
345 dh_info_st *dh;
346
347 switch (gnutls_auth_get_type (session))
348 {
349 case GNUTLS_CRD_ANON:
350 {
351 anon_auth_info_t info;
352
353 info = _gnutls_get_auth_info (session);
354 if (info == NULL)
355 return GNUTLS_E_INTERNAL_ERROR;
356
357 dh = &info->dh;
358 break;
359 }
360 case GNUTLS_CRD_CERTIFICATE:
361 {
362 cert_auth_info_t info;
363
364 info = _gnutls_get_auth_info (session);
365 if (info == NULL)
366 return GNUTLS_E_INTERNAL_ERROR;
367
368 dh = &info->dh;
369 break;
370 }
371 default:
372 gnutls_assert ();
373 return GNUTLS_E_INVALID_REQUEST;
374 }
375
376 return dh->public_key.size * 8;
377
378}
379
380/* CERTIFICATE STUFF */
381
382/**
383 * gnutls_certificate_get_ours - This function returns the raw certificate sent in the last handshake
384 * @session: is a gnutls session
385 *
386 * This function will return the certificate as sent to the peer,
387 * in the last handshake. These certificates are in raw format.
388 * In X.509 this is a certificate list. In OpenPGP this is a single
389 * certificate.
390 * Returns NULL in case of an error, or if no certificate was used.
391 *
392 **/
393const gnutls_datum_t *
394gnutls_certificate_get_ours (gnutls_session_t session)
395{
396 gnutls_certificate_credentials_t cred;
397
398 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, NULL);
399
400 cred
401 = (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
402 GNUTLS_CRD_CERTIFICATE,
403 NULL);
404 if (cred == NULL || cred->cert_list == NULL)
405 {
406 gnutls_assert ();
407 return NULL;
408 }
409
410 if (session->internals.selected_cert_list == NULL)
411 return NULL;
412
413 return &session->internals.selected_cert_list[0].raw;
414}
415
416/**
417 * gnutls_certificate_get_peers - This function returns the peer's raw certificate
418 * @session: is a gnutls session
419 * @list_size: is the length of the certificate list
420 *
421 * This function will return the peer's raw certificate (chain) as
422 * sent by the peer. These certificates are in raw format (DER encoded
423 * for X.509). In case of a X.509 then a certificate list may be present.
424 * The first certificate in the list is the peer's certificate,
425 * following the issuer's certificate, then the issuer's issuer etc.
426 *
427 * In case of OpenPGP keys a single key will be returned
428 * in raw format.
429 *
430 * Returns NULL in case of an error, or if no certificate was sent.
431 *
432 **/
433const gnutls_datum_t *
434gnutls_certificate_get_peers (gnutls_session_t
435 session, unsigned int *list_size)
436{
437 cert_auth_info_t info;
438
439 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, NULL);
440
441 info = _gnutls_get_auth_info (session);
442 if (info == NULL)
443 return NULL;
444
445 *list_size = info->ncerts;
446 return info->raw_certificate_list;
447}
448
449/**
450 * gnutls_certificate_client_get_request_status - This function returns the certificate request status
451 * @session: is a gnutls session
452 *
453 * This function will return 0 if the peer (server) did not request client
454 * authentication or 1 otherwise.
455 * Returns a negative value in case of an error.
456 *
457 **/
458int
459gnutls_certificate_client_get_request_status (gnutls_session_t session)
460{
461 cert_auth_info_t info;
462
463 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, 0);
464
465 info = _gnutls_get_auth_info (session);
466 if (info == NULL)
467 return GNUTLS_E_INTERNAL_ERROR;
468 return info->certificate_requested;
469}
470
471/**
472 * gnutls_fingerprint - This function calculates the fingerprint of the given data
473 * @algo: is a digest algorithm
474 * @data: is the data
475 * @result: is the place where the result will be copied (may be null).
476 * @result_size: should hold the size of the result. The actual size
477 * of the returned result will also be copied there.
478 *
479 * This function will calculate a fingerprint (actually a hash), of the
480 * given data. The result is not printable data. You should convert it
481 * to hex, or to something else printable.
482 *
483 * This is the usual way to calculate a fingerprint of an X.509
484 * DER encoded certificate. Note however that the fingerprint
485 * of an OpenPGP is not just a hash and cannot be calculated with
486 * this function.
487 *
488 * Returns a negative value in case of an error.
489 *
490 **/
491int
492gnutls_fingerprint (gnutls_digest_algorithm_t algo,
493 const gnutls_datum_t * data,
494 void *result, size_t * result_size)
495{
496 GNUTLS_HASH_HANDLE td;
497 int hash_len = _gnutls_hash_get_algo_len (HASH2MAC (algo));
498
499 if (hash_len < 0 || (unsigned) hash_len > *result_size || result == NULL)
500 {
501 *result_size = hash_len;
502 return GNUTLS_E_SHORT_MEMORY_BUFFER;
503 }
504 *result_size = hash_len;
505
506 if (result)
507 {
508 td = _gnutls_hash_init (HASH2MAC (algo));
509 if (td == NULL)
510 return GNUTLS_E_HASH_FAILED;
511
512 _gnutls_hash (td, data->data, data->size);
513
514 _gnutls_hash_deinit (td, result);
515 }
516
517 return 0;
518}
519
520/**
521 * gnutls_certificate_set_dh_params - This function will set the DH parameters for a server to use
522 * @res: is a gnutls_certificate_credentials_t structure
523 * @dh_params: is a structure that holds diffie hellman parameters.
524 *
525 * This function will set the diffie hellman parameters for a
526 * certificate server to use. These parameters will be used in
527 * Ephemeral Diffie Hellman cipher suites. Note that only a pointer
528 * to the parameters are stored in the certificate handle, so if you
529 * deallocate the parameters before the certificate is deallocated,
530 * you must change the parameters stored in the certificate first.
531 *
532 **/
533void
534gnutls_certificate_set_dh_params (gnutls_certificate_credentials_t res,
535 gnutls_dh_params_t dh_params)
536{
537 res->dh_params = dh_params;
538}
539
540/**
541 * gnutls_certificate_set_params_function - This function will set the DH or RSA parameters callback
542 * @res: is a gnutls_certificate_credentials_t structure
543 * @func: is the function to be called
544 *
545 * This function will set a callback in order for the server to get the
546 * diffie hellman or RSA parameters for certificate authentication. The callback
547 * should return zero on success.
548 *
549 **/
550void
551gnutls_certificate_set_params_function (gnutls_certificate_credentials_t res,
552 gnutls_params_function * func)
553{
554 res->params_func = func;
555}
556
557/**
558 * gnutls_certificate_set_verify_flags - This function will set the flags to be used at certificate verification
559 * @res: is a gnutls_certificate_credentials_t structure
560 * @flags: are the flags
561 *
562 * This function will set the flags to be used at verification of the
563 * certificates. Flags must be OR of the
564 * #gnutls_certificate_verify_flags enumerations.
565 *
566 **/
567void
568gnutls_certificate_set_verify_flags (gnutls_certificate_credentials_t
569 res, unsigned int flags)
570{
571 res->verify_flags = flags;
572}
573
574/**
575 * gnutls_certificate_set_verify_limits - This function will set the upper limits to be used at certificate verification
576 * @res: is a gnutls_certificate_credentials structure
577 * @max_bits: is the number of bits of an acceptable certificate (default 8200)
578 * @max_depth: is maximum depth of the verification of a certificate chain (default 5)
579 *
580 * This function will set some upper limits for the default verification function,
581 * gnutls_certificate_verify_peers2(), to avoid denial of service attacks.
582 * You can set them to zero to disable limits.
583 *
584 **/
585void
586gnutls_certificate_set_verify_limits (gnutls_certificate_credentials_t
587 res,
588 unsigned int max_bits,
589 unsigned int max_depth)
590{
591 res->verify_depth = max_depth;
592 res->verify_bits = max_bits;
593}
594
595/**
596 * gnutls_certificate_set_rsa_export_params - This function will set the RSA parameters for a server to use
597 * @res: is a gnutls_certificate_credentials_t structure
598 * @rsa_params: is a structure that holds temporary RSA parameters.
599 *
600 * This function will set the temporary RSA parameters for a certificate
601 * server to use. These parameters will be used in RSA-EXPORT
602 * cipher suites.
603 *
604 **/
605void
606gnutls_certificate_set_rsa_export_params (gnutls_certificate_credentials_t
607 res, gnutls_rsa_params_t rsa_params)
608{
609 res->rsa_params = rsa_params;
610}
611
612/**
613 * gnutls_anon_set_params_function - This function will set the DH or RSA parameters callback
614 * @res: is a gnutls_anon_server_credentials_t structure
615 * @func: is the function to be called
616 *
617 * This function will set a callback in order for the server to get the
618 * diffie hellman or RSA parameters for anonymous authentication. The callback
619 * should return zero on success.
620 *
621 **/
622void
623gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res,
624 gnutls_params_function * func)
625{
626 res->params_func = func;
627}
diff --git a/src/daemon/https/tls/gnutls_v2_compat.c b/src/daemon/https/tls/gnutls_v2_compat.c
new file mode 100644
index 00000000..ecf8c936
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_v2_compat.c
@@ -0,0 +1,259 @@
1/*
2 * Copyright (C) 2001, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Functions to parse the SSLv2.0 hello message.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_errors.h"
30#include "gnutls_dh.h"
31#include "debug.h"
32#include "gnutls_algorithms.h"
33#include "gnutls_compress.h"
34#include "gnutls_cipher.h"
35#include "gnutls_buffers.h"
36#include "gnutls_kx.h"
37#include "gnutls_handshake.h"
38#include "gnutls_num.h"
39#include "gnutls_hash_int.h"
40#include "gnutls_db.h"
41#include "gnutls_extensions.h"
42#include "gnutls_auth_int.h"
43
44/* This selects the best supported ciphersuite from the ones provided */
45static int
46_gnutls_handshake_select_v2_suite (gnutls_session_t session,
47 opaque * data, int datalen)
48{
49 int i, j, ret;
50 opaque *_data;
51 int _datalen;
52
53 _gnutls_handshake_log ("HSK[%x]: Parsing a version 2.0 client hello.\n",
54 session);
55
56 _data = gnutls_malloc (datalen);
57 if (_data == NULL)
58 {
59 gnutls_assert ();
60 return GNUTLS_E_MEMORY_ERROR;
61 }
62
63 if (datalen % 3 != 0)
64 {
65 gnutls_assert ();
66 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
67 }
68
69 i = _datalen = 0;
70 for (j = 0; j < datalen; j += 3)
71 {
72 if (data[j] == 0)
73 {
74 memcpy (&_data[i], &data[j + 1], 2);
75 i += 2;
76 _datalen += 2;
77 }
78 }
79
80 ret = _gnutls_server_select_suite (session, _data, _datalen);
81 gnutls_free (_data);
82
83 return ret;
84
85}
86
87
88/* Read a v2 client hello. Some browsers still use that beast!
89 * However they set their version to 3.0 or 3.1.
90 */
91int
92_gnutls_read_client_hello_v2 (gnutls_session_t session, opaque * data,
93 int datalen)
94{
95 uint16_t session_id_len = 0;
96 int pos = 0;
97 int ret = 0;
98 uint16_t sizeOfSuites;
99 gnutls_protocol_t adv_version;
100 opaque rnd[TLS_RANDOM_SIZE];
101 int len = datalen;
102 int err;
103 uint16_t challenge;
104 opaque session_id[TLS_MAX_SESSION_ID_SIZE];
105
106 /* we only want to get here once - only in client hello */
107 session->internals.v2_hello = 0;
108
109 DECR_LEN (len, 2);
110
111 _gnutls_handshake_log
112 ("HSK[%x]: SSL 2.0 Hello: Client's version: %d.%d\n", session,
113 data[pos], data[pos + 1]);
114
115 set_adv_version (session, data[pos], data[pos + 1]);
116
117 adv_version = _gnutls_version_get (data[pos], data[pos + 1]);
118
119 ret = _gnutls_negotiate_version (session, adv_version);
120 if (ret < 0)
121 {
122 gnutls_assert ();
123 return ret;
124 }
125
126 pos += 2;
127
128 /* Read uint16_t cipher_spec_length */
129 DECR_LEN (len, 2);
130 sizeOfSuites = _gnutls_read_uint16 (&data[pos]);
131 pos += 2;
132
133 /* read session id length */
134 DECR_LEN (len, 2);
135 session_id_len = _gnutls_read_uint16 (&data[pos]);
136 pos += 2;
137
138 if (session_id_len > TLS_MAX_SESSION_ID_SIZE)
139 {
140 gnutls_assert ();
141 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
142 }
143
144 /* read challenge length */
145 DECR_LEN (len, 2);
146 challenge = _gnutls_read_uint16 (&data[pos]);
147 pos += 2;
148
149 if (challenge < 16 || challenge > TLS_RANDOM_SIZE)
150 {
151 gnutls_assert ();
152 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
153 }
154
155 /* call the user hello callback
156 */
157 ret = _gnutls_user_hello_func (session, adv_version);
158 if (ret < 0)
159 {
160 gnutls_assert ();
161 return ret;
162 }
163
164 /* find an appropriate cipher suite */
165
166 DECR_LEN (len, sizeOfSuites);
167 ret = _gnutls_handshake_select_v2_suite (session, &data[pos], sizeOfSuites);
168
169 pos += sizeOfSuites;
170 if (ret < 0)
171 {
172 gnutls_assert ();
173 return ret;
174 }
175
176 /* check if the credentials (username, public key etc.) are ok
177 */
178 if (_gnutls_get_kx_cred
179 (session,
180 _gnutls_cipher_suite_get_kx_algo (&session->security_parameters.
181 current_cipher_suite),
182 &err) == NULL && err != 0)
183 {
184 gnutls_assert ();
185 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
186 }
187
188 /* set the mod_auth_st to the appropriate struct
189 * according to the KX algorithm. This is needed since all the
190 * handshake functions are read from there;
191 */
192 session->internals.auth_struct =
193 _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo
194 (&session->security_parameters.
195 current_cipher_suite));
196 if (session->internals.auth_struct == NULL)
197 {
198
199 _gnutls_handshake_log
200 ("HSK[%x]: SSL 2.0 Hello: Cannot find the appropriate handler for the KX algorithm\n",
201 session);
202
203 gnutls_assert ();
204 return GNUTLS_E_INTERNAL_ERROR;
205 }
206
207
208
209 /* read random new values -skip session id for now */
210 DECR_LEN (len, session_id_len); /* skip session id for now */
211 memcpy (session_id, &data[pos], session_id_len);
212 pos += session_id_len;
213
214 DECR_LEN (len, challenge);
215 memset (rnd, 0, TLS_RANDOM_SIZE);
216
217 memcpy (&rnd[TLS_RANDOM_SIZE - challenge], &data[pos], challenge);
218
219 _gnutls_set_client_random (session, rnd);
220
221 /* generate server random value */
222
223 _gnutls_tls_create_random (rnd);
224 _gnutls_set_server_random (session, rnd);
225
226 session->security_parameters.timestamp = time (NULL);
227
228
229 /* RESUME SESSION */
230
231 DECR_LEN (len, session_id_len);
232 ret = _gnutls_server_restore_session (session, session_id, session_id_len);
233
234 if (ret == 0)
235 { /* resumed! */
236 /* get the new random values */
237 memcpy (session->internals.resumed_security_parameters.
238 server_random, session->security_parameters.server_random,
239 TLS_RANDOM_SIZE);
240 memcpy (session->internals.resumed_security_parameters.
241 client_random, session->security_parameters.client_random,
242 TLS_RANDOM_SIZE);
243
244 session->internals.resumed = RESUME_TRUE;
245 return 0;
246 }
247 else
248 {
249 _gnutls_generate_session_id (session->security_parameters.
250 session_id,
251 &session->security_parameters.
252 session_id_size);
253 session->internals.resumed = RESUME_FALSE;
254 }
255
256 session->internals.compression_method = GNUTLS_COMP_NULL;
257
258 return 0;
259}
diff --git a/src/daemon/https/tls/gnutls_v2_compat.h b/src/daemon/https/tls/gnutls_v2_compat.h
new file mode 100644
index 00000000..59ee6130
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_v2_compat.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_read_client_hello_v2 (gnutls_session_t session, opaque * data,
26 int datalen);
diff --git a/src/daemon/https/tls/gnutls_x509.c b/src/daemon/https/tls/gnutls_x509.c
new file mode 100644
index 00000000..29d20957
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_x509.c
@@ -0,0 +1,1991 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <gnutls_int.h>
26#include "gnutls_auth_int.h"
27#include "gnutls_errors.h"
28#include <gnutls_cert.h>
29#include <auth_cert.h>
30#include "gnutls_dh.h"
31#include "gnutls_num.h"
32#include "libtasn1.h"
33#include "gnutls_datum.h"
34#include <gnutls_pk.h>
35#include <gnutls_algorithms.h>
36#include <gnutls_global.h>
37#include <gnutls_record.h>
38#include <gnutls_sig.h>
39#include <gnutls_state.h>
40#include <gnutls_pk.h>
41#include <gnutls_str.h>
42#include <debug.h>
43#include <x509_b64.h>
44#include <gnutls_x509.h>
45#include <read-file.h>
46
47/* x509 */
48#include "common.h"
49#include "x509.h"
50#include "verify.h"
51#include "mpi.h"
52#include "pkcs7.h"
53#include "privkey.h"
54
55
56/*
57 * some x509 certificate parsing functions.
58 */
59
60/* Check if the number of bits of the key in the certificate
61 * is unacceptable.
62 */
63inline static int
64check_bits (gnutls_x509_crt_t crt, unsigned int max_bits)
65{
66 int ret;
67 unsigned int bits;
68
69 ret = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
70 if (ret < 0)
71 {
72 gnutls_assert ();
73 return ret;
74 }
75
76 if (bits > max_bits && max_bits > 0)
77 {
78 gnutls_assert ();
79 return GNUTLS_E_CONSTRAINT_ERROR;
80 }
81
82 return 0;
83}
84
85
86#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
87 if (peer_certificate_list[x]) \
88 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
89 } \
90 gnutls_free( peer_certificate_list)
91
92/*-
93 * _gnutls_x509_cert_verify_peers - This function returns the peer's certificate status
94 * @session: is a gnutls session
95 *
96 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
97 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
98 * However you must also check the peer's name in order to check if the verified certificate belongs to the
99 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
100 *
101 -*/
102int
103_gnutls_x509_cert_verify_peers (gnutls_session_t session,
104 unsigned int *status)
105{
106 cert_auth_info_t info;
107 gnutls_certificate_credentials_t cred;
108 gnutls_x509_crt_t *peer_certificate_list;
109 int peer_certificate_list_size, i, x, ret;
110
111 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
112
113 info = _gnutls_get_auth_info (session);
114 if (info == NULL)
115 {
116 gnutls_assert ();
117 return GNUTLS_E_INVALID_REQUEST;
118 }
119
120 cred = (gnutls_certificate_credentials_t)
121 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
122 if (cred == NULL)
123 {
124 gnutls_assert ();
125 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
126 }
127
128 if (info->raw_certificate_list == NULL || info->ncerts == 0)
129 return GNUTLS_E_NO_CERTIFICATE_FOUND;
130
131 if (info->ncerts > cred->verify_depth && cred->verify_depth > 0)
132 {
133 gnutls_assert ();
134 return GNUTLS_E_CONSTRAINT_ERROR;
135 }
136
137 /* generate a list of gnutls_certs based on the auth info
138 * raw certs.
139 */
140 peer_certificate_list_size = info->ncerts;
141 peer_certificate_list =
142 gnutls_calloc (1,
143 peer_certificate_list_size * sizeof (gnutls_x509_crt_t));
144 if (peer_certificate_list == NULL)
145 {
146 gnutls_assert ();
147 return GNUTLS_E_MEMORY_ERROR;
148 }
149
150 for (i = 0; i < peer_certificate_list_size; i++)
151 {
152 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
153 if (ret < 0)
154 {
155 gnutls_assert ();
156 CLEAR_CERTS;
157 return ret;
158 }
159
160 ret =
161 gnutls_x509_crt_import (peer_certificate_list[i],
162 &info->raw_certificate_list[i],
163 GNUTLS_X509_FMT_DER);
164 if (ret < 0)
165 {
166 gnutls_assert ();
167 CLEAR_CERTS;
168 return ret;
169 }
170
171 ret = check_bits (peer_certificate_list[i], cred->verify_bits);
172 if (ret < 0)
173 {
174 gnutls_assert ();
175 CLEAR_CERTS;
176 return ret;
177 }
178
179 }
180
181 /* Verify certificate
182 */
183 ret =
184 gnutls_x509_crt_list_verify (peer_certificate_list,
185 peer_certificate_list_size,
186 cred->x509_ca_list, cred->x509_ncas,
187 cred->x509_crl_list, cred->x509_ncrls,
188 cred->verify_flags, status);
189
190 CLEAR_CERTS;
191
192 if (ret < 0)
193 {
194 gnutls_assert ();
195 return ret;
196 }
197
198 return 0;
199}
200
201/*
202 * Read certificates and private keys, from files, memory etc.
203 */
204
205/* returns error if the certificate has different algorithm than
206 * the given key parameters.
207 */
208static int
209_gnutls_check_key_cert_match (gnutls_certificate_credentials_t res)
210{
211 gnutls_datum_t cid;
212 gnutls_datum_t kid;
213 unsigned pk = res->cert_list[res->ncerts - 1][0].subject_pk_algorithm;
214
215 if (res->pkey[res->ncerts - 1].pk_algorithm != pk)
216 {
217 gnutls_assert ();
218 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
219 }
220
221 _gnutls_x509_write_rsa_params (res->pkey[res->ncerts - 1].params,
222 res->pkey[res->ncerts -
223 1].params_size, &kid);
224
225
226 _gnutls_x509_write_rsa_params (res->cert_list[res->ncerts - 1][0].
227 params,
228 res->cert_list[res->ncerts -
229 1][0].params_size, &cid);
230
231 if (cid.size != kid.size)
232 {
233 gnutls_assert ();
234 _gnutls_free_datum (&kid);
235 _gnutls_free_datum (&cid);
236 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
237 }
238
239 if (memcmp (kid.data, cid.data, kid.size) != 0)
240 {
241 gnutls_assert ();
242 _gnutls_free_datum (&kid);
243 _gnutls_free_datum (&cid);
244 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
245 }
246
247 _gnutls_free_datum (&kid);
248 _gnutls_free_datum (&cid);
249 return 0;
250}
251
252/* Reads a DER encoded certificate list from memory and stores it to
253 * a gnutls_cert structure. This is only called if PKCS7 read fails.
254 * returns the number of certificates parsed (1)
255 */
256static int
257parse_crt_mem (gnutls_cert ** cert_list, unsigned *ncerts,
258 gnutls_x509_crt_t cert)
259{
260 int i;
261 int ret;
262
263 i = *ncerts + 1;
264
265 *cert_list =
266 (gnutls_cert *) gnutls_realloc_fast (*cert_list,
267 i * sizeof (gnutls_cert));
268
269 if (*cert_list == NULL)
270 {
271 gnutls_assert ();
272 return GNUTLS_E_MEMORY_ERROR;
273 }
274
275 ret = _gnutls_x509_crt_to_gcert (&cert_list[0][i - 1], cert, 0);
276 if (ret < 0)
277 {
278 gnutls_assert ();
279 return ret;
280 }
281
282 *ncerts = i;
283
284 return 1; /* one certificate parsed */
285}
286
287/* Reads a DER encoded certificate list from memory and stores it to
288 * a gnutls_cert structure. This is only called if PKCS7 read fails.
289 * returns the number of certificates parsed (1)
290 */
291static int
292parse_der_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts,
293 const void *input_cert, int input_cert_size)
294{
295 gnutls_datum_t tmp;
296 gnutls_x509_crt_t cert;
297 int ret;
298
299 ret = gnutls_x509_crt_init (&cert);
300 if (ret < 0)
301 {
302 gnutls_assert ();
303 return ret;
304 }
305
306 tmp.data = (opaque *) input_cert;
307 tmp.size = input_cert_size;
308
309 ret = gnutls_x509_crt_import (cert, &tmp, GNUTLS_X509_FMT_DER);
310 if (ret < 0)
311 {
312 gnutls_assert ();
313 gnutls_x509_crt_deinit (cert);
314 return ret;
315 }
316
317 ret = parse_crt_mem (cert_list, ncerts, cert);
318 gnutls_x509_crt_deinit (cert);
319
320 return ret;
321}
322
323#define CERT_PEM 1
324
325
326/* Reads a PKCS7 base64 encoded certificate list from memory and stores it to
327 * a gnutls_cert structure.
328 * returns the number of certificate parsed
329 */
330static int
331parse_pkcs7_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts, const
332 void *input_cert, int input_cert_size, int flags)
333{
334#ifdef ENABLE_PKI
335 int i, j, count;
336 gnutls_datum_t tmp, tmp2;
337 int ret;
338 opaque *pcert = NULL;
339 size_t pcert_size;
340 gnutls_pkcs7_t pkcs7;
341
342 ret = gnutls_pkcs7_init (&pkcs7);
343 if (ret < 0)
344 {
345 gnutls_assert ();
346 return ret;
347 }
348
349 if (flags & CERT_PEM)
350 ret = gnutls_pkcs7_import (pkcs7, &tmp, GNUTLS_X509_FMT_PEM);
351 else
352 ret = gnutls_pkcs7_import (pkcs7, &tmp, GNUTLS_X509_FMT_DER);
353 if (ret < 0)
354 {
355 /* if we failed to read the structure,
356 * then just try to decode a plain DER
357 * certificate.
358 */
359 gnutls_assert ();
360 gnutls_pkcs7_deinit (pkcs7);
361#endif
362 return parse_der_cert_mem (cert_list, ncerts,
363 input_cert, input_cert_size);
364#ifdef ENABLE_PKI
365 }
366
367 i = *ncerts + 1;
368
369 /* tmp now contains the decoded certificate list */
370 tmp.data = (opaque *) input_cert;
371 tmp.size = input_cert_size;
372
373 ret = gnutls_pkcs7_get_crt_count (pkcs7);
374
375 if (ret < 0)
376 {
377 gnutls_assert ();
378 gnutls_pkcs7_deinit (pkcs7);
379 return ret;
380 }
381 count = ret;
382
383 j = count - 1;
384 do
385 {
386 pcert_size = 0;
387 ret = gnutls_pkcs7_get_crt_raw (pkcs7, j, NULL, &pcert_size);
388 if (ret != GNUTLS_E_MEMORY_ERROR)
389 {
390 count--;
391 continue;
392 }
393
394 pcert = gnutls_malloc (pcert_size);
395 if (ret == GNUTLS_E_MEMORY_ERROR)
396 {
397 gnutls_assert ();
398 count--;
399 continue;
400 }
401
402 /* read the certificate
403 */
404 ret = gnutls_pkcs7_get_crt_raw (pkcs7, j, pcert, &pcert_size);
405
406 j--;
407
408 if (ret >= 0)
409 {
410 *cert_list =
411 (gnutls_cert *) gnutls_realloc_fast (*cert_list,
412 i * sizeof (gnutls_cert));
413
414 if (*cert_list == NULL)
415 {
416 gnutls_assert ();
417 gnutls_free (pcert);
418 return GNUTLS_E_MEMORY_ERROR;
419 }
420
421 tmp2.data = pcert;
422 tmp2.size = pcert_size;
423
424 ret =
425 _gnutls_x509_raw_cert_to_gcert (&cert_list[0][i - 1], &tmp2, 0);
426
427 if (ret < 0)
428 {
429 gnutls_assert ();
430 gnutls_pkcs7_deinit (pkcs7);
431 gnutls_free (pcert);
432 return ret;
433 }
434
435 i++;
436 }
437
438 gnutls_free (pcert);
439
440 }
441 while (ret >= 0 && j >= 0);
442
443 *ncerts = i - 1;
444
445 gnutls_pkcs7_deinit (pkcs7);
446 return count;
447#endif
448}
449
450/* Reads a base64 encoded certificate list from memory and stores it to
451 * a gnutls_cert structure. Returns the number of certificate parsed.
452 */
453static int
454parse_pem_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts,
455 const char *input_cert, int input_cert_size)
456{
457 int size, siz2, i;
458 const char *ptr;
459 opaque *ptr2;
460 gnutls_datum_t tmp;
461 int ret, count;
462
463#ifdef ENABLE_PKI
464 if ((ptr = memmem (input_cert, input_cert_size,
465 PEM_PKCS7_SEP, sizeof (PEM_PKCS7_SEP) - 1)) != NULL)
466 {
467 size = strlen (ptr);
468
469 ret = parse_pkcs7_cert_mem (cert_list, ncerts, ptr, size, CERT_PEM);
470
471 return ret;
472 }
473#endif
474
475 /* move to the certificate
476 */
477 ptr = memmem (input_cert, input_cert_size,
478 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
479 if (ptr == NULL)
480 ptr = memmem (input_cert, input_cert_size,
481 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
482
483 if (ptr == NULL)
484 {
485 gnutls_assert ();
486 return GNUTLS_E_BASE64_DECODING_ERROR;
487 }
488 size = input_cert_size - (ptr - input_cert);
489
490 i = *ncerts + 1;
491 count = 0;
492
493 do
494 {
495
496 siz2 = _gnutls_fbase64_decode (NULL, ptr, size, &ptr2);
497
498 if (siz2 < 0)
499 {
500 gnutls_assert ();
501 return GNUTLS_E_BASE64_DECODING_ERROR;
502 }
503
504 *cert_list =
505 (gnutls_cert *) gnutls_realloc_fast (*cert_list,
506 i * sizeof (gnutls_cert));
507
508 if (*cert_list == NULL)
509 {
510 gnutls_assert ();
511 return GNUTLS_E_MEMORY_ERROR;
512 }
513
514 tmp.data = ptr2;
515 tmp.size = siz2;
516
517 ret = _gnutls_x509_raw_cert_to_gcert (&cert_list[0][i - 1], &tmp, 0);
518 if (ret < 0)
519 {
520 gnutls_assert ();
521 return ret;
522 }
523 _gnutls_free_datum (&tmp); /* free ptr2 */
524
525 /* now we move ptr after the pem header
526 */
527 ptr++;
528 /* find the next certificate (if any)
529 */
530 size = input_cert_size - (ptr - input_cert);
531
532 if (size > 0)
533 {
534 char *ptr3;
535
536 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
537 if (ptr3 == NULL)
538 ptr3 = memmem (ptr, size, PEM_CERT_SEP2,
539 sizeof (PEM_CERT_SEP2) - 1);
540
541 ptr = ptr3;
542 }
543 else
544 ptr = NULL;
545
546 i++;
547 count++;
548
549 }
550 while (ptr != NULL);
551
552 *ncerts = i - 1;
553
554 return count;
555}
556
557
558
559/* Reads a DER or PEM certificate from memory
560 */
561static int
562read_cert_mem (gnutls_certificate_credentials_t res, const void *cert,
563 int cert_size, gnutls_x509_crt_fmt_t type)
564{
565 int ret;
566
567 /* allocate space for the certificate to add
568 */
569 res->cert_list = gnutls_realloc_fast (res->cert_list,
570 (1 +
571 res->ncerts) *
572 sizeof (gnutls_cert *));
573 if (res->cert_list == NULL)
574 {
575 gnutls_assert ();
576 return GNUTLS_E_MEMORY_ERROR;
577 }
578
579 res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
580 (1 +
581 res->ncerts) * sizeof (int));
582 if (res->cert_list_length == NULL)
583 {
584 gnutls_assert ();
585 return GNUTLS_E_MEMORY_ERROR;
586 }
587
588 res->cert_list[res->ncerts] = NULL; /* for realloc */
589 res->cert_list_length[res->ncerts] = 0;
590
591 if (type == GNUTLS_X509_FMT_DER)
592 ret = parse_pkcs7_cert_mem (&res->cert_list[res->ncerts],
593 &res->cert_list_length[res->ncerts],
594 cert, cert_size, 0);
595 else
596 ret =
597 parse_pem_cert_mem (&res->cert_list[res->ncerts],
598 &res->cert_list_length[res->ncerts], cert,
599 cert_size);
600
601 if (ret < 0)
602 {
603 gnutls_assert ();
604 return ret;
605 }
606
607 return ret;
608}
609
610
611int
612_gnutls_x509_privkey_to_gkey (gnutls_privkey * dest,
613 gnutls_x509_privkey_t src)
614{
615 int i, ret;
616
617 memset (dest, 0, sizeof (gnutls_privkey));
618
619 for (i = 0; i < src->params_size; i++)
620 {
621 dest->params[i] = _gnutls_mpi_copy (src->params[i]);
622 if (dest->params[i] == NULL)
623 {
624 gnutls_assert ();
625 ret = GNUTLS_E_MEMORY_ERROR;
626 goto cleanup;
627 }
628 }
629
630 dest->pk_algorithm = src->pk_algorithm;
631 dest->params_size = src->params_size;
632
633 return 0;
634
635cleanup:
636
637 for (i = 0; i < src->params_size; i++)
638 {
639 _gnutls_mpi_release (&dest->params[i]);
640 }
641 return ret;
642}
643
644void
645_gnutls_gkey_deinit (gnutls_privkey * key)
646{
647 int i;
648 if (key == NULL)
649 return;
650
651 for (i = 0; i < key->params_size; i++)
652 {
653 _gnutls_mpi_release (&key->params[i]);
654 }
655}
656
657int
658_gnutls_x509_raw_privkey_to_gkey (gnutls_privkey * privkey,
659 const gnutls_datum_t * raw_key,
660 gnutls_x509_crt_fmt_t type)
661{
662 gnutls_x509_privkey_t tmpkey;
663 int ret;
664
665 ret = gnutls_x509_privkey_init (&tmpkey);
666 if (ret < 0)
667 {
668 gnutls_assert ();
669 return ret;
670 }
671
672 ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);
673
674 /* If normal key decoding doesn't work try decoding a plain PKCS #8 key */
675 if (ret < 0)
676 ret =
677 gnutls_x509_privkey_import_pkcs8 (tmpkey, raw_key, type, NULL,
678 GNUTLS_PKCS_PLAIN);
679
680 if (ret < 0)
681 {
682 gnutls_assert ();
683 gnutls_x509_privkey_deinit (tmpkey);
684 return ret;
685 }
686
687 ret = _gnutls_x509_privkey_to_gkey (privkey, tmpkey);
688 if (ret < 0)
689 {
690 gnutls_assert ();
691 gnutls_x509_privkey_deinit (tmpkey);
692 return ret;
693 }
694
695 gnutls_x509_privkey_deinit (tmpkey);
696
697 return 0;
698}
699
700/* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
701 * indicates the certificate format. KEY can be NULL, to indicate
702 * that GnuTLS doesn't know the private key.
703 */
704static int
705read_key_mem (gnutls_certificate_credentials_t res,
706 const void *key, int key_size, gnutls_x509_crt_fmt_t type)
707{
708 int ret;
709 gnutls_datum_t tmp;
710
711 /* allocate space for the pkey list
712 */
713 res->pkey =
714 gnutls_realloc_fast (res->pkey,
715 (res->ncerts + 1) * sizeof (gnutls_privkey));
716 if (res->pkey == NULL)
717 {
718 gnutls_assert ();
719 return GNUTLS_E_MEMORY_ERROR;
720 }
721
722 if (key)
723 {
724 tmp.data = (opaque *) key;
725 tmp.size = key_size;
726
727 ret =
728 _gnutls_x509_raw_privkey_to_gkey (&res->pkey[res->ncerts], &tmp,
729 type);
730 if (ret < 0)
731 {
732 gnutls_assert ();
733 return ret;
734 }
735 }
736 else
737 memset (&res->pkey[res->ncerts], 0, sizeof (gnutls_privkey));
738
739 return 0;
740}
741
742/* Reads a certificate file
743 */
744static int
745read_cert_file (gnutls_certificate_credentials_t res,
746 const char *certfile, gnutls_x509_crt_fmt_t type)
747{
748 int ret;
749 size_t size;
750 char *data = read_binary_file (certfile, &size);
751
752 if (data == NULL)
753 {
754 gnutls_assert ();
755 return GNUTLS_E_FILE_ERROR;
756 }
757
758 ret = read_cert_mem (res, data, size, type);
759 free (data);
760
761 return ret;
762
763}
764
765
766
767/* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
768 * stores it).
769 */
770static int
771read_key_file (gnutls_certificate_credentials_t res,
772 const char *keyfile, gnutls_x509_crt_fmt_t type)
773{
774 int ret;
775 size_t size;
776 char *data = read_binary_file (keyfile, &size);
777
778 if (data == NULL)
779 {
780 gnutls_assert ();
781 return GNUTLS_E_FILE_ERROR;
782 }
783
784 ret = read_key_mem (res, data, size, type);
785 free (data);
786
787 return ret;
788}
789
790/**
791 * gnutls_certificate_set_x509_key_mem - Used to set keys in a gnutls_certificate_credentials_t structure
792 * @res: is an #gnutls_certificate_credentials_t structure.
793 * @cert: contains a certificate list (path) for the specified private key
794 * @key: is the private key, or %NULL
795 * @type: is PEM or DER
796 *
797 * This function sets a certificate/private key pair in the
798 * gnutls_certificate_credentials_t structure. This function may be called
799 * more than once (in case multiple keys/certificates exist for the
800 * server).
801 *
802 * Currently are supported: RSA PKCS-1 encoded private keys,
803 * DSA private keys.
804 *
805 * DSA private keys are encoded the OpenSSL way, which is an ASN.1
806 * DER sequence of 6 INTEGERs - version, p, q, g, pub, priv.
807 *
808 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
809 * is supported. This means that certificates intended for signing cannot
810 * be used for ciphersuites that require encryption.
811 *
812 * If the certificate and the private key are given in PEM encoding
813 * then the strings that hold their values must be null terminated.
814 *
815 * The @key may be %NULL if you are using a sign callback, see
816 * gnutls_sign_callback_set().
817 *
818 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
819 **/
820int
821gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t
822 res, const gnutls_datum_t * cert,
823 const gnutls_datum_t * key,
824 gnutls_x509_crt_fmt_t type)
825{
826 int ret;
827
828 /* this should be first
829 */
830 if ((ret = read_key_mem (res, key ? key->data : NULL,
831 key ? key->size : 0, type)) < 0)
832 return ret;
833
834 if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0)
835 return ret;
836
837 res->ncerts++;
838
839 if (key && (ret = _gnutls_check_key_cert_match (res)) < 0)
840 {
841 gnutls_assert ();
842 return ret;
843 }
844
845 return 0;
846}
847
848/**
849 * gnutls_certificate_set_x509_key - Used to set keys in a gnutls_certificate_credentials_t structure
850 * @res: is an #gnutls_certificate_credentials_t structure.
851 * @cert_list: contains a certificate list (path) for the specified private key
852 * @cert_list_size: holds the size of the certificate list
853 * @key: is a gnutls_x509_privkey_t key
854 *
855 * This function sets a certificate/private key pair in the
856 * gnutls_certificate_credentials_t structure. This function may be
857 * called more than once (in case multiple keys/certificates exist
858 * for the server).
859 *
860 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
861 **/
862int
863gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
864 gnutls_x509_crt_t * cert_list,
865 int cert_list_size,
866 gnutls_x509_privkey_t key)
867{
868 int ret, i;
869
870 /* this should be first
871 */
872
873 res->pkey =
874 gnutls_realloc_fast (res->pkey,
875 (res->ncerts + 1) * sizeof (gnutls_privkey));
876 if (res->pkey == NULL)
877 {
878 gnutls_assert ();
879 return GNUTLS_E_MEMORY_ERROR;
880 }
881
882 ret = _gnutls_x509_privkey_to_gkey (&res->pkey[res->ncerts], key);
883 if (ret < 0)
884 {
885 gnutls_assert ();
886 return ret;
887 }
888
889 res->cert_list = gnutls_realloc_fast (res->cert_list,
890 (1 +
891 res->ncerts) *
892 sizeof (gnutls_cert *));
893 if (res->cert_list == NULL)
894 {
895 gnutls_assert ();
896 return GNUTLS_E_MEMORY_ERROR;
897 }
898
899 res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
900 (1 +
901 res->ncerts) * sizeof (int));
902 if (res->cert_list_length == NULL)
903 {
904 gnutls_assert ();
905 return GNUTLS_E_MEMORY_ERROR;
906 }
907
908 res->cert_list[res->ncerts] = NULL; /* for realloc */
909 res->cert_list_length[res->ncerts] = 0;
910
911
912 for (i = 0; i < cert_list_size; i++)
913 {
914 ret = parse_crt_mem (&res->cert_list[res->ncerts],
915 &res->cert_list_length[res->ncerts], cert_list[i]);
916 if (ret < 0)
917 {
918 gnutls_assert ();
919 return ret;
920 }
921 }
922 res->ncerts++;
923
924 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
925 {
926 gnutls_assert ();
927 return ret;
928 }
929
930 return 0;
931}
932
933/**
934 * gnutls_certificate_set_x509_key_file - Used to set keys in a gnutls_certificate_credentials_t structure
935 * @res: is an #gnutls_certificate_credentials_t structure.
936 * @CERTFILE: is a file that containing the certificate list (path) for
937 * the specified private key, in PKCS7 format, or a list of certificates
938 * @KEYFILE: is a file that contains the private key
939 * @type: is PEM or DER
940 *
941 * This function sets a certificate/private key pair in the
942 * gnutls_certificate_credentials_t structure. This function may be
943 * called more than once (in case multiple keys/certificates exist
944 * for the server).
945 *
946 * Currently only PKCS-1 encoded RSA and DSA private keys are accepted by
947 * this function.
948 *
949 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
950 **/
951int
952gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t
953 res, const char *CERTFILE,
954 const char *KEYFILE,
955 gnutls_x509_crt_fmt_t type)
956{
957 int ret;
958
959 /* this should be first
960 */
961 if ((ret = read_key_file (res, KEYFILE, type)) < 0)
962 return ret;
963
964 if ((ret = read_cert_file (res, CERTFILE, type)) < 0)
965 return ret;
966
967 res->ncerts++;
968
969 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
970 {
971 gnutls_assert ();
972 return ret;
973 }
974
975 return 0;
976}
977
978static int
979generate_rdn_seq (gnutls_certificate_credentials_t res)
980{
981 gnutls_datum_t tmp;
982 int ret;
983 unsigned size, i;
984 opaque *pdata;
985
986 /* Generate the RDN sequence
987 * This will be sent to clients when a certificate
988 * request message is sent.
989 */
990
991 /* FIXME: in case of a client it is not needed
992 * to do that. This would save time and memory.
993 * However we don't have that information available
994 * here.
995 */
996
997 size = 0;
998 for (i = 0; i < res->x509_ncas; i++)
999 {
1000 if ((ret = gnutls_x509_crt_get_raw_dn (res->x509_ca_list[i], &tmp)) < 0)
1001 {
1002 gnutls_assert ();
1003 return ret;
1004 }
1005 size += (2 + tmp.size);
1006 _gnutls_free_datum (&tmp);
1007 }
1008
1009 if (res->x509_rdn_sequence.data != NULL)
1010 gnutls_free (res->x509_rdn_sequence.data);
1011
1012 res->x509_rdn_sequence.data = gnutls_malloc (size);
1013 if (res->x509_rdn_sequence.data == NULL)
1014 {
1015 gnutls_assert ();
1016 return GNUTLS_E_MEMORY_ERROR;
1017 }
1018 res->x509_rdn_sequence.size = size;
1019
1020 pdata = res->x509_rdn_sequence.data;
1021
1022 for (i = 0; i < res->x509_ncas; i++)
1023 {
1024 if ((ret = gnutls_x509_crt_get_raw_dn (res->x509_ca_list[i], &tmp)) < 0)
1025 {
1026 _gnutls_free_datum (&res->x509_rdn_sequence);
1027 gnutls_assert ();
1028 return ret;
1029 }
1030
1031 _gnutls_write_datum16 (pdata, tmp);
1032 pdata += (2 + tmp.size);
1033 _gnutls_free_datum (&tmp);
1034 }
1035
1036 return 0;
1037}
1038
1039
1040
1041
1042/* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1043 * certificate (uses the KeyUsage field).
1044 */
1045int
1046_gnutls_check_key_usage (const gnutls_cert * cert, gnutls_kx_algorithm_t alg)
1047{
1048 unsigned int key_usage = 0;
1049 int encipher_type;
1050
1051 if (cert == NULL)
1052 {
1053 gnutls_assert ();
1054 return GNUTLS_E_INTERNAL_ERROR;
1055 }
1056
1057 if (_gnutls_map_kx_get_cred (alg, 1) == GNUTLS_CRD_CERTIFICATE ||
1058 _gnutls_map_kx_get_cred (alg, 0) == GNUTLS_CRD_CERTIFICATE)
1059 {
1060
1061 key_usage = cert->key_usage;
1062
1063 encipher_type = _gnutls_kx_encipher_type (alg);
1064
1065 if (key_usage != 0 && encipher_type != CIPHER_IGN)
1066 {
1067 /* If key_usage has been set in the certificate
1068 */
1069
1070 if (encipher_type == CIPHER_ENCRYPT)
1071 {
1072 /* If the key exchange method requires an encipher
1073 * type algorithm, and key's usage does not permit
1074 * encipherment, then fail.
1075 */
1076 if (!(key_usage & KEY_KEY_ENCIPHERMENT))
1077 {
1078 gnutls_assert ();
1079 return GNUTLS_E_KEY_USAGE_VIOLATION;
1080 }
1081 }
1082
1083 if (encipher_type == CIPHER_SIGN)
1084 {
1085 /* The same as above, but for sign only keys
1086 */
1087 if (!(key_usage & KEY_DIGITAL_SIGNATURE))
1088 {
1089 gnutls_assert ();
1090 return GNUTLS_E_KEY_USAGE_VIOLATION;
1091 }
1092 }
1093 }
1094 }
1095 return 0;
1096}
1097
1098
1099
1100static int
1101parse_pem_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
1102 const opaque * input_cert, int input_cert_size)
1103{
1104 int i, size;
1105 const opaque *ptr;
1106 gnutls_datum_t tmp;
1107 int ret, count;
1108
1109 /* move to the certificate
1110 */
1111 ptr = memmem (input_cert, input_cert_size,
1112 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
1113 if (ptr == NULL)
1114 ptr = memmem (input_cert, input_cert_size,
1115 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
1116
1117 if (ptr == NULL)
1118 {
1119 gnutls_assert ();
1120 return GNUTLS_E_BASE64_DECODING_ERROR;
1121 }
1122 size = input_cert_size - (ptr - input_cert);
1123
1124 i = *ncerts + 1;
1125 count = 0;
1126
1127 do
1128 {
1129
1130 *cert_list =
1131 (gnutls_x509_crt_t *) gnutls_realloc_fast (*cert_list,
1132 i *
1133 sizeof
1134 (gnutls_x509_crt_t));
1135
1136 if (*cert_list == NULL)
1137 {
1138 gnutls_assert ();
1139 return GNUTLS_E_MEMORY_ERROR;
1140 }
1141
1142 ret = gnutls_x509_crt_init (&cert_list[0][i - 1]);
1143 if (ret < 0)
1144 {
1145 gnutls_assert ();
1146 return ret;
1147 }
1148
1149 tmp.data = (opaque *) ptr;
1150 tmp.size = size;
1151
1152 ret =
1153 gnutls_x509_crt_import (cert_list[0][i - 1],
1154 &tmp, GNUTLS_X509_FMT_PEM);
1155 if (ret < 0)
1156 {
1157 gnutls_assert ();
1158 return ret;
1159 }
1160
1161 /* now we move ptr after the pem header
1162 */
1163 ptr++;
1164 size--;
1165 /* find the next certificate (if any)
1166 */
1167
1168 if (size > 0)
1169 {
1170 char *ptr3;
1171
1172 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
1173 if (ptr3 == NULL)
1174 ptr3 = memmem (ptr, size,
1175 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
1176
1177 ptr = ptr3;
1178 size = input_cert_size - (ptr - input_cert);
1179 }
1180 else
1181 ptr = NULL;
1182
1183 i++;
1184 count++;
1185
1186 }
1187 while (ptr != NULL);
1188
1189 *ncerts = i - 1;
1190
1191 return count;
1192}
1193
1194/* Reads a DER encoded certificate list from memory and stores it to
1195 * a gnutls_cert structure. This is only called if PKCS7 read fails.
1196 * returns the number of certificates parsed (1)
1197 */
1198static int
1199parse_der_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
1200 const void *input_cert, int input_cert_size)
1201{
1202 int i;
1203 gnutls_datum_t tmp;
1204 int ret;
1205
1206 i = *ncerts + 1;
1207
1208 *cert_list =
1209 (gnutls_x509_crt_t *) gnutls_realloc_fast (*cert_list,
1210 i *
1211 sizeof (gnutls_x509_crt_t));
1212
1213 if (*cert_list == NULL)
1214 {
1215 gnutls_assert ();
1216 return GNUTLS_E_MEMORY_ERROR;
1217 }
1218
1219 tmp.data = (opaque *) input_cert;
1220 tmp.size = input_cert_size;
1221
1222 ret = gnutls_x509_crt_init (&cert_list[0][i - 1]);
1223 if (ret < 0)
1224 {
1225 gnutls_assert ();
1226 return ret;
1227 }
1228
1229 ret =
1230 gnutls_x509_crt_import (cert_list[0][i - 1], &tmp, GNUTLS_X509_FMT_DER);
1231 if (ret < 0)
1232 {
1233 gnutls_assert ();
1234 return ret;
1235 }
1236
1237 *ncerts = i;
1238
1239 return 1; /* one certificate parsed */
1240}
1241
1242/**
1243 * gnutls_certificate_set_x509_trust_mem - Used to add trusted CAs in a gnutls_certificate_credentials_t structure
1244 * @res: is an #gnutls_certificate_credentials_t structure.
1245 * @ca: is a list of trusted CAs or a DER certificate
1246 * @type: is DER or PEM
1247 *
1248 * This function adds the trusted CAs in order to verify client or
1249 * server certificates. In case of a client this is not required to
1250 * be called if the certificates are not verified using
1251 * gnutls_certificate_verify_peers2(). This function may be called
1252 * multiple times.
1253 *
1254 * In case of a server the CAs set here will be sent to the client if
1255 * a certificate request is sent. This can be disabled using
1256 * gnutls_certificate_send_x509_rdn_sequence().
1257 *
1258 * Returns: the number of certificates processed or a negative value
1259 * on error.
1260 **/
1261int
1262gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t
1263 res, const gnutls_datum_t * ca,
1264 gnutls_x509_crt_fmt_t type)
1265{
1266 int ret, ret2;
1267
1268 if (type == GNUTLS_X509_FMT_DER)
1269 ret = parse_der_ca_mem (&res->x509_ca_list, &res->x509_ncas,
1270 ca->data, ca->size);
1271 else
1272 ret = parse_pem_ca_mem (&res->x509_ca_list, &res->x509_ncas,
1273 ca->data, ca->size);
1274
1275 if ((ret2 = generate_rdn_seq (res)) < 0)
1276 return ret2;
1277
1278 return ret;
1279}
1280
1281/**
1282 * gnutls_certificate_set_x509_trust - Used to add trusted CAs in a gnutls_certificate_credentials_t structure
1283 * @res: is an #gnutls_certificate_credentials_t structure.
1284 * @ca_list: is a list of trusted CAs
1285 * @ca_list_size: holds the size of the CA list
1286 *
1287 * This function adds the trusted CAs in order to verify client
1288 * or server certificates. In case of a client this is not required
1289 * to be called if the certificates are not verified using
1290 * gnutls_certificate_verify_peers2().
1291 * This function may be called multiple times.
1292 *
1293 * In case of a server the CAs set here will be sent to the client if
1294 * a certificate request is sent. This can be disabled using
1295 * gnutls_certificate_send_x509_rdn_sequence().
1296 *
1297 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1298 **/
1299int
1300gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
1301 gnutls_x509_crt_t * ca_list,
1302 int ca_list_size)
1303{
1304 int ret, i, ret2;
1305
1306 res->x509_ca_list = gnutls_realloc_fast (res->x509_ca_list,
1307 (ca_list_size +
1308 res->x509_ncas) *
1309 sizeof (gnutls_x509_crt_t));
1310 if (res->x509_ca_list == NULL)
1311 {
1312 gnutls_assert ();
1313 return GNUTLS_E_MEMORY_ERROR;
1314 }
1315
1316 for (i = 0; i < ca_list_size; i++)
1317 {
1318 ret = gnutls_x509_crt_init (&res->x509_ca_list[res->x509_ncas]);
1319 if (ret < 0)
1320 {
1321 gnutls_assert ();
1322 return ret;
1323 }
1324
1325 ret = _gnutls_x509_crt_cpy (res->x509_ca_list[res->x509_ncas],
1326 ca_list[i]);
1327 if (ret < 0)
1328 {
1329 gnutls_assert ();
1330 gnutls_x509_crt_deinit (res->x509_ca_list[res->x509_ncas]);
1331 return ret;
1332 }
1333 res->x509_ncas++;
1334 }
1335
1336 if ((ret2 = generate_rdn_seq (res)) < 0)
1337 return ret2;
1338
1339 return 0;
1340}
1341
1342/**
1343 * gnutls_certificate_set_x509_trust_file - Used to add trusted CAs in a gnutls_certificate_credentials_t structure
1344 * @res: is an #gnutls_certificate_credentials_t structure.
1345 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1346 * @type: is PEM or DER
1347 *
1348 * This function adds the trusted CAs in order to verify client or
1349 * server certificates. In case of a client this is not required to
1350 * be called if the certificates are not verified using
1351 * gnutls_certificate_verify_peers2(). This function may be called
1352 * multiple times.
1353 *
1354 * In case of a server the names of the CAs set here will be sent to
1355 * the client if a certificate request is sent. This can be disabled
1356 * using gnutls_certificate_send_x509_rdn_sequence().
1357 *
1358 * Returns: number of certificates processed, or a negative value on
1359 * error.
1360 **/
1361int
1362gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t
1363 res, const char *cafile,
1364 gnutls_x509_crt_fmt_t type)
1365{
1366 int ret, ret2;
1367 size_t size;
1368 char *data = read_binary_file (cafile, &size);
1369
1370 if (data == NULL)
1371 {
1372 gnutls_assert ();
1373 return GNUTLS_E_FILE_ERROR;
1374 }
1375
1376 if (type == GNUTLS_X509_FMT_DER)
1377 ret = parse_der_ca_mem (&res->x509_ca_list, &res->x509_ncas, data, size);
1378 else
1379 ret = parse_pem_ca_mem (&res->x509_ca_list, &res->x509_ncas, data, size);
1380
1381 free (data);
1382
1383 if (ret < 0)
1384 {
1385 gnutls_assert ();
1386 return ret;
1387 }
1388
1389 if ((ret2 = generate_rdn_seq (res)) < 0)
1390 return ret2;
1391
1392 return ret;
1393}
1394
1395#ifdef ENABLE_PKI
1396
1397static int
1398parse_pem_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1399 const opaque * input_crl, int input_crl_size)
1400{
1401 int size, i;
1402 const opaque *ptr;
1403 gnutls_datum_t tmp;
1404 int ret, count;
1405
1406 /* move to the certificate
1407 */
1408 ptr = memmem (input_crl, input_crl_size,
1409 PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1410 if (ptr == NULL)
1411 {
1412 gnutls_assert ();
1413 return GNUTLS_E_BASE64_DECODING_ERROR;
1414 }
1415
1416 size = input_crl_size - (ptr - input_crl);
1417
1418 i = *ncrls + 1;
1419 count = 0;
1420
1421 do
1422 {
1423
1424 *crl_list =
1425 (gnutls_x509_crl_t *) gnutls_realloc_fast (*crl_list,
1426 i *
1427 sizeof
1428 (gnutls_x509_crl_t));
1429
1430 if (*crl_list == NULL)
1431 {
1432 gnutls_assert ();
1433 return GNUTLS_E_MEMORY_ERROR;
1434 }
1435
1436 ret = gnutls_x509_crl_init (&crl_list[0][i - 1]);
1437 if (ret < 0)
1438 {
1439 gnutls_assert ();
1440 return ret;
1441 }
1442
1443 tmp.data = (char *) ptr;
1444 tmp.size = size;
1445
1446 ret =
1447 gnutls_x509_crl_import (crl_list[0][i - 1],
1448 &tmp, GNUTLS_X509_FMT_PEM);
1449 if (ret < 0)
1450 {
1451 gnutls_assert ();
1452 return ret;
1453 }
1454
1455 /* now we move ptr after the pem header
1456 */
1457 ptr++;
1458 /* find the next certificate (if any)
1459 */
1460
1461 size = input_crl_size - (ptr - input_crl);
1462
1463 if (size > 0)
1464 ptr = memmem (ptr, size, PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1465 else
1466 ptr = NULL;
1467 i++;
1468 count++;
1469
1470 }
1471 while (ptr != NULL);
1472
1473 *ncrls = i - 1;
1474
1475 return count;
1476}
1477
1478/* Reads a DER encoded certificate list from memory and stores it to
1479 * a gnutls_cert structure. This is only called if PKCS7 read fails.
1480 * returns the number of certificates parsed (1)
1481 */
1482static int
1483parse_der_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1484 const void *input_crl, int input_crl_size)
1485{
1486 int i;
1487 gnutls_datum_t tmp;
1488 int ret;
1489
1490 i = *ncrls + 1;
1491
1492 *crl_list =
1493 (gnutls_x509_crl_t *) gnutls_realloc_fast (*crl_list,
1494 i *
1495 sizeof (gnutls_x509_crl_t));
1496
1497 if (*crl_list == NULL)
1498 {
1499 gnutls_assert ();
1500 return GNUTLS_E_MEMORY_ERROR;
1501 }
1502
1503 tmp.data = (opaque *) input_crl;
1504 tmp.size = input_crl_size;
1505
1506 ret = gnutls_x509_crl_init (&crl_list[0][i - 1]);
1507 if (ret < 0)
1508 {
1509 gnutls_assert ();
1510 return ret;
1511 }
1512
1513 ret =
1514 gnutls_x509_crl_import (crl_list[0][i - 1], &tmp, GNUTLS_X509_FMT_DER);
1515 if (ret < 0)
1516 {
1517 gnutls_assert ();
1518 return ret;
1519 }
1520
1521 *ncrls = i;
1522
1523 return 1; /* one certificate parsed */
1524}
1525
1526
1527/* Reads a DER or PEM CRL from memory
1528 */
1529static int
1530read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
1531 int crl_size, gnutls_x509_crt_fmt_t type)
1532{
1533 int ret;
1534
1535 /* allocate space for the certificate to add
1536 */
1537 res->x509_crl_list = gnutls_realloc_fast (res->x509_crl_list,
1538 (1 +
1539 res->x509_ncrls) *
1540 sizeof (gnutls_x509_crl_t));
1541 if (res->x509_crl_list == NULL)
1542 {
1543 gnutls_assert ();
1544 return GNUTLS_E_MEMORY_ERROR;
1545 }
1546
1547 if (type == GNUTLS_X509_FMT_DER)
1548 ret = parse_der_crl_mem (&res->x509_crl_list,
1549 &res->x509_ncrls, crl, crl_size);
1550 else
1551 ret = parse_pem_crl_mem (&res->x509_crl_list,
1552 &res->x509_ncrls, crl, crl_size);
1553
1554 if (ret < 0)
1555 {
1556 gnutls_assert ();
1557 return ret;
1558 }
1559
1560 return ret;
1561}
1562
1563/**
1564 * gnutls_certificate_set_x509_crl_mem - Used to add CRLs in a gnutls_certificate_credentials_t structure
1565 * @res: is an #gnutls_certificate_credentials_t structure.
1566 * @CRL: is a list of trusted CRLs. They should have been verified before.
1567 * @type: is DER or PEM
1568 *
1569 * This function adds the trusted CRLs in order to verify client or
1570 * server certificates. In case of a client this is not required to
1571 * be called if the certificates are not verified using
1572 * gnutls_certificate_verify_peers2(). This function may be called
1573 * multiple times.
1574 *
1575 * Returns: number of CRLs processed, or a negative value on error.
1576 **/
1577int
1578gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t
1579 res, const gnutls_datum_t * CRL,
1580 gnutls_x509_crt_fmt_t type)
1581{
1582 int ret;
1583
1584 if ((ret = read_crl_mem (res, CRL->data, CRL->size, type)) < 0)
1585 return ret;
1586
1587 return ret;
1588}
1589
1590/**
1591 * gnutls_certificate_set_x509_crl - Used to add CRLs in a gnutls_certificate_credentials_t structure
1592 * @res: is an #gnutls_certificate_credentials_t structure.
1593 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1594 * @crl_list_size: holds the size of the crl_list
1595 *
1596 * This function adds the trusted CRLs in order to verify client or
1597 * server certificates. In case of a client this is not required to
1598 * be called if the certificates are not verified using
1599 * gnutls_certificate_verify_peers2(). This function may be called
1600 * multiple times.
1601 *
1602 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1603 **/
1604int
1605gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
1606 gnutls_x509_crl_t * crl_list,
1607 int crl_list_size)
1608{
1609 int ret, i;
1610
1611 res->x509_crl_list = gnutls_realloc_fast (res->x509_crl_list,
1612 (crl_list_size +
1613 res->x509_ncrls) *
1614 sizeof (gnutls_x509_crl_t));
1615 if (res->x509_crl_list == NULL)
1616 {
1617 gnutls_assert ();
1618 return GNUTLS_E_MEMORY_ERROR;
1619 }
1620
1621 for (i = 0; i < crl_list_size; i++)
1622 {
1623 ret = gnutls_x509_crl_init (&res->x509_crl_list[res->x509_ncrls]);
1624 if (ret < 0)
1625 {
1626 gnutls_assert ();
1627 return ret;
1628 }
1629
1630 ret = _gnutls_x509_crl_cpy (res->x509_crl_list[res->x509_ncrls],
1631 crl_list[i]);
1632 if (ret < 0)
1633 {
1634 gnutls_assert ();
1635 return ret;
1636 }
1637 res->x509_ncrls++;
1638 }
1639
1640 return 0;
1641}
1642
1643/**
1644 * gnutls_certificate_set_x509_crl_file - Used to add CRLs in a gnutls_certificate_credentials_t structure
1645 * @res: is an #gnutls_certificate_credentials_t structure.
1646 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1647 * @type: is PEM or DER
1648 *
1649 * This function adds the trusted CRLs in order to verify client or server
1650 * certificates. In case of a client this is not required
1651 * to be called if the certificates are not verified using
1652 * gnutls_certificate_verify_peers2().
1653 * This function may be called multiple times.
1654 *
1655 * Returns: number of CRLs processed or a negative value on error.
1656 **/
1657int
1658gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t
1659 res, const char *crlfile,
1660 gnutls_x509_crt_fmt_t type)
1661{
1662 int ret;
1663 size_t size;
1664 char *data = read_binary_file (crlfile, &size);
1665
1666 if (data == NULL)
1667 {
1668 gnutls_assert ();
1669 return GNUTLS_E_FILE_ERROR;
1670 }
1671
1672 if (type == GNUTLS_X509_FMT_DER)
1673 ret = parse_der_crl_mem (&res->x509_crl_list, &res->x509_ncrls,
1674 data, size);
1675 else
1676 ret = parse_pem_crl_mem (&res->x509_crl_list, &res->x509_ncrls,
1677 data, size);
1678
1679 free (data);
1680
1681 if (ret < 0)
1682 {
1683 gnutls_assert ();
1684 return ret;
1685 }
1686
1687 return ret;
1688}
1689
1690#include <pkcs12.h>
1691
1692static int
1693parse_pkcs12 (gnutls_certificate_credentials_t res,
1694 gnutls_pkcs12_t p12,
1695 const char *password,
1696 gnutls_x509_privkey_t * key,
1697 gnutls_x509_crt_t * cert, gnutls_x509_crl_t * crl)
1698{
1699 gnutls_pkcs12_bag_t bag = NULL;
1700 int index = 0;
1701 int ret;
1702
1703 for (;;)
1704 {
1705 int elements_in_bag;
1706 int i;
1707
1708 ret = gnutls_pkcs12_bag_init (&bag);
1709 if (ret < 0)
1710 {
1711 bag = NULL;
1712 gnutls_assert ();
1713 goto done;
1714 }
1715
1716 ret = gnutls_pkcs12_get_bag (p12, index, bag);
1717 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1718 break;
1719 if (ret < 0)
1720 {
1721 gnutls_assert ();
1722 goto done;
1723 }
1724
1725 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1726 if (ret < 0)
1727 {
1728 gnutls_assert ();
1729 goto done;
1730 }
1731
1732 if (ret == GNUTLS_BAG_ENCRYPTED)
1733 {
1734 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1735 if (ret < 0)
1736 {
1737 gnutls_assert ();
1738 goto done;
1739 }
1740 }
1741
1742 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
1743 if (elements_in_bag < 0)
1744 {
1745 gnutls_assert ();
1746 goto done;
1747 }
1748
1749 for (i = 0; i < elements_in_bag; i++)
1750 {
1751 int type;
1752 gnutls_datum_t data;
1753
1754 type = gnutls_pkcs12_bag_get_type (bag, i);
1755 if (type < 0)
1756 {
1757 gnutls_assert ();
1758 goto done;
1759 }
1760
1761 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
1762 if (ret < 0)
1763 {
1764 gnutls_assert ();
1765 goto done;
1766 }
1767
1768 switch (type)
1769 {
1770 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
1771 case GNUTLS_BAG_PKCS8_KEY:
1772 ret = gnutls_x509_privkey_init (key);
1773 if (ret < 0)
1774 {
1775 gnutls_assert ();
1776 goto done;
1777 }
1778
1779 ret = gnutls_x509_privkey_import_pkcs8
1780 (*key, &data, GNUTLS_X509_FMT_DER, password,
1781 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
1782 if (ret < 0)
1783 {
1784 gnutls_assert ();
1785 goto done;
1786 }
1787 break;
1788
1789 case GNUTLS_BAG_CERTIFICATE:
1790 ret = gnutls_x509_crt_init (cert);
1791 if (ret < 0)
1792 {
1793 gnutls_assert ();
1794 goto done;
1795 }
1796
1797 ret =
1798 gnutls_x509_crt_import (*cert, &data, GNUTLS_X509_FMT_DER);
1799 if (ret < 0)
1800 {
1801 gnutls_assert ();
1802 goto done;
1803 }
1804 break;
1805
1806 case GNUTLS_BAG_CRL:
1807 ret = gnutls_x509_crl_init (crl);
1808 if (ret < 0)
1809 {
1810 gnutls_assert ();
1811 goto done;
1812 }
1813
1814 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
1815 if (ret < 0)
1816 {
1817 gnutls_assert ();
1818 goto done;
1819 }
1820 break;
1821
1822 case GNUTLS_BAG_ENCRYPTED:
1823 /* XXX Bother to recurse one level down? Unlikely to
1824 use the same password anyway. */
1825 case GNUTLS_BAG_EMPTY:
1826 default:
1827 break;
1828 }
1829 }
1830
1831 index++;
1832 gnutls_pkcs12_bag_deinit (bag);
1833 }
1834
1835 ret = 0;
1836
1837done:
1838 if (bag)
1839 gnutls_pkcs12_bag_deinit (bag);
1840
1841 return ret;
1842}
1843
1844/**
1845 * gnutls_certificate_set_x509_simple_pkcs12_file:
1846 * @res: is an #gnutls_certificate_credentials_t structure.
1847 * @pkcs12file: filename of file containing PKCS#12 blob.
1848 * @type: is PEM or DER of the @pkcs12file.
1849 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1850 *
1851 * This function sets a certificate/private key pair and/or a CRL in
1852 * the gnutls_certificate_credentials_t structure. This function may
1853 * be called more than once (in case multiple keys/certificates exist
1854 * for the server).
1855 *
1856 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
1857 * supported. Encrypted PKCS#8 private keys are supported. However,
1858 * only password based security, and the same password for all
1859 * operations, are supported.
1860 *
1861 * The private keys may be RSA PKCS#1 or DSA private keys encoded in
1862 * the OpenSSL way.
1863 *
1864 * PKCS#12 file may contain many keys and/or certificates, and there
1865 * is no way to identify which key/certificate pair you want. You
1866 * should make sure the PKCS#12 file only contain one key/certificate
1867 * pair and/or one CRL.
1868 *
1869 * It is believed that the limitations of this function is acceptable
1870 * for most usage, and that any more flexibility would introduce
1871 * complexity that would make it harder to use this functionality at
1872 * all.
1873 *
1874 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1875 **/
1876int
1877 gnutls_certificate_set_x509_simple_pkcs12_file
1878 (gnutls_certificate_credentials_t res, const char *pkcs12file,
1879 gnutls_x509_crt_fmt_t type, const char *password)
1880{
1881 gnutls_pkcs12_t p12;
1882 gnutls_datum_t p12blob;
1883 gnutls_x509_privkey_t key = NULL;
1884 gnutls_x509_crt_t cert = NULL;
1885 gnutls_x509_crl_t crl = NULL;
1886 int ret;
1887 size_t size;
1888
1889 ret = gnutls_pkcs12_init (&p12);
1890 if (ret < 0)
1891 {
1892 gnutls_assert ();
1893 return ret;
1894 }
1895
1896 p12blob.data = read_binary_file (pkcs12file, &size);
1897 p12blob.size = (unsigned int) size;
1898 if (p12blob.data == NULL)
1899 {
1900 gnutls_assert ();
1901 gnutls_pkcs12_deinit (p12);
1902 return GNUTLS_E_FILE_ERROR;
1903 }
1904
1905 ret = gnutls_pkcs12_import (p12, &p12blob, type, 0);
1906 free (p12blob.data);
1907 if (ret < 0)
1908 {
1909 gnutls_assert ();
1910 gnutls_pkcs12_deinit (p12);
1911 return ret;
1912 }
1913
1914 if (password)
1915 {
1916 ret = gnutls_pkcs12_verify_mac (p12, password);
1917 if (ret < 0)
1918 {
1919 gnutls_assert ();
1920 gnutls_pkcs12_deinit (p12);
1921 return ret;
1922 }
1923 }
1924
1925 ret = parse_pkcs12 (res, p12, password, &key, &cert, &crl);
1926 gnutls_pkcs12_deinit (p12);
1927 if (ret < 0)
1928 {
1929 gnutls_assert ();
1930 return ret;
1931 }
1932
1933 if (key && cert)
1934 {
1935 ret = gnutls_certificate_set_x509_key (res, &cert, 1, key);
1936 if (ret < 0)
1937 {
1938 gnutls_assert ();
1939 goto done;
1940 }
1941 }
1942
1943 if (crl)
1944 {
1945 ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
1946 if (ret < 0)
1947 {
1948 gnutls_assert ();
1949 goto done;
1950 }
1951 }
1952
1953 ret = 0;
1954
1955done:
1956 if (cert)
1957 gnutls_x509_crt_deinit (cert);
1958 if (key)
1959 gnutls_x509_privkey_deinit (key);
1960 if (crl)
1961 gnutls_x509_crl_deinit (crl);
1962
1963 return ret;
1964}
1965
1966
1967/**
1968 * gnutls_certificate_free_crls - Used to free all the CRLs from a gnutls_certificate_credentials_t structure
1969 * @sc: is an #gnutls_certificate_credentials_t structure.
1970 *
1971 * This function will delete all the CRLs associated
1972 * with the given credentials.
1973 *
1974 **/
1975void
1976gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
1977{
1978 unsigned j;
1979
1980 for (j = 0; j < sc->x509_ncrls; j++)
1981 {
1982 gnutls_x509_crl_deinit (sc->x509_crl_list[j]);
1983 }
1984
1985 sc->x509_ncrls = 0;
1986
1987 gnutls_free (sc->x509_crl_list);
1988 sc->x509_crl_list = NULL;
1989}
1990
1991#endif
diff --git a/src/daemon/https/tls/gnutls_x509.h b/src/daemon/https/tls/gnutls_x509.h
new file mode 100644
index 00000000..3aa0d915
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_x509.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25#include <libtasn1.h>
26
27int _gnutls_x509_cert_verify_peers (gnutls_session_t session,
28 unsigned int *status);
29
30#define PEM_CERT_SEP2 "-----BEGIN X509 CERTIFICATE"
31#define PEM_CERT_SEP "-----BEGIN CERTIFICATE"
32#define PEM_PKCS7_SEP "-----BEGIN PKCS7"
33
34#define PEM_CRL_SEP "-----BEGIN X509 CRL"
35
36#define PEM_KEY_RSA_SEP "-----BEGIN RSA"
37#define PEM_KEY_DSA_SEP "-----BEGIN DSA"
38
39int _gnutls_check_key_usage (const gnutls_cert * cert,
40 gnutls_kx_algorithm_t alg);
41
42int _gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params);
43int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params);
44
45int _gnutls_x509_raw_privkey_to_gkey (gnutls_privkey * privkey,
46 const gnutls_datum_t * raw_key,
47 gnutls_x509_crt_fmt_t type);
48int _gnutls_x509_privkey_to_gkey (gnutls_privkey * privkey,
49 gnutls_x509_privkey_t);
diff --git a/src/daemon/https/tls/gnutlsxx.cpp b/src/daemon/https/tls/gnutlsxx.cpp
new file mode 100644
index 00000000..70621a43
--- /dev/null
+++ b/src/daemon/https/tls/gnutlsxx.cpp
@@ -0,0 +1,907 @@
1#include <gnutlsxx.h>
2
3using namespace gnutls;
4
5inline int RETWRAP_NET(int ret)
6{
7 if (gnutls_error_is_fatal(ret)) throw(exception(ret));
8 else return ret;
9}
10
11inline int RETWRAP(int ret)
12{
13 if (ret < 0) throw(exception(ret));
14 return ret;
15}
16
17session::session( gnutls_connection_end_t end)
18{
19 RETWRAP(gnutls_init( &this->s, end));
20}
21
22session::session( session& s)
23{
24 this->s = s.s;
25}
26
27session::~session()
28{
29 gnutls_deinit( this->s);
30}
31
32int session::bye( gnutls_close_request_t how)
33{
34 return RETWRAP_NET( gnutls_bye( this->s, how));
35}
36
37int session::handshake ()
38{
39 return RETWRAP_NET( gnutls_handshake( this->s));
40}
41
42
43server_session::server_session() : session( GNUTLS_SERVER)
44{
45}
46
47int server_session::rehandshake()
48{
49 return RETWRAP_NET( gnutls_rehandshake( this->s));
50}
51
52gnutls_alert_description_t session::get_alert() const
53{
54 return gnutls_alert_get( this->s);
55}
56
57int session::send_alert ( gnutls_alert_level_t level,
58 gnutls_alert_description_t desc)
59{
60 return RETWRAP_NET(gnutls_alert_send( this->s, level, desc));
61}
62
63int session::send_appropriate_alert (int err)
64{
65 return RETWRAP_NET(gnutls_alert_send_appropriate( this->s, err));
66}
67
68gnutls_cipher_algorithm_t session::get_cipher() const
69{
70 return gnutls_cipher_get( this->s);
71}
72
73gnutls_kx_algorithm_t session::get_kx () const
74{
75 return gnutls_kx_get( this->s);
76}
77
78gnutls_mac_algorithm_t session::get_mac () const
79{
80 return gnutls_mac_get( this->s);
81}
82
83gnutls_compression_method_t session::get_compression() const
84{
85 return gnutls_compression_get( this->s);
86}
87
88gnutls_certificate_type_t session::get_certificate_type() const
89{
90 return gnutls_certificate_type_get( this->s);
91}
92
93void session::set_private_extensions ( bool allow)
94{
95 gnutls_handshake_set_private_extensions( this->s, (int)allow);
96}
97
98gnutls_handshake_description_t session::get_handshake_last_out() const
99{
100 return gnutls_handshake_get_last_out( this->s);
101}
102
103gnutls_handshake_description_t session::get_handshake_last_in() const
104{
105 return gnutls_handshake_get_last_in( this->s);
106}
107
108ssize_t session::send (const void *data, size_t sizeofdata)
109{
110 return RETWRAP_NET(gnutls_record_send( this->s, data, sizeofdata));
111}
112
113ssize_t session::recv (void *data, size_t sizeofdata)
114{
115 return RETWRAP_NET(gnutls_record_recv( this->s, data, sizeofdata));
116}
117
118bool session::get_record_direction() const
119{
120 return gnutls_record_get_direction(this->s);
121}
122
123 // maximum packet size
124size_t session::get_max_size () const
125{
126 return gnutls_record_get_max_size( this->s);
127}
128
129void session::set_max_size(size_t size)
130{
131 RETWRAP( gnutls_record_set_max_size( this->s, size));
132}
133
134size_t session::check_pending () const
135{
136 return gnutls_record_check_pending( this->s);
137}
138
139
140void session::prf (size_t label_size, const char *label,
141 int server_random_first,
142 size_t extra_size, const char *extra,
143 size_t outsize, char *out)
144{
145 RETWRAP(gnutls_prf( this->s, label_size, label, server_random_first,
146 extra_size, extra, outsize, out));
147}
148
149void session::prf_raw ( size_t label_size, const char *label,
150 size_t seed_size, const char *seed,
151 size_t outsize, char *out)
152{
153 RETWRAP( gnutls_prf_raw( this->s, label_size, label, seed_size, seed, outsize, out));
154}
155
156
157void session::set_cipher_priority (const int *list)
158{
159 RETWRAP( gnutls_cipher_set_priority( this->s, list));
160}
161
162void session::set_mac_priority (const int *list)
163{
164 RETWRAP( gnutls_mac_set_priority( this->s, list));
165}
166
167void session::set_compression_priority (const int *list)
168{
169 RETWRAP( gnutls_compression_set_priority( this->s, list));
170}
171
172void session::set_kx_priority (const int *list)
173{
174 RETWRAP( gnutls_kx_set_priority( this->s, list));
175}
176
177void session::set_protocol_priority (const int *list)
178{
179 RETWRAP( gnutls_protocol_set_priority( this->s, list));
180}
181
182void session::set_certificate_type_priority (const int *list)
183{
184 RETWRAP( gnutls_certificate_type_set_priority( this->s, list));
185}
186
187
188/* if you just want some defaults, use the following.
189 */
190void session::set_priority(const char* prio, const char** err_pos)
191{
192 RETWRAP(gnutls_priority_set_direct( this->s, prio, err_pos));
193}
194
195void session::set_priority(gnutls_priority_t p)
196{
197 RETWRAP(gnutls_priority_set( this->s, p));
198}
199
200gnutls_protocol_t session::get_protocol_version() const
201{
202 return gnutls_protocol_get_version( this->s);
203}
204
205void session::set_data ( const void *session_data,
206 size_t session_data_size)
207{
208 RETWRAP(gnutls_session_set_data( this->s, session_data, session_data_size));
209}
210
211void session::get_data (void *session_data,
212 size_t * session_data_size) const
213{
214 RETWRAP(gnutls_session_get_data( this->s, session_data, session_data_size));
215}
216
217void session::get_data(gnutls_session_t session,
218 gnutls_datum_t & data) const
219{
220 RETWRAP(gnutls_session_get_data2( this->s, &data));
221
222}
223
224void session::get_id ( void *session_id,
225 size_t * session_id_size) const
226{
227 RETWRAP( gnutls_session_get_id( this->s, session_id, session_id_size));
228}
229
230bool session::is_resumed() const
231{
232 int ret = gnutls_session_is_resumed( this->s);
233
234 if (ret != 0) return true;
235 return false;
236}
237
238
239bool session::get_peers_certificate(std::vector<gnutls_datum_t> &out_certs) const
240{
241 const gnutls_datum_t *certs;
242 unsigned int certs_size;
243
244 certs = gnutls_certificate_get_peers (this->s, &certs_size);
245
246 if (certs==NULL) return false;
247
248 for(unsigned int i=0;i<certs_size;i++)
249 out_certs.push_back( certs[i]);
250
251 return true;
252}
253
254bool session::get_peers_certificate(const gnutls_datum_t** certs, unsigned int *certs_size) const
255{
256 *certs = gnutls_certificate_get_peers (this->s, certs_size);
257
258 if (*certs==NULL) return false;
259 return true;
260}
261
262void session::get_our_certificate(gnutls_datum_t& cert) const
263{
264const gnutls_datum_t *d;
265
266 d = gnutls_certificate_get_ours(this->s);
267 if (d==NULL)
268 throw(exception( GNUTLS_E_INVALID_REQUEST));
269 cert = *d;
270}
271
272time_t session::get_peers_certificate_activation_time() const
273{
274 return gnutls_certificate_activation_time_peers( this->s);
275}
276
277time_t session::get_peers_certificate_expiration_time() const
278{
279 return gnutls_certificate_expiration_time_peers( this->s);
280}
281void session::verify_peers_certificate( unsigned int& status) const
282{
283 RETWRAP( gnutls_certificate_verify_peers2( this->s, &status));
284}
285
286
287client_session::client_session() : session( GNUTLS_CLIENT)
288{
289}
290
291// client session
292void client_session::set_server_name (gnutls_server_name_type_t type,
293 const void *name, size_t name_length)
294{
295 RETWRAP( gnutls_server_name_set( this->s, type, name, name_length));
296}
297
298bool client_session::get_request_status()
299{
300 return RETWRAP(gnutls_certificate_client_get_request_status (this->s));
301}
302
303// server_session
304void server_session::get_server_name (void *data, size_t * data_length,
305 unsigned int *type, unsigned int indx) const
306{
307 RETWRAP( gnutls_server_name_get( this->s, data, data_length, type, indx));
308}
309
310// internal DB stuff
311static int store_function(void *_db, gnutls_datum_t key, gnutls_datum_t data)
312{
313 try {
314 DB* db = static_cast<DB*>(_db);
315
316 if (db->store( key, data)==false) return -1;
317 } catch(...) {
318 return -1;
319 }
320
321 return 0;
322}
323
324const static gnutls_datum_t null_datum = { NULL, 0 };
325
326static gnutls_datum_t retrieve_function(void *_db, gnutls_datum_t key)
327{
328 gnutls_datum_t data;
329
330 try {
331 DB* db = static_cast<DB*>(_db);
332
333 if (db->retrieve( key, data)==false) return null_datum;
334
335 } catch(...) {
336 return null_datum;
337 }
338
339 return data;
340}
341
342static int remove_function(void *_db, gnutls_datum_t key)
343{
344 try {
345 DB* db = static_cast<DB*>(_db);
346
347 if (db->remove( key)==false) return -1;
348 } catch(...) {
349 return -1;
350 }
351
352 return 0;
353}
354
355void server_session::set_db( const DB& db)
356{
357 gnutls_db_set_ptr( this->s, const_cast<DB*>(&db));
358 gnutls_db_set_store_function( this->s, store_function);
359 gnutls_db_set_retrieve_function( this->s, retrieve_function);
360 gnutls_db_set_remove_function( this->s, remove_function);
361}
362
363void server_session::set_db_cache_expiration (unsigned int seconds)
364{
365 gnutls_db_set_cache_expiration( this->s, seconds);
366}
367
368void server_session::db_remove () const
369{
370 gnutls_db_remove_session( this->s);
371}
372
373bool server_session::db_check_entry ( gnutls_datum_t &session_data) const
374{
375 int ret = gnutls_db_check_entry( this->s, session_data);
376
377 if (ret != 0) return true;
378 return false;
379}
380
381void session::set_max_handshake_packet_length ( size_t max)
382{
383 gnutls_handshake_set_max_packet_length( this->s, max);
384}
385
386void session::clear_credentials()
387{
388 gnutls_credentials_clear( this->s);
389}
390
391void session::set_credentials( credentials &cred)
392{
393 RETWRAP(gnutls_credentials_set( this->s, cred.get_type(), cred.ptr()));
394}
395
396const char* server_session::get_srp_username() const
397{
398 return gnutls_srp_server_get_username( this->s);
399}
400
401const char* server_session::get_psk_username() const
402{
403 return gnutls_psk_server_get_username( this->s);
404}
405
406
407void session::set_transport_ptr( gnutls_transport_ptr_t ptr)
408{
409 gnutls_transport_set_ptr( this->s, ptr);
410}
411
412void session::set_transport_ptr( gnutls_transport_ptr_t recv_ptr, gnutls_transport_ptr_t send_ptr)
413{
414 gnutls_transport_set_ptr2( this->s, recv_ptr, send_ptr);
415}
416
417
418gnutls_transport_ptr_t session::get_transport_ptr () const
419{
420 return gnutls_transport_get_ptr (this->s);
421}
422
423void session::get_transport_ptr( gnutls_transport_ptr_t & recv_ptr,
424 gnutls_transport_ptr_t & send_ptr) const
425{
426 gnutls_transport_get_ptr2 (this->s, &recv_ptr, &send_ptr);
427}
428
429void session::set_transport_lowat( size_t num)
430{
431 gnutls_transport_set_lowat (this->s, num);
432}
433
434void session::set_transport_push_function( gnutls_push_func push_func)
435{
436 gnutls_transport_set_push_function ( this->s, push_func);
437}
438
439void session::set_transport_pull_function( gnutls_pull_func pull_func)
440{
441 gnutls_transport_set_pull_function ( this->s, pull_func);
442}
443
444void session::set_user_ptr( void* ptr)
445{
446 gnutls_session_set_ptr( this->s, ptr);
447}
448
449void* session::get_user_ptr( ) const
450{
451 return gnutls_session_get_ptr(this->s);
452}
453
454void session::send_openpgp_cert( gnutls_openpgp_crt_status_t status)
455{
456 gnutls_openpgp_send_cert(this->s, status);
457}
458
459
460void session::set_dh_prime_bits( unsigned int bits)
461{
462 gnutls_dh_set_prime_bits( this->s, bits);
463}
464
465unsigned int session::get_dh_secret_bits() const
466{
467 return RETWRAP( gnutls_dh_get_secret_bits( this->s));
468}
469
470unsigned int session::get_dh_peers_public_bits() const
471{
472 return RETWRAP(gnutls_dh_get_peers_public_bits( this->s));
473}
474
475unsigned int session::get_dh_prime_bits() const
476{
477 return RETWRAP( gnutls_dh_get_prime_bits( this->s));
478}
479
480void session::get_dh_group( gnutls_datum_t & gen, gnutls_datum_t & prime) const
481{
482 RETWRAP( gnutls_dh_get_group( this->s, &gen, &prime));
483}
484
485void session::get_dh_pubkey( gnutls_datum_t & raw_key) const
486{
487 RETWRAP(gnutls_dh_get_pubkey( this->s, &raw_key));
488}
489
490void session::get_rsa_export_pubkey( gnutls_datum_t& exponent, gnutls_datum_t& modulus) const
491{
492 RETWRAP( gnutls_rsa_export_get_pubkey( this->s, &exponent, &modulus));
493}
494
495unsigned int session::get_rsa_export_modulus_bits() const
496{
497 return RETWRAP(gnutls_rsa_export_get_modulus_bits( this->s));
498}
499
500void server_session::set_certificate_request( gnutls_certificate_request_t req)
501{
502 gnutls_certificate_server_set_request (this->s, req);
503}
504
505
506
507
508gnutls_credentials_type_t session::get_auth_type() const
509{
510 return gnutls_auth_get_type( this->s);
511}
512
513gnutls_credentials_type_t session::get_server_auth_type() const
514{
515 return gnutls_auth_server_get_type( this->s);
516}
517
518gnutls_credentials_type_t session::get_client_auth_type() const
519{
520 return gnutls_auth_client_get_type( this->s);
521}
522
523
524void* certificate_credentials::ptr() const
525{
526 return this->cred;
527}
528
529void certificate_credentials::set_ptr(void* p)
530{
531 this->cred = static_cast<gnutls_certificate_credentials_t> (p);
532}
533
534certificate_credentials::~certificate_credentials()
535{
536 gnutls_certificate_free_credentials (this->cred);
537}
538
539certificate_credentials::certificate_credentials() : credentials(GNUTLS_CRD_CERTIFICATE)
540{
541 RETWRAP(gnutls_certificate_allocate_credentials ( &this->cred));
542}
543
544void certificate_server_credentials::set_params_function( gnutls_params_function* func)
545{
546 gnutls_certificate_set_params_function( this->cred, func);
547}
548
549anon_server_credentials::anon_server_credentials() : credentials(GNUTLS_CRD_ANON)
550{
551 RETWRAP(gnutls_anon_allocate_server_credentials( &this->cred));
552}
553
554anon_server_credentials::~anon_server_credentials()
555{
556 gnutls_anon_free_server_credentials( this->cred);
557}
558
559void anon_server_credentials::set_dh_params( const dh_params& params)
560{
561 gnutls_anon_set_server_dh_params (this->cred, params.get_params_t());
562}
563
564void anon_server_credentials::set_params_function ( gnutls_params_function * func)
565{
566 gnutls_anon_set_server_params_function ( this->cred, func);
567}
568
569anon_client_credentials::anon_client_credentials() : credentials(GNUTLS_CRD_ANON)
570{
571 RETWRAP(gnutls_anon_allocate_client_credentials( &this->cred));
572}
573
574anon_client_credentials::~anon_client_credentials()
575{
576 gnutls_anon_free_client_credentials( this->cred);
577}
578
579void certificate_credentials::free_keys ()
580{
581 gnutls_certificate_free_keys( this->cred);
582}
583
584void certificate_credentials::free_cas ()
585{
586 gnutls_certificate_free_cas( this->cred);
587}
588
589void certificate_credentials::free_ca_names ()
590{
591 gnutls_certificate_free_ca_names( this->cred);
592}
593
594void certificate_credentials::free_crls ()
595{
596 gnutls_certificate_free_crls( this->cred);
597}
598
599
600void certificate_credentials::set_dh_params ( const dh_params& params)
601{
602 gnutls_certificate_set_dh_params( this->cred, params.get_params_t());
603}
604
605void certificate_credentials::set_rsa_export_params ( const rsa_params & params)
606{
607 gnutls_certificate_set_rsa_export_params( this->cred, params.get_params_t());
608}
609
610void certificate_credentials::set_verify_flags ( unsigned int flags)
611{
612 gnutls_certificate_set_verify_flags( this->cred, flags);
613}
614
615void certificate_credentials::set_verify_limits ( unsigned int max_bits, unsigned int max_depth)
616{
617 gnutls_certificate_set_verify_limits( this->cred, max_bits, max_depth);
618}
619
620void certificate_credentials::set_x509_trust_file(const char *cafile, gnutls_x509_crt_fmt_t type)
621{
622 RETWRAP( gnutls_certificate_set_x509_trust_file( this->cred, cafile, type));
623}
624
625void certificate_credentials::set_x509_trust(const gnutls_datum_t & CA, gnutls_x509_crt_fmt_t type)
626{
627 RETWRAP( gnutls_certificate_set_x509_trust_mem( this->cred, &CA, type));
628}
629
630
631void certificate_credentials::set_x509_crl_file( const char *crlfile, gnutls_x509_crt_fmt_t type)
632{
633 RETWRAP( gnutls_certificate_set_x509_crl_file( this->cred, crlfile, type));
634}
635
636void certificate_credentials::set_x509_crl(const gnutls_datum_t & CRL, gnutls_x509_crt_fmt_t type)
637{
638 RETWRAP( gnutls_certificate_set_x509_crl_mem( this->cred, &CRL, type));
639}
640
641void certificate_credentials::set_x509_key_file(const char *certfile, const char *keyfile, gnutls_x509_crt_fmt_t type)
642{
643 RETWRAP( gnutls_certificate_set_x509_key_file( this->cred, certfile, keyfile, type));
644}
645
646void certificate_credentials::set_x509_key(const gnutls_datum_t & CERT, const gnutls_datum_t & KEY, gnutls_x509_crt_fmt_t type)
647{
648 RETWRAP( gnutls_certificate_set_x509_key_mem( this->cred, &CERT, &KEY, type));
649}
650
651void certificate_credentials::set_simple_pkcs12_file( const char *pkcs12file,
652 gnutls_x509_crt_fmt_t type, const char *password)
653{
654 RETWRAP( gnutls_certificate_set_x509_simple_pkcs12_file( this->cred, pkcs12file, type, password));
655}
656
657void certificate_credentials::set_x509_key ( gnutls_x509_crt_t * cert_list, int cert_list_size,
658 gnutls_x509_privkey_t key)
659{
660 RETWRAP( gnutls_certificate_set_x509_key( this->cred, cert_list, cert_list_size, key));
661}
662
663void certificate_credentials::set_x509_trust ( gnutls_x509_crt_t * ca_list, int ca_list_size)
664{
665 RETWRAP( gnutls_certificate_set_x509_trust( this->cred, ca_list, ca_list_size));
666}
667
668void certificate_credentials::set_x509_crl ( gnutls_x509_crl_t * crl_list, int crl_list_size)
669{
670 RETWRAP( gnutls_certificate_set_x509_crl( this->cred, crl_list, crl_list_size));
671}
672
673void certificate_server_credentials::set_retrieve_function( gnutls_certificate_server_retrieve_function* func)
674{
675 gnutls_certificate_server_set_retrieve_function( this->cred, func);
676}
677
678void certificate_client_credentials::set_retrieve_function( gnutls_certificate_client_retrieve_function* func)
679{
680 gnutls_certificate_client_set_retrieve_function( this->cred, func);
681}
682
683// SRP
684
685srp_server_credentials::srp_server_credentials() : credentials(GNUTLS_CRD_SRP)
686{
687 RETWRAP(gnutls_srp_allocate_server_credentials( &this->cred));
688}
689
690srp_server_credentials::~srp_server_credentials()
691{
692 gnutls_srp_free_server_credentials( this->cred);
693}
694
695void* srp_server_credentials::ptr() const
696{
697 return this->cred;
698}
699
700void srp_server_credentials::set_ptr(void* p)
701{
702 this->cred = static_cast<gnutls_srp_server_credentials_t> (p);
703}
704
705srp_client_credentials::srp_client_credentials() : credentials(GNUTLS_CRD_SRP)
706{
707 RETWRAP(gnutls_srp_allocate_client_credentials( &this->cred));
708}
709
710srp_client_credentials::~srp_client_credentials()
711{
712 gnutls_srp_free_client_credentials( this->cred);
713}
714
715void* srp_client_credentials::ptr() const
716{
717 return this->cred;
718}
719
720void srp_client_credentials::set_ptr(void* p)
721{
722 this->cred = static_cast<gnutls_srp_client_credentials_t> (p);
723}
724
725void srp_client_credentials::set_credentials( const char* username, const char* password)
726{
727 RETWRAP(gnutls_srp_set_client_credentials (this->cred, username, password));
728}
729
730void srp_server_credentials::set_credentials_file (
731 const char *password_file, const char *password_conf_file)
732{
733 RETWRAP( gnutls_srp_set_server_credentials_file( this->cred, password_file, password_conf_file));
734}
735
736
737void srp_server_credentials::set_credentials_function(gnutls_srp_server_credentials_function * func)
738{
739 gnutls_srp_set_server_credentials_function( this->cred, func);
740}
741
742void srp_client_credentials::set_credentials_function(gnutls_srp_client_credentials_function * func)
743{
744 gnutls_srp_set_client_credentials_function( this->cred, func);
745}
746
747credentials::credentials(gnutls_credentials_type_t t) : type(t)
748{
749}
750
751#if !(defined(__APPLE__) || defined(__MACOS__))
752/* FIXME: This #if is due to a compile bug in Mac OS X. Give it some
753 time and then remove this cruft. See also
754 includes/gnutls/gnutlsxx.h. */
755credentials::credentials( credentials& c)
756{
757 this->type = c.type;
758 this->set_ptr( c.ptr());
759}
760#endif
761
762gnutls_credentials_type_t credentials::get_type() const
763{
764 return type;
765}
766
767exception::exception( int x)
768{
769 retcode = x;
770}
771
772int exception::get_code()
773{
774 return retcode;
775}
776
777const char* exception::what() const throw()
778{
779 return gnutls_strerror(retcode);
780}
781
782
783
784
785dh_params::dh_params()
786{
787 RETWRAP(gnutls_dh_params_init( &params));
788}
789
790dh_params::~dh_params()
791{
792 gnutls_dh_params_deinit(params);
793}
794
795void dh_params::import_raw( const gnutls_datum_t & prime,
796 const gnutls_datum_t & generator)
797{
798 RETWRAP( gnutls_dh_params_import_raw( params, &prime, &generator));
799}
800
801void dh_params::import_pkcs3( const gnutls_datum_t & pkcs3_params,
802 gnutls_x509_crt_fmt_t format)
803{
804 RETWRAP(gnutls_dh_params_import_pkcs3( params, &pkcs3_params, format));
805}
806
807void dh_params::generate( unsigned int bits)
808{
809 RETWRAP(gnutls_dh_params_generate2( params, bits));
810}
811
812void dh_params::export_pkcs3( gnutls_x509_crt_fmt_t format, unsigned char *params_data, size_t * params_data_size)
813{
814 RETWRAP( gnutls_dh_params_export_pkcs3( params, format, params_data, params_data_size));
815}
816
817void dh_params::export_raw( gnutls_datum_t& prime, gnutls_datum_t &generator)
818{
819 RETWRAP( gnutls_dh_params_export_raw( params, &prime, &generator, NULL));
820}
821
822gnutls_dh_params_t dh_params::get_params_t() const
823{
824 return params;
825}
826
827dh_params & dh_params::operator=(const dh_params& src)
828{
829 dh_params* dst = new dh_params;
830 int ret;
831
832 ret = gnutls_dh_params_cpy( dst->params, src.params);
833
834 if (ret < 0) {
835 delete dst;
836 throw(ret);
837 }
838
839 return *dst;
840}
841
842
843// RSA
844
845rsa_params::rsa_params()
846{
847 RETWRAP(gnutls_rsa_params_init( &params));
848}
849
850rsa_params::~rsa_params()
851{
852 gnutls_rsa_params_deinit(params);
853}
854
855void rsa_params::import_pkcs1( const gnutls_datum_t & pkcs1_params,
856 gnutls_x509_crt_fmt_t format)
857{
858 RETWRAP(gnutls_rsa_params_import_pkcs1( params, &pkcs1_params, format));
859}
860
861void rsa_params::generate( unsigned int bits)
862{
863 RETWRAP(gnutls_rsa_params_generate2( params, bits));
864}
865
866void rsa_params::export_pkcs1( gnutls_x509_crt_fmt_t format, unsigned char *params_data, size_t * params_data_size)
867{
868 RETWRAP( gnutls_rsa_params_export_pkcs1( params, format, params_data, params_data_size));
869}
870
871gnutls_rsa_params_t rsa_params::get_params_t() const
872{
873 return params;
874}
875
876rsa_params & rsa_params::operator=(const rsa_params& src)
877{
878 rsa_params* dst = new rsa_params;
879 int ret;
880
881 ret = gnutls_rsa_params_cpy( dst->params, src.params);
882
883 if (ret < 0)
884 delete dst;
885 throw(ret);
886
887 return *dst;
888}
889
890void rsa_params::import_raw( const gnutls_datum_t & m,
891 const gnutls_datum_t & e,
892 const gnutls_datum_t & d,
893 const gnutls_datum_t & p,
894 const gnutls_datum_t & q,
895 const gnutls_datum_t & u)
896{
897
898 RETWRAP(gnutls_rsa_params_import_raw ( params, &m, &e, &d, &p, &q, &u));
899}
900
901
902void rsa_params::export_raw( gnutls_datum_t & m, gnutls_datum_t & e,
903 gnutls_datum_t & d, gnutls_datum_t & p,
904 gnutls_datum_t & q, gnutls_datum_t & u)
905{
906 RETWRAP( gnutls_rsa_params_export_raw ( params, &m, &e, &d, &p, &q, &u, NULL));
907}
diff --git a/src/daemon/https/tls/io_debug.h b/src/daemon/https/tls/io_debug.h
new file mode 100644
index 00000000..9800565e
--- /dev/null
+++ b/src/daemon/https/tls/io_debug.h
@@ -0,0 +1,79 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* This debug file was contributed by
26 * Paul Sheer <psheer@icon.co.za>. Some changes were made by nmav.
27 * Its purpose is to debug non blocking behaviour of gnutls. The included
28 * send() and recv() functions return EAGAIN errors in random.
29 *
30 */
31
32#ifdef IO_DEBUG
33
34#include <gnutls_int.h>
35
36#define EDUNNO EAGAIN /* EAGAIN */
37
38extern int errno;
39static int initialized_rand = 0;
40
41#define INITIALIZE_RAND if (initialized_rand==0) {\
42 srand(time(0)); \
43 initialized_rand = 1; \
44 }
45static int
46recv_debug (int fd, char *buf, int len, int flags)
47{
48 INITIALIZE_RAND;
49
50 if (!(rand () % IO_DEBUG))
51 {
52 errno = EDUNNO;
53 return -1;
54 }
55 if (len > 1)
56 len = 1;
57 return recv (fd, buf, len, flags);
58}
59
60#define recv recv_debug
61
62static int
63send_debug (int fd, const char *buf, int len, int flags)
64{
65 INITIALIZE_RAND;
66
67 if (!(rand () % IO_DEBUG))
68 {
69 errno = EDUNNO;
70 return -1;
71 }
72 if (len > 10)
73 len = 10;
74 return send (fd, buf, len, flags);
75}
76
77#define send send_debug
78
79#endif
diff --git a/src/daemon/https/tls/libgnutls-config b/src/daemon/https/tls/libgnutls-config
new file mode 100644
index 00000000..80580a89
--- /dev/null
+++ b/src/daemon/https/tls/libgnutls-config
@@ -0,0 +1,104 @@
1#!/bin/sh
2
3prefix=/home/lama/workbench/programming/c/gnunet/gnutls-2.2.3/build
4exec_prefix=${prefix}
5exec_prefix_set=no
6
7gnutls_libs="-L${exec_prefix}/lib -lgnutls -L/usr/lib -ltasn1 -lgcrypt "
8gnutls_cflags=" -I/usr/include -I${prefix}/include"
9gnutls_la_file="${exec_prefix}/lib/libgnutls.la"
10
11usage()
12{
13 cat <<EOF
14Usage: libgnutls-config [OPTIONS]
15Options:
16 [--prefix[=DIR]]
17 [--exec-prefix[=DIR]]
18 [--version]
19 [--libs]
20 [--cflags]
21EOF
22 exit $1
23}
24
25if test $# -eq 0; then
26 usage 1 1>&2
27fi
28
29while test $# -gt 0; do
30 case "$1" in
31 -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
32 *) optarg= ;;
33 esac
34
35 case $1 in
36 --prefix=*)
37 prefix=$optarg
38 if test $exec_prefix_set = no ; then
39 exec_prefix=$optarg
40 fi
41 ;;
42 --prefix)
43 echo_prefix=yes
44 ;;
45 --exec-prefix=*)
46 exec_prefix=$optarg
47 exec_prefix_set=yes
48 ;;
49 --exec-prefix)
50 echo_exec_prefix=yes
51 ;;
52 --version)
53 echo "2.2.3"
54 exit 0
55 ;;
56 --cflags)
57 echo_cflags=yes
58 ;;
59 --libs)
60 echo_libs=yes
61 ;;
62 --la-file)
63 echo_la_file=yes
64 ;;
65 --help)
66 usage 0
67 ;;
68 *)
69 usage 1 1>&2
70 ;;
71 esac
72 shift
73done
74
75if test "$echo_prefix" = "yes"; then
76 echo $prefix
77fi
78
79if test "$echo_exec_prefix" = "yes"; then
80 echo $exec_prefix
81fi
82
83if test "$echo_cflags" = "yes"; then
84 if test "${prefix}/include" != "/usr/include" ; then
85 includes="-I${prefix}/include"
86 for i in $gnutls_cflags ; do
87 if test "$i" = "-I${prefix}/include" ; then
88 includes=""
89 fi
90 done
91 fi
92 echo $includes $gnutls_cflags
93fi
94
95if test "$echo_la_file" = "yes"; then
96 echo ${gnutls_la_file}
97fi
98
99if test "$echo_libs" = "yes"; then
100 echo ${gnutls_libs}
101fi
102
103
104
diff --git a/src/daemon/https/tls/libgnutls.m4 b/src/daemon/https/tls/libgnutls.m4
new file mode 100644
index 00000000..1851ca23
--- /dev/null
+++ b/src/daemon/https/tls/libgnutls.m4
@@ -0,0 +1,160 @@
1dnl Autoconf macros for libgnutls
2dnl $id$
3
4# Modified for LIBGNUTLS -- nmav
5# Configure paths for LIBGCRYPT
6# Shamelessly stolen from the one of XDELTA by Owen Taylor
7# Werner Koch 99-12-09
8
9dnl AM_PATH_LIBGNUTLS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
10dnl Test for libgnutls, and define LIBGNUTLS_CFLAGS and LIBGNUTLS_LIBS
11dnl
12AC_DEFUN([AM_PATH_LIBGNUTLS],
13[dnl
14dnl Get the cflags and libraries from the libgnutls-config script
15dnl
16AC_ARG_WITH(libgnutls-prefix,
17 [ --with-libgnutls-prefix=PFX Prefix where libgnutls is installed (optional)],
18 libgnutls_config_prefix="$withval", libgnutls_config_prefix="")
19
20 if test x$libgnutls_config_prefix != x ; then
21 if test x${LIBGNUTLS_CONFIG+set} != xset ; then
22 LIBGNUTLS_CONFIG=$libgnutls_config_prefix/bin/libgnutls-config
23 fi
24 fi
25
26 AC_PATH_PROG(LIBGNUTLS_CONFIG, libgnutls-config, no)
27 min_libgnutls_version=ifelse([$1], ,0.1.0,$1)
28 AC_MSG_CHECKING(for libgnutls - version >= $min_libgnutls_version)
29 no_libgnutls=""
30 if test "$LIBGNUTLS_CONFIG" = "no" ; then
31 no_libgnutls=yes
32 else
33 LIBGNUTLS_CFLAGS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --cflags`
34 LIBGNUTLS_LIBS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --libs`
35 libgnutls_config_version=`$LIBGNUTLS_CONFIG $libgnutls_config_args --version`
36
37
38 ac_save_CFLAGS="$CFLAGS"
39 ac_save_LIBS="$LIBS"
40 CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS"
41 LIBS="$LIBS $LIBGNUTLS_LIBS"
42dnl
43dnl Now check if the installed libgnutls is sufficiently new. Also sanity
44dnl checks the results of libgnutls-config to some extent
45dnl
46 rm -f conf.libgnutlstest
47 AC_TRY_RUN([
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <gnutls.h>
52
53int
54main ()
55{
56 system ("touch conf.libgnutlstest");
57
58 if( strcmp( gnutls_check_version(NULL), "$libgnutls_config_version" ) )
59 {
60 printf("\n*** 'libgnutls-config --version' returned %s, but LIBGNUTLS (%s)\n",
61 "$libgnutls_config_version", gnutls_check_version(NULL) );
62 printf("*** was found! If libgnutls-config was correct, then it is best\n");
63 printf("*** to remove the old version of LIBGNUTLS. You may also be able to fix the error\n");
64 printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
65 printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
66 printf("*** required on your system.\n");
67 printf("*** If libgnutls-config was wrong, set the environment variable LIBGNUTLS_CONFIG\n");
68 printf("*** to point to the correct copy of libgnutls-config, and remove the file config.cache\n");
69 printf("*** before re-running configure\n");
70 }
71 else if ( strcmp(gnutls_check_version(NULL), LIBGNUTLS_VERSION ) )
72 {
73 printf("\n*** LIBGNUTLS header file (version %s) does not match\n", LIBGNUTLS_VERSION);
74 printf("*** library (version %s)\n", gnutls_check_version(NULL) );
75 }
76 else
77 {
78 if ( gnutls_check_version( "$min_libgnutls_version" ) )
79 {
80 return 0;
81 }
82 else
83 {
84 printf("no\n*** An old version of LIBGNUTLS (%s) was found.\n",
85 gnutls_check_version(NULL) );
86 printf("*** You need a version of LIBGNUTLS newer than %s. The latest version of\n",
87 "$min_libgnutls_version" );
88 printf("*** LIBGNUTLS is always available from ftp://gnutls.hellug.gr/pub/gnutls.\n");
89 printf("*** \n");
90 printf("*** If you have already installed a sufficiently new version, this error\n");
91 printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n");
92 printf("*** being found. The easiest way to fix this is to remove the old version\n");
93 printf("*** of LIBGNUTLS, but you can also set the LIBGNUTLS_CONFIG environment to point to the\n");
94 printf("*** correct copy of libgnutls-config. (In this case, you will have to\n");
95 printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
96 printf("*** so that the correct libraries are found at run-time))\n");
97 }
98 }
99 return 1;
100}
101],, no_libgnutls=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
102 CFLAGS="$ac_save_CFLAGS"
103 LIBS="$ac_save_LIBS"
104 fi
105
106 if test "x$no_libgnutls" = x ; then
107 AC_MSG_RESULT(yes)
108 ifelse([$2], , :, [$2])
109 else
110 if test -f conf.libgnutlstest ; then
111 :
112 else
113 AC_MSG_RESULT(no)
114 fi
115 if test "$LIBGNUTLS_CONFIG" = "no" ; then
116 echo "*** The libgnutls-config script installed by LIBGNUTLS could not be found"
117 echo "*** If LIBGNUTLS was installed in PREFIX, make sure PREFIX/bin is in"
118 echo "*** your path, or set the LIBGNUTLS_CONFIG environment variable to the"
119 echo "*** full path to libgnutls-config."
120 else
121 if test -f conf.libgnutlstest ; then
122 :
123 else
124 echo "*** Could not run libgnutls test program, checking why..."
125 CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS"
126 LIBS="$LIBS $LIBGNUTLS_LIBS"
127 AC_TRY_LINK([
128#include <stdio.h>
129#include <stdlib.h>
130#include <string.h>
131#include <gnutls.h>
132], [ return !!gnutls_check_version(NULL); ],
133 [ echo "*** The test program compiled, but did not run. This usually means"
134 echo "*** that the run-time linker is not finding LIBGNUTLS or finding the wrong"
135 echo "*** version of LIBGNUTLS. If it is not finding LIBGNUTLS, you'll need to set your"
136 echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
137 echo "*** to the installed location Also, make sure you have run ldconfig if that"
138 echo "*** is required on your system"
139 echo "***"
140 echo "*** If you have an old version installed, it is best to remove it, although"
141 echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
142 echo "***" ],
143 [ echo "*** The test program failed to compile or link. See the file config.log for the"
144 echo "*** exact error that occured. This usually means LIBGNUTLS was incorrectly installed"
145 echo "*** or that you have moved LIBGNUTLS since it was installed. In the latter case, you"
146 echo "*** may want to edit the libgnutls-config script: $LIBGNUTLS_CONFIG" ])
147 CFLAGS="$ac_save_CFLAGS"
148 LIBS="$ac_save_LIBS"
149 fi
150 fi
151 LIBGNUTLS_CFLAGS=""
152 LIBGNUTLS_LIBS=""
153 ifelse([$3], , :, [$3])
154 fi
155 rm -f conf.libgnutlstest
156 AC_SUBST(LIBGNUTLS_CFLAGS)
157 AC_SUBST(LIBGNUTLS_LIBS)
158])
159
160dnl *-*wedit:notab*-* Please keep this as the last line.
diff --git a/src/daemon/https/tls/libgnutls.vers b/src/daemon/https/tls/libgnutls.vers
new file mode 100644
index 00000000..f793617b
--- /dev/null
+++ b/src/daemon/https/tls/libgnutls.vers
@@ -0,0 +1,27 @@
1# libgnutls.vers -- Versioning script to control what symbols to export.
2# Copyright (C) 2005, 2006, 2007 Free Software Foundation
3#
4# Author: Simon Josefsson
5#
6# This file is part of GNUTLS.
7#
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.
12#
13# The GNUTLS library is distributed in the hope that it will be
14#useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15#of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16#Lesser General Public License for more details.
17#
18# You should have received a copy of the GNU Lesser General Public
19# License along with the GNUTLS library; if not, write to the Free
20# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21# MA 02110-1301, USA
22
23GNUTLS_1_4
24{
25 global: _gnutls*; gnutls*;
26 local: *;
27};
diff --git a/src/daemon/https/tls/libgnutlsxx.vers b/src/daemon/https/tls/libgnutlsxx.vers
new file mode 100644
index 00000000..8b8af51d
--- /dev/null
+++ b/src/daemon/https/tls/libgnutlsxx.vers
@@ -0,0 +1,30 @@
1# libgnutlsxx.vers -- Versioning script to control what symbols to export.
2# Copyright (C) 2005, 2006 Free Software Foundation
3#
4# Author: Simon Josefsson
5#
6# This file is part of GNUTLS.
7#
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.
12#
13# The GNUTLS library is distributed in the hope that it will be
14#useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15#of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16#Lesser General Public License for more details.
17#
18# You should have received a copy of the GNU Lesser General Public
19# License along with the GNUTLS library; if not, write to the Free
20# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21# MA 02110-1301, USA
22
23GNUTLS_1_6
24{
25 global:
26 extern "C++" {
27 gnutls*;
28 };
29 local: *;
30};
diff --git a/src/daemon/https/tls/pkix.asn b/src/daemon/https/tls/pkix.asn
new file mode 100644
index 00000000..d46dfa07
--- /dev/null
+++ b/src/daemon/https/tls/pkix.asn
@@ -0,0 +1,1241 @@
1
2PKIX1 { }
3
4DEFINITIONS IMPLICIT TAGS ::=
5
6BEGIN
7
8-- This contains both PKIX1Implicit88 and RFC2630 ASN.1 modules.
9
10-- ISO arc for standard certificate and CRL extensions
11
12id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
13
14
15-- authority key identifier OID and syntax
16
17id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
18
19AuthorityKeyIdentifier ::= SEQUENCE {
20 keyIdentifier [0] KeyIdentifier OPTIONAL,
21 authorityCertIssuer [1] GeneralNames OPTIONAL,
22 authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
23 -- authorityCertIssuer and authorityCertSerialNumber shall both
24 -- be present or both be absgent
25
26KeyIdentifier ::= OCTET STRING
27
28-- subject key identifier OID and syntax
29
30id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 }
31
32SubjectKeyIdentifier ::= KeyIdentifier
33
34-- key usage extension OID and syntax
35
36id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
37
38KeyUsage ::= BIT STRING {
39 digitalSignature (0),
40 nonRepudiation (1),
41 keyEncipherment (2),
42 dataEncipherment (3),
43 keyAgreement (4),
44 keyCertSign (5),
45 cRLSign (6),
46 encipherOnly (7),
47 decipherOnly (8) }
48
49-- private key usage period extension OID and syntax
50
51id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 }
52
53PrivateKeyUsagePeriod ::= SEQUENCE {
54 notBefore [0] GeneralizedTime OPTIONAL,
55 notAfter [1] GeneralizedTime OPTIONAL }
56 -- either notBefore or notAfter shall be present
57
58-- certificate policies extension OID and syntax
59
60id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
61
62CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
63
64PolicyInformation ::= SEQUENCE {
65 policyIdentifier CertPolicyId,
66 policyQualifiers SEQUENCE SIZE (1..MAX) OF
67 PolicyQualifierInfo OPTIONAL }
68
69CertPolicyId ::= OBJECT IDENTIFIER
70
71PolicyQualifierInfo ::= SEQUENCE {
72 policyQualifierId PolicyQualifierId,
73 qualifier ANY DEFINED BY policyQualifierId }
74
75-- Implementations that recognize additional policy qualifiers shall
76-- augment the following definition for PolicyQualifierId
77
78PolicyQualifierId ::=
79 OBJECT IDENTIFIER -- ( id-qt-cps | id-qt-unotice )
80
81-- CPS pointer qualifier
82
83CPSuri ::= IA5String
84
85-- user notice qualifier
86
87UserNotice ::= SEQUENCE {
88 noticeRef NoticeReference OPTIONAL,
89 explicitText DisplayText OPTIONAL}
90
91NoticeReference ::= SEQUENCE {
92 organization DisplayText,
93 noticeNumbers SEQUENCE OF INTEGER }
94
95DisplayText ::= CHOICE {
96 visibleString VisibleString (SIZE (1..200)),
97 bmpString BMPString (SIZE (1..200)),
98 utf8String UTF8String (SIZE (1..200)) }
99
100-- policy mapping extension OID and syntax
101
102id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 }
103
104PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
105 issuerDomainPolicy CertPolicyId,
106 subjectDomainPolicy CertPolicyId }
107
108-- subject alternative name extension OID and syntax
109
110-- Directory string type --
111
112DirectoryString ::= CHOICE {
113 teletexString TeletexString (SIZE (1..MAX)),
114 printableString PrintableString (SIZE (1..MAX)),
115 universalString UniversalString (SIZE (1..MAX)),
116 utf8String UTF8String (SIZE (1..MAX)),
117 bmpString BMPString (SIZE(1..MAX)),
118 -- IA5String is added here to handle old UID encoded as ia5String --
119 -- See tests/userid/ for more information. It shouldn't be here, --
120 -- so if it causes problems, considering dropping it. --
121 ia5String IA5String (SIZE(1..MAX)) }
122
123id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
124
125SubjectAltName ::= GeneralNames
126
127GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
128
129GeneralName ::= CHOICE {
130 otherName [0] AnotherName,
131 rfc822Name [1] IA5String,
132 dNSName [2] IA5String,
133 x400Address [3] ORAddress,
134-- Changed to work with the libtasn1 parser.
135 directoryName [4] EXPLICIT RDNSequence, --Name,
136 ediPartyName [5] EDIPartyName,
137 uniformResourceIdentifier [6] IA5String,
138 iPAddress [7] OCTET STRING,
139 registeredID [8] OBJECT IDENTIFIER }
140
141-- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as
142-- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax
143
144AnotherName ::= SEQUENCE {
145 type-id OBJECT IDENTIFIER,
146 value [0] EXPLICIT ANY DEFINED BY type-id }
147
148EDIPartyName ::= SEQUENCE {
149 nameAssigner [0] DirectoryString OPTIONAL,
150 partyName [1] DirectoryString }
151
152-- issuer alternative name extension OID and syntax
153
154id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 }
155
156IssuerAltName ::= GeneralNames
157
158id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }
159
160SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
161
162-- basic constraints extension OID and syntax
163
164id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
165
166BasicConstraints ::= SEQUENCE {
167 cA BOOLEAN DEFAULT FALSE,
168 pathLenConstraint INTEGER (0..MAX) OPTIONAL }
169
170-- name constraints extension OID and syntax
171
172id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
173
174NameConstraints ::= SEQUENCE {
175 permittedSubtrees [0] GeneralSubtrees OPTIONAL,
176 excludedSubtrees [1] GeneralSubtrees OPTIONAL }
177
178GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
179
180GeneralSubtree ::= SEQUENCE {
181 base GeneralName,
182 minimum [0] BaseDistance DEFAULT 0,
183 maximum [1] BaseDistance OPTIONAL }
184
185BaseDistance ::= INTEGER (0..MAX)
186
187-- policy constraints extension OID and syntax
188
189id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
190
191PolicyConstraints ::= SEQUENCE {
192 requireExplicitPolicy [0] SkipCerts OPTIONAL,
193 inhibitPolicyMapping [1] SkipCerts OPTIONAL }
194
195SkipCerts ::= INTEGER (0..MAX)
196
197-- CRL distribution points extension OID and syntax
198
199id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31}
200
201CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
202
203DistributionPoint ::= SEQUENCE {
204 distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL,
205 reasons [1] ReasonFlags OPTIONAL,
206 cRLIssuer [2] GeneralNames OPTIONAL
207}
208
209DistributionPointName ::= CHOICE {
210 fullName [0] GeneralNames,
211 nameRelativeToCRLIssuer [1] RelativeDistinguishedName
212}
213
214ReasonFlags ::= BIT STRING {
215 unused (0),
216 keyCompromise (1),
217 cACompromise (2),
218 affiliationChanged (3),
219 superseded (4),
220 cessationOfOperation (5),
221 certificateHold (6),
222 privilegeWithdrawn (7),
223 aACompromise (8) }
224
225-- extended key usage extension OID and syntax
226
227id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
228
229ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
230
231KeyPurposeId ::= OBJECT IDENTIFIER
232
233-- extended key purpose OIDs
234id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
235id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
236id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
237id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
238id-kp-ipsecEndSystem OBJECT IDENTIFIER ::= { id-kp 5 }
239id-kp-ipsecTunnel OBJECT IDENTIFIER ::= { id-kp 6 }
240id-kp-ipsecUser OBJECT IDENTIFIER ::= { id-kp 7 }
241id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
242
243-- authority info access
244
245id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
246
247AuthorityInfoAccessSyntax ::=
248 SEQUENCE SIZE (1..MAX) OF AccessDescription
249
250AccessDescription ::= SEQUENCE {
251 accessMethod OBJECT IDENTIFIER,
252 accessLocation GeneralName }
253
254-- CRL number extension OID and syntax
255
256id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }
257
258CRLNumber ::= INTEGER (0..MAX)
259
260-- issuing distribution point extension OID and syntax
261
262id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
263
264IssuingDistributionPoint ::= SEQUENCE {
265 distributionPoint [0] DistributionPointName OPTIONAL,
266 onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
267 onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
268 onlySomeReasons [3] ReasonFlags OPTIONAL,
269 indirectCRL [4] BOOLEAN DEFAULT FALSE }
270
271
272id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 }
273
274-- deltaCRLIndicator ::= BaseCRLNumber
275
276BaseCRLNumber ::= CRLNumber
277
278-- CRL reasons extension OID and syntax
279
280id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }
281
282CRLReason ::= ENUMERATED {
283 unspecified (0),
284 keyCompromise (1),
285 cACompromise (2),
286 affiliationChanged (3),
287 superseded (4),
288 cessationOfOperation (5),
289 certificateHold (6),
290 removeFromCRL (8) }
291
292-- certificate issuer CRL entry extension OID and syntax
293
294id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 }
295
296CertificateIssuer ::= GeneralNames
297
298-- hold instruction extension OID and syntax
299
300id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 }
301
302HoldInstructionCode ::= OBJECT IDENTIFIER
303
304-- ANSI x9 holdinstructions
305
306-- ANSI x9 arc holdinstruction arc
307holdInstruction OBJECT IDENTIFIER ::=
308 {joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2}
309
310-- ANSI X9 holdinstructions referenced by this standard
311id-holdinstruction-none OBJECT IDENTIFIER ::=
312 {holdInstruction 1} -- deprecated
313id-holdinstruction-callissuer OBJECT IDENTIFIER ::=
314 {holdInstruction 2}
315id-holdinstruction-reject OBJECT IDENTIFIER ::=
316 {holdInstruction 3}
317
318-- invalidity date CRL entry extension OID and syntax
319
320id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }
321
322InvalidityDate ::= GeneralizedTime
323
324
325-- --------------------------------------
326-- EXPLICIT
327-- --------------------------------------
328
329-- UNIVERSAL Types defined in '93 and '98 ASN.1
330-- but required by this specification
331
332VisibleString ::= [UNIVERSAL 26] IMPLICIT OCTET STRING
333
334NumericString ::= [UNIVERSAL 18] IMPLICIT OCTET STRING
335
336IA5String ::= [UNIVERSAL 22] IMPLICIT OCTET STRING
337
338TeletexString ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
339
340PrintableString ::= [UNIVERSAL 19] IMPLICIT OCTET STRING
341
342UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING
343 -- UniversalString is defined in ASN.1:1993
344
345BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING
346 -- BMPString is the subtype of UniversalString and models
347 -- the Basic Multilingual Plane of ISO/IEC/ITU 10646-1
348
349UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING
350 -- The content of this type conforms to RFC 2279.
351
352
353-- PKIX specific OIDs
354
355id-pkix OBJECT IDENTIFIER ::=
356 { iso(1) identified-organization(3) dod(6) internet(1)
357 security(5) mechanisms(5) pkix(7) }
358
359-- PKIX arcs
360
361id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
362 -- arc for private certificate extensions
363id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
364 -- arc for policy qualifier types
365id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
366 -- arc for extended key purpose OIDS
367id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
368 -- arc for access descriptors
369
370-- policyQualifierIds for Internet policy qualifiers
371
372id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
373 -- OID for CPS qualifier
374id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
375 -- OID for user notice qualifier
376
377-- access descriptor definitions
378
379id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
380id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
381
382-- attribute data types --
383
384Attribute ::= SEQUENCE {
385 type AttributeType,
386 values SET OF AttributeValue
387 -- at least one value is required --
388}
389
390AttributeType ::= OBJECT IDENTIFIER
391
392AttributeValue ::= ANY DEFINED BY type
393
394AttributeTypeAndValue ::= SEQUENCE {
395 type AttributeType,
396 value AttributeValue }
397
398-- suggested naming attributes: Definition of the following
399-- information object set may be augmented to meet local
400-- requirements. Note that deleting members of the set may
401-- prevent interoperability with conforming implementations.
402-- presented in pairs: the AttributeType followed by the
403-- type definition for the corresponding AttributeValue
404
405-- Arc for standard naming attributes
406id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4}
407
408-- Attributes of type NameDirectoryString
409id-at-initials AttributeType ::= { id-at 43 }
410X520initials ::= DirectoryString
411
412id-at-generationQualifier AttributeType ::= { id-at 44 }
413X520generationQualifier ::= DirectoryString
414
415id-at-surname AttributeType ::= { id-at 4 }
416X520surName ::= DirectoryString
417
418id-at-givenName AttributeType ::= { id-at 42 }
419X520givenName ::= DirectoryString
420
421id-at-name AttributeType ::= { id-at 41 }
422X520name ::= DirectoryString
423
424id-at-commonName AttributeType ::= {id-at 3}
425X520CommonName ::= DirectoryString
426
427id-at-localityName AttributeType ::= {id-at 7}
428X520LocalityName ::= DirectoryString
429
430id-at-stateOrProvinceName AttributeType ::= {id-at 8}
431X520StateOrProvinceName ::= DirectoryString
432
433id-at-organizationName AttributeType ::= {id-at 10}
434X520OrganizationName ::= DirectoryString
435
436id-at-organizationalUnitName AttributeType ::= {id-at 11}
437X520OrganizationalUnitName ::= DirectoryString
438
439id-at-title AttributeType ::= {id-at 12}
440X520Title ::= DirectoryString
441
442id-at-description AttributeType ::= {id-at 13}
443X520Description ::= DirectoryString
444
445id-at-dnQualifier AttributeType ::= {id-at 46}
446X520dnQualifier ::= PrintableString
447
448id-at-countryName AttributeType ::= {id-at 6}
449X520countryName ::= PrintableString (SIZE (2)) -- IS 3166 codes
450
451id-at-serialNumber AttributeType ::= {id-at 5}
452X520serialNumber ::= PrintableString
453
454id-at-telephoneNumber AttributeType ::= {id-at 20}
455X520telephoneNumber ::= PrintableString
456
457id-at-facsimileTelephoneNumber AttributeType ::= {id-at 23}
458X520facsimileTelephoneNumber ::= PrintableString
459
460id-at-pseudonym AttributeType ::= {id-at 65}
461X520pseudonym ::= DirectoryString
462
463id-at-name AttributeType ::= {id-at 41}
464X520name ::= DirectoryString
465
466id-at-streetAddress AttributeType ::= {id-at 9}
467X520streetAddress ::= DirectoryString
468
469id-at-postalAddress AttributeType ::= {id-at 16}
470X520postalAddress ::= PostalAddress
471
472PostalAddress ::= SEQUENCE OF DirectoryString
473
474
475 -- Legacy attributes
476
477pkcs OBJECT IDENTIFIER ::=
478 { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) }
479
480pkcs-9 OBJECT IDENTIFIER ::=
481 { pkcs 9 }
482
483
484emailAddress AttributeType ::= { pkcs-9 1 }
485
486Pkcs9email ::= IA5String (SIZE (1..ub-emailaddress-length))
487
488-- naming data types --
489
490Name ::= CHOICE { -- only one possibility for now --
491 rdnSequence RDNSequence }
492
493RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
494
495DistinguishedName ::= RDNSequence
496
497RelativeDistinguishedName ::=
498 SET SIZE (1 .. MAX) OF AttributeTypeAndValue
499
500
501
502-- --------------------------------------------------------
503-- certificate and CRL specific structures begin here
504-- --------------------------------------------------------
505
506Certificate ::= SEQUENCE {
507 tbsCertificate TBSCertificate,
508 signatureAlgorithm AlgorithmIdentifier,
509 signature BIT STRING }
510
511TBSCertificate ::= SEQUENCE {
512 version [0] EXPLICIT Version DEFAULT v1,
513 serialNumber CertificateSerialNumber,
514 signature AlgorithmIdentifier,
515 issuer Name,
516 validity Validity,
517 subject Name,
518 subjectPublicKeyInfo SubjectPublicKeyInfo,
519 issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
520 -- If present, version shall be v2 or v3
521 subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
522 -- If present, version shall be v2 or v3
523 extensions [3] EXPLICIT Extensions OPTIONAL
524 -- If present, version shall be v3 --
525}
526
527Version ::= INTEGER { v1(0), v2(1), v3(2) }
528
529CertificateSerialNumber ::= INTEGER
530
531Validity ::= SEQUENCE {
532 notBefore Time,
533 notAfter Time }
534
535Time ::= CHOICE {
536 utcTime UTCTime,
537 generalTime GeneralizedTime }
538
539UniqueIdentifier ::= BIT STRING
540
541SubjectPublicKeyInfo ::= SEQUENCE {
542 algorithm AlgorithmIdentifier,
543 subjectPublicKey BIT STRING }
544
545Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
546
547Extension ::= SEQUENCE {
548 extnID OBJECT IDENTIFIER,
549 critical BOOLEAN DEFAULT FALSE,
550 extnValue OCTET STRING }
551
552
553-- ------------------------------------------
554-- CRL structures
555-- ------------------------------------------
556
557CertificateList ::= SEQUENCE {
558 tbsCertList TBSCertList,
559 signatureAlgorithm AlgorithmIdentifier,
560 signature BIT STRING }
561
562TBSCertList ::= SEQUENCE {
563 version Version OPTIONAL,
564 -- if present, shall be v2
565 signature AlgorithmIdentifier,
566 issuer Name,
567 thisUpdate Time,
568 nextUpdate Time OPTIONAL,
569 revokedCertificates SEQUENCE OF SEQUENCE {
570 userCertificate CertificateSerialNumber,
571 revocationDate Time,
572 crlEntryExtensions Extensions OPTIONAL
573 -- if present, shall be v2
574 } OPTIONAL,
575 crlExtensions [0] EXPLICIT Extensions OPTIONAL
576 -- if present, shall be v2 --
577}
578
579-- Version, Time, CertificateSerialNumber, and Extensions were
580-- defined earlier for use in the certificate structure
581
582AlgorithmIdentifier ::= SEQUENCE {
583 algorithm OBJECT IDENTIFIER,
584 parameters ANY DEFINED BY algorithm OPTIONAL }
585 -- contains a value of the type
586 -- registered for use with the
587 -- algorithm object identifier value
588
589-- Algorithm OIDs and parameter structures
590
591pkcs-1 OBJECT IDENTIFIER ::= {
592 pkcs 1 }
593
594rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
595
596md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
597
598md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
599
600sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
601
602id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
603 iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 }
604
605Dss-Sig-Value ::= SEQUENCE {
606 r INTEGER,
607 s INTEGER
608}
609
610dhpublicnumber OBJECT IDENTIFIER ::= {
611 iso(1) member-body(2) us(840) ansi-x942(10046) number-type(2) 1 }
612
613DomainParameters ::= SEQUENCE {
614 p INTEGER, -- odd prime, p=jq +1
615 g INTEGER, -- generator, g
616 q INTEGER, -- factor of p-1
617 j INTEGER OPTIONAL, -- subgroup factor, j>= 2
618 validationParms ValidationParms OPTIONAL }
619
620ValidationParms ::= SEQUENCE {
621 seed BIT STRING,
622 pgenCounter INTEGER }
623
624id-dsa OBJECT IDENTIFIER ::= {
625 iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
626
627Dss-Parms ::= SEQUENCE {
628 p INTEGER,
629 q INTEGER,
630 g INTEGER }
631
632-- x400 address syntax starts here
633-- OR Names
634
635ORAddress ::= SEQUENCE {
636 built-in-standard-attributes BuiltInStandardAttributes,
637 built-in-domain-defined-attributes
638 BuiltInDomainDefinedAttributes OPTIONAL,
639 -- see also teletex-domain-defined-attributes
640 extension-attributes ExtensionAttributes OPTIONAL }
641-- The OR-address is semantically absent from the OR-name if the
642-- built-in-standard-attribute sequence is empty and the
643-- built-in-domain-defined-attributes and extension-attributes are
644-- both omitted.
645
646-- Built-in Standard Attributes
647
648BuiltInStandardAttributes ::= SEQUENCE {
649 country-name CountryName OPTIONAL,
650 administration-domain-name AdministrationDomainName OPTIONAL,
651 network-address [0] EXPLICIT NetworkAddress OPTIONAL,
652 -- see also extended-network-address
653 terminal-identifier [1] EXPLICIT TerminalIdentifier OPTIONAL,
654 private-domain-name [2] EXPLICIT PrivateDomainName OPTIONAL,
655 organization-name [3] EXPLICIT OrganizationName OPTIONAL,
656 -- see also teletex-organization-name
657 numeric-user-identifier [4] EXPLICIT NumericUserIdentifier OPTIONAL,
658 personal-name [5] EXPLICIT PersonalName OPTIONAL,
659 -- see also teletex-personal-name
660 organizational-unit-names [6] EXPLICIT OrganizationalUnitNames OPTIONAL
661 -- see also teletex-organizational-unit-names --
662}
663
664CountryName ::= [APPLICATION 1] CHOICE {
665 x121-dcc-code NumericString
666 (SIZE (ub-country-name-numeric-length)),
667 iso-3166-alpha2-code PrintableString
668 (SIZE (ub-country-name-alpha-length)) }
669
670AdministrationDomainName ::= [APPLICATION 2] EXPLICIT CHOICE {
671 numeric NumericString (SIZE (0..ub-domain-name-length)),
672 printable PrintableString (SIZE (0..ub-domain-name-length)) }
673
674NetworkAddress ::= X121Address -- see also extended-network-address
675
676X121Address ::= NumericString (SIZE (1..ub-x121-address-length))
677
678TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length))
679
680PrivateDomainName ::= CHOICE {
681 numeric NumericString (SIZE (1..ub-domain-name-length)),
682 printable PrintableString (SIZE (1..ub-domain-name-length)) }
683
684OrganizationName ::= PrintableString
685 (SIZE (1..ub-organization-name-length))
686-- see also teletex-organization-name
687
688NumericUserIdentifier ::= NumericString
689 (SIZE (1..ub-numeric-user-id-length))
690
691PersonalName ::= SET {
692 surname [0] PrintableString (SIZE (1..ub-surname-length)),
693 given-name [1] PrintableString
694 (SIZE (1..ub-given-name-length)) OPTIONAL,
695 initials [2] PrintableString (SIZE (1..ub-initials-length)) OPTIONAL,
696 generation-qualifier [3] PrintableString
697 (SIZE (1..ub-generation-qualifier-length)) OPTIONAL }
698-- see also teletex-personal-name
699
700OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units)
701 OF OrganizationalUnitName
702-- see also teletex-organizational-unit-names
703
704OrganizationalUnitName ::= PrintableString (SIZE
705 (1..ub-organizational-unit-name-length))
706
707-- Built-in Domain-defined Attributes
708
709BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE
710 (1..ub-domain-defined-attributes) OF
711 BuiltInDomainDefinedAttribute
712
713BuiltInDomainDefinedAttribute ::= SEQUENCE {
714 type PrintableString (SIZE
715 (1..ub-domain-defined-attribute-type-length)),
716 value PrintableString (SIZE
717 (1..ub-domain-defined-attribute-value-length))}
718
719-- Extension Attributes
720
721ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF
722 ExtensionAttribute
723
724ExtensionAttribute ::= SEQUENCE {
725 extension-attribute-type [0] EXPLICIT INTEGER (0..ub-extension-attributes),
726 extension-attribute-value [1] EXPLICIT
727 ANY DEFINED BY extension-attribute-type }
728
729-- Extension types and attribute values
730--
731
732common-name INTEGER ::= 1
733
734CommonName ::= PrintableString (SIZE (1..ub-common-name-length))
735
736teletex-common-name INTEGER ::= 2
737
738TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length))
739
740teletex-organization-name INTEGER ::= 3
741
742TeletexOrganizationName ::=
743 TeletexString (SIZE (1..ub-organization-name-length))
744
745teletex-personal-name INTEGER ::= 4
746
747TeletexPersonalName ::= SET {
748 surname [0] EXPLICIT TeletexString (SIZE (1..ub-surname-length)),
749 given-name [1] EXPLICIT TeletexString
750 (SIZE (1..ub-given-name-length)) OPTIONAL,
751 initials [2] EXPLICIT TeletexString (SIZE (1..ub-initials-length)) OPTIONAL,
752 generation-qualifier [3] EXPLICIT TeletexString (SIZE
753 (1..ub-generation-qualifier-length)) OPTIONAL }
754
755teletex-organizational-unit-names INTEGER ::= 5
756
757TeletexOrganizationalUnitNames ::= SEQUENCE SIZE
758 (1..ub-organizational-units) OF TeletexOrganizationalUnitName
759
760TeletexOrganizationalUnitName ::= TeletexString
761 (SIZE (1..ub-organizational-unit-name-length))
762
763pds-name INTEGER ::= 7
764
765PDSName ::= PrintableString (SIZE (1..ub-pds-name-length))
766
767physical-delivery-country-name INTEGER ::= 8
768
769PhysicalDeliveryCountryName ::= CHOICE {
770 x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)),
771 iso-3166-alpha2-code PrintableString
772 (SIZE (ub-country-name-alpha-length)) }
773
774postal-code INTEGER ::= 9
775
776PostalCode ::= CHOICE {
777 numeric-code NumericString (SIZE (1..ub-postal-code-length)),
778 printable-code PrintableString (SIZE (1..ub-postal-code-length)) }
779
780physical-delivery-office-name INTEGER ::= 10
781
782PhysicalDeliveryOfficeName ::= PDSParameter
783
784physical-delivery-office-number INTEGER ::= 11
785
786PhysicalDeliveryOfficeNumber ::= PDSParameter
787
788extension-OR-address-components INTEGER ::= 12
789
790ExtensionORAddressComponents ::= PDSParameter
791
792physical-delivery-personal-name INTEGER ::= 13
793
794PhysicalDeliveryPersonalName ::= PDSParameter
795
796physical-delivery-organization-name INTEGER ::= 14
797
798PhysicalDeliveryOrganizationName ::= PDSParameter
799
800extension-physical-delivery-address-components INTEGER ::= 15
801
802ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter
803
804unformatted-postal-address INTEGER ::= 16
805
806UnformattedPostalAddress ::= SET {
807 printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines) OF
808 PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL,
809 teletex-string TeletexString
810 (SIZE (1..ub-unformatted-address-length)) OPTIONAL }
811
812street-address INTEGER ::= 17
813
814StreetAddress ::= PDSParameter
815
816post-office-box-address INTEGER ::= 18
817
818PostOfficeBoxAddress ::= PDSParameter
819
820poste-restante-address INTEGER ::= 19
821
822PosteRestanteAddress ::= PDSParameter
823
824unique-postal-name INTEGER ::= 20
825
826UniquePostalName ::= PDSParameter
827
828local-postal-attributes INTEGER ::= 21
829
830LocalPostalAttributes ::= PDSParameter
831
832PDSParameter ::= SET {
833 printable-string PrintableString
834 (SIZE(1..ub-pds-parameter-length)) OPTIONAL,
835 teletex-string TeletexString
836 (SIZE(1..ub-pds-parameter-length)) OPTIONAL }
837
838extended-network-address INTEGER ::= 22
839
840ExtendedNetworkAddress ::= CHOICE {
841 e163-4-address SEQUENCE {
842 number [0] EXPLICIT NumericString (SIZE (1..ub-e163-4-number-length)),
843 sub-address [1] EXPLICIT NumericString
844 (SIZE (1..ub-e163-4-sub-address-length)) OPTIONAL },
845 psap-address [0] EXPLICIT PresentationAddress }
846
847PresentationAddress ::= SEQUENCE {
848 pSelector [0] EXPLICIT OCTET STRING OPTIONAL,
849 sSelector [1] EXPLICIT OCTET STRING OPTIONAL,
850 tSelector [2] EXPLICIT OCTET STRING OPTIONAL,
851 nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING }
852
853terminal-type INTEGER ::= 23
854
855TerminalType ::= INTEGER {
856 telex (3),
857 teletex (4),
858 g3-facsimile (5),
859 g4-facsimile (6),
860 ia5-terminal (7),
861 videotex (8) } -- (0..ub-integer-options)
862
863-- Extension Domain-defined Attributes
864
865teletex-domain-defined-attributes INTEGER ::= 6
866
867TeletexDomainDefinedAttributes ::= SEQUENCE SIZE
868 (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute
869
870TeletexDomainDefinedAttribute ::= SEQUENCE {
871 type TeletexString
872 (SIZE (1..ub-domain-defined-attribute-type-length)),
873 value TeletexString
874 (SIZE (1..ub-domain-defined-attribute-value-length)) }
875
876-- specifications of Upper Bounds shall be regarded as mandatory
877-- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
878-- Upper Bounds
879
880-- Upper Bounds
881ub-name INTEGER ::= 32768
882ub-common-name INTEGER ::= 64
883ub-locality-name INTEGER ::= 128
884ub-state-name INTEGER ::= 128
885ub-organization-name INTEGER ::= 64
886ub-organizational-unit-name INTEGER ::= 64
887ub-title INTEGER ::= 64
888ub-match INTEGER ::= 128
889
890ub-emailaddress-length INTEGER ::= 128
891
892ub-common-name-length INTEGER ::= 64
893ub-country-name-alpha-length INTEGER ::= 2
894ub-country-name-numeric-length INTEGER ::= 3
895ub-domain-defined-attributes INTEGER ::= 4
896ub-domain-defined-attribute-type-length INTEGER ::= 8
897ub-domain-defined-attribute-value-length INTEGER ::= 128
898ub-domain-name-length INTEGER ::= 16
899ub-extension-attributes INTEGER ::= 256
900ub-e163-4-number-length INTEGER ::= 15
901ub-e163-4-sub-address-length INTEGER ::= 40
902ub-generation-qualifier-length INTEGER ::= 3
903ub-given-name-length INTEGER ::= 16
904ub-initials-length INTEGER ::= 5
905ub-integer-options INTEGER ::= 256
906ub-numeric-user-id-length INTEGER ::= 32
907ub-organization-name-length INTEGER ::= 64
908ub-organizational-unit-name-length INTEGER ::= 32
909ub-organizational-units INTEGER ::= 4
910ub-pds-name-length INTEGER ::= 16
911ub-pds-parameter-length INTEGER ::= 30
912ub-pds-physical-address-lines INTEGER ::= 6
913ub-postal-code-length INTEGER ::= 16
914ub-surname-length INTEGER ::= 40
915ub-terminal-id-length INTEGER ::= 24
916ub-unformatted-address-length INTEGER ::= 180
917ub-x121-address-length INTEGER ::= 16
918
919-- Note - upper bounds on string types, such as TeletexString, are
920-- measured in characters. Excepting PrintableString or IA5String, a
921-- significantly greater number of octets will be required to hold
922-- such a value. As a minimum, 16 octets, or twice the specified upper
923-- bound, whichever is the larger, should be allowed for TeletexString.
924-- For UTF8String or UniversalString at least four times the upper
925-- bound should be allowed.
926
927
928
929-- END of PKIX1Implicit88
930
931
932-- BEGIN of RFC2630
933
934-- Cryptographic Message Syntax
935
936pkcs-7-ContentInfo ::= SEQUENCE {
937 contentType pkcs-7-ContentType,
938 content [0] EXPLICIT ANY DEFINED BY contentType }
939
940pkcs-7-DigestInfo ::= SEQUENCE {
941 digestAlgorithm pkcs-7-DigestAlgorithmIdentifier,
942 digest pkcs-7-Digest
943}
944
945pkcs-7-Digest ::= OCTET STRING
946
947pkcs-7-ContentType ::= OBJECT IDENTIFIER
948
949pkcs-7-SignedData ::= SEQUENCE {
950 version pkcs-7-CMSVersion,
951 digestAlgorithms pkcs-7-DigestAlgorithmIdentifiers,
952 encapContentInfo pkcs-7-EncapsulatedContentInfo,
953 certificates [0] IMPLICIT pkcs-7-CertificateSet OPTIONAL,
954 crls [1] IMPLICIT pkcs-7-CertificateRevocationLists OPTIONAL,
955 signerInfos pkcs-7-SignerInfos
956}
957
958pkcs-7-CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4) }
959
960pkcs-7-DigestAlgorithmIdentifiers ::= SET OF pkcs-7-DigestAlgorithmIdentifier
961
962pkcs-7-DigestAlgorithmIdentifier ::= AlgorithmIdentifier
963
964pkcs-7-EncapsulatedContentInfo ::= SEQUENCE {
965 eContentType pkcs-7-ContentType,
966 eContent [0] EXPLICIT OCTET STRING OPTIONAL }
967
968-- We don't use CertificateList here since we only want
969-- to read the raw data.
970pkcs-7-CertificateRevocationLists ::= SET OF ANY
971
972pkcs-7-CertificateChoices ::= CHOICE {
973-- Although the paper uses Certificate type, we
974-- don't use it since, we don't need to parse it.
975-- We only need to read and store it.
976 certificate ANY
977}
978
979pkcs-7-CertificateSet ::= SET OF pkcs-7-CertificateChoices
980
981pkcs-7-SignerInfos ::= SET OF ANY -- this is not correct but we don't use it
982 -- anyway
983
984
985-- BEGIN of RFC2986
986
987-- Certificate requests
988pkcs-10-CertificationRequestInfo ::= SEQUENCE {
989 version INTEGER { v1(0) },
990 subject Name,
991 subjectPKInfo SubjectPublicKeyInfo,
992 attributes [0] Attributes
993}
994
995Attributes ::= SET OF Attribute
996
997pkcs-10-CertificationRequest ::= SEQUENCE {
998 certificationRequestInfo pkcs-10-CertificationRequestInfo,
999 signatureAlgorithm AlgorithmIdentifier,
1000 signature BIT STRING
1001}
1002
1003-- stuff from PKCS#9
1004
1005pkcs-9-ub-challengePassword INTEGER ::= 255
1006
1007pkcs-9-certTypes OBJECT IDENTIFIER ::= {pkcs-9 22}
1008pkcs-9-crlTypes OBJECT IDENTIFIER ::= {pkcs-9 23}
1009
1010pkcs-9-at-challengePassword OBJECT IDENTIFIER ::= {pkcs-9 7}
1011
1012pkcs-9-challengePassword ::= CHOICE {
1013 printableString PrintableString (SIZE (1..pkcs-9-ub-challengePassword)),
1014 utf8String UTF8String (SIZE (1..pkcs-9-ub-challengePassword)) }
1015
1016pkcs-9-at-localKeyId OBJECT IDENTIFIER ::= {pkcs-9 21}
1017
1018pkcs-9-localKeyId ::= OCTET STRING
1019
1020pkcs-9-at-friendlyName OBJECT IDENTIFIER ::= {pkcs-9 20}
1021
1022pkcs-9-friendlyName ::= BMPString (SIZE (1..255))
1023
1024-- PKCS #8 stuff
1025
1026-- Private-key information syntax
1027
1028pkcs-8-PrivateKeyInfo ::= SEQUENCE {
1029 version pkcs-8-Version,
1030 privateKeyAlgorithm AlgorithmIdentifier,
1031 privateKey pkcs-8-PrivateKey,
1032 attributes [0] Attributes OPTIONAL }
1033
1034pkcs-8-Version ::= INTEGER {v1(0)}
1035
1036pkcs-8-PrivateKey ::= OCTET STRING
1037
1038pkcs-8-Attributes ::= SET OF Attribute
1039
1040-- Encrypted private-key information syntax
1041
1042pkcs-8-EncryptedPrivateKeyInfo ::= SEQUENCE {
1043 encryptionAlgorithm AlgorithmIdentifier,
1044 encryptedData pkcs-8-EncryptedData
1045}
1046
1047pkcs-8-EncryptedData ::= OCTET STRING
1048
1049-- PKCS #5 stuff
1050
1051pkcs-5 OBJECT IDENTIFIER ::=
1052 { pkcs 5 }
1053
1054pkcs-5-encryptionAlgorithm OBJECT IDENTIFIER ::=
1055 { iso(1) member-body(2) us(840) rsadsi(113549) 3 }
1056
1057pkcs-5-des-EDE3-CBC OBJECT IDENTIFIER ::= {pkcs-5-encryptionAlgorithm 7}
1058
1059pkcs-5-des-EDE3-CBC-params ::= OCTET STRING (SIZE(8))
1060
1061pkcs-5-id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13}
1062
1063pkcs-5-PBES2-params ::= SEQUENCE {
1064 keyDerivationFunc AlgorithmIdentifier,
1065 encryptionScheme AlgorithmIdentifier }
1066
1067-- PBKDF2
1068
1069pkcs-5-id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12}
1070
1071-- pkcs-5-id-hmacWithSHA1 OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) rsadsi(113549) 2 7}
1072
1073-- pkcs-5-algid-hmacWithSHA1 AlgorithmIdentifier ::=
1074-- {algorithm pkcs-5-id-hmacWithSHA1, parameters NULL : NULL}
1075
1076pkcs-5-PBKDF2-params ::= SEQUENCE {
1077 salt CHOICE {
1078 specified OCTET STRING,
1079 otherSource AlgorithmIdentifier
1080 },
1081 iterationCount INTEGER (1..MAX),
1082 keyLength INTEGER (1..MAX) OPTIONAL,
1083 prf AlgorithmIdentifier OPTIONAL -- DEFAULT pkcs-5-id-hmacWithSHA1
1084}
1085
1086-- PKCS #12 stuff
1087
1088pkcs-12 OBJECT IDENTIFIER ::= {pkcs 12}
1089
1090pkcs-12-PFX ::= SEQUENCE {
1091 version INTEGER {v3(3)},
1092 authSafe pkcs-7-ContentInfo,
1093 macData pkcs-12-MacData OPTIONAL
1094}
1095
1096pkcs-12-PbeParams ::= SEQUENCE {
1097 salt OCTET STRING,
1098 iterations INTEGER
1099}
1100
1101pkcs-12-MacData ::= SEQUENCE {
1102 mac pkcs-7-DigestInfo,
1103 macSalt OCTET STRING,
1104 iterations INTEGER DEFAULT 1
1105-- Note: The default is for historical reasons and its use is
1106-- deprecated. A higher value, like 1024 is recommended.
1107}
1108
1109pkcs-12-AuthenticatedSafe ::= SEQUENCE OF pkcs-7-ContentInfo
1110 -- Data if unencrypted
1111 -- EncryptedData if password-encrypted
1112 -- EnvelopedData if public key-encrypted
1113
1114pkcs-12-SafeContents ::= SEQUENCE OF pkcs-12-SafeBag
1115
1116pkcs-12-SafeBag ::= SEQUENCE {
1117 bagId OBJECT IDENTIFIER,
1118 bagValue [0] EXPLICIT ANY DEFINED BY badId,
1119 bagAttributes SET OF pkcs-12-PKCS12Attribute OPTIONAL
1120}
1121
1122-- Bag types
1123
1124
1125pkcs-12-bagtypes OBJECT IDENTIFIER ::= {pkcs-12 10 1}
1126
1127pkcs-12-keyBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 1}
1128pkcs-12-pkcs8ShroudedKeyBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 2}
1129pkcs-12-certBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 3}
1130pkcs-12-crlBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 4}
1131
1132pkcs-12-KeyBag ::= pkcs-8-PrivateKeyInfo
1133
1134-- Shrouded KeyBag
1135
1136pkcs-12-PKCS8ShroudedKeyBag ::= pkcs-8-EncryptedPrivateKeyInfo
1137
1138-- CertBag
1139
1140pkcs-12-CertBag ::= SEQUENCE {
1141 certId OBJECT IDENTIFIER,
1142 certValue [0] EXPLICIT ANY DEFINED BY certId
1143}
1144
1145-- x509Certificate BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {pkcs-9-certTypes 1}}
1146-- DER-encoded X.509 certificate stored in OCTET STRING
1147
1148pkcs-12-CRLBag ::= SEQUENCE {
1149 crlId OBJECT IDENTIFIER,
1150 crlValue [0] EXPLICIT ANY DEFINED BY crlId
1151}
1152
1153-- x509CRL BAG-TYPE ::=
1154-- {OCTET STRING IDENTIFIED BY {pkcs-9-crlTypes 1}}
1155-- DER-encoded X.509 CRL stored in OCTET STRING
1156
1157pkcs-12-PKCS12Attribute ::= Attribute
1158
1159-- PKCS #7 stuff (needed in PKCS 12)
1160
1161pkcs-7-data OBJECT IDENTIFIER ::= { iso(1) member-body(2)
1162 us(840) rsadsi(113549) pkcs(1) pkcs7(7) 1 }
1163
1164pkcs-7-encryptedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
1165 us(840) rsadsi(113549) pkcs(1) pkcs7(7) 6 }
1166
1167pkcs-7-Data ::= OCTET STRING
1168
1169pkcs-7-EncryptedData ::= SEQUENCE {
1170 version pkcs-7-CMSVersion,
1171 encryptedContentInfo pkcs-7-EncryptedContentInfo,
1172 unprotectedAttrs [1] IMPLICIT pkcs-7-UnprotectedAttributes OPTIONAL }
1173
1174pkcs-7-EncryptedContentInfo ::= SEQUENCE {
1175 contentType pkcs-7-ContentType,
1176 contentEncryptionAlgorithm pkcs-7-ContentEncryptionAlgorithmIdentifier,
1177 encryptedContent [0] IMPLICIT pkcs-7-EncryptedContent OPTIONAL }
1178
1179pkcs-7-ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
1180
1181pkcs-7-EncryptedContent ::= OCTET STRING
1182
1183pkcs-7-UnprotectedAttributes ::= SET SIZE (1..MAX) OF Attribute
1184
1185-- LDAP stuff
1186-- may not be correct
1187
1188id-at-ldap-DC AttributeType ::= { 0 9 2342 19200300 100 1 25 }
1189
1190ldap-DC ::= IA5String
1191
1192id-at-ldap-UID AttributeType ::= { 0 9 2342 19200300 100 1 1 }
1193
1194ldap-UID ::= DirectoryString
1195
1196-- rfc3039
1197
1198id-pda OBJECT IDENTIFIER ::= { id-pkix 9 }
1199
1200id-pda-dateOfBirth AttributeType ::= { id-pda 1 }
1201DateOfBirth ::= GeneralizedTime
1202
1203id-pda-placeOfBirth AttributeType ::= { id-pda 2 }
1204PlaceOfBirth ::= DirectoryString
1205
1206id-pda-gender AttributeType ::= { id-pda 3 }
1207Gender ::= PrintableString (SIZE(1))
1208 -- "M", "F", "m" or "f"
1209
1210id-pda-countryOfCitizenship AttributeType ::= { id-pda 4 }
1211CountryOfCitizenship ::= PrintableString (SIZE (2))
1212 -- ISO 3166 Country Code
1213
1214id-pda-countryOfResidence AttributeType ::= { id-pda 5 }
1215CountryOfResidence ::= PrintableString (SIZE (2))
1216 -- ISO 3166 Country Code
1217
1218-- rfc3820
1219
1220id-pe-proxyCertInfo OBJECT IDENTIFIER ::= { id-pe 14 }
1221
1222id-ppl-inheritAll OBJECT IDENTIFIER ::= { id-pkix 21 1 }
1223id-ppl-independent OBJECT IDENTIFIER ::= { id-pkix 21 2 }
1224
1225ProxyCertInfo ::= SEQUENCE {
1226 pCPathLenConstraint INTEGER (0..MAX) OPTIONAL,
1227 proxyPolicy ProxyPolicy }
1228
1229ProxyPolicy ::= SEQUENCE {
1230 policyLanguage OBJECT IDENTIFIER,
1231 policy OCTET STRING OPTIONAL }
1232
1233-- rfc3920 section 5.1.1
1234
1235id-on OBJECT IDENTIFIER ::= { id-pkix 8 } -- other name forms
1236
1237id-on-xmppAddr OBJECT IDENTIFIER ::= { id-on 5 }
1238
1239XmppAddr ::= UTF8String
1240
1241END
diff --git a/src/daemon/https/tls/pkix_asn1_tab.c b/src/daemon/https/tls/pkix_asn1_tab.c
new file mode 100644
index 00000000..3370bb46
--- /dev/null
+++ b/src/daemon/https/tls/pkix_asn1_tab.c
@@ -0,0 +1,1130 @@
1#if HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <libtasn1.h>
6
7extern const ASN1_ARRAY_TYPE pkix_asn1_tab[] = {
8 {"PKIX1", 536875024, 0},
9 {0, 1073741836, 0},
10 {"id-ce", 1879048204, 0},
11 {"joint-iso-ccitt", 1073741825, "2"},
12 {"ds", 1073741825, "5"},
13 {0, 1, "29"},
14 {"id-ce-authorityKeyIdentifier", 1879048204, 0},
15 {0, 1073741825, "id-ce"},
16 {0, 1, "35"},
17 {"AuthorityKeyIdentifier", 1610612741, 0},
18 {"keyIdentifier", 1610637314, "KeyIdentifier"},
19 {0, 4104, "0"},
20 {"authorityCertIssuer", 1610637314, "GeneralNames"},
21 {0, 4104, "1"},
22 {"authorityCertSerialNumber", 536895490, "CertificateSerialNumber"},
23 {0, 4104, "2"},
24 {"KeyIdentifier", 1073741831, 0},
25 {"id-ce-subjectKeyIdentifier", 1879048204, 0},
26 {0, 1073741825, "id-ce"},
27 {0, 1, "14"},
28 {"SubjectKeyIdentifier", 1073741826, "KeyIdentifier"},
29 {"id-ce-keyUsage", 1879048204, 0},
30 {0, 1073741825, "id-ce"},
31 {0, 1, "15"},
32 {"KeyUsage", 1610874886, 0},
33 {"digitalSignature", 1073741825, "0"},
34 {"nonRepudiation", 1073741825, "1"},
35 {"keyEncipherment", 1073741825, "2"},
36 {"dataEncipherment", 1073741825, "3"},
37 {"keyAgreement", 1073741825, "4"},
38 {"keyCertSign", 1073741825, "5"},
39 {"cRLSign", 1073741825, "6"},
40 {"encipherOnly", 1073741825, "7"},
41 {"decipherOnly", 1, "8"},
42 {"id-ce-privateKeyUsagePeriod", 1879048204, 0},
43 {0, 1073741825, "id-ce"},
44 {0, 1, "16"},
45 {"PrivateKeyUsagePeriod", 1610612741, 0},
46 {"notBefore", 1619025937, 0},
47 {0, 4104, "0"},
48 {"notAfter", 545284113, 0},
49 {0, 4104, "1"},
50 {"id-ce-certificatePolicies", 1879048204, 0},
51 {0, 1073741825, "id-ce"},
52 {0, 1, "32"},
53 {"CertificatePolicies", 1612709899, 0},
54 {"MAX", 1074266122, "1"},
55 {0, 2, "PolicyInformation"},
56 {"PolicyInformation", 1610612741, 0},
57 {"policyIdentifier", 1073741826, "CertPolicyId"},
58 {"policyQualifiers", 538984459, 0},
59 {"MAX", 1074266122, "1"},
60 {0, 2, "PolicyQualifierInfo"},
61 {"CertPolicyId", 1073741836, 0},
62 {"PolicyQualifierInfo", 1610612741, 0},
63 {"policyQualifierId", 1073741826, "PolicyQualifierId"},
64 {"qualifier", 541065229, 0},
65 {"policyQualifierId", 1, 0},
66 {"PolicyQualifierId", 1073741836, 0},
67 {"CPSuri", 1073741826, "IA5String"},
68 {"UserNotice", 1610612741, 0},
69 {"noticeRef", 1073758210, "NoticeReference"},
70 {"explicitText", 16386, "DisplayText"},
71 {"NoticeReference", 1610612741, 0},
72 {"organization", 1073741826, "DisplayText"},
73 {"noticeNumbers", 536870923, 0},
74 {0, 3, 0},
75 {"DisplayText", 1610612754, 0},
76 {"visibleString", 1612709890, "VisibleString"},
77 {"200", 524298, "1"},
78 {"bmpString", 1612709890, "BMPString"},
79 {"200", 524298, "1"},
80 {"utf8String", 538968066, "UTF8String"},
81 {"200", 524298, "1"},
82 {"id-ce-policyMappings", 1879048204, 0},
83 {0, 1073741825, "id-ce"},
84 {0, 1, "33"},
85 {"PolicyMappings", 1612709899, 0},
86 {"MAX", 1074266122, "1"},
87 {0, 536870917, 0},
88 {"issuerDomainPolicy", 1073741826, "CertPolicyId"},
89 {"subjectDomainPolicy", 2, "CertPolicyId"},
90 {"DirectoryString", 1610612754, 0},
91 {"teletexString", 1612709890, "TeletexString"},
92 {"MAX", 524298, "1"},
93 {"printableString", 1612709890, "PrintableString"},
94 {"MAX", 524298, "1"},
95 {"universalString", 1612709890, "UniversalString"},
96 {"MAX", 524298, "1"},
97 {"utf8String", 1612709890, "UTF8String"},
98 {"MAX", 524298, "1"},
99 {"bmpString", 1612709890, "BMPString"},
100 {"MAX", 524298, "1"},
101 {"ia5String", 538968066, "IA5String"},
102 {"MAX", 524298, "1"},
103 {"id-ce-subjectAltName", 1879048204, 0},
104 {0, 1073741825, "id-ce"},
105 {0, 1, "17"},
106 {"SubjectAltName", 1073741826, "GeneralNames"},
107 {"GeneralNames", 1612709899, 0},
108 {"MAX", 1074266122, "1"},
109 {0, 2, "GeneralName"},
110 {"GeneralName", 1610612754, 0},
111 {"otherName", 1610620930, "AnotherName"},
112 {0, 4104, "0"},
113 {"rfc822Name", 1610620930, "IA5String"},
114 {0, 4104, "1"},
115 {"dNSName", 1610620930, "IA5String"},
116 {0, 4104, "2"},
117 {"x400Address", 1610620930, "ORAddress"},
118 {0, 4104, "3"},
119 {"directoryName", 1610620930, "RDNSequence"},
120 {0, 2056, "4"},
121 {"ediPartyName", 1610620930, "EDIPartyName"},
122 {0, 4104, "5"},
123 {"uniformResourceIdentifier", 1610620930, "IA5String"},
124 {0, 4104, "6"},
125 {"iPAddress", 1610620935, 0},
126 {0, 4104, "7"},
127 {"registeredID", 536879116, 0},
128 {0, 4104, "8"},
129 {"AnotherName", 1610612741, 0},
130 {"type-id", 1073741836, 0},
131 {"value", 541073421, 0},
132 {0, 1073743880, "0"},
133 {"type-id", 1, 0},
134 {"EDIPartyName", 1610612741, 0},
135 {"nameAssigner", 1610637314, "DirectoryString"},
136 {0, 4104, "0"},
137 {"partyName", 536879106, "DirectoryString"},
138 {0, 4104, "1"},
139 {"id-ce-issuerAltName", 1879048204, 0},
140 {0, 1073741825, "id-ce"},
141 {0, 1, "18"},
142 {"IssuerAltName", 1073741826, "GeneralNames"},
143 {"id-ce-subjectDirectoryAttributes", 1879048204, 0},
144 {0, 1073741825, "id-ce"},
145 {0, 1, "9"},
146 {"SubjectDirectoryAttributes", 1612709899, 0},
147 {"MAX", 1074266122, "1"},
148 {0, 2, "Attribute"},
149 {"id-ce-basicConstraints", 1879048204, 0},
150 {0, 1073741825, "id-ce"},
151 {0, 1, "19"},
152 {"BasicConstraints", 1610612741, 0},
153 {"cA", 1610645508, 0},
154 {0, 131081, 0},
155 {"pathLenConstraint", 537411587, 0},
156 {"0", 10, "MAX"},
157 {"id-ce-nameConstraints", 1879048204, 0},
158 {0, 1073741825, "id-ce"},
159 {0, 1, "30"},
160 {"NameConstraints", 1610612741, 0},
161 {"permittedSubtrees", 1610637314, "GeneralSubtrees"},
162 {0, 4104, "0"},
163 {"excludedSubtrees", 536895490, "GeneralSubtrees"},
164 {0, 4104, "1"},
165 {"GeneralSubtrees", 1612709899, 0},
166 {"MAX", 1074266122, "1"},
167 {0, 2, "GeneralSubtree"},
168 {"GeneralSubtree", 1610612741, 0},
169 {"base", 1073741826, "GeneralName"},
170 {"minimum", 1610653698, "BaseDistance"},
171 {0, 1073741833, "0"},
172 {0, 4104, "0"},
173 {"maximum", 536895490, "BaseDistance"},
174 {0, 4104, "1"},
175 {"BaseDistance", 1611137027, 0},
176 {"0", 10, "MAX"},
177 {"id-ce-policyConstraints", 1879048204, 0},
178 {0, 1073741825, "id-ce"},
179 {0, 1, "36"},
180 {"PolicyConstraints", 1610612741, 0},
181 {"requireExplicitPolicy", 1610637314, "SkipCerts"},
182 {0, 4104, "0"},
183 {"inhibitPolicyMapping", 536895490, "SkipCerts"},
184 {0, 4104, "1"},
185 {"SkipCerts", 1611137027, 0},
186 {"0", 10, "MAX"},
187 {"id-ce-cRLDistributionPoints", 1879048204, 0},
188 {0, 1073741825, "id-ce"},
189 {0, 1, "31"},
190 {"CRLDistributionPoints", 1612709899, 0},
191 {"MAX", 1074266122, "1"},
192 {0, 2, "DistributionPoint"},
193 {"DistributionPoint", 1610612741, 0},
194 {"distributionPoint", 1610637314, "DistributionPointName"},
195 {0, 2056, "0"},
196 {"reasons", 1610637314, "ReasonFlags"},
197 {0, 4104, "1"},
198 {"cRLIssuer", 536895490, "GeneralNames"},
199 {0, 4104, "2"},
200 {"DistributionPointName", 1610612754, 0},
201 {"fullName", 1610620930, "GeneralNames"},
202 {0, 4104, "0"},
203 {"nameRelativeToCRLIssuer", 536879106, "RelativeDistinguishedName"},
204 {0, 4104, "1"},
205 {"ReasonFlags", 1610874886, 0},
206 {"unused", 1073741825, "0"},
207 {"keyCompromise", 1073741825, "1"},
208 {"cACompromise", 1073741825, "2"},
209 {"affiliationChanged", 1073741825, "3"},
210 {"superseded", 1073741825, "4"},
211 {"cessationOfOperation", 1073741825, "5"},
212 {"certificateHold", 1073741825, "6"},
213 {"privilegeWithdrawn", 1073741825, "7"},
214 {"aACompromise", 1, "8"},
215 {"id-ce-extKeyUsage", 1879048204, 0},
216 {0, 1073741825, "id-ce"},
217 {0, 1, "37"},
218 {"ExtKeyUsageSyntax", 1612709899, 0},
219 {"MAX", 1074266122, "1"},
220 {0, 2, "KeyPurposeId"},
221 {"KeyPurposeId", 1073741836, 0},
222 {"id-kp-serverAuth", 1879048204, 0},
223 {0, 1073741825, "id-kp"},
224 {0, 1, "1"},
225 {"id-kp-clientAuth", 1879048204, 0},
226 {0, 1073741825, "id-kp"},
227 {0, 1, "2"},
228 {"id-kp-codeSigning", 1879048204, 0},
229 {0, 1073741825, "id-kp"},
230 {0, 1, "3"},
231 {"id-kp-emailProtection", 1879048204, 0},
232 {0, 1073741825, "id-kp"},
233 {0, 1, "4"},
234 {"id-kp-ipsecEndSystem", 1879048204, 0},
235 {0, 1073741825, "id-kp"},
236 {0, 1, "5"},
237 {"id-kp-ipsecTunnel", 1879048204, 0},
238 {0, 1073741825, "id-kp"},
239 {0, 1, "6"},
240 {"id-kp-ipsecUser", 1879048204, 0},
241 {0, 1073741825, "id-kp"},
242 {0, 1, "7"},
243 {"id-kp-timeStamping", 1879048204, 0},
244 {0, 1073741825, "id-kp"},
245 {0, 1, "8"},
246 {"id-pe-authorityInfoAccess", 1879048204, 0},
247 {0, 1073741825, "id-pe"},
248 {0, 1, "1"},
249 {"AuthorityInfoAccessSyntax", 1612709899, 0},
250 {"MAX", 1074266122, "1"},
251 {0, 2, "AccessDescription"},
252 {"AccessDescription", 1610612741, 0},
253 {"accessMethod", 1073741836, 0},
254 {"accessLocation", 2, "GeneralName"},
255 {"id-ce-cRLNumber", 1879048204, 0},
256 {0, 1073741825, "id-ce"},
257 {0, 1, "20"},
258 {"CRLNumber", 1611137027, 0},
259 {"0", 10, "MAX"},
260 {"id-ce-issuingDistributionPoint", 1879048204, 0},
261 {0, 1073741825, "id-ce"},
262 {0, 1, "28"},
263 {"IssuingDistributionPoint", 1610612741, 0},
264 {"distributionPoint", 1610637314, "DistributionPointName"},
265 {0, 4104, "0"},
266 {"onlyContainsUserCerts", 1610653700, 0},
267 {0, 1073872905, 0},
268 {0, 4104, "1"},
269 {"onlyContainsCACerts", 1610653700, 0},
270 {0, 1073872905, 0},
271 {0, 4104, "2"},
272 {"onlySomeReasons", 1610637314, "ReasonFlags"},
273 {0, 4104, "3"},
274 {"indirectCRL", 536911876, 0},
275 {0, 1073872905, 0},
276 {0, 4104, "4"},
277 {"id-ce-deltaCRLIndicator", 1879048204, 0},
278 {0, 1073741825, "id-ce"},
279 {0, 1, "27"},
280 {"BaseCRLNumber", 1073741826, "CRLNumber"},
281 {"id-ce-cRLReasons", 1879048204, 0},
282 {0, 1073741825, "id-ce"},
283 {0, 1, "21"},
284 {"CRLReason", 1610874901, 0},
285 {"unspecified", 1073741825, "0"},
286 {"keyCompromise", 1073741825, "1"},
287 {"cACompromise", 1073741825, "2"},
288 {"affiliationChanged", 1073741825, "3"},
289 {"superseded", 1073741825, "4"},
290 {"cessationOfOperation", 1073741825, "5"},
291 {"certificateHold", 1073741825, "6"},
292 {"removeFromCRL", 1, "8"},
293 {"id-ce-certificateIssuer", 1879048204, 0},
294 {0, 1073741825, "id-ce"},
295 {0, 1, "29"},
296 {"CertificateIssuer", 1073741826, "GeneralNames"},
297 {"id-ce-holdInstructionCode", 1879048204, 0},
298 {0, 1073741825, "id-ce"},
299 {0, 1, "23"},
300 {"HoldInstructionCode", 1073741836, 0},
301 {"holdInstruction", 1879048204, 0},
302 {"joint-iso-itu-t", 1073741825, "2"},
303 {"member-body", 1073741825, "2"},
304 {"us", 1073741825, "840"},
305 {"x9cm", 1073741825, "10040"},
306 {0, 1, "2"},
307 {"id-holdinstruction-none", 1879048204, 0},
308 {0, 1073741825, "holdInstruction"},
309 {0, 1, "1"},
310 {"id-holdinstruction-callissuer", 1879048204, 0},
311 {0, 1073741825, "holdInstruction"},
312 {0, 1, "2"},
313 {"id-holdinstruction-reject", 1879048204, 0},
314 {0, 1073741825, "holdInstruction"},
315 {0, 1, "3"},
316 {"id-ce-invalidityDate", 1879048204, 0},
317 {0, 1073741825, "id-ce"},
318 {0, 1, "24"},
319 {"InvalidityDate", 1082130449, 0},
320 {"VisibleString", 1610620935, 0},
321 {0, 4360, "26"},
322 {"NumericString", 1610620935, 0},
323 {0, 4360, "18"},
324 {"IA5String", 1610620935, 0},
325 {0, 4360, "22"},
326 {"TeletexString", 1610620935, 0},
327 {0, 4360, "20"},
328 {"PrintableString", 1610620935, 0},
329 {0, 4360, "19"},
330 {"UniversalString", 1610620935, 0},
331 {0, 4360, "28"},
332 {"BMPString", 1610620935, 0},
333 {0, 4360, "30"},
334 {"UTF8String", 1610620935, 0},
335 {0, 4360, "12"},
336 {"id-pkix", 1879048204, 0},
337 {"iso", 1073741825, "1"},
338 {"identified-organization", 1073741825, "3"},
339 {"dod", 1073741825, "6"},
340 {"internet", 1073741825, "1"},
341 {"security", 1073741825, "5"},
342 {"mechanisms", 1073741825, "5"},
343 {"pkix", 1, "7"},
344 {"id-pe", 1879048204, 0},
345 {0, 1073741825, "id-pkix"},
346 {0, 1, "1"},
347 {"id-qt", 1879048204, 0},
348 {0, 1073741825, "id-pkix"},
349 {0, 1, "2"},
350 {"id-kp", 1879048204, 0},
351 {0, 1073741825, "id-pkix"},
352 {0, 1, "3"},
353 {"id-ad", 1879048204, 0},
354 {0, 1073741825, "id-pkix"},
355 {0, 1, "48"},
356 {"id-qt-cps", 1879048204, 0},
357 {0, 1073741825, "id-qt"},
358 {0, 1, "1"},
359 {"id-qt-unotice", 1879048204, 0},
360 {0, 1073741825, "id-qt"},
361 {0, 1, "2"},
362 {"id-ad-ocsp", 1879048204, 0},
363 {0, 1073741825, "id-ad"},
364 {0, 1, "1"},
365 {"id-ad-caIssuers", 1879048204, 0},
366 {0, 1073741825, "id-ad"},
367 {0, 1, "2"},
368 {"Attribute", 1610612741, 0},
369 {"type", 1073741826, "AttributeType"},
370 {"values", 536870927, 0},
371 {0, 2, "AttributeValue"},
372 {"AttributeType", 1073741836, 0},
373 {"AttributeValue", 1614807053, 0},
374 {"type", 1, 0},
375 {"AttributeTypeAndValue", 1610612741, 0},
376 {"type", 1073741826, "AttributeType"},
377 {"value", 2, "AttributeValue"},
378 {"id-at", 1879048204, 0},
379 {"joint-iso-ccitt", 1073741825, "2"},
380 {"ds", 1073741825, "5"},
381 {0, 1, "4"},
382 {"id-at-initials", 1880096780, "AttributeType"},
383 {0, 1073741825, "id-at"},
384 {0, 1, "43"},
385 {"X520initials", 1073741826, "DirectoryString"},
386 {"id-at-generationQualifier", 1880096780, "AttributeType"},
387 {0, 1073741825, "id-at"},
388 {0, 1, "44"},
389 {"X520generationQualifier", 1073741826, "DirectoryString"},
390 {"id-at-surname", 1880096780, "AttributeType"},
391 {0, 1073741825, "id-at"},
392 {0, 1, "4"},
393 {"X520surName", 1073741826, "DirectoryString"},
394 {"id-at-givenName", 1880096780, "AttributeType"},
395 {0, 1073741825, "id-at"},
396 {0, 1, "42"},
397 {"X520givenName", 1073741826, "DirectoryString"},
398 {"id-at-name", 1880096780, "AttributeType"},
399 {0, 1073741825, "id-at"},
400 {0, 1, "41"},
401 {"X520name", 1073741826, "DirectoryString"},
402 {"id-at-commonName", 1880096780, "AttributeType"},
403 {0, 1073741825, "id-at"},
404 {0, 1, "3"},
405 {"X520CommonName", 1073741826, "DirectoryString"},
406 {"id-at-localityName", 1880096780, "AttributeType"},
407 {0, 1073741825, "id-at"},
408 {0, 1, "7"},
409 {"X520LocalityName", 1073741826, "DirectoryString"},
410 {"id-at-stateOrProvinceName", 1880096780, "AttributeType"},
411 {0, 1073741825, "id-at"},
412 {0, 1, "8"},
413 {"X520StateOrProvinceName", 1073741826, "DirectoryString"},
414 {"id-at-organizationName", 1880096780, "AttributeType"},
415 {0, 1073741825, "id-at"},
416 {0, 1, "10"},
417 {"X520OrganizationName", 1073741826, "DirectoryString"},
418 {"id-at-organizationalUnitName", 1880096780, "AttributeType"},
419 {0, 1073741825, "id-at"},
420 {0, 1, "11"},
421 {"X520OrganizationalUnitName", 1073741826, "DirectoryString"},
422 {"id-at-title", 1880096780, "AttributeType"},
423 {0, 1073741825, "id-at"},
424 {0, 1, "12"},
425 {"X520Title", 1073741826, "DirectoryString"},
426 {"id-at-description", 1880096780, "AttributeType"},
427 {0, 1073741825, "id-at"},
428 {0, 1, "13"},
429 {"X520Description", 1073741826, "DirectoryString"},
430 {"id-at-dnQualifier", 1880096780, "AttributeType"},
431 {0, 1073741825, "id-at"},
432 {0, 1, "46"},
433 {"X520dnQualifier", 1073741826, "PrintableString"},
434 {"id-at-countryName", 1880096780, "AttributeType"},
435 {0, 1073741825, "id-at"},
436 {0, 1, "6"},
437 {"X520countryName", 1612709890, "PrintableString"},
438 {0, 1048586, "2"},
439 {"id-at-serialNumber", 1880096780, "AttributeType"},
440 {0, 1073741825, "id-at"},
441 {0, 1, "5"},
442 {"X520serialNumber", 1073741826, "PrintableString"},
443 {"id-at-telephoneNumber", 1880096780, "AttributeType"},
444 {0, 1073741825, "id-at"},
445 {0, 1, "20"},
446 {"X520telephoneNumber", 1073741826, "PrintableString"},
447 {"id-at-facsimileTelephoneNumber", 1880096780, "AttributeType"},
448 {0, 1073741825, "id-at"},
449 {0, 1, "23"},
450 {"X520facsimileTelephoneNumber", 1073741826, "PrintableString"},
451 {"id-at-pseudonym", 1880096780, "AttributeType"},
452 {0, 1073741825, "id-at"},
453 {0, 1, "65"},
454 {"X520pseudonym", 1073741826, "DirectoryString"},
455 {"id-at-name", 1880096780, "AttributeType"},
456 {0, 1073741825, "id-at"},
457 {0, 1, "41"},
458 {"X520name", 1073741826, "DirectoryString"},
459 {"id-at-streetAddress", 1880096780, "AttributeType"},
460 {0, 1073741825, "id-at"},
461 {0, 1, "9"},
462 {"X520streetAddress", 1073741826, "DirectoryString"},
463 {"id-at-postalAddress", 1880096780, "AttributeType"},
464 {0, 1073741825, "id-at"},
465 {0, 1, "16"},
466 {"X520postalAddress", 1073741826, "PostalAddress"},
467 {"PostalAddress", 1610612747, 0},
468 {0, 2, "DirectoryString"},
469 {"pkcs", 1879048204, 0},
470 {"iso", 1073741825, "1"},
471 {"member-body", 1073741825, "2"},
472 {"us", 1073741825, "840"},
473 {"rsadsi", 1073741825, "113549"},
474 {"pkcs", 1, "1"},
475 {"pkcs-9", 1879048204, 0},
476 {0, 1073741825, "pkcs"},
477 {0, 1, "9"},
478 {"emailAddress", 1880096780, "AttributeType"},
479 {0, 1073741825, "pkcs-9"},
480 {0, 1, "1"},
481 {"Pkcs9email", 1612709890, "IA5String"},
482 {"ub-emailaddress-length", 524298, "1"},
483 {"Name", 1610612754, 0},
484 {"rdnSequence", 2, "RDNSequence"},
485 {"RDNSequence", 1610612747, 0},
486 {0, 2, "RelativeDistinguishedName"},
487 {"DistinguishedName", 1073741826, "RDNSequence"},
488 {"RelativeDistinguishedName", 1612709903, 0},
489 {"MAX", 1074266122, "1"},
490 {0, 2, "AttributeTypeAndValue"},
491 {"Certificate", 1610612741, 0},
492 {"tbsCertificate", 1073741826, "TBSCertificate"},
493 {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
494 {"signature", 6, 0},
495 {"TBSCertificate", 1610612741, 0},
496 {"version", 1610653698, "Version"},
497 {0, 1073741833, "v1"},
498 {0, 2056, "0"},
499 {"serialNumber", 1073741826, "CertificateSerialNumber"},
500 {"signature", 1073741826, "AlgorithmIdentifier"},
501 {"issuer", 1073741826, "Name"},
502 {"validity", 1073741826, "Validity"},
503 {"subject", 1073741826, "Name"},
504 {"subjectPublicKeyInfo", 1073741826, "SubjectPublicKeyInfo"},
505 {"issuerUniqueID", 1610637314, "UniqueIdentifier"},
506 {0, 4104, "1"},
507 {"subjectUniqueID", 1610637314, "UniqueIdentifier"},
508 {0, 4104, "2"},
509 {"extensions", 536895490, "Extensions"},
510 {0, 2056, "3"},
511 {"Version", 1610874883, 0},
512 {"v1", 1073741825, "0"},
513 {"v2", 1073741825, "1"},
514 {"v3", 1, "2"},
515 {"CertificateSerialNumber", 1073741827, 0},
516 {"Validity", 1610612741, 0},
517 {"notBefore", 1073741826, "Time"},
518 {"notAfter", 2, "Time"},
519 {"Time", 1610612754, 0},
520 {"utcTime", 1090519057, 0},
521 {"generalTime", 8388625, 0},
522 {"UniqueIdentifier", 1073741830, 0},
523 {"SubjectPublicKeyInfo", 1610612741, 0},
524 {"algorithm", 1073741826, "AlgorithmIdentifier"},
525 {"subjectPublicKey", 6, 0},
526 {"Extensions", 1612709899, 0},
527 {"MAX", 1074266122, "1"},
528 {0, 2, "Extension"},
529 {"Extension", 1610612741, 0},
530 {"extnID", 1073741836, 0},
531 {"critical", 1610645508, 0},
532 {0, 131081, 0},
533 {"extnValue", 7, 0},
534 {"CertificateList", 1610612741, 0},
535 {"tbsCertList", 1073741826, "TBSCertList"},
536 {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
537 {"signature", 6, 0},
538 {"TBSCertList", 1610612741, 0},
539 {"version", 1073758210, "Version"},
540 {"signature", 1073741826, "AlgorithmIdentifier"},
541 {"issuer", 1073741826, "Name"},
542 {"thisUpdate", 1073741826, "Time"},
543 {"nextUpdate", 1073758210, "Time"},
544 {"revokedCertificates", 1610629131, 0},
545 {0, 536870917, 0},
546 {"userCertificate", 1073741826, "CertificateSerialNumber"},
547 {"revocationDate", 1073741826, "Time"},
548 {"crlEntryExtensions", 16386, "Extensions"},
549 {"crlExtensions", 536895490, "Extensions"},
550 {0, 2056, "0"},
551 {"AlgorithmIdentifier", 1610612741, 0},
552 {"algorithm", 1073741836, 0},
553 {"parameters", 541081613, 0},
554 {"algorithm", 1, 0},
555 {"pkcs-1", 1879048204, 0},
556 {0, 1073741825, "pkcs"},
557 {0, 1, "1"},
558 {"rsaEncryption", 1879048204, 0},
559 {0, 1073741825, "pkcs-1"},
560 {0, 1, "1"},
561 {"md2WithRSAEncryption", 1879048204, 0},
562 {0, 1073741825, "pkcs-1"},
563 {0, 1, "2"},
564 {"md5WithRSAEncryption", 1879048204, 0},
565 {0, 1073741825, "pkcs-1"},
566 {0, 1, "4"},
567 {"sha1WithRSAEncryption", 1879048204, 0},
568 {0, 1073741825, "pkcs-1"},
569 {0, 1, "5"},
570 {"id-dsa-with-sha1", 1879048204, 0},
571 {"iso", 1073741825, "1"},
572 {"member-body", 1073741825, "2"},
573 {"us", 1073741825, "840"},
574 {"x9-57", 1073741825, "10040"},
575 {"x9algorithm", 1073741825, "4"},
576 {0, 1, "3"},
577 {"Dss-Sig-Value", 1610612741, 0},
578 {"r", 1073741827, 0},
579 {"s", 3, 0},
580 {"dhpublicnumber", 1879048204, 0},
581 {"iso", 1073741825, "1"},
582 {"member-body", 1073741825, "2"},
583 {"us", 1073741825, "840"},
584 {"ansi-x942", 1073741825, "10046"},
585 {"number-type", 1073741825, "2"},
586 {0, 1, "1"},
587 {"DomainParameters", 1610612741, 0},
588 {"p", 1073741827, 0},
589 {"g", 1073741827, 0},
590 {"q", 1073741827, 0},
591 {"j", 1073758211, 0},
592 {"validationParms", 16386, "ValidationParms"},
593 {"ValidationParms", 1610612741, 0},
594 {"seed", 1073741830, 0},
595 {"pgenCounter", 3, 0},
596 {"id-dsa", 1879048204, 0},
597 {"iso", 1073741825, "1"},
598 {"member-body", 1073741825, "2"},
599 {"us", 1073741825, "840"},
600 {"x9-57", 1073741825, "10040"},
601 {"x9algorithm", 1073741825, "4"},
602 {0, 1, "1"},
603 {"Dss-Parms", 1610612741, 0},
604 {"p", 1073741827, 0},
605 {"q", 1073741827, 0},
606 {"g", 3, 0},
607 {"ORAddress", 1610612741, 0},
608 {"built-in-standard-attributes", 1073741826, "BuiltInStandardAttributes"},
609 {"built-in-domain-defined-attributes", 1073758210,
610 "BuiltInDomainDefinedAttributes"},
611 {"extension-attributes", 16386, "ExtensionAttributes"},
612 {"BuiltInStandardAttributes", 1610612741, 0},
613 {"country-name", 1073758210, "CountryName"},
614 {"administration-domain-name", 1073758210, "AdministrationDomainName"},
615 {"network-address", 1610637314, "NetworkAddress"},
616 {0, 2056, "0"},
617 {"terminal-identifier", 1610637314, "TerminalIdentifier"},
618 {0, 2056, "1"},
619 {"private-domain-name", 1610637314, "PrivateDomainName"},
620 {0, 2056, "2"},
621 {"organization-name", 1610637314, "OrganizationName"},
622 {0, 2056, "3"},
623 {"numeric-user-identifier", 1610637314, "NumericUserIdentifier"},
624 {0, 2056, "4"},
625 {"personal-name", 1610637314, "PersonalName"},
626 {0, 2056, "5"},
627 {"organizational-unit-names", 536895490, "OrganizationalUnitNames"},
628 {0, 2056, "6"},
629 {"CountryName", 1610620946, 0},
630 {0, 1073746952, "1"},
631 {"x121-dcc-code", 1612709890, "NumericString"},
632 {0, 1048586, "ub-country-name-numeric-length"},
633 {"iso-3166-alpha2-code", 538968066, "PrintableString"},
634 {0, 1048586, "ub-country-name-alpha-length"},
635 {"AdministrationDomainName", 1610620946, 0},
636 {0, 1073744904, "2"},
637 {"numeric", 1612709890, "NumericString"},
638 {"ub-domain-name-length", 524298, "0"},
639 {"printable", 538968066, "PrintableString"},
640 {"ub-domain-name-length", 524298, "0"},
641 {"NetworkAddress", 1073741826, "X121Address"},
642 {"X121Address", 1612709890, "NumericString"},
643 {"ub-x121-address-length", 524298, "1"},
644 {"TerminalIdentifier", 1612709890, "PrintableString"},
645 {"ub-terminal-id-length", 524298, "1"},
646 {"PrivateDomainName", 1610612754, 0},
647 {"numeric", 1612709890, "NumericString"},
648 {"ub-domain-name-length", 524298, "1"},
649 {"printable", 538968066, "PrintableString"},
650 {"ub-domain-name-length", 524298, "1"},
651 {"OrganizationName", 1612709890, "PrintableString"},
652 {"ub-organization-name-length", 524298, "1"},
653 {"NumericUserIdentifier", 1612709890, "NumericString"},
654 {"ub-numeric-user-id-length", 524298, "1"},
655 {"PersonalName", 1610612750, 0},
656 {"surname", 1814044674, "PrintableString"},
657 {0, 1073745928, "0"},
658 {"ub-surname-length", 524298, "1"},
659 {"given-name", 1814061058, "PrintableString"},
660 {0, 1073745928, "1"},
661 {"ub-given-name-length", 524298, "1"},
662 {"initials", 1814061058, "PrintableString"},
663 {0, 1073745928, "2"},
664 {"ub-initials-length", 524298, "1"},
665 {"generation-qualifier", 740319234, "PrintableString"},
666 {0, 1073745928, "3"},
667 {"ub-generation-qualifier-length", 524298, "1"},
668 {"OrganizationalUnitNames", 1612709899, 0},
669 {"ub-organizational-units", 1074266122, "1"},
670 {0, 2, "OrganizationalUnitName"},
671 {"OrganizationalUnitName", 1612709890, "PrintableString"},
672 {"ub-organizational-unit-name-length", 524298, "1"},
673 {"BuiltInDomainDefinedAttributes", 1612709899, 0},
674 {"ub-domain-defined-attributes", 1074266122, "1"},
675 {0, 2, "BuiltInDomainDefinedAttribute"},
676 {"BuiltInDomainDefinedAttribute", 1610612741, 0},
677 {"type", 1612709890, "PrintableString"},
678 {"ub-domain-defined-attribute-type-length", 524298, "1"},
679 {"value", 538968066, "PrintableString"},
680 {"ub-domain-defined-attribute-value-length", 524298, "1"},
681 {"ExtensionAttributes", 1612709903, 0},
682 {"ub-extension-attributes", 1074266122, "1"},
683 {0, 2, "ExtensionAttribute"},
684 {"ExtensionAttribute", 1610612741, 0},
685 {"extension-attribute-type", 1611145219, 0},
686 {0, 1073743880, "0"},
687 {"0", 10, "ub-extension-attributes"},
688 {"extension-attribute-value", 541073421, 0},
689 {0, 1073743880, "1"},
690 {"extension-attribute-type", 1, 0},
691 {"common-name", 1342177283, "1"},
692 {"CommonName", 1612709890, "PrintableString"},
693 {"ub-common-name-length", 524298, "1"},
694 {"teletex-common-name", 1342177283, "2"},
695 {"TeletexCommonName", 1612709890, "TeletexString"},
696 {"ub-common-name-length", 524298, "1"},
697 {"teletex-organization-name", 1342177283, "3"},
698 {"TeletexOrganizationName", 1612709890, "TeletexString"},
699 {"ub-organization-name-length", 524298, "1"},
700 {"teletex-personal-name", 1342177283, "4"},
701 {"TeletexPersonalName", 1610612750, 0},
702 {"surname", 1814044674, "TeletexString"},
703 {0, 1073743880, "0"},
704 {"ub-surname-length", 524298, "1"},
705 {"given-name", 1814061058, "TeletexString"},
706 {0, 1073743880, "1"},
707 {"ub-given-name-length", 524298, "1"},
708 {"initials", 1814061058, "TeletexString"},
709 {0, 1073743880, "2"},
710 {"ub-initials-length", 524298, "1"},
711 {"generation-qualifier", 740319234, "TeletexString"},
712 {0, 1073743880, "3"},
713 {"ub-generation-qualifier-length", 524298, "1"},
714 {"teletex-organizational-unit-names", 1342177283, "5"},
715 {"TeletexOrganizationalUnitNames", 1612709899, 0},
716 {"ub-organizational-units", 1074266122, "1"},
717 {0, 2, "TeletexOrganizationalUnitName"},
718 {"TeletexOrganizationalUnitName", 1612709890, "TeletexString"},
719 {"ub-organizational-unit-name-length", 524298, "1"},
720 {"pds-name", 1342177283, "7"},
721 {"PDSName", 1612709890, "PrintableString"},
722 {"ub-pds-name-length", 524298, "1"},
723 {"physical-delivery-country-name", 1342177283, "8"},
724 {"PhysicalDeliveryCountryName", 1610612754, 0},
725 {"x121-dcc-code", 1612709890, "NumericString"},
726 {0, 1048586, "ub-country-name-numeric-length"},
727 {"iso-3166-alpha2-code", 538968066, "PrintableString"},
728 {0, 1048586, "ub-country-name-alpha-length"},
729 {"postal-code", 1342177283, "9"},
730 {"PostalCode", 1610612754, 0},
731 {"numeric-code", 1612709890, "NumericString"},
732 {"ub-postal-code-length", 524298, "1"},
733 {"printable-code", 538968066, "PrintableString"},
734 {"ub-postal-code-length", 524298, "1"},
735 {"physical-delivery-office-name", 1342177283, "10"},
736 {"PhysicalDeliveryOfficeName", 1073741826, "PDSParameter"},
737 {"physical-delivery-office-number", 1342177283, "11"},
738 {"PhysicalDeliveryOfficeNumber", 1073741826, "PDSParameter"},
739 {"extension-OR-address-components", 1342177283, "12"},
740 {"ExtensionORAddressComponents", 1073741826, "PDSParameter"},
741 {"physical-delivery-personal-name", 1342177283, "13"},
742 {"PhysicalDeliveryPersonalName", 1073741826, "PDSParameter"},
743 {"physical-delivery-organization-name", 1342177283, "14"},
744 {"PhysicalDeliveryOrganizationName", 1073741826, "PDSParameter"},
745 {"extension-physical-delivery-address-components", 1342177283, "15"},
746 {"ExtensionPhysicalDeliveryAddressComponents", 1073741826, "PDSParameter"},
747 {"unformatted-postal-address", 1342177283, "16"},
748 {"UnformattedPostalAddress", 1610612750, 0},
749 {"printable-address", 1814052875, 0},
750 {"ub-pds-physical-address-lines", 1074266122, "1"},
751 {0, 538968066, "PrintableString"},
752 {"ub-pds-parameter-length", 524298, "1"},
753 {"teletex-string", 740311042, "TeletexString"},
754 {"ub-unformatted-address-length", 524298, "1"},
755 {"street-address", 1342177283, "17"},
756 {"StreetAddress", 1073741826, "PDSParameter"},
757 {"post-office-box-address", 1342177283, "18"},
758 {"PostOfficeBoxAddress", 1073741826, "PDSParameter"},
759 {"poste-restante-address", 1342177283, "19"},
760 {"PosteRestanteAddress", 1073741826, "PDSParameter"},
761 {"unique-postal-name", 1342177283, "20"},
762 {"UniquePostalName", 1073741826, "PDSParameter"},
763 {"local-postal-attributes", 1342177283, "21"},
764 {"LocalPostalAttributes", 1073741826, "PDSParameter"},
765 {"PDSParameter", 1610612750, 0},
766 {"printable-string", 1814052866, "PrintableString"},
767 {"ub-pds-parameter-length", 524298, "1"},
768 {"teletex-string", 740311042, "TeletexString"},
769 {"ub-pds-parameter-length", 524298, "1"},
770 {"extended-network-address", 1342177283, "22"},
771 {"ExtendedNetworkAddress", 1610612754, 0},
772 {"e163-4-address", 1610612741, 0},
773 {"number", 1612718082, "NumericString"},
774 {0, 1073743880, "0"},
775 {"ub-e163-4-number-length", 524298, "1"},
776 {"sub-address", 538992642, "NumericString"},
777 {0, 1073743880, "1"},
778 {"ub-e163-4-sub-address-length", 524298, "1"},
779 {"psap-address", 536879106, "PresentationAddress"},
780 {0, 2056, "0"},
781 {"PresentationAddress", 1610612741, 0},
782 {"pSelector", 1610637319, 0},
783 {0, 2056, "0"},
784 {"sSelector", 1610637319, 0},
785 {0, 2056, "1"},
786 {"tSelector", 1610637319, 0},
787 {0, 2056, "2"},
788 {"nAddresses", 538976271, 0},
789 {0, 1073743880, "3"},
790 {"MAX", 1074266122, "1"},
791 {0, 7, 0},
792 {"terminal-type", 1342177283, "23"},
793 {"TerminalType", 1610874883, 0},
794 {"telex", 1073741825, "3"},
795 {"teletex", 1073741825, "4"},
796 {"g3-facsimile", 1073741825, "5"},
797 {"g4-facsimile", 1073741825, "6"},
798 {"ia5-terminal", 1073741825, "7"},
799 {"videotex", 1, "8"},
800 {"teletex-domain-defined-attributes", 1342177283, "6"},
801 {"TeletexDomainDefinedAttributes", 1612709899, 0},
802 {"ub-domain-defined-attributes", 1074266122, "1"},
803 {0, 2, "TeletexDomainDefinedAttribute"},
804 {"TeletexDomainDefinedAttribute", 1610612741, 0},
805 {"type", 1612709890, "TeletexString"},
806 {"ub-domain-defined-attribute-type-length", 524298, "1"},
807 {"value", 538968066, "TeletexString"},
808 {"ub-domain-defined-attribute-value-length", 524298, "1"},
809 {"ub-name", 1342177283, "32768"},
810 {"ub-common-name", 1342177283, "64"},
811 {"ub-locality-name", 1342177283, "128"},
812 {"ub-state-name", 1342177283, "128"},
813 {"ub-organization-name", 1342177283, "64"},
814 {"ub-organizational-unit-name", 1342177283, "64"},
815 {"ub-title", 1342177283, "64"},
816 {"ub-match", 1342177283, "128"},
817 {"ub-emailaddress-length", 1342177283, "128"},
818 {"ub-common-name-length", 1342177283, "64"},
819 {"ub-country-name-alpha-length", 1342177283, "2"},
820 {"ub-country-name-numeric-length", 1342177283, "3"},
821 {"ub-domain-defined-attributes", 1342177283, "4"},
822 {"ub-domain-defined-attribute-type-length", 1342177283, "8"},
823 {"ub-domain-defined-attribute-value-length", 1342177283, "128"},
824 {"ub-domain-name-length", 1342177283, "16"},
825 {"ub-extension-attributes", 1342177283, "256"},
826 {"ub-e163-4-number-length", 1342177283, "15"},
827 {"ub-e163-4-sub-address-length", 1342177283, "40"},
828 {"ub-generation-qualifier-length", 1342177283, "3"},
829 {"ub-given-name-length", 1342177283, "16"},
830 {"ub-initials-length", 1342177283, "5"},
831 {"ub-integer-options", 1342177283, "256"},
832 {"ub-numeric-user-id-length", 1342177283, "32"},
833 {"ub-organization-name-length", 1342177283, "64"},
834 {"ub-organizational-unit-name-length", 1342177283, "32"},
835 {"ub-organizational-units", 1342177283, "4"},
836 {"ub-pds-name-length", 1342177283, "16"},
837 {"ub-pds-parameter-length", 1342177283, "30"},
838 {"ub-pds-physical-address-lines", 1342177283, "6"},
839 {"ub-postal-code-length", 1342177283, "16"},
840 {"ub-surname-length", 1342177283, "40"},
841 {"ub-terminal-id-length", 1342177283, "24"},
842 {"ub-unformatted-address-length", 1342177283, "180"},
843 {"ub-x121-address-length", 1342177283, "16"},
844 {"pkcs-7-ContentInfo", 1610612741, 0},
845 {"contentType", 1073741826, "pkcs-7-ContentType"},
846 {"content", 541073421, 0},
847 {0, 1073743880, "0"},
848 {"contentType", 1, 0},
849 {"pkcs-7-DigestInfo", 1610612741, 0},
850 {"digestAlgorithm", 1073741826, "pkcs-7-DigestAlgorithmIdentifier"},
851 {"digest", 2, "pkcs-7-Digest"},
852 {"pkcs-7-Digest", 1073741831, 0},
853 {"pkcs-7-ContentType", 1073741836, 0},
854 {"pkcs-7-SignedData", 1610612741, 0},
855 {"version", 1073741826, "pkcs-7-CMSVersion"},
856 {"digestAlgorithms", 1073741826, "pkcs-7-DigestAlgorithmIdentifiers"},
857 {"encapContentInfo", 1073741826, "pkcs-7-EncapsulatedContentInfo"},
858 {"certificates", 1610637314, "pkcs-7-CertificateSet"},
859 {0, 4104, "0"},
860 {"crls", 1610637314, "pkcs-7-CertificateRevocationLists"},
861 {0, 4104, "1"},
862 {"signerInfos", 2, "pkcs-7-SignerInfos"},
863 {"pkcs-7-CMSVersion", 1610874883, 0},
864 {"v0", 1073741825, "0"},
865 {"v1", 1073741825, "1"},
866 {"v2", 1073741825, "2"},
867 {"v3", 1073741825, "3"},
868 {"v4", 1, "4"},
869 {"pkcs-7-DigestAlgorithmIdentifiers", 1610612751, 0},
870 {0, 2, "pkcs-7-DigestAlgorithmIdentifier"},
871 {"pkcs-7-DigestAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
872 {"pkcs-7-EncapsulatedContentInfo", 1610612741, 0},
873 {"eContentType", 1073741826, "pkcs-7-ContentType"},
874 {"eContent", 536895495, 0},
875 {0, 2056, "0"},
876 {"pkcs-7-CertificateRevocationLists", 1610612751, 0},
877 {0, 13, 0},
878 {"pkcs-7-CertificateChoices", 1610612754, 0},
879 {"certificate", 13, 0},
880 {"pkcs-7-CertificateSet", 1610612751, 0},
881 {0, 2, "pkcs-7-CertificateChoices"},
882 {"pkcs-7-SignerInfos", 1610612751, 0},
883 {0, 13, 0},
884 {"pkcs-10-CertificationRequestInfo", 1610612741, 0},
885 {"version", 1610874883, 0},
886 {"v1", 1, "0"},
887 {"subject", 1073741826, "Name"},
888 {"subjectPKInfo", 1073741826, "SubjectPublicKeyInfo"},
889 {"attributes", 536879106, "Attributes"},
890 {0, 4104, "0"},
891 {"Attributes", 1610612751, 0},
892 {0, 2, "Attribute"},
893 {"pkcs-10-CertificationRequest", 1610612741, 0},
894 {"certificationRequestInfo", 1073741826,
895 "pkcs-10-CertificationRequestInfo"},
896 {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
897 {"signature", 6, 0},
898 {"pkcs-9-ub-challengePassword", 1342177283, "255"},
899 {"pkcs-9-certTypes", 1879048204, 0},
900 {0, 1073741825, "pkcs-9"},
901 {0, 1, "22"},
902 {"pkcs-9-crlTypes", 1879048204, 0},
903 {0, 1073741825, "pkcs-9"},
904 {0, 1, "23"},
905 {"pkcs-9-at-challengePassword", 1879048204, 0},
906 {0, 1073741825, "pkcs-9"},
907 {0, 1, "7"},
908 {"pkcs-9-challengePassword", 1610612754, 0},
909 {"printableString", 1612709890, "PrintableString"},
910 {"pkcs-9-ub-challengePassword", 524298, "1"},
911 {"utf8String", 538968066, "UTF8String"},
912 {"pkcs-9-ub-challengePassword", 524298, "1"},
913 {"pkcs-9-at-localKeyId", 1879048204, 0},
914 {0, 1073741825, "pkcs-9"},
915 {0, 1, "21"},
916 {"pkcs-9-localKeyId", 1073741831, 0},
917 {"pkcs-9-at-friendlyName", 1879048204, 0},
918 {0, 1073741825, "pkcs-9"},
919 {0, 1, "20"},
920 {"pkcs-9-friendlyName", 1612709890, "BMPString"},
921 {"255", 524298, "1"},
922 {"pkcs-8-PrivateKeyInfo", 1610612741, 0},
923 {"version", 1073741826, "pkcs-8-Version"},
924 {"privateKeyAlgorithm", 1073741826, "AlgorithmIdentifier"},
925 {"privateKey", 1073741826, "pkcs-8-PrivateKey"},
926 {"attributes", 536895490, "Attributes"},
927 {0, 4104, "0"},
928 {"pkcs-8-Version", 1610874883, 0},
929 {"v1", 1, "0"},
930 {"pkcs-8-PrivateKey", 1073741831, 0},
931 {"pkcs-8-Attributes", 1610612751, 0},
932 {0, 2, "Attribute"},
933 {"pkcs-8-EncryptedPrivateKeyInfo", 1610612741, 0},
934 {"encryptionAlgorithm", 1073741826, "AlgorithmIdentifier"},
935 {"encryptedData", 2, "pkcs-8-EncryptedData"},
936 {"pkcs-8-EncryptedData", 1073741831, 0},
937 {"pkcs-5", 1879048204, 0},
938 {0, 1073741825, "pkcs"},
939 {0, 1, "5"},
940 {"pkcs-5-encryptionAlgorithm", 1879048204, 0},
941 {"iso", 1073741825, "1"},
942 {"member-body", 1073741825, "2"},
943 {"us", 1073741825, "840"},
944 {"rsadsi", 1073741825, "113549"},
945 {0, 1, "3"},
946 {"pkcs-5-des-EDE3-CBC", 1879048204, 0},
947 {0, 1073741825, "pkcs-5-encryptionAlgorithm"},
948 {0, 1, "7"},
949 {"pkcs-5-des-EDE3-CBC-params", 1612709895, 0},
950 {0, 1048586, "8"},
951 {"pkcs-5-id-PBES2", 1879048204, 0},
952 {0, 1073741825, "pkcs-5"},
953 {0, 1, "13"},
954 {"pkcs-5-PBES2-params", 1610612741, 0},
955 {"keyDerivationFunc", 1073741826, "AlgorithmIdentifier"},
956 {"encryptionScheme", 2, "AlgorithmIdentifier"},
957 {"pkcs-5-id-PBKDF2", 1879048204, 0},
958 {0, 1073741825, "pkcs-5"},
959 {0, 1, "12"},
960 {"pkcs-5-PBKDF2-params", 1610612741, 0},
961 {"salt", 1610612754, 0},
962 {"specified", 1073741831, 0},
963 {"otherSource", 2, "AlgorithmIdentifier"},
964 {"iterationCount", 1611137027, 0},
965 {"1", 10, "MAX"},
966 {"keyLength", 1611153411, 0},
967 {"1", 10, "MAX"},
968 {"prf", 16386, "AlgorithmIdentifier"},
969 {"pkcs-12", 1879048204, 0},
970 {0, 1073741825, "pkcs"},
971 {0, 1, "12"},
972 {"pkcs-12-PFX", 1610612741, 0},
973 {"version", 1610874883, 0},
974 {"v3", 1, "3"},
975 {"authSafe", 1073741826, "pkcs-7-ContentInfo"},
976 {"macData", 16386, "pkcs-12-MacData"},
977 {"pkcs-12-PbeParams", 1610612741, 0},
978 {"salt", 1073741831, 0},
979 {"iterations", 3, 0},
980 {"pkcs-12-MacData", 1610612741, 0},
981 {"mac", 1073741826, "pkcs-7-DigestInfo"},
982 {"macSalt", 1073741831, 0},
983 {"iterations", 536903683, 0},
984 {0, 9, "1"},
985 {"pkcs-12-AuthenticatedSafe", 1610612747, 0},
986 {0, 2, "pkcs-7-ContentInfo"},
987 {"pkcs-12-SafeContents", 1610612747, 0},
988 {0, 2, "pkcs-12-SafeBag"},
989 {"pkcs-12-SafeBag", 1610612741, 0},
990 {"bagId", 1073741836, 0},
991 {"bagValue", 1614815245, 0},
992 {0, 1073743880, "0"},
993 {"badId", 1, 0},
994 {"bagAttributes", 536887311, 0},
995 {0, 2, "pkcs-12-PKCS12Attribute"},
996 {"pkcs-12-bagtypes", 1879048204, 0},
997 {0, 1073741825, "pkcs-12"},
998 {0, 1073741825, "10"},
999 {0, 1, "1"},
1000 {"pkcs-12-keyBag", 1879048204, 0},
1001 {0, 1073741825, "pkcs-12-bagtypes"},
1002 {0, 1, "1"},
1003 {"pkcs-12-pkcs8ShroudedKeyBag", 1879048204, 0},
1004 {0, 1073741825, "pkcs-12-bagtypes"},
1005 {0, 1, "2"},
1006 {"pkcs-12-certBag", 1879048204, 0},
1007 {0, 1073741825, "pkcs-12-bagtypes"},
1008 {0, 1, "3"},
1009 {"pkcs-12-crlBag", 1879048204, 0},
1010 {0, 1073741825, "pkcs-12-bagtypes"},
1011 {0, 1, "4"},
1012 {"pkcs-12-KeyBag", 1073741826, "pkcs-8-PrivateKeyInfo"},
1013 {"pkcs-12-PKCS8ShroudedKeyBag", 1073741826,
1014 "pkcs-8-EncryptedPrivateKeyInfo"},
1015 {"pkcs-12-CertBag", 1610612741, 0},
1016 {"certId", 1073741836, 0},
1017 {"certValue", 541073421, 0},
1018 {0, 1073743880, "0"},
1019 {"certId", 1, 0},
1020 {"pkcs-12-CRLBag", 1610612741, 0},
1021 {"crlId", 1073741836, 0},
1022 {"crlValue", 541073421, 0},
1023 {0, 1073743880, "0"},
1024 {"crlId", 1, 0},
1025 {"pkcs-12-PKCS12Attribute", 1073741826, "Attribute"},
1026 {"pkcs-7-data", 1879048204, 0},
1027 {"iso", 1073741825, "1"},
1028 {"member-body", 1073741825, "2"},
1029 {"us", 1073741825, "840"},
1030 {"rsadsi", 1073741825, "113549"},
1031 {"pkcs", 1073741825, "1"},
1032 {"pkcs7", 1073741825, "7"},
1033 {0, 1, "1"},
1034 {"pkcs-7-encryptedData", 1879048204, 0},
1035 {"iso", 1073741825, "1"},
1036 {"member-body", 1073741825, "2"},
1037 {"us", 1073741825, "840"},
1038 {"rsadsi", 1073741825, "113549"},
1039 {"pkcs", 1073741825, "1"},
1040 {"pkcs7", 1073741825, "7"},
1041 {0, 1, "6"},
1042 {"pkcs-7-Data", 1073741831, 0},
1043 {"pkcs-7-EncryptedData", 1610612741, 0},
1044 {"version", 1073741826, "pkcs-7-CMSVersion"},
1045 {"encryptedContentInfo", 1073741826, "pkcs-7-EncryptedContentInfo"},
1046 {"unprotectedAttrs", 536895490, "pkcs-7-UnprotectedAttributes"},
1047 {0, 4104, "1"},
1048 {"pkcs-7-EncryptedContentInfo", 1610612741, 0},
1049 {"contentType", 1073741826, "pkcs-7-ContentType"},
1050 {"contentEncryptionAlgorithm", 1073741826,
1051 "pkcs-7-ContentEncryptionAlgorithmIdentifier"},
1052 {"encryptedContent", 536895490, "pkcs-7-EncryptedContent"},
1053 {0, 4104, "0"},
1054 {"pkcs-7-ContentEncryptionAlgorithmIdentifier", 1073741826,
1055 "AlgorithmIdentifier"},
1056 {"pkcs-7-EncryptedContent", 1073741831, 0},
1057 {"pkcs-7-UnprotectedAttributes", 1612709903, 0},
1058 {"MAX", 1074266122, "1"},
1059 {0, 2, "Attribute"},
1060 {"id-at-ldap-DC", 1880096780, "AttributeType"},
1061 {0, 1073741825, "0"},
1062 {0, 1073741825, "9"},
1063 {0, 1073741825, "2342"},
1064 {0, 1073741825, "19200300"},
1065 {0, 1073741825, "100"},
1066 {0, 1073741825, "1"},
1067 {0, 1, "25"},
1068 {"ldap-DC", 1073741826, "IA5String"},
1069 {"id-at-ldap-UID", 1880096780, "AttributeType"},
1070 {0, 1073741825, "0"},
1071 {0, 1073741825, "9"},
1072 {0, 1073741825, "2342"},
1073 {0, 1073741825, "19200300"},
1074 {0, 1073741825, "100"},
1075 {0, 1073741825, "1"},
1076 {0, 1, "1"},
1077 {"ldap-UID", 1073741826, "DirectoryString"},
1078 {"id-pda", 1879048204, 0},
1079 {0, 1073741825, "id-pkix"},
1080 {0, 1, "9"},
1081 {"id-pda-dateOfBirth", 1880096780, "AttributeType"},
1082 {0, 1073741825, "id-pda"},
1083 {0, 1, "1"},
1084 {"DateOfBirth", 1082130449, 0},
1085 {"id-pda-placeOfBirth", 1880096780, "AttributeType"},
1086 {0, 1073741825, "id-pda"},
1087 {0, 1, "2"},
1088 {"PlaceOfBirth", 1073741826, "DirectoryString"},
1089 {"id-pda-gender", 1880096780, "AttributeType"},
1090 {0, 1073741825, "id-pda"},
1091 {0, 1, "3"},
1092 {"Gender", 1612709890, "PrintableString"},
1093 {0, 1048586, "1"},
1094 {"id-pda-countryOfCitizenship", 1880096780, "AttributeType"},
1095 {0, 1073741825, "id-pda"},
1096 {0, 1, "4"},
1097 {"CountryOfCitizenship", 1612709890, "PrintableString"},
1098 {0, 1048586, "2"},
1099 {"id-pda-countryOfResidence", 1880096780, "AttributeType"},
1100 {0, 1073741825, "id-pda"},
1101 {0, 1, "5"},
1102 {"CountryOfResidence", 1612709890, "PrintableString"},
1103 {0, 1048586, "2"},
1104 {"id-pe-proxyCertInfo", 1879048204, 0},
1105 {0, 1073741825, "id-pe"},
1106 {0, 1, "14"},
1107 {"id-ppl-inheritAll", 1879048204, 0},
1108 {0, 1073741825, "id-pkix"},
1109 {0, 1073741825, "21"},
1110 {0, 1, "1"},
1111 {"id-ppl-independent", 1879048204, 0},
1112 {0, 1073741825, "id-pkix"},
1113 {0, 1073741825, "21"},
1114 {0, 1, "2"},
1115 {"ProxyCertInfo", 1610612741, 0},
1116 {"pCPathLenConstraint", 1611153411, 0},
1117 {"0", 10, "MAX"},
1118 {"proxyPolicy", 2, "ProxyPolicy"},
1119 {"ProxyPolicy", 1610612741, 0},
1120 {"policyLanguage", 1073741836, 0},
1121 {"policy", 16391, 0},
1122 {"id-on", 1879048204, 0},
1123 {0, 1073741825, "id-pkix"},
1124 {0, 1, "8"},
1125 {"id-on-xmppAddr", 1879048204, 0},
1126 {0, 1073741825, "id-on"},
1127 {0, 1, "5"},
1128 {"XmppAddr", 2, "UTF8String"},
1129 {0, 0, 0}
1130};
diff --git a/src/daemon/https/tls/x509_b64.c b/src/daemon/https/tls/x509_b64.c
new file mode 100644
index 00000000..50a9b475
--- /dev/null
+++ b/src/daemon/https/tls/x509_b64.c
@@ -0,0 +1,599 @@
1/*
2 * Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25/* Functions that relate to base64 encoding and decoding.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_errors.h"
30#include <gnutls_datum.h>
31#include <x509_b64.h>
32
33static const uint8_t b64table[] =
34 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
35
36static const uint8_t asciitable[128] = {
37 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
38 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
39 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
40 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
41 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
44 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
45 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
46 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
47 0xff, 0xf1, 0xff, 0xff, 0xff, 0x00, /* 0xf1 for '=' */
48 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
49 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
50 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
51 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
52 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
53 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
54 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
55 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
56 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
57 0x31, 0x32, 0x33, 0xff, 0xff, 0xff,
58 0xff, 0xff
59};
60
61inline static int
62encode (char *result, const uint8_t * data, int left)
63{
64
65 int data_len;
66
67 if (left > 3)
68 data_len = 3;
69 else
70 data_len = left;
71
72 switch (data_len)
73 {
74 case 3:
75 result[0] = b64table[(data[0] >> 2)];
76 result[1] =
77 b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) |
78 (data[1] >> 4))];
79 result[2] =
80 b64table[((((data[1] & 0x0f) << 2) & 0xff) | (data[2] >> 6))];
81 result[3] = b64table[(((data[2] << 2) & 0xff) >> 2)];
82 break;
83 case 2:
84 result[0] = b64table[(data[0] >> 2)];
85 result[1] =
86 b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) |
87 (data[1] >> 4))];
88 result[2] = b64table[(((data[1] << 4) & 0xff) >> 2)];
89 result[3] = '=';
90 break;
91 case 1:
92 result[0] = b64table[(data[0] >> 2)];
93 result[1] = b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff))];
94 result[2] = '=';
95 result[3] = '=';
96 break;
97 default:
98 return -1;
99 }
100
101 return 4;
102
103}
104
105/* data must be 4 bytes
106 * result should be 3 bytes
107 */
108#define TOASCII(c) (c < 127 ? asciitable[c] : 0xff)
109inline static int
110decode (uint8_t * result, const opaque * data)
111{
112 uint8_t a1, a2;
113 int ret = 3;
114
115 a1 = TOASCII (data[0]);
116 a2 = TOASCII (data[1]);
117 if (a1 == 0xff || a2 == 0xff)
118 return -1;
119 result[0] = ((a1 << 2) & 0xff) | ((a2 >> 4) & 0xff);
120
121 a1 = a2;
122 a2 = TOASCII (data[2]);
123 if (a2 == 0xff)
124 return -1;
125 result[1] = ((a1 << 4) & 0xff) | ((a2 >> 2) & 0xff);
126
127 a1 = a2;
128 a2 = TOASCII (data[3]);
129 if (a2 == 0xff)
130 return -1;
131 result[2] = ((a1 << 6) & 0xff) | (a2 & 0xff);
132
133 if (data[2] == '=')
134 ret--;
135
136 if (data[3] == '=')
137 ret--;
138 return ret;
139}
140
141/* encodes data and puts the result into result (locally allocated)
142 * The result_size is the return value
143 */
144int
145_gnutls_base64_encode (const uint8_t * data, size_t data_size,
146 uint8_t ** result)
147{
148 unsigned int i, j;
149 int ret, tmp;
150 char tmpres[4];
151
152 ret = B64SIZE (data_size);
153
154 (*result) = gnutls_malloc (ret + 1);
155 if ((*result) == NULL)
156 return GNUTLS_E_MEMORY_ERROR;
157
158 for (i = j = 0; i < data_size; i += 3, j += 4)
159 {
160 tmp = encode (tmpres, &data[i], data_size - i);
161 if (tmp == -1)
162 {
163 gnutls_free ((*result));
164 return GNUTLS_E_MEMORY_ERROR;
165 }
166 memcpy (&(*result)[j], tmpres, tmp);
167 }
168 (*result)[ret] = 0; /* null terminated */
169
170 return ret;
171}
172
173#define INCR(what, size) \
174 do { \
175 what+=size; \
176 if (what > ret) { \
177 gnutls_assert(); \
178 gnutls_free( (*result)); *result = NULL; \
179 return GNUTLS_E_INTERNAL_ERROR; \
180 } \
181 } while(0)
182
183/* encodes data and puts the result into result (locally allocated)
184 * The result_size (including the null terminator) is the return value.
185 */
186int
187_gnutls_fbase64_encode (const char *msg, const uint8_t * data,
188 int data_size, uint8_t ** result)
189{
190 int i, ret, tmp, j;
191 char tmpres[4];
192 uint8_t *ptr;
193 uint8_t top[80];
194 uint8_t bottom[80];
195 int pos, bytes, top_len, bottom_len;
196 size_t msglen = strlen (msg);
197
198 if (msglen > 50)
199 {
200 gnutls_assert ();
201 return GNUTLS_E_BASE64_ENCODING_ERROR;
202 }
203
204 memset (bottom, 0, sizeof (bottom));
205 memset (top, 0, sizeof (top));
206
207 strcat (top, "-----BEGIN "); /* Flawfinder: ignore */
208 strcat (top, msg); /* Flawfinder: ignore */
209 strcat (top, "-----"); /* Flawfinder: ignore */
210
211 strcat (bottom, "\n-----END "); /* Flawfinder: ignore */
212 strcat (bottom, msg); /* Flawfinder: ignore */
213 strcat (bottom, "-----\n"); /* Flawfinder: ignore */
214
215 top_len = strlen (top);
216 bottom_len = strlen (bottom);
217
218 ret = B64FSIZE (msglen, data_size);
219
220 (*result) = gnutls_calloc (1, ret + 1);
221 if ((*result) == NULL)
222 {
223 gnutls_assert ();
224 return GNUTLS_E_MEMORY_ERROR;
225 }
226
227 bytes = pos = 0;
228 INCR (bytes, top_len);
229 pos = top_len;
230
231 strcpy (*result, top); /* Flawfinder: ignore */
232
233 for (i = j = 0; i < data_size; i += 3, j += 4)
234 {
235
236 tmp = encode (tmpres, &data[i], data_size - i);
237 if (tmp == -1)
238 {
239 gnutls_assert ();
240 gnutls_free ((*result));
241 *result = NULL;
242 return GNUTLS_E_BASE64_ENCODING_ERROR;
243 }
244
245 INCR (bytes, 4);
246 ptr = &(*result)[j + pos];
247
248 if ((j) % 64 == 0)
249 {
250 INCR (bytes, 1);
251 pos++;
252 *ptr++ = '\n';
253 }
254 *ptr++ = tmpres[0];
255
256 if ((j + 1) % 64 == 0)
257 {
258 INCR (bytes, 1);
259 pos++;
260 *ptr++ = '\n';
261 }
262 *ptr++ = tmpres[1];
263
264 if ((j + 2) % 64 == 0)
265 {
266 INCR (bytes, 1);
267 pos++;
268 *ptr++ = '\n';
269 }
270 *ptr++ = tmpres[2];
271
272 if ((j + 3) % 64 == 0)
273 {
274 INCR (bytes, 1);
275 pos++;
276 *ptr++ = '\n';
277 }
278 *ptr++ = tmpres[3];
279 }
280
281 INCR (bytes, bottom_len);
282
283 memcpy (&(*result)[bytes - bottom_len], bottom, bottom_len);
284 (*result)[bytes] = 0;
285
286 return ret + 1;
287}
288
289/**
290 * gnutls_pem_base64_encode - This function will convert raw data to Base64 encoded
291 * @msg: is a message to be put in the header
292 * @data: contain the raw data
293 * @result: the place where base64 data will be copied
294 * @result_size: holds the size of the result
295 *
296 * This function will convert the given data to printable data, using the base64
297 * encoding. This is the encoding used in PEM messages. If the provided
298 * buffer is not long enough GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
299 *
300 * The output string will be null terminated, although the size will not include
301 * the terminating null.
302 *
303 **/
304int
305gnutls_pem_base64_encode (const char *msg, const gnutls_datum_t * data,
306 char *result, size_t * result_size)
307{
308 opaque *ret;
309 int size;
310
311 size = _gnutls_fbase64_encode (msg, data->data, data->size, &ret);
312 if (size < 0)
313 return size;
314
315 if (result == NULL || *result_size < (unsigned) size)
316 {
317 gnutls_free (ret);
318 *result_size = size;
319 return GNUTLS_E_SHORT_MEMORY_BUFFER;
320 }
321 else
322 {
323 memcpy (result, ret, size);
324 gnutls_free (ret);
325 *result_size = size - 1;
326 }
327
328 return 0;
329}
330
331/**
332 * gnutls_pem_base64_encode_alloc - This function will convert raw data to Base64 encoded
333 * @msg: is a message to be put in the encoded header
334 * @data: contains the raw data
335 * @result: will hold the newly allocated encoded data
336 *
337 * This function will convert the given data to printable data, using the base64
338 * encoding. This is the encoding used in PEM messages. This function will
339 * allocate the required memory to hold the encoded data.
340 *
341 * You should use gnutls_free() to free the returned data.
342 *
343 **/
344int
345gnutls_pem_base64_encode_alloc (const char *msg,
346 const gnutls_datum_t * data,
347 gnutls_datum_t * result)
348{
349 opaque *ret;
350 int size;
351
352 if (result == NULL)
353 return GNUTLS_E_INVALID_REQUEST;
354
355 size = _gnutls_fbase64_encode (msg, data->data, data->size, &ret);
356 if (size < 0)
357 return size;
358
359 result->data = ret;
360 result->size = size - 1;
361 return 0;
362}
363
364
365/* decodes data and puts the result into result (locally allocated)
366 * The result_size is the return value
367 */
368int
369_gnutls_base64_decode (const uint8_t * data, size_t data_size,
370 uint8_t ** result)
371{
372 unsigned int i, j;
373 int ret, tmp, est;
374 uint8_t tmpres[3];
375
376 est = ((data_size * 3) / 4) + 1;
377 (*result) = gnutls_malloc (est);
378 if ((*result) == NULL)
379 return GNUTLS_E_MEMORY_ERROR;
380
381 ret = 0;
382 for (i = j = 0; i < data_size; i += 4, j += 3)
383 {
384 tmp = decode (tmpres, &data[i]);
385 if (tmp < 0)
386 {
387 gnutls_free (*result);
388 *result = NULL;
389 return tmp;
390 }
391 memcpy (&(*result)[j], tmpres, tmp);
392 ret += tmp;
393 }
394 return ret;
395}
396
397/* copies data to result but removes newlines and <CR>
398 * returns the size of the data copied.
399 */
400inline static int
401cpydata (const uint8_t * data, int data_size, uint8_t ** result)
402{
403 int i, j;
404
405 (*result) = gnutls_malloc (data_size);
406 if (*result == NULL)
407 return GNUTLS_E_MEMORY_ERROR;
408
409 for (j = i = 0; i < data_size; i++)
410 {
411 if (data[i] == '\n' || data[i] == '\r')
412 continue;
413 (*result)[j] = data[i];
414 j++;
415 }
416 return j;
417}
418
419/* Searches the given string for ONE PEM encoded certificate, and
420 * stores it in the result.
421 *
422 * The result_size is the return value
423 */
424#define ENDSTR "-----\n"
425#define ENDSTR2 "-----\r"
426int
427_gnutls_fbase64_decode (const char *header, const opaque * data,
428 size_t data_size, uint8_t ** result)
429{
430 int ret;
431 static const char top[] = "-----BEGIN ";
432 static const char bottom[] = "\n-----END ";
433 uint8_t *rdata;
434 int rdata_size;
435 uint8_t *kdata;
436 int kdata_size;
437 char pem_header[128];
438
439 _gnutls_str_cpy (pem_header, sizeof (pem_header), top);
440 if (header != NULL)
441 _gnutls_str_cat (pem_header, sizeof (pem_header), header);
442
443 rdata = memmem (data, data_size, pem_header, strlen (pem_header));
444
445 if (rdata == NULL)
446 {
447 gnutls_assert ();
448 _gnutls_debug_log ("Could not find '%s'\n", pem_header);
449 return GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR;
450 }
451
452 data_size -= (unsigned long int) rdata - (unsigned long int) data;
453
454 if (data_size < 4 + strlen (bottom))
455 {
456 gnutls_assert ();
457 return GNUTLS_E_BASE64_DECODING_ERROR;
458 }
459
460 kdata = memmem (rdata, data_size, ENDSTR, sizeof (ENDSTR) - 1);
461 /* allow CR as well.
462 */
463 if (kdata == NULL)
464 kdata = memmem (rdata, data_size, ENDSTR2, sizeof (ENDSTR2) - 1);
465
466 if (kdata == NULL)
467 {
468 gnutls_assert ();
469 _gnutls_x509_log ("Could not find '%s'\n", ENDSTR);
470 return GNUTLS_E_BASE64_DECODING_ERROR;
471 }
472 data_size -= strlen (ENDSTR);
473 data_size -= (unsigned long int) kdata - (unsigned long int) rdata;
474
475 rdata = kdata + strlen (ENDSTR);
476
477 /* position is now after the ---BEGIN--- headers */
478
479 kdata = memmem (rdata, data_size, bottom, strlen (bottom));
480 if (kdata == NULL)
481 {
482 gnutls_assert ();
483 return GNUTLS_E_BASE64_DECODING_ERROR;
484 }
485
486 /* position of kdata is before the ----END--- footer
487 */
488 rdata_size = (unsigned long int) kdata - (unsigned long int) rdata;
489
490 if (rdata_size < 4)
491 {
492 gnutls_assert ();
493 return GNUTLS_E_BASE64_DECODING_ERROR;
494 }
495
496 kdata_size = cpydata (rdata, rdata_size, &kdata);
497
498 if (kdata_size < 0)
499 {
500 gnutls_assert ();
501 return kdata_size;
502 }
503
504 if (kdata_size < 4)
505 {
506 gnutls_assert ();
507 gnutls_free (kdata);
508 return GNUTLS_E_BASE64_DECODING_ERROR;
509 }
510
511 if ((ret = _gnutls_base64_decode (kdata, kdata_size, result)) < 0)
512 {
513 gnutls_free (kdata);
514 gnutls_assert ();
515 return GNUTLS_E_BASE64_DECODING_ERROR;
516 }
517 gnutls_free (kdata);
518
519 return ret;
520}
521
522/**
523 * gnutls_pem_base64_decode - This function will decode base64 encoded data
524 * @header: A null terminated string with the PEM header (eg. CERTIFICATE)
525 * @b64_data: contain the encoded data
526 * @result: the place where decoded data will be copied
527 * @result_size: holds the size of the result
528 *
529 * This function will decode the given encoded data. If the header given
530 * is non null this function will search for "-----BEGIN header" and decode
531 * only this part. Otherwise it will decode the first PEM packet found.
532 *
533 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not long enough,
534 * or 0 on success.
535 **/
536int
537gnutls_pem_base64_decode (const char *header,
538 const gnutls_datum_t * b64_data,
539 unsigned char *result, size_t * result_size)
540{
541 opaque *ret;
542 int size;
543
544 size =
545 _gnutls_fbase64_decode (header, b64_data->data, b64_data->size, &ret);
546 if (size < 0)
547 return size;
548
549 if (result == NULL || *result_size < (unsigned) size)
550 {
551 gnutls_free (ret);
552 *result_size = size;
553 return GNUTLS_E_SHORT_MEMORY_BUFFER;
554 }
555 else
556 {
557 memcpy (result, ret, size);
558 gnutls_free (ret);
559 *result_size = size;
560 }
561
562 return 0;
563}
564
565/**
566 * gnutls_pem_base64_decode_alloc - This function will decode base64 encoded data
567 * @header: The PEM header (eg. CERTIFICATE)
568 * @b64_data: contains the encoded data
569 * @result: the place where decoded data lie
570 *
571 * This function will decode the given encoded data. The decoded data
572 * will be allocated, and stored into result.
573 * If the header given is non null this function will search for
574 * "-----BEGIN header" and decode only this part. Otherwise it will decode the
575 * first PEM packet found.
576 *
577 * You should use gnutls_free() to free the returned data.
578 *
579 **/
580int
581gnutls_pem_base64_decode_alloc (const char *header,
582 const gnutls_datum_t * b64_data,
583 gnutls_datum_t * result)
584{
585 opaque *ret;
586 int size;
587
588 if (result == NULL)
589 return GNUTLS_E_INVALID_REQUEST;
590
591 size =
592 _gnutls_fbase64_decode (header, b64_data->data, b64_data->size, &ret);
593 if (size < 0)
594 return size;
595
596 result->data = ret;
597 result->size = size;
598 return 0;
599}
diff --git a/src/daemon/https/tls/x509_b64.h b/src/daemon/https/tls/x509_b64.h
new file mode 100644
index 00000000..539bec42
--- /dev/null
+++ b/src/daemon/https/tls/x509_b64.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
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.
12 *
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.
17 *
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
22 *
23 */
24
25int _gnutls_base64_encode (const uint8_t * data, size_t data_size,
26 uint8_t ** result);
27int _gnutls_fbase64_encode (const char *msg, const uint8_t * data,
28 int data_size, uint8_t ** result);
29int _gnutls_base64_decode (const uint8_t * data, size_t data_size,
30 uint8_t ** result);
31int _gnutls_fbase64_decode (const char *header, const uint8_t * data,
32 size_t data_size, uint8_t ** result);
33
34#define B64SIZE( data_size) ((data_size%3==0)?((data_size*4)/3):(4+((data_size/3)*4)))
35
36/* The size for B64 encoding + newlines plus header
37 */
38
39#define HEADSIZE( hsize) \
40 sizeof("-----BEGIN ")-1+sizeof("-----")-1+ \
41 sizeof("\n-----END ")-1+sizeof("-----\n")-1+hsize+hsize
42
43#define B64FSIZE( hsize, dsize) \
44 (B64SIZE(dsize) + HEADSIZE(hsize) + /*newlines*/ \
45 B64SIZE(dsize)/64 + (((B64SIZE(dsize) % 64) > 0) ? 1 : 0))