diff options
Diffstat (limited to 'src/daemon/https/tls')
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 @@ | |||
1 | SUBDIRS = . | ||
2 | |||
3 | AM_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 | |||
12 | noinst_LTLIBRARIES = libtls.la | ||
13 | |||
14 | libtls_la_LDFLAGS = \ | ||
15 | -L$(GCRYPT_LIB_PATH) | ||
16 | |||
17 | libtls_la_SOURCES = \ | ||
18 | auth_anon.c \ | ||
19 | auth_cert.c \ | ||
20 | auth_dh_common.c \ | ||
21 | auth_dhe.c \ | ||
22 | auth_rsa.c \ | ||
23 | auth_rsa_export.c \ | ||
24 | debug.c \ | ||
25 | ext_cert_type.c \ | ||
26 | ext_inner_application.c \ | ||
27 | ext_max_record.c \ | ||
28 | ext_oprfi.c \ | ||
29 | ext_server_name.c \ | ||
30 | gnutls_alert.c \ | ||
31 | gnutls_algorithms.c \ | ||
32 | gnutls_anon_cred.c \ | ||
33 | gnutls_asn1_tab.c \ | ||
34 | gnutls_auth.c \ | ||
35 | gnutls_buffers.c \ | ||
36 | gnutls_cert.c \ | ||
37 | gnutls_cipher.c \ | ||
38 | gnutls_cipher_int.c \ | ||
39 | gnutls_compress.c \ | ||
40 | gnutls_compress_int.c \ | ||
41 | gnutls_constate.c \ | ||
42 | gnutls_datum.c \ | ||
43 | gnutls_db.c \ | ||
44 | gnutls_dh.c \ | ||
45 | gnutls_dh_primes.c \ | ||
46 | gnutls_errors.c \ | ||
47 | gnutls_extensions.c \ | ||
48 | gnutls_extra_hooks.c \ | ||
49 | gnutls_global.c \ | ||
50 | gnutls_handshake.c \ | ||
51 | gnutls_hash_int.c \ | ||
52 | gnutls_kx.c \ | ||
53 | gnutls_mem.c \ | ||
54 | gnutls_mpi.c \ | ||
55 | gnutls_num.c \ | ||
56 | gnutls_pk.c \ | ||
57 | gnutls_priority.c \ | ||
58 | gnutls_record.c \ | ||
59 | gnutls_rsa_export.c \ | ||
60 | gnutls_session.c \ | ||
61 | gnutls_session_pack.c \ | ||
62 | gnutls_sig.c \ | ||
63 | gnutls_state.c \ | ||
64 | gnutls_str.c \ | ||
65 | gnutls_supplemental.c \ | ||
66 | gnutls_ui.c \ | ||
67 | gnutls_v2_compat.c \ | ||
68 | gnutls_x509.c \ | ||
69 | pkix_asn1_tab.c \ | ||
70 | x509_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 | |||
43 | static int gen_anon_server_kx (gnutls_session_t, opaque **); | ||
44 | static int proc_anon_client_kx (gnutls_session_t, opaque *, size_t); | ||
45 | static int proc_anon_server_kx (gnutls_session_t, opaque *, size_t); | ||
46 | |||
47 | const 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 | |||
64 | static int | ||
65 | gen_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 | |||
113 | static int | ||
114 | proc_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 | |||
152 | int | ||
153 | proc_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 | |||
29 | typedef 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 | |||
38 | typedef struct gnutls_anon_client_credentials_st | ||
39 | { | ||
40 | int dummy; | ||
41 | } anon_client_credentials_st; | ||
42 | |||
43 | typedef struct anon_auth_info_st | ||
44 | { | ||
45 | dh_info_st dh; | ||
46 | } *anon_auth_info_t; | ||
47 | |||
48 | typedef 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 | |||
49 | static gnutls_cert *alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, | ||
50 | unsigned); | ||
51 | static gnutls_privkey *alloc_and_load_x509_key (gnutls_x509_privkey_t key); | ||
52 | static gnutls_cert *alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert); | ||
53 | static 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 | */ | ||
60 | static 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 | |||
102 | clear: | ||
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 | */ | ||
119 | inline static int | ||
120 | _gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t * | ||
121 | pk_algos, int pk_algos_length, | ||
122 | gnutls_pk_algorithm_t algo_to_check) | ||
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 | */ | ||
139 | static 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 | */ | ||
189 | static int | ||
190 | _find_x509_cert (const gnutls_certificate_credentials_t cred, | ||
191 | opaque * _data, size_t _data_size, | ||
192 | const gnutls_pk_algorithm_t * pk_algos, | ||
193 | int pk_algos_length, int *indx) | ||
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 | */ | ||
260 | static int | ||
261 | _find_openpgp_cert (const gnutls_certificate_credentials_t cred, | ||
262 | gnutls_pk_algorithm_t * pk_algos, | ||
263 | int pk_algos_length, int *indx) | ||
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 | */ | ||
296 | static int | ||
297 | get_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 | |||
338 | error: | ||
339 | return result; | ||
340 | } | ||
341 | |||
342 | /* Returns the issuers in the server's certificate request | ||
343 | * packet. | ||
344 | */ | ||
345 | static int | ||
346 | get_issuers (gnutls_session_t session, | ||
347 | gnutls_datum_t * issuers_dn, int issuers_len, | ||
348 | opaque * data, size_t data_size) | ||
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 | */ | ||
386 | static int | ||
387 | call_get_cert_callback (gnutls_session_t session, | ||
388 | gnutls_datum_t * issuers_dn, | ||
389 | int issuers_dn_length, | ||
390 | gnutls_pk_algorithm_t * pk_algos, int pk_algos_length) | ||
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 | |||
466 | cleanup: | ||
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 | */ | ||
506 | static int | ||
507 | _select_client_cert (gnutls_session_t session, | ||
508 | opaque * _data, size_t _data_size, | ||
509 | gnutls_pk_algorithm_t * pk_algos, int pk_algos_length) | ||
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 | |||
606 | cleanup: | ||
607 | gnutls_free (issuers_dn); | ||
608 | return result; | ||
609 | |||
610 | } | ||
611 | |||
612 | /* Generate client certificate | ||
613 | */ | ||
614 | |||
615 | int | ||
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 | |||
670 | enum PGPKeyDescriptorType | ||
671 | { PGP_KEY_FINGERPRINT, PGP_KEY }; | ||
672 | |||
673 | int | ||
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 | |||
722 | int | ||
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 | |||
789 | int | ||
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 | |||
809 | int | ||
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]) | ||
828 | int | ||
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 | |||
962 | cleanup: | ||
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]) | ||
970 | int | ||
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 | |||
1140 | cleanup: | ||
1141 | |||
1142 | _gnutls_free_datum (&akey); | ||
1143 | CLEAR_CERTS; | ||
1144 | gnutls_afree (peer_certificate_list); | ||
1145 | return ret; | ||
1146 | |||
1147 | } | ||
1148 | |||
1149 | int | ||
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 | ||
1167 | typedef 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 | */ | ||
1175 | inline 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 | |||
1187 | int | ||
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 | |||
1292 | int | ||
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 | |||
1344 | int | ||
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 | ||
1394 | int | ||
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 | */ | ||
1472 | int | ||
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 | */ | ||
1514 | static gnutls_cert * | ||
1515 | alloc_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 | */ | ||
1555 | static gnutls_privkey * | ||
1556 | alloc_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 | */ | ||
1584 | static gnutls_cert * | ||
1585 | alloc_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 | */ | ||
1627 | static gnutls_privkey * | ||
1628 | alloc_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 | |||
1660 | void | ||
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 | |||
1686 | void | ||
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 | */ | ||
1711 | int | ||
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 | */ | ||
1776 | void | ||
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 | */ | ||
37 | typedef 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 | |||
102 | typedef struct rsa_info_st | ||
103 | { | ||
104 | gnutls_datum_t modulus; | ||
105 | gnutls_datum_t exponent; | ||
106 | } rsa_info_st; | ||
107 | |||
108 | typedef 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 | |||
126 | typedef struct cert_auth_info_st cert_auth_info_st; | ||
127 | |||
128 | void _gnutls_free_rsa_info (rsa_info_st * rsa); | ||
129 | |||
130 | /* AUTH X509 functions */ | ||
131 | int _gnutls_gen_cert_server_certificate (gnutls_session_t, opaque **); | ||
132 | int _gnutls_gen_cert_client_certificate (gnutls_session_t, opaque **); | ||
133 | int _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t, opaque **); | ||
134 | int _gnutls_gen_cert_server_cert_req (gnutls_session_t, opaque **); | ||
135 | int _gnutls_proc_cert_cert_req (gnutls_session_t, opaque *, size_t); | ||
136 | int _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t, opaque *, size_t); | ||
137 | int _gnutls_proc_cert_server_certificate (gnutls_session_t, opaque *, size_t); | ||
138 | int _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 | |||
143 | int _gnutls_server_select_cert (struct gnutls_session_int *, | ||
144 | gnutls_pk_algorithm_t); | ||
145 | void _gnutls_selected_certs_deinit (gnutls_session_t session); | ||
146 | void _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 | |||
152 | gnutls_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 | */ | ||
44 | void | ||
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 | |||
53 | int | ||
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 | |||
123 | int | ||
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 | |||
205 | error: | ||
206 | _gnutls_mpi_release (&x); | ||
207 | _gnutls_mpi_release (&X); | ||
208 | gnutls_free (*data); | ||
209 | *data = NULL; | ||
210 | return ret; | ||
211 | } | ||
212 | |||
213 | int | ||
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 */ | ||
308 | int | ||
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 | |||
28 | typedef 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 | |||
37 | void _gnutls_free_dh_info (dh_info_st * dh); | ||
38 | int _gnutls_gen_dh_common_client_kx (gnutls_session_t, opaque **); | ||
39 | int _gnutls_proc_dh_common_client_kx (gnutls_session_t session, | ||
40 | opaque * data, size_t _data_size, | ||
41 | mpi_t p, mpi_t g); | ||
42 | int _gnutls_dh_common_print_server_kx (gnutls_session_t, mpi_t g, mpi_t p, | ||
43 | opaque ** data, int psk); | ||
44 | int _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 | |||
42 | static int gen_dhe_server_kx (gnutls_session_t, opaque **); | ||
43 | static int proc_dhe_server_kx (gnutls_session_t, opaque *, size_t); | ||
44 | static int proc_dhe_client_kx (gnutls_session_t, opaque *, size_t); | ||
45 | |||
46 | const 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 | |||
63 | const 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 | |||
81 | static int | ||
82 | gen_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 | |||
181 | static int | ||
182 | proc_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 | |||
242 | static int | ||
243 | proc_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 | |||
45 | int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **); | ||
46 | int _gnutls_proc_rsa_client_kx (gnutls_session_t, opaque *, size_t); | ||
47 | |||
48 | const 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 | */ | ||
67 | int | ||
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 | */ | ||
149 | int | ||
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 | |||
208 | int | ||
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, ¶ms, ¶ms_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 | */ | ||
320 | int | ||
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, ¶ms_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 (¶ms[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 | |||
46 | int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **); | ||
47 | int _gnutls_proc_rsa_client_kx (gnutls_session_t, opaque *, size_t); | ||
48 | static int gen_rsa_export_server_kx (gnutls_session_t, opaque **); | ||
49 | static int proc_rsa_export_server_kx (gnutls_session_t, opaque *, size_t); | ||
50 | |||
51 | const 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 | |||
68 | static int | ||
69 | gen_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 | */ | ||
192 | int | ||
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 | |||
234 | static int | ||
235 | proc_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 | |||
34 | void | ||
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 | |||
53 | const 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 | |||
74 | const 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 | |||
119 | void | ||
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 | ||
26 | void _gnutls_print_state (gnutls_session_t session); | ||
27 | #endif | ||
28 | const char *_gnutls_packet2str (content_type_t packet); | ||
29 | const char *_gnutls_handshake2str (gnutls_handshake_description_t handshake); | ||
30 | void _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 | ||
42 | typedef 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 | */ | ||
59 | typedef 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 | |||
36 | inline static int _gnutls_num2cert_type (int num); | ||
37 | inline 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 | |||
48 | int | ||
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 | */ | ||
143 | int | ||
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 | */ | ||
213 | inline 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 | */ | ||
230 | inline 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 | */ | ||
28 | int _gnutls_cert_type_recv_params (gnutls_session_t session, | ||
29 | const opaque * data, size_t data_size); | ||
30 | int _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 | |||
34 | int | ||
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 | */ | ||
68 | int | ||
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 | |||
25 | int _gnutls_inner_application_recv_params (gnutls_session_t session, | ||
26 | const opaque * data, | ||
27 | size_t data_size); | ||
28 | int _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 | |||
43 | int | ||
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 | */ | ||
104 | int | ||
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 | */ | ||
158 | int | ||
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 | */ | ||
179 | int | ||
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 | */ | ||
28 | int _gnutls_mre_num2record (int num); | ||
29 | int _gnutls_mre_record2num (uint16_t record_size); | ||
30 | int _gnutls_max_record_recv_params (gnutls_session_t session, | ||
31 | const opaque * data, size_t data_size); | ||
32 | int _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 | |||
35 | int | ||
36 | oprfi_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 | |||
72 | int | ||
73 | oprfi_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 | |||
115 | int | ||
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 | |||
125 | int | ||
126 | oprfi_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 | |||
146 | int | ||
147 | oprfi_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 | |||
196 | int | ||
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 | **/ | ||
219 | void | ||
220 | gnutls_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 | **/ | ||
247 | void | ||
248 | gnutls_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 | |||
27 | int _gnutls_oprfi_recv_params (gnutls_session_t state, | ||
28 | const opaque * data, | ||
29 | size_t data_size); | ||
30 | |||
31 | int _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 | |||
41 | int | ||
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 | */ | ||
126 | int | ||
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 | **/ | ||
235 | int | ||
236 | gnutls_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 | **/ | ||
297 | int | ||
298 | gnutls_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 | |||
25 | int _gnutls_server_name_recv_params (gnutls_session_t session, | ||
26 | const opaque * data, size_t data_size); | ||
27 | int _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 @@ | |||
1 | GNUTLS { } | ||
2 | |||
3 | DEFINITIONS EXPLICIT TAGS ::= | ||
4 | |||
5 | BEGIN | ||
6 | |||
7 | -- This file contains parts of PKCS-1 structures and some stuff | ||
8 | -- required for DSA keys. | ||
9 | |||
10 | RSAPublicKey ::= 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 | -- | ||
19 | RSAPrivateKey ::= 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 | |||
32 | Version ::= INTEGER { two-prime(0), multi(1) } | ||
33 | -- (CONSTRAINED BY { version must be multi if otherPrimeInfos present }) -- | ||
34 | |||
35 | OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo | ||
36 | |||
37 | OtherPrimeInfo ::= SEQUENCE { | ||
38 | prime INTEGER, -- ri | ||
39 | exponent INTEGER, -- di | ||
40 | coefficient INTEGER -- ti | ||
41 | } | ||
42 | |||
43 | -- for signature calculation | ||
44 | -- added by nmav | ||
45 | |||
46 | AlgorithmIdentifier ::= 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 | |||
54 | DigestInfo ::= SEQUENCE { | ||
55 | digestAlgorithm DigestAlgorithmIdentifier, | ||
56 | digest Digest | ||
57 | } | ||
58 | |||
59 | DigestAlgorithmIdentifier ::= AlgorithmIdentifier | ||
60 | |||
61 | Digest ::= OCTET STRING | ||
62 | |||
63 | DSAPublicKey ::= INTEGER | ||
64 | |||
65 | DSAParameters ::= SEQUENCE { | ||
66 | p INTEGER, | ||
67 | q INTEGER, | ||
68 | g INTEGER | ||
69 | } | ||
70 | |||
71 | DSASignatureValue ::= SEQUENCE { | ||
72 | r INTEGER, | ||
73 | s INTEGER | ||
74 | } | ||
75 | |||
76 | DSAPrivateKey ::= 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 | ||
86 | DHParameter ::= SEQUENCE { | ||
87 | prime INTEGER, -- p | ||
88 | base INTEGER, -- g | ||
89 | privateValueLength INTEGER OPTIONAL | ||
90 | } | ||
91 | |||
92 | |||
93 | END | ||
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 | |||
13 | prefix=/home/lama/workbench/programming/c/gnunet/gnutls-2.2.3/build | ||
14 | exec_prefix=${prefix} | ||
15 | libdir=${exec_prefix}/lib | ||
16 | includedir=${prefix}/include | ||
17 | |||
18 | Name: GnuTLS | ||
19 | Description: Transport Security Layer implementation for the GNU system | ||
20 | Version: 2.2.3 | ||
21 | Libs: -L${libdir} -lgnutls | ||
22 | Libs.private: -L${exec_prefix}/lib -lgnutls -L/usr/lib -ltasn1 -lgcrypt | ||
23 | Cflags: -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 | |||
30 | typedef struct | ||
31 | { | ||
32 | gnutls_alert_description_t alert; | ||
33 | const char *desc; | ||
34 | } gnutls_alert_entry; | ||
35 | |||
36 | static 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 | **/ | ||
90 | const char * | ||
91 | gnutls_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 | **/ | ||
117 | int | ||
118 | gnutls_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 | **/ | ||
155 | int | ||
156 | gnutls_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 | */ | ||
272 | int | ||
273 | gnutls_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 | **/ | ||
300 | gnutls_alert_description_t | ||
301 | gnutls_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 | */ | ||
36 | typedef 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 | |||
44 | static 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 */ | ||
91 | typedef 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 | */ | ||
109 | static 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 | |||
136 | typedef 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 | |||
145 | static 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. */ | ||
174 | static 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 | |||
188 | struct 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 | }; | ||
198 | typedef 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 | */ | ||
205 | static 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. */ | ||
278 | static 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 | |||
301 | struct 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 | }; | ||
308 | typedef struct gnutls_hash_entry gnutls_hash_entry; | ||
309 | |||
310 | static 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. */ | ||
334 | static 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 | ||
353 | const int _gnutls_comp_algorithms_size = MAX_COMP_METHODS; | ||
354 | |||
355 | /* the compression entry is defined in gnutls_algorithms.h */ | ||
356 | |||
357 | gnutls_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 | |||
371 | static 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 */ | ||
388 | extern mod_auth_st rsa_auth_struct; | ||
389 | extern mod_auth_st rsa_export_auth_struct; | ||
390 | extern mod_auth_st dhe_rsa_auth_struct; | ||
391 | extern mod_auth_st dhe_dss_auth_struct; | ||
392 | extern mod_auth_st anon_auth_struct; | ||
393 | extern mod_auth_st srp_auth_struct; | ||
394 | extern mod_auth_st psk_auth_struct; | ||
395 | extern mod_auth_st dhe_psk_auth_struct; | ||
396 | extern mod_auth_st srp_rsa_auth_struct; | ||
397 | extern mod_auth_st srp_dss_auth_struct; | ||
398 | |||
399 | struct 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 | }; | ||
407 | typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry; | ||
408 | |||
409 | static 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. */ | ||
452 | static 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 | |||
483 | typedef 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 | |||
591 | static 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 | |||
775 | int | ||
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 | **/ | ||
795 | const char * | ||
796 | gnutls_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 | **/ | ||
814 | gnutls_mac_algorithm_t | ||
815 | gnutls_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 | **/ | ||
833 | size_t | ||
834 | gnutls_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 | **/ | ||
855 | const gnutls_mac_algorithm_t * | ||
856 | gnutls_mac_list (void) | ||
857 | { | ||
858 | return supported_macs; | ||
859 | } | ||
860 | |||
861 | const 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 | |||
872 | gnutls_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 | |||
888 | int | ||
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 */ | ||
901 | int | ||
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 | **/ | ||
921 | const char * | ||
922 | gnutls_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 | **/ | ||
942 | gnutls_compression_method_t | ||
943 | gnutls_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 | **/ | ||
966 | const gnutls_compression_method_t * | ||
967 | gnutls_compression_list (void) | ||
968 | { | ||
969 | return supported_compressions; | ||
970 | } | ||
971 | |||
972 | /* return the tls number of the specified algorithm */ | ||
973 | int | ||
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 | |||
984 | int | ||
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 | |||
993 | int | ||
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 | |||
1002 | int | ||
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 | */ | ||
1014 | gnutls_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 | |||
1025 | int | ||
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 */ | ||
1038 | int | ||
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 */ | ||
1048 | int | ||
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 | |||
1061 | int | ||
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 | **/ | ||
1078 | size_t | ||
1079 | gnutls_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 | |||
1087 | int | ||
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 | |||
1096 | int | ||
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 | **/ | ||
1112 | const char * | ||
1113 | gnutls_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 | **/ | ||
1133 | gnutls_cipher_algorithm_t | ||
1134 | gnutls_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 | **/ | ||
1156 | const gnutls_cipher_algorithm_t * | ||
1157 | gnutls_cipher_list (void) | ||
1158 | { | ||
1159 | return supported_ciphers; | ||
1160 | } | ||
1161 | |||
1162 | int | ||
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 */ | ||
1175 | mod_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 | |||
1184 | int | ||
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 | **/ | ||
1204 | const char * | ||
1205 | gnutls_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 | **/ | ||
1224 | gnutls_kx_algorithm_t | ||
1225 | gnutls_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 | **/ | ||
1243 | const gnutls_kx_algorithm_t * | ||
1244 | gnutls_kx_list (void) | ||
1245 | { | ||
1246 | return supported_kxs; | ||
1247 | } | ||
1248 | |||
1249 | int | ||
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 | |||
1261 | int | ||
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 | |||
1269 | int | ||
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 */ | ||
1278 | int | ||
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 | |||
1297 | gnutls_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 | |||
1319 | gnutls_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 | **/ | ||
1348 | const char * | ||
1349 | gnutls_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 | **/ | ||
1367 | gnutls_protocol_t | ||
1368 | gnutls_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 | **/ | ||
1387 | const gnutls_protocol_t * | ||
1388 | gnutls_protocol_list (void) | ||
1389 | { | ||
1390 | return supported_protocols; | ||
1391 | } | ||
1392 | |||
1393 | int | ||
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 | |||
1402 | gnutls_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 | |||
1413 | int | ||
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 | |||
1424 | int | ||
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 */ | ||
1441 | gnutls_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 | |||
1457 | gnutls_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 */ | ||
1476 | gnutls_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 | |||
1484 | gnutls_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 | |||
1492 | gnutls_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 | |||
1502 | gnutls_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 | |||
1511 | const 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 | **/ | ||
1534 | const char * | ||
1535 | gnutls_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 | **/ | ||
1569 | const char * | ||
1570 | gnutls_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 | |||
1594 | static 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 | ||
1614 | static 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 | |||
1662 | static 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 | */ | ||
1695 | static 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 | ||
1734 | static 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 | |||
1758 | int | ||
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 | |||
1794 | int | ||
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 | ||
1900 | int | ||
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 | **/ | ||
1945 | const char * | ||
1946 | gnutls_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 | **/ | ||
1967 | gnutls_certificate_type_t | ||
1968 | gnutls_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 | |||
1980 | static 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 | **/ | ||
1997 | const gnutls_certificate_type_t * | ||
1998 | gnutls_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 | */ | ||
2006 | gnutls_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 | */ | ||
2019 | enum 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 | */ | ||
2029 | struct 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 | }; | ||
2037 | typedef struct gnutls_sign_entry gnutls_sign_entry; | ||
2038 | |||
2039 | static 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 | **/ | ||
2088 | const char * | ||
2089 | gnutls_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 | |||
2099 | gnutls_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 | |||
2117 | gnutls_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 | |||
2132 | const 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 | */ | ||
2149 | struct gnutls_pk_entry | ||
2150 | { | ||
2151 | const char *name; | ||
2152 | const char *oid; | ||
2153 | gnutls_pk_algorithm_t id; | ||
2154 | }; | ||
2155 | typedef struct gnutls_pk_entry gnutls_pk_entry; | ||
2156 | |||
2157 | static 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 | **/ | ||
2179 | const char * | ||
2180 | gnutls_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 | |||
2195 | gnutls_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 | |||
2211 | const 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. */ | ||
31 | gnutls_protocol_t _gnutls_version_lowest (gnutls_session_t session); | ||
32 | gnutls_protocol_t _gnutls_version_max (gnutls_session_t session); | ||
33 | int _gnutls_version_priority (gnutls_session_t session, | ||
34 | gnutls_protocol_t version); | ||
35 | int _gnutls_version_is_supported (gnutls_session_t session, | ||
36 | const gnutls_protocol_t version); | ||
37 | int _gnutls_version_get_major (gnutls_protocol_t ver); | ||
38 | int _gnutls_version_get_minor (gnutls_protocol_t ver); | ||
39 | gnutls_protocol_t _gnutls_version_get (int major, int minor); | ||
40 | |||
41 | /* Functions for MACs. */ | ||
42 | int _gnutls_mac_is_ok (gnutls_mac_algorithm_t algorithm); | ||
43 | gnutls_mac_algorithm_t _gnutls_x509_oid2mac_algorithm (const char *oid); | ||
44 | const char *_gnutls_x509_mac_to_oid (gnutls_mac_algorithm_t mac); | ||
45 | |||
46 | /* Functions for cipher suites. */ | ||
47 | int _gnutls_supported_ciphersuites (gnutls_session_t session, | ||
48 | cipher_suite_st ** ciphers); | ||
49 | int _gnutls_supported_ciphersuites_sorted (gnutls_session_t session, | ||
50 | cipher_suite_st ** ciphers); | ||
51 | int _gnutls_supported_compression_methods (gnutls_session_t session, | ||
52 | uint8_t ** comp); | ||
53 | const char *_gnutls_cipher_suite_get_name (cipher_suite_st * algorithm); | ||
54 | gnutls_cipher_algorithm_t _gnutls_cipher_suite_get_cipher_algo (const | ||
55 | cipher_suite_st | ||
56 | * algorithm); | ||
57 | gnutls_kx_algorithm_t _gnutls_cipher_suite_get_kx_algo (const cipher_suite_st | ||
58 | * algorithm); | ||
59 | gnutls_mac_algorithm_t _gnutls_cipher_suite_get_mac_algo (const | ||
60 | cipher_suite_st * | ||
61 | algorithm); | ||
62 | gnutls_protocol_t _gnutls_cipher_suite_get_version (const cipher_suite_st * | ||
63 | algorithm); | ||
64 | cipher_suite_st _gnutls_cipher_suite_get_suite_name (cipher_suite_st * | ||
65 | algorithm); | ||
66 | |||
67 | /* Functions for ciphers. */ | ||
68 | int _gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm); | ||
69 | int _gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm); | ||
70 | int _gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm); | ||
71 | int _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm); | ||
72 | int _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm); | ||
73 | |||
74 | /* Functions for key exchange. */ | ||
75 | int _gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm); | ||
76 | int _gnutls_kx_needs_rsa_params (gnutls_kx_algorithm_t algorithm); | ||
77 | mod_auth_st *_gnutls_kx_auth_struct (gnutls_kx_algorithm_t algorithm); | ||
78 | int _gnutls_kx_is_ok (gnutls_kx_algorithm_t algorithm); | ||
79 | |||
80 | /* Functions for compression. */ | ||
81 | int _gnutls_compression_is_ok (gnutls_compression_method_t algorithm); | ||
82 | int _gnutls_compression_get_num (gnutls_compression_method_t algorithm); | ||
83 | gnutls_compression_method_t _gnutls_compression_get_id (int num); | ||
84 | int _gnutls_compression_get_mem_level (gnutls_compression_method_t algorithm); | ||
85 | int _gnutls_compression_get_comp_level (gnutls_compression_method_t | ||
86 | algorithm); | ||
87 | int _gnutls_compression_get_wbits (gnutls_compression_method_t algorithm); | ||
88 | |||
89 | /* Type to KX mappings. */ | ||
90 | gnutls_kx_algorithm_t _gnutls_map_kx_get_kx (gnutls_credentials_type_t type, | ||
91 | int server); | ||
92 | gnutls_credentials_type_t _gnutls_map_kx_get_cred (gnutls_kx_algorithm_t | ||
93 | algorithm, int server); | ||
94 | |||
95 | /* KX to PK mapping. */ | ||
96 | gnutls_pk_algorithm_t _gnutls_map_pk_get_pk (gnutls_kx_algorithm_t | ||
97 | kx_algorithm); | ||
98 | gnutls_pk_algorithm_t _gnutls_x509_oid2pk_algorithm (const char *oid); | ||
99 | const char *_gnutls_x509_pk_to_oid (gnutls_pk_algorithm_t pk); | ||
100 | |||
101 | enum encipher_type | ||
102 | { CIPHER_ENCRYPT = 0, CIPHER_SIGN = 1, CIPHER_IGN }; | ||
103 | |||
104 | enum encipher_type _gnutls_kx_encipher_type (gnutls_kx_algorithm_t algorithm); | ||
105 | |||
106 | struct 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 | }; | ||
117 | typedef struct gnutls_compression_entry gnutls_compression_entry; | ||
118 | |||
119 | /* Functions for sign algorithms. */ | ||
120 | gnutls_sign_algorithm_t _gnutls_x509_oid2sign_algorithm (const char *oid); | ||
121 | gnutls_sign_algorithm_t _gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk, | ||
122 | gnutls_mac_algorithm_t mac); | ||
123 | const char *_gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t, | ||
124 | gnutls_mac_algorithm_t mac); | ||
125 | |||
126 | int _gnutls_mac_priority (gnutls_session_t session, | ||
127 | gnutls_mac_algorithm_t algorithm); | ||
128 | int _gnutls_cipher_priority (gnutls_session_t session, | ||
129 | gnutls_cipher_algorithm_t algorithm); | ||
130 | int _gnutls_kx_priority (gnutls_session_t session, | ||
131 | gnutls_kx_algorithm_t algorithm); | ||
132 | int _gnutls_compression_priority (gnutls_session_t session, | ||
133 | gnutls_compression_method_t algorithm); | ||
134 | |||
135 | gnutls_mac_algorithm_t gnutls_mac_get_id (const char* name); | ||
136 | gnutls_cipher_algorithm_t gnutls_cipher_get_id (const char* name); | ||
137 | gnutls_kx_algorithm_t gnutls_kx_get_id (const char* name); | ||
138 | gnutls_protocol_t gnutls_protocol_get_id (const char* name); | ||
139 | gnutls_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 | |||
36 | static 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 | **/ | ||
45 | void | ||
46 | gnutls_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 | **/ | ||
61 | int | ||
62 | gnutls_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 | **/ | ||
79 | void | ||
80 | gnutls_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 | **/ | ||
93 | int | ||
94 | gnutls_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 | **/ | ||
114 | void | ||
115 | gnutls_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 | **/ | ||
130 | void | ||
131 | gnutls_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 | |||
7 | extern 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 | **/ | ||
46 | void | ||
47 | gnutls_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 | **/ | ||
92 | int | ||
93 | gnutls_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 | **/ | ||
163 | gnutls_credentials_type_t | ||
164 | gnutls_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 | **/ | ||
186 | gnutls_credentials_type_t | ||
187 | gnutls_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 | **/ | ||
204 | gnutls_credentials_type_t | ||
205 | gnutls_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 | */ | ||
218 | const 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 | |||
228 | const 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 | |||
253 | out: | ||
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 | -*/ | ||
272 | void * | ||
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 | -*/ | ||
286 | void | ||
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 | */ | ||
355 | int | ||
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 | |||
28 | typedef 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 | |||
25 | const void *_gnutls_get_cred (gnutls_key_st key, | ||
26 | gnutls_credentials_type_t kx, int *err); | ||
27 | const void *_gnutls_get_kx_cred (gnutls_session_t session, | ||
28 | gnutls_kx_algorithm_t algo, int *err); | ||
29 | void *_gnutls_get_auth_info (gnutls_session_t session); | ||
30 | int _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 | |||
27 | typedef 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 | **/ | ||
90 | void 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 | **/ | ||
116 | void 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 | */ | ||
124 | int _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 | |||
169 | int _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 | **/ | ||
199 | size_t gnutls_record_check_pending(gnutls_session_t session) | ||
200 | { | ||
201 | return _gnutls_record_buffer_get_size(GNUTLS_APPLICATION_DATA, session); | ||
202 | } | ||
203 | |||
204 | int _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 | */ | ||
291 | static 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 | */ | ||
420 | int _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 | |||
458 | void _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 | */ | ||
472 | ssize_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 | |||
651 | inline 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 | |||
689 | inline 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 | */ | ||
710 | ssize_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 | */ | ||
870 | ssize_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 | */ | ||
888 | ssize_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 | */ | ||
912 | ssize_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 | */ | ||
1043 | ssize_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 | */ | ||
1147 | int _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 | |||
1179 | int _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 | */ | ||
1188 | int _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 | */ | ||
1206 | int _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 | */ | ||
1223 | int _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 | |||
1233 | int _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 | |||
25 | int _gnutls_record_buffer_put (content_type_t type, | ||
26 | gnutls_session_t session, opaque * data, | ||
27 | size_t length); | ||
28 | int _gnutls_record_buffer_get_size (content_type_t type, | ||
29 | gnutls_session_t session); | ||
30 | int _gnutls_record_buffer_get (content_type_t type, | ||
31 | gnutls_session_t session, opaque * data, | ||
32 | size_t length); | ||
33 | ssize_t _gnutls_io_read_buffered (gnutls_session_t, opaque ** iptr, | ||
34 | size_t n, content_type_t); | ||
35 | void _gnutls_io_clear_read_buffer (gnutls_session_t); | ||
36 | int _gnutls_io_clear_peeked_data (gnutls_session_t session); | ||
37 | |||
38 | ssize_t _gnutls_io_write_buffered (gnutls_session_t, const void *iptr, | ||
39 | size_t n); | ||
40 | ssize_t _gnutls_io_write_buffered2 (gnutls_session_t, const void *iptr, | ||
41 | size_t n, const void *iptr2, size_t n2); | ||
42 | |||
43 | int _gnutls_handshake_buffer_get_size (gnutls_session_t session); | ||
44 | int _gnutls_handshake_buffer_peek (gnutls_session_t session, opaque * data, | ||
45 | size_t length); | ||
46 | int _gnutls_handshake_buffer_put (gnutls_session_t session, opaque * data, | ||
47 | size_t length); | ||
48 | int _gnutls_handshake_buffer_clear (gnutls_session_t session); | ||
49 | int _gnutls_handshake_buffer_empty (gnutls_session_t session); | ||
50 | int _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 | |||
58 | ssize_t _gnutls_handshake_io_recv_int (gnutls_session_t, content_type_t, | ||
59 | gnutls_handshake_description_t, void *, | ||
60 | size_t); | ||
61 | ssize_t _gnutls_handshake_io_send_int (gnutls_session_t, content_type_t, | ||
62 | gnutls_handshake_description_t, | ||
63 | const void *, size_t); | ||
64 | ssize_t _gnutls_io_write_flush (gnutls_session_t session); | ||
65 | ssize_t _gnutls_handshake_io_write_flush (gnutls_session_t session); | ||
66 | |||
67 | size_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 | **/ | ||
57 | void | ||
58 | gnutls_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 | **/ | ||
99 | void | ||
100 | gnutls_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 | **/ | ||
128 | void | ||
129 | gnutls_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 | -*/ | ||
143 | gnutls_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, ¶ms); | ||
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 | **/ | ||
185 | void | ||
186 | gnutls_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 | **/ | ||
215 | int | ||
216 | gnutls_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 | */ | ||
237 | int | ||
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 | **/ | ||
302 | void | ||
303 | gnutls_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 | **/ | ||
339 | void 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 | **/ | ||
365 | void 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 | -*/ | ||
382 | static 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 | -*/ | ||
416 | static 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 | -*/ | ||
448 | int | ||
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 | **/ | ||
534 | int | ||
535 | gnutls_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 | **/ | ||
579 | int | ||
580 | gnutls_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 | **/ | ||
604 | time_t | ||
605 | gnutls_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 | **/ | ||
649 | time_t | ||
650 | gnutls_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 | |||
685 | int | ||
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 | |||
708 | int | ||
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 | */ | ||
743 | int | ||
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 | */ | ||
774 | int | ||
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 | |||
859 | void | ||
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 | **/ | ||
894 | void | ||
895 | gnutls_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 | **/ | ||
912 | gnutls_sign_func | ||
913 | gnutls_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 | |||
51 | typedef 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 | |||
78 | typedef 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 | |||
101 | struct gnutls_session_int; /* because gnutls_session_t is not defined when this file is included */ | ||
102 | |||
103 | typedef enum ConvFlags | ||
104 | { | ||
105 | CERT_NO_COPY = 2, | ||
106 | CERT_ONLY_PUBKEY = 4, | ||
107 | CERT_ONLY_EXTENSIONS = 16 | ||
108 | } ConvFlags; | ||
109 | |||
110 | int _gnutls_x509_raw_cert_to_gcert (gnutls_cert * gcert, | ||
111 | const gnutls_datum_t * derCert, | ||
112 | int flags); | ||
113 | int _gnutls_x509_crt_to_gcert (gnutls_cert * gcert, gnutls_x509_crt_t cert, | ||
114 | unsigned int flags); | ||
115 | |||
116 | void _gnutls_gkey_deinit (gnutls_privkey * key); | ||
117 | void _gnutls_gcert_deinit (gnutls_cert * cert); | ||
118 | |||
119 | int _gnutls_selected_cert_supported_kx (struct gnutls_session_int *session, | ||
120 | gnutls_kx_algorithm_t ** alg, | ||
121 | int *alg_size); | ||
122 | |||
123 | int _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 */ ); | ||
127 | int _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 | |||
44 | inline static int | ||
45 | is_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 | |||
54 | inline static int | ||
55 | is_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 | */ | ||
70 | int | ||
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 | */ | ||
126 | int | ||
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, >xt, &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 (>xt); | ||
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 (>xt); | ||
184 | return GNUTLS_E_INTERNAL_ERROR; | ||
185 | } | ||
186 | |||
187 | memcpy (data, gtxt.data, gtxt.size); | ||
188 | ret = gtxt.size; | ||
189 | |||
190 | _gnutls_free_datum (>xt); | ||
191 | } | ||
192 | |||
193 | return ret; | ||
194 | } | ||
195 | |||
196 | inline static mac_hd_t | ||
197 | mac_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 | |||
217 | inline static void | ||
218 | mac_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 | |||
230 | inline static int | ||
231 | calc_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 | */ | ||
291 | int | ||
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 | */ | ||
417 | int | ||
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 | |||
25 | int _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 | |||
31 | int _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); | ||
34 | int _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); | ||
38 | int _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 | |||
30 | cipher_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 | |||
97 | int | ||
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 | |||
111 | int | ||
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 | |||
126 | void | ||
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 | ||
32 | void * _gnutls_cipher_init(gnutls_cipher_algorithm_t cipher, | ||
33 | const gnutls_datum_t * key, | ||
34 | const gnutls_datum_t * iv); | ||
35 | |||
36 | int _gnutls_cipher_encrypt(void * handle, | ||
37 | void *text, | ||
38 | int textlen); | ||
39 | |||
40 | int _gnutls_cipher_decrypt(void * handle, | ||
41 | void *ciphertext, | ||
42 | int ciphertextlen); | ||
43 | |||
44 | void _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 | */ | ||
36 | int | ||
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 | |||
59 | int | ||
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 | |||
25 | int _gnutls_m_plaintext2compressed (gnutls_session_t session, | ||
26 | gnutls_datum_t * compressed, | ||
27 | const gnutls_datum_t *plaintext); | ||
28 | int _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 | */ | ||
33 | comp_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 | |||
97 | cleanup_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 | */ | ||
105 | void | ||
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 | |||
134 | int | ||
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 | |||
210 | int | ||
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 | |||
34 | typedef struct comp_hd_t_STRUCT | ||
35 | { | ||
36 | void *handle; | ||
37 | gnutls_compression_method_t algo; | ||
38 | } *comp_hd_t; | ||
39 | |||
40 | comp_hd_t _gnutls_comp_init (gnutls_compression_method_t, int d); | ||
41 | void _gnutls_comp_deinit (comp_hd_t handle, int d); | ||
42 | |||
43 | int _gnutls_decompress (comp_hd_t handle, opaque * compressed, | ||
44 | size_t compressed_size, opaque ** plain, | ||
45 | size_t max_record_size); | ||
46 | int _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 | |||
38 | static const char keyexp[] = "key expansion"; | ||
39 | static const int keyexp_length = sizeof (keyexp) - 1; | ||
40 | |||
41 | static const char ivblock[] = "IV block"; | ||
42 | static const int ivblock_length = sizeof (ivblock) - 1; | ||
43 | |||
44 | static const char cliwrite[] = "client write key"; | ||
45 | static const int cliwrite_length = sizeof (cliwrite) - 1; | ||
46 | |||
47 | static const char servwrite[] = "server write key"; | ||
48 | static 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 | */ | ||
57 | int | ||
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 | |||
387 | int | ||
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 | |||
408 | int | ||
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 | |||
445 | static 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 | |||
456 | static 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 | */ | ||
473 | int | ||
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 | */ | ||
494 | int | ||
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 | */ | ||
684 | int | ||
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 | */ | ||
875 | int | ||
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 | |||
901 | int | ||
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 | */ | ||
930 | int | ||
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 | |||
948 | int | ||
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 | */ | ||
968 | int | ||
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 */ | ||
993 | int | ||
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 | |||
1017 | int | ||
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 | |||
25 | int _gnutls_connection_state_init (gnutls_session_t session); | ||
26 | int _gnutls_read_connection_state_init (gnutls_session_t session); | ||
27 | int _gnutls_write_connection_state_init (gnutls_session_t session); | ||
28 | int _gnutls_set_write_cipher (gnutls_session_t session, | ||
29 | gnutls_cipher_algorithm_t algo); | ||
30 | int _gnutls_set_write_mac (gnutls_session_t session, | ||
31 | gnutls_mac_algorithm_t algo); | ||
32 | int _gnutls_set_read_cipher (gnutls_session_t session, | ||
33 | gnutls_cipher_algorithm_t algo); | ||
34 | int _gnutls_set_read_mac (gnutls_session_t session, | ||
35 | gnutls_mac_algorithm_t algo); | ||
36 | int _gnutls_set_read_compression (gnutls_session_t session, | ||
37 | gnutls_compression_method_t algo); | ||
38 | int _gnutls_set_write_compression (gnutls_session_t session, | ||
39 | gnutls_compression_method_t algo); | ||
40 | int _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 | |||
36 | void | ||
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 | |||
44 | void | ||
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 | |||
52 | void | ||
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 | |||
60 | void | ||
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 | |||
69 | int | ||
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 | |||
90 | int | ||
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 | |||
106 | void | ||
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 | |||
25 | void _gnutls_write_datum16 (opaque * dest, gnutls_datum_t dat); | ||
26 | void _gnutls_write_datum24 (opaque * dest, gnutls_datum_t dat); | ||
27 | void _gnutls_write_datum32 (opaque * dest, gnutls_datum_t dat); | ||
28 | void _gnutls_write_datum8 (opaque * dest, gnutls_datum_t dat); | ||
29 | |||
30 | int _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 | |||
35 | int _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 | |||
39 | void _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 | **/ | ||
53 | void | ||
54 | gnutls_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 | **/ | ||
72 | void | ||
73 | gnutls_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 | **/ | ||
91 | void | ||
92 | gnutls_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 | **/ | ||
107 | void | ||
108 | gnutls_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 | **/ | ||
121 | void * | ||
122 | gnutls_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 | **/ | ||
135 | void | ||
136 | gnutls_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 | **/ | ||
152 | int | ||
153 | gnutls_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 | */ | ||
174 | int | ||
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 | */ | ||
214 | static 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 | |||
226 | int | ||
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 | |||
264 | int | ||
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 | */ | ||
279 | int | ||
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 | */ | ||
320 | gnutls_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 | */ | ||
342 | int | ||
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 | **/ | ||
377 | void | ||
378 | gnutls_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 | |||
25 | int _gnutls_server_register_current_session (gnutls_session_t session); | ||
26 | int _gnutls_server_restore_session (gnutls_session_t session, | ||
27 | uint8_t * session_id, | ||
28 | int session_id_size); | ||
29 | int _gnutls_db_remove_session (gnutls_session_t session, uint8_t * session_id, | ||
30 | int session_id_size); | ||
31 | int _gnutls_store_session (gnutls_session_t session, | ||
32 | gnutls_datum_t session_id, | ||
33 | gnutls_datum_t session_data); | ||
34 | gnutls_datum_t _gnutls_retrieve_session (gnutls_session_t session, | ||
35 | gnutls_datum_t session_id); | ||
36 | int _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 | */ | ||
49 | mpi_t | ||
50 | gnutls_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 | |||
106 | mpi_t | ||
107 | gnutls_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 | -*/ | ||
135 | gnutls_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, ¶ms); | ||
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 | |||
28 | const mpi_t *_gnutls_dh_params_to_mpi (gnutls_dh_params_t); | ||
29 | mpi_t gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime); | ||
30 | mpi_t gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime); | ||
31 | int _gnutls_dh_generate_prime (mpi_t * ret_g, mpi_t * ret_n, unsigned bits); | ||
32 | |||
33 | gnutls_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 | */ | ||
38 | const 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 | |||
50 | int | ||
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 | |||
130 | cleanup: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 | **/ | ||
152 | int | ||
153 | gnutls_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 | **/ | ||
191 | int | ||
192 | gnutls_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 | **/ | ||
213 | void | ||
214 | gnutls_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 | **/ | ||
235 | int | ||
236 | gnutls_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 | **/ | ||
266 | int | ||
267 | gnutls_dh_params_generate2 (gnutls_dh_params_t params, unsigned int bits) | ||
268 | { | ||
269 | int ret; | ||
270 | |||
271 | ret = | ||
272 | _gnutls_dh_generate_prime (¶ms->params[1], ¶ms->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 | **/ | ||
298 | int | ||
299 | gnutls_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", ¶ms->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", ¶ms->params[1]); | ||
378 | if (result < 0) | ||
379 | { | ||
380 | asn1_delete_structure (&c2); | ||
381 | _gnutls_mpi_release (¶ms->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 | **/ | ||
410 | int | ||
411 | gnutls_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 | **/ | ||
582 | int | ||
583 | gnutls_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 | |||
37 | extern LOG_FUNC _gnutls_log_func; | ||
38 | |||
39 | #define ERROR_ENTRY(desc, name, fatal) \ | ||
40 | { desc, #name, name, fatal} | ||
41 | |||
42 | struct gnutls_error_entry | ||
43 | { | ||
44 | const char *desc; | ||
45 | const char *_name; | ||
46 | int number; | ||
47 | int fatal; | ||
48 | }; | ||
49 | typedef struct gnutls_error_entry gnutls_error_entry; | ||
50 | |||
51 | static 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 | **/ | ||
281 | int | ||
282 | gnutls_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 | **/ | ||
303 | void | ||
304 | gnutls_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 | **/ | ||
324 | const char * | ||
325 | gnutls_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 | */ | ||
339 | const 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 | |||
350 | int | ||
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 | */ | ||
392 | void | ||
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 | */ | ||
415 | void | ||
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 | |||
39 | int _gnutls_asn2err (int asn_err); | ||
40 | void _gnutls_log (int, const char *fmt, ...); | ||
41 | |||
42 | extern 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 | |||
71 | void _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 | ||
46 | const int _gnutls_extensions_size = MAX_EXT_SIZE; | ||
47 | |||
48 | gnutls_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 | |||
90 | ext_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 | |||
102 | ext_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 | |||
111 | const 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 | */ | ||
125 | static 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 | |||
142 | int | ||
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 | */ | ||
217 | static 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 | |||
236 | int | ||
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 | |||
27 | const char *_gnutls_extension_get_name (uint16_t type); | ||
28 | int _gnutls_parse_extensions (gnutls_session_t, tls_ext_parse_type_t, const opaque *, int); | ||
29 | int _gnutls_gen_extensions (gnutls_session_t session, opaque * data, | ||
30 | size_t data_size); | ||
31 | |||
32 | typedef int (*ext_recv_func) (gnutls_session_t, const opaque *, size_t); /* recv data */ | ||
33 | typedef int (*ext_send_func) (gnutls_session_t, opaque *, size_t); /* send data */ | ||
34 | |||
35 | ext_send_func _gnutls_ext_func_send (uint16_t type); | ||
36 | ext_recv_func _gnutls_ext_func_recv (uint16_t type, tls_ext_parse_type_t); | ||
37 | |||
38 | typedef 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. */ | ||
50 | extern 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 | |||
31 | typedef int (*_gnutls_openpgp_verify_key_func) | ||
32 | (const gnutls_certificate_credentials_t, | ||
33 | const gnutls_datum_t *, int, | ||
34 | unsigned int *); | ||
35 | |||
36 | typedef time_t (*_gnutls_openpgp_crt_creation_time_func) | ||
37 | (const gnutls_datum_t *); | ||
38 | |||
39 | typedef time_t (*_gnutls_openpgp_crt_expiration_time_func) | ||
40 | (const gnutls_datum_t *); | ||
41 | |||
42 | typedef int (*_gnutls_openpgp_crt_request_func) | ||
43 | (gnutls_session_t, gnutls_datum_t *, | ||
44 | const gnutls_certificate_credentials_t, | ||
45 | opaque *, int); | ||
46 | |||
47 | typedef int (*_gnutls_openpgp_fingerprint_func) | ||
48 | (const gnutls_datum_t *, | ||
49 | unsigned char *, size_t *); | ||
50 | |||
51 | typedef int (*_gnutls_openpgp_raw_key_to_gcert_func) | ||
52 | (gnutls_cert *, | ||
53 | const gnutls_datum_t *); | ||
54 | typedef int (*_gnutls_openpgp_raw_privkey_to_gkey_func) | ||
55 | (gnutls_privkey *, | ||
56 | const gnutls_datum_t *, | ||
57 | gnutls_openpgp_crt_fmt_t); | ||
58 | |||
59 | typedef int (*_gnutls_openpgp_crt_to_gcert_func) | ||
60 | (gnutls_cert *, gnutls_openpgp_crt_t); | ||
61 | |||
62 | typedef int (*_gnutls_openpgp_privkey_to_gkey_func) | ||
63 | (gnutls_privkey *, | ||
64 | gnutls_openpgp_privkey_t); | ||
65 | |||
66 | typedef void (*_gnutls_openpgp_crt_deinit_func) | ||
67 | (gnutls_openpgp_crt_t); | ||
68 | |||
69 | typedef void (*_gnutls_openpgp_keyring_deinit_func) | ||
70 | (gnutls_openpgp_keyring_t); | ||
71 | |||
72 | typedef 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. */ | ||
79 | extern _gnutls_openpgp_verify_key_func _E_gnutls_openpgp_verify_key; | ||
80 | extern _gnutls_openpgp_crt_creation_time_func | ||
81 | _E_gnutls_openpgp_get_raw_key_creation_time; | ||
82 | extern _gnutls_openpgp_crt_expiration_time_func | ||
83 | _E_gnutls_openpgp_get_raw_key_expiration_time; | ||
84 | extern _gnutls_openpgp_fingerprint_func _E_gnutls_openpgp_fingerprint; | ||
85 | extern _gnutls_openpgp_crt_request_func _E_gnutls_openpgp_request_key; | ||
86 | extern _gnutls_openpgp_raw_key_to_gcert_func _E_gnutls_openpgp_raw_key_to_gcert; | ||
87 | extern _gnutls_openpgp_raw_privkey_to_gkey_func _E_gnutls_openpgp_raw_privkey_to_gkey; | ||
88 | extern _gnutls_openpgp_crt_to_gcert_func _E_gnutls_openpgp_crt_to_gcert; | ||
89 | extern _gnutls_openpgp_privkey_to_gkey_func _E_gnutls_openpgp_privkey_to_gkey; | ||
90 | extern _gnutls_openpgp_crt_deinit_func _E_gnutls_openpgp_crt_deinit; | ||
91 | extern _gnutls_openpgp_keyring_deinit_func _E_gnutls_openpgp_keyring_deinit; | ||
92 | extern _gnutls_openpgp_privkey_deinit_func _E_gnutls_openpgp_privkey_deinit; | ||
93 | |||
94 | extern 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 */ | ||
39 | extern const ASN1_ARRAY_TYPE gnutls_asn1_tab[]; | ||
40 | extern const ASN1_ARRAY_TYPE pkix_asn1_tab[]; | ||
41 | |||
42 | LOG_FUNC _gnutls_log_func; | ||
43 | int _gnutls_log_level = 0; /* default log level */ | ||
44 | |||
45 | ASN1_TYPE _gnutls_pkix1_asn; | ||
46 | ASN1_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 | **/ | ||
60 | void 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 | **/ | ||
77 | void gnutls_global_set_log_level(int level) | ||
78 | { | ||
79 | _gnutls_log_level = level; | ||
80 | } | ||
81 | |||
82 | #ifdef DEBUG | ||
83 | /* default logging function */ | ||
84 | static void | ||
85 | dlog (int level, const char *str) | ||
86 | { | ||
87 | fputs (str, stderr); | ||
88 | } | ||
89 | #endif | ||
90 | |||
91 | extern gnutls_alloc_function gnutls_secure_malloc; | ||
92 | extern gnutls_alloc_function gnutls_malloc; | ||
93 | extern gnutls_free_function gnutls_free; | ||
94 | extern int (*_gnutls_is_secure_memory)(const void *); | ||
95 | extern gnutls_realloc_function gnutls_realloc; | ||
96 | extern char *(*gnutls_strdup)(const char *); | ||
97 | extern void *(*gnutls_calloc)(size_t, | ||
98 | size_t); | ||
99 | |||
100 | int _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 | **/ | ||
119 | void 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 | ||
153 | static 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 | |||
161 | static 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 | **/ | ||
193 | int 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 | **/ | ||
294 | void 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 | **/ | ||
325 | void 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 | **/ | ||
345 | void 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 | **/ | ||
369 | const 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 | |||
30 | int gnutls_is_secure_memory (const void *mem); | ||
31 | |||
32 | extern ASN1_TYPE _gnutls_pkix1_asn; | ||
33 | extern 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 | |||
63 | int _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 | */ | ||
69 | inline 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 | */ | ||
83 | static void | ||
84 | resume_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 | |||
126 | void | ||
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 | |||
132 | void | ||
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 | ||
143 | static 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 | ||
193 | int | ||
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 | */ | ||
251 | int | ||
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 | */ | ||
276 | int | ||
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 | |||
307 | int | ||
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 | */ | ||
339 | int | ||
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 | */ | ||
483 | inline 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 | */ | ||
521 | int | ||
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 | */ | ||
574 | int | ||
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 | */ | ||
644 | static 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 | */ | ||
681 | int | ||
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 | |||
761 | finish: | ||
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 | */ | ||
808 | int | ||
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 | */ | ||
862 | int | ||
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 | */ | ||
880 | static 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 | */ | ||
910 | int | ||
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 | ||
985 | static 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 | */ | ||
1118 | static 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 | */ | ||
1167 | int | ||
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 | */ | ||
1291 | static 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 | */ | ||
1371 | static 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 | */ | ||
1414 | static 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 | */ | ||
1461 | static 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 | */ | ||
1565 | static 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 | */ | ||
1634 | static 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 | */ | ||
1679 | static 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 | |||
1863 | static 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 | |||
1976 | int | ||
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 | */ | ||
1998 | int | ||
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 | **/ | ||
2072 | int | ||
2073 | gnutls_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 | |||
2096 | inline 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 | */ | ||
2112 | inline 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 | |||
2142 | int | ||
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 | |||
2172 | int | ||
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 | **/ | ||
2229 | int | ||
2230 | gnutls_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 | */ | ||
2292 | int | ||
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 | */ | ||
2410 | static 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 | */ | ||
2472 | static 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 | |||
2532 | int | ||
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 | |||
2633 | int | ||
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 | |||
2674 | int | ||
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 | |||
2688 | int | ||
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 | */ | ||
2717 | inline static int | ||
2718 | check_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 | */ | ||
2833 | int | ||
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 | **/ | ||
2971 | void | ||
2972 | gnutls_handshake_set_max_packet_length (gnutls_session_t session, size_t max) | ||
2973 | { | ||
2974 | session->internals.max_handshake_data_buffer_size = max; | ||
2975 | } | ||
2976 | |||
2977 | void | ||
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 | |||
2984 | gnutls_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 | **/ | ||
3005 | gnutls_handshake_description_t | ||
3006 | gnutls_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 | **/ | ||
3025 | gnutls_handshake_description_t | ||
3026 | gnutls_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 | |||
25 | typedef enum Optional | ||
26 | { OPTIONAL_PACKET, MANDATORY_PACKET } Optional; | ||
27 | |||
28 | int _gnutls_send_handshake (gnutls_session_t session, void *i_data, | ||
29 | uint32_t i_datasize, | ||
30 | gnutls_handshake_description_t type); | ||
31 | int _gnutls_recv_hello_request (gnutls_session_t session, void *data, | ||
32 | uint32_t data_size); | ||
33 | int _gnutls_send_hello (gnutls_session_t session, int again); | ||
34 | int _gnutls_recv_hello (gnutls_session_t session, opaque * data, int datalen); | ||
35 | int _gnutls_recv_handshake (gnutls_session_t session, uint8_t **, int *, | ||
36 | gnutls_handshake_description_t, | ||
37 | Optional optional); | ||
38 | int _gnutls_generate_session_id (opaque * session_id, uint8_t * len); | ||
39 | int _gnutls_handshake_common (gnutls_session_t session); | ||
40 | int _gnutls_handshake_client (gnutls_session_t session); | ||
41 | int _gnutls_handshake_server (gnutls_session_t session); | ||
42 | void _gnutls_set_server_random (gnutls_session_t session, uint8_t * rnd); | ||
43 | void _gnutls_set_client_random (gnutls_session_t session, uint8_t * rnd); | ||
44 | int _gnutls_tls_create_random (opaque * dst); | ||
45 | int _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session, | ||
46 | cipher_suite_st ** cipherSuites, | ||
47 | int numCipherSuites, | ||
48 | gnutls_pk_algorithm_t); | ||
49 | int _gnutls_find_pk_algos_in_ciphersuites (opaque * data, int datalen); | ||
50 | int _gnutls_server_select_suite (gnutls_session_t session, opaque * data, | ||
51 | int datalen); | ||
52 | |||
53 | int _gnutls_negotiate_version( gnutls_session_t session, gnutls_protocol_t adv_version); | ||
54 | int _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 | |||
33 | static 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 | |||
57 | GNUTLS_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 | |||
83 | int | ||
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 | |||
94 | int | ||
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 | |||
102 | GNUTLS_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 | |||
128 | void | ||
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 | |||
146 | mac_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 | |||
173 | void | ||
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 | |||
191 | inline static int | ||
192 | get_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 | |||
205 | mac_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 | |||
236 | void | ||
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 | |||
269 | void | ||
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 | |||
311 | static int | ||
312 | ssl3_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 | |||
340 | static int | ||
341 | ssl3_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 | |||
371 | int | ||
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 | |||
404 | int | ||
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 | |||
32 | typedef struct | ||
33 | { | ||
34 | gc_hash_handle handle; | ||
35 | gnutls_mac_algorithm_t algorithm; | ||
36 | const void *key; | ||
37 | int keysize; | ||
38 | } mac_hd_st; | ||
39 | typedef mac_hd_st *mac_hd_t; | ||
40 | typedef mac_hd_t GNUTLS_HASH_HANDLE; | ||
41 | |||
42 | #define GNUTLS_HASH_FAILED NULL | ||
43 | #define GNUTLS_MAC_FAILED NULL | ||
44 | |||
45 | mac_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 | ||
49 | void _gnutls_hmac_deinit (mac_hd_t handle, void *digest); | ||
50 | |||
51 | mac_hd_t _gnutls_mac_init_ssl3 (gnutls_mac_algorithm_t algorithm, void *key, | ||
52 | int keylen); | ||
53 | void _gnutls_mac_deinit_ssl3 (mac_hd_t handle, void *digest); | ||
54 | |||
55 | GNUTLS_HASH_HANDLE _gnutls_hash_init (gnutls_mac_algorithm_t algorithm); | ||
56 | int _gnutls_hash_get_algo_len (gnutls_mac_algorithm_t algorithm); | ||
57 | int _gnutls_hash (GNUTLS_HASH_HANDLE handle, const void *text, | ||
58 | size_t textlen); | ||
59 | void _gnutls_hash_deinit (GNUTLS_HASH_HANDLE handle, void *digest); | ||
60 | |||
61 | int _gnutls_ssl3_generate_random (void *secret, int secret_len, | ||
62 | void *rnd, int random_len, int bytes, | ||
63 | opaque * ret); | ||
64 | int _gnutls_ssl3_hash_md5 (void *first, int first_len, void *second, | ||
65 | int second_len, int ret_len, opaque * ret); | ||
66 | |||
67 | void _gnutls_mac_deinit_ssl3_handshake (mac_hd_t handle, void *digest, | ||
68 | opaque * key, uint32_t key_size); | ||
69 | |||
70 | GNUTLS_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 | |||
106 | typedef unsigned char opaque; | ||
107 | typedef struct | ||
108 | { | ||
109 | opaque pint[3]; | ||
110 | } uint24; | ||
111 | |||
112 | #include <gnutls_mpi.h> | ||
113 | |||
114 | typedef enum change_cipher_spec_t | ||
115 | { | ||
116 | GNUTLS_TYPE_CHANGE_CIPHER_SPEC = 1 | ||
117 | } change_cipher_spec_t; | ||
118 | |||
119 | typedef 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 | |||
137 | typedef 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 | |||
148 | typedef enum | ||
149 | { CIPHER_STREAM, CIPHER_BLOCK} cipher_type_t; | ||
150 | |||
151 | typedef enum valid_session_t | ||
152 | { VALID_TRUE, VALID_FALSE} valid_session_t; | ||
153 | typedef enum resumable_session_t | ||
154 | { RESUME_TRUE, | ||
155 | RESUME_FALSE | ||
156 | } resumable_session_t; | ||
157 | |||
158 | /* Record Protocol */ | ||
159 | typedef 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 | |||
171 | typedef void (*LOG_FUNC)(int, | ||
172 | const char *); | ||
173 | |||
174 | /* Store & Retrieve functions defines: */ | ||
175 | typedef 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 | |||
185 | struct 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 | }; | ||
229 | typedef 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 | |||
237 | typedef 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 | */ | ||
246 | typedef 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 | ||
254 | typedef 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 | */ | ||
283 | typedef 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 | */ | ||
308 | typedef 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 | */ | ||
351 | typedef 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 | |||
365 | typedef 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 | |||
377 | typedef struct | ||
378 | { | ||
379 | unsigned int priority[MAX_ALGOS]; | ||
380 | unsigned int algorithms; | ||
381 | } priority_st; | ||
382 | |||
383 | /* For the external api */ | ||
384 | struct 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 | */ | ||
399 | typedef 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 | |||
406 | typedef 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 | |||
414 | typedef 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 | |||
424 | typedef 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 | |||
646 | struct 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 | */ | ||
657 | void _gnutls_set_current_version(gnutls_session_t session, | ||
658 | gnutls_protocol_t version); | ||
659 | |||
660 | void _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 | |||
675 | void _gnutls_set_adv_version(gnutls_session_t, | ||
676 | gnutls_protocol_t); | ||
677 | gnutls_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" | ||
45 | static int generate_normal_master (gnutls_session_t session, int); | ||
46 | |||
47 | int | ||
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 | ||
58 | static int | ||
59 | generate_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 | */ | ||
184 | int | ||
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 | */ | ||
232 | int | ||
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 | */ | ||
278 | int | ||
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 | */ | ||
321 | int | ||
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 | |||
372 | int | ||
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 | |||
417 | int | ||
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 | |||
450 | int | ||
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 | */ | ||
485 | int | ||
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 | */ | ||
555 | int | ||
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 | |||
597 | int | ||
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 | |||
690 | int | ||
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 | */ | ||
730 | int | ||
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 | |||
25 | int _gnutls_send_server_kx_message (gnutls_session_t session, int again); | ||
26 | int _gnutls_send_client_kx_message (gnutls_session_t session, int again); | ||
27 | int _gnutls_recv_server_kx_message (gnutls_session_t session); | ||
28 | int _gnutls_recv_client_kx_message (gnutls_session_t session); | ||
29 | int _gnutls_send_client_certificate_verify (gnutls_session_t session, | ||
30 | int again); | ||
31 | int _gnutls_send_server_certificate (gnutls_session_t session, int again); | ||
32 | int _gnutls_generate_master (gnutls_session_t session, int keep_premaster); | ||
33 | int _gnutls_recv_client_certificate (gnutls_session_t session); | ||
34 | int _gnutls_recv_server_certificate (gnutls_session_t session); | ||
35 | int _gnutls_send_client_certificate (gnutls_session_t session, int again); | ||
36 | int _gnutls_recv_server_certificate_request (gnutls_session_t session); | ||
37 | int _gnutls_send_server_certificate_request (gnutls_session_t session, | ||
38 | int again); | ||
39 | int _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 | |||
29 | gnutls_alloc_function gnutls_secure_malloc = malloc; | ||
30 | gnutls_alloc_function gnutls_malloc = malloc; | ||
31 | gnutls_free_function gnutls_free = free; | ||
32 | gnutls_realloc_function gnutls_realloc = realloc; | ||
33 | |||
34 | void *(*gnutls_calloc) (size_t, size_t) = calloc; | ||
35 | char *(*gnutls_strdup) (const char *) = _gnutls_strdup; | ||
36 | |||
37 | int | ||
38 | _gnutls_is_secure_mem_null (const void *ign) | ||
39 | { | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | int (*_gnutls_is_secure_memory) (const void *) = _gnutls_is_secure_mem_null; | ||
44 | |||
45 | |||
46 | void * | ||
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 | |||
57 | svoid * | ||
58 | gnutls_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 | */ | ||
71 | void * | ||
72 | gnutls_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 | |||
88 | char * | ||
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 | **/ | ||
115 | void * | ||
116 | gnutls_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 | **/ | ||
129 | void | ||
130 | gnutls_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 | |||
32 | typedef 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 | |||
58 | extern 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 | */ | ||
63 | void *gnutls_realloc_fast (void *ptr, size_t size); | ||
64 | |||
65 | svoid *gnutls_secure_calloc (size_t nmemb, size_t size); | ||
66 | |||
67 | void *_gnutls_calloc (size_t nmemb, size_t size); | ||
68 | char *_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 | |||
37 | void | ||
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 | */ | ||
48 | int | ||
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 | */ | ||
62 | int | ||
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 | |||
82 | int | ||
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 | |||
101 | int | ||
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 */ | ||
117 | int | ||
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 */ | ||
133 | int | ||
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 | |||
162 | int | ||
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 | */ | ||
196 | int | ||
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 | */ | ||
242 | int | ||
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 | |||
34 | typedef 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 | |||
63 | void _gnutls_mpi_release (mpi_t * x); | ||
64 | |||
65 | int _gnutls_mpi_scan_nz (mpi_t * ret_mpi, const opaque * buffer, | ||
66 | size_t * nbytes); | ||
67 | int _gnutls_mpi_scan (mpi_t * ret_mpi, const opaque * buffer, | ||
68 | size_t * nbytes); | ||
69 | int _gnutls_mpi_scan_pgp (mpi_t * ret_mpi, const opaque * buffer, | ||
70 | size_t * nbytes); | ||
71 | |||
72 | int _gnutls_mpi_print (void *buffer, size_t * nbytes, const mpi_t a); | ||
73 | int _gnutls_mpi_print_lz (void *buffer, size_t * nbytes, const mpi_t a); | ||
74 | |||
75 | int _gnutls_mpi_dprint_lz (gnutls_datum_t * dest, const mpi_t a); | ||
76 | int _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 | */ | ||
37 | int | ||
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 | |||
62 | uint32_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 | |||
73 | uint24 | ||
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 */ | ||
86 | uint32_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 | |||
103 | void | ||
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 | |||
118 | uint32_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 | |||
130 | void | ||
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 | |||
140 | uint16_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 | |||
151 | void | ||
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 | |||
161 | uint32_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 | |||
171 | uint16_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 | |||
181 | uint32_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 | |||
35 | uint32_t _gnutls_uint24touint32 (uint24 num); | ||
36 | uint24 _gnutls_uint32touint24 (uint32_t num); | ||
37 | uint32_t _gnutls_read_uint32 (const opaque * data); | ||
38 | uint16_t _gnutls_read_uint16 (const opaque * data); | ||
39 | uint32_t _gnutls_conv_uint32 (uint32_t data); | ||
40 | uint16_t _gnutls_conv_uint16 (uint16_t data); | ||
41 | uint32_t _gnutls_read_uint24 (const opaque * data); | ||
42 | void _gnutls_write_uint24 (uint32_t num, opaque * data); | ||
43 | void _gnutls_write_uint32 (uint32_t num, opaque * data); | ||
44 | void _gnutls_write_uint16 (uint16_t num, opaque * data); | ||
45 | uint32_t _gnutls_uint64touint32 (const uint64 *); | ||
46 | |||
47 | int _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 | |||
43 | static int _gnutls_pk_encrypt (int algo, mpi_t * resarr, mpi_t data, | ||
44 | mpi_t * pkey, int pkey_len); | ||
45 | static int _gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash, | ||
46 | mpi_t * pkey, int); | ||
47 | static int _gnutls_pk_verify (int algo, mpi_t hash, mpi_t * data, | ||
48 | mpi_t * pkey, int); | ||
49 | static 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 | */ | ||
56 | int | ||
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 | */ | ||
210 | int | ||
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 | |||
347 | int | ||
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 | */ | ||
386 | static int | ||
387 | encode_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 | */ | ||
435 | int | ||
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 | */ | ||
484 | static int | ||
485 | decode_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 | */ | ||
531 | int | ||
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 | */ | ||
586 | static 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 | |||
658 | static 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 | */ | ||
725 | static 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 | |||
835 | static 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 | |||
28 | int _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, | ||
29 | const gnutls_datum_t * plaintext, | ||
30 | mpi_t * params, unsigned params_len, | ||
31 | unsigned btype); | ||
32 | int _gnutls_dsa_sign (gnutls_datum_t * signature, | ||
33 | const gnutls_datum_t * plaintext, mpi_t * params, | ||
34 | unsigned params_len); | ||
35 | int _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, | ||
36 | const gnutls_datum_t * ciphertext, | ||
37 | mpi_t * params, unsigned params_len, | ||
38 | unsigned btype); | ||
39 | int _gnutls_rsa_verify (const gnutls_datum_t * vdata, | ||
40 | const gnutls_datum_t * ciphertext, mpi_t * params, | ||
41 | int params_len, int btype); | ||
42 | int _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 | |||
35 | static 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 | **/ | ||
54 | int | ||
55 | gnutls_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 | |||
73 | inline 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 | **/ | ||
108 | int | ||
109 | gnutls_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 | **/ | ||
129 | int | ||
130 | gnutls_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 | **/ | ||
154 | int | ||
155 | gnutls_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 | **/ | ||
172 | int | ||
173 | gnutls_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 | **/ | ||
203 | int | ||
204 | gnutls_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 | |||
217 | static const int protocol_priority[] = { GNUTLS_TLS1_1, | ||
218 | GNUTLS_TLS1_0, | ||
219 | 0 | ||
220 | }; | ||
221 | |||
222 | static const int cipher_priority_secure256[] = { GNUTLS_CIPHER_AES_256_CBC, | ||
223 | 0 | ||
224 | }; | ||
225 | |||
226 | static const int kx_priority_secure[] = { GNUTLS_KX_RSA, | ||
227 | 0 | ||
228 | }; | ||
229 | |||
230 | static const int mac_priority_secure[] = { GNUTLS_MAC_SHA1, | ||
231 | 0 | ||
232 | }; | ||
233 | |||
234 | static int cert_type_priority[] = { GNUTLS_CRT_X509, | ||
235 | 0 | ||
236 | }; | ||
237 | |||
238 | static const int comp_priority[] = { GNUTLS_COMP_NULL, | ||
239 | 0 | ||
240 | }; | ||
241 | |||
242 | typedef 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 | **/ | ||
255 | int | ||
256 | gnutls_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 | **/ | ||
335 | int | ||
336 | gnutls_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 | **/ | ||
369 | void | ||
370 | gnutls_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 | **/ | ||
389 | int | ||
390 | gnutls_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 | */ | ||
418 | static void | ||
419 | break_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 | **/ | ||
468 | int | ||
469 | gnutls_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 | **/ | ||
493 | int | ||
494 | gnutls_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 | **/ | ||
53 | gnutls_protocol_t gnutls_protocol_get_version(gnutls_session_t session) | ||
54 | { | ||
55 | return session->security_parameters.version; | ||
56 | } | ||
57 | |||
58 | void _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 | **/ | ||
76 | void 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 | **/ | ||
94 | void 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 | **/ | ||
108 | void 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 | **/ | ||
126 | void 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 | **/ | ||
144 | gnutls_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 | **/ | ||
159 | void 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 | **/ | ||
201 | int 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 | |||
261 | inline static void session_invalidate(gnutls_session_t session) | ||
262 | { | ||
263 | session->internals.valid_connection = VALID_FALSE; | ||
264 | } | ||
265 | |||
266 | inline 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 | */ | ||
273 | inline 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 | */ | ||
284 | inline 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 | */ | ||
319 | ssize_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 | */ | ||
463 | ssize_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 | |||
480 | inline 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 | */ | ||
501 | static 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 | */ | ||
538 | static 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 | */ | ||
596 | inline 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 | */ | ||
634 | static 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 | */ | ||
774 | inline 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 | */ | ||
822 | ssize_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 | **/ | ||
1104 | ssize_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 | **/ | ||
1142 | ssize_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 | **/ | ||
1158 | size_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 | **/ | ||
1183 | ssize_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 | |||
25 | ssize_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); | ||
28 | ssize_t _gnutls_recv_int (gnutls_session_t session, content_type_t type, | ||
29 | gnutls_handshake_description_t, opaque * data, | ||
30 | size_t sizeofdata); | ||
31 | ssize_t _gnutls_send_change_cipher_spec (gnutls_session_t session, int again); | ||
32 | void 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 | */ | ||
48 | const 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 | */ | ||
63 | int | ||
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 | **/ | ||
185 | int | ||
186 | gnutls_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 | **/ | ||
204 | int | ||
205 | gnutls_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 | **/ | ||
228 | void | ||
229 | gnutls_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 | **/ | ||
243 | int | ||
244 | gnutls_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 | **/ | ||
264 | int | ||
265 | gnutls_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 | **/ | ||
286 | int | ||
287 | gnutls_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 | **/ | ||
313 | int | ||
314 | gnutls_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 | **/ | ||
340 | int | ||
341 | gnutls_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 | |||
25 | const mpi_t *_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t); | ||
26 | int _gnutls_peers_cert_less_512 (gnutls_session_t session); | ||
27 | int _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 | **/ | ||
43 | int | ||
44 | gnutls_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 | |||
75 | error: | ||
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 | **/ | ||
93 | int | ||
94 | gnutls_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 | **/ | ||
134 | int | ||
135 | gnutls_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 | **/ | ||
176 | int | ||
177 | gnutls_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 | ||
46 | static int pack_certificate_auth_info (gnutls_session_t, | ||
47 | gnutls_datum_t * packed_session); | ||
48 | static int unpack_certificate_auth_info (gnutls_session_t, | ||
49 | const gnutls_datum_t * | ||
50 | packed_session); | ||
51 | |||
52 | static int unpack_srp_auth_info (gnutls_session_t session, | ||
53 | const gnutls_datum_t * packed_session); | ||
54 | static int pack_srp_auth_info (gnutls_session_t session, | ||
55 | gnutls_datum_t * packed_session); | ||
56 | |||
57 | static int unpack_psk_auth_info (gnutls_session_t session, | ||
58 | const gnutls_datum_t * packed_session); | ||
59 | static int pack_psk_auth_info (gnutls_session_t session, | ||
60 | gnutls_datum_t * packed_session); | ||
61 | |||
62 | static int unpack_anon_auth_info (gnutls_session_t session, | ||
63 | const gnutls_datum_t * packed_session); | ||
64 | static int pack_anon_auth_info (gnutls_session_t session, | ||
65 | gnutls_datum_t * packed_session); | ||
66 | |||
67 | static int unpack_security_parameters (gnutls_session_t session, | ||
68 | const gnutls_datum_t * packed_session); | ||
69 | static 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 | */ | ||
81 | int | ||
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 | */ | ||
156 | int | ||
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 | */ | ||
255 | static int | ||
256 | pack_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 | */ | ||
333 | static int | ||
334 | unpack_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 | |||
474 | error: | ||
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 | */ | ||
500 | static int | ||
501 | pack_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 | |||
535 | static int | ||
536 | unpack_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 | */ | ||
602 | static int | ||
603 | pack_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 | |||
651 | static int | ||
652 | unpack_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 | |||
735 | error: | ||
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 | */ | ||
760 | static int | ||
761 | pack_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 | |||
824 | static int | ||
825 | unpack_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 | |||
915 | error: | ||
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 | */ | ||
972 | static int | ||
973 | pack_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 | |||
1076 | static int | ||
1077 | unpack_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 | |||
25 | int _gnutls_session_pack (gnutls_session_t session, | ||
26 | gnutls_datum_t * packed_session); | ||
27 | int _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 | |||
40 | static 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 | */ | ||
49 | int | ||
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 | */ | ||
121 | int | ||
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 | */ | ||
206 | int | ||
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 | */ | ||
240 | static 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 | |||
276 | static 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 | */ | ||
329 | int | ||
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 | */ | ||
394 | int | ||
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 | |||
28 | int _gnutls_tls_sign_hdata (gnutls_session_t session, | ||
29 | gnutls_cert * cert, | ||
30 | gnutls_privkey * pkey, | ||
31 | gnutls_datum_t * signature); | ||
32 | |||
33 | int _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 | |||
39 | int _gnutls_verify_sig_hdata (gnutls_session_t session, | ||
40 | gnutls_cert * cert, gnutls_datum_t * signature); | ||
41 | |||
42 | int _gnutls_verify_sig_params (gnutls_session_t session, | ||
43 | gnutls_cert * cert, | ||
44 | const gnutls_datum_t * params, | ||
45 | gnutls_datum_t * signature); | ||
46 | |||
47 | int _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 | |||
46 | void | ||
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 | **/ | ||
59 | gnutls_cipher_algorithm_t | ||
60 | gnutls_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 | **/ | ||
75 | gnutls_certificate_type_t | ||
76 | gnutls_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 | **/ | ||
87 | gnutls_kx_algorithm_t | ||
88 | gnutls_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 | **/ | ||
99 | gnutls_mac_algorithm_t | ||
100 | gnutls_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 | **/ | ||
111 | gnutls_compression_method_t | ||
112 | gnutls_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 | */ | ||
121 | int | ||
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 | */ | ||
175 | inline static void | ||
176 | deinit_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 | */ | ||
191 | void | ||
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 | ||
237 | int | ||
238 | gnutls_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 | */ | ||
327 | int | ||
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 | **/ | ||
341 | void | ||
342 | gnutls_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 | */ | ||
424 | int | ||
425 | _gnutls_dh_get_allowed_prime_bits (gnutls_session_t session) | ||
426 | { | ||
427 | return session->internals.dh_prime_bits; | ||
428 | } | ||
429 | |||
430 | int | ||
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 | |||
474 | int | ||
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 | */ | ||
510 | int | ||
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 | */ | ||
541 | int | ||
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 | **/ | ||
607 | void | ||
608 | gnutls_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 | **/ | ||
628 | void | ||
629 | gnutls_certificate_send_x509_rdn_sequence (gnutls_session_t session, | ||
630 | int status) | ||
631 | { | ||
632 | session->internals.ignore_rdn_sequence = status; | ||
633 | } | ||
634 | |||
635 | int | ||
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 | -*/ | ||
652 | void | ||
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 | **/ | ||
676 | void | ||
677 | gnutls_handshake_set_private_extensions (gnutls_session_t session, int allow) | ||
678 | { | ||
679 | session->internals.enable_private = allow; | ||
680 | } | ||
681 | |||
682 | inline 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 | */ | ||
708 | static 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 | */ | ||
787 | inline 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 | */ | ||
803 | int | ||
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 | **/ | ||
911 | int | ||
912 | gnutls_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 | **/ | ||
955 | int | ||
956 | gnutls_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 | **/ | ||
1004 | const void * | ||
1005 | gnutls_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 | **/ | ||
1023 | const void * | ||
1024 | gnutls_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 | **/ | ||
1045 | const void * | ||
1046 | gnutls_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 | **/ | ||
1058 | int | ||
1059 | gnutls_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 | -*/ | ||
1088 | int | ||
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 | **/ | ||
1110 | void * | ||
1111 | gnutls_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 | **/ | ||
1125 | void | ||
1126 | gnutls_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 | **/ | ||
1148 | int | ||
1149 | gnutls_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 | -*/ | ||
1165 | void | ||
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 | **/ | ||
1195 | void | ||
1196 | gnutls_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 | **/ | ||
1215 | void | ||
1216 | gnutls_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 | |||
30 | void _gnutls_session_cert_type_set (gnutls_session_t session, | ||
31 | gnutls_certificate_type_t); | ||
32 | gnutls_kx_algorithm_t gnutls_kx_get (gnutls_session_t session); | ||
33 | gnutls_cipher_algorithm_t gnutls_cipher_get (gnutls_session_t session); | ||
34 | gnutls_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 | |||
45 | int _gnutls_session_cert_type_supported (gnutls_session_t, | ||
46 | gnutls_certificate_type_t); | ||
47 | |||
48 | int _gnutls_dh_set_secret_bits (gnutls_session_t session, unsigned bits); | ||
49 | |||
50 | int _gnutls_dh_set_peer_public (gnutls_session_t session, mpi_t public); | ||
51 | int _gnutls_dh_set_group (gnutls_session_t session, mpi_t gen, mpi_t prime); | ||
52 | |||
53 | int _gnutls_dh_get_allowed_prime_bits (gnutls_session_t session); | ||
54 | void _gnutls_handshake_internal_state_clear (gnutls_session_t); | ||
55 | |||
56 | int _gnutls_rsa_export_set_pubkey (gnutls_session_t session, | ||
57 | mpi_t exponent, mpi_t modulus); | ||
58 | |||
59 | int _gnutls_session_is_resumable (gnutls_session_t session); | ||
60 | int _gnutls_session_is_export (gnutls_session_t session); | ||
61 | |||
62 | int _gnutls_openpgp_send_fingerprint (gnutls_session_t session); | ||
63 | |||
64 | int _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 | |||
70 | int 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 | */ | ||
36 | void _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 | |||
57 | void _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 | |||
77 | void _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 | |||
96 | void _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 | |||
110 | void _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 | */ | ||
123 | gnutls_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 | |||
135 | int _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 | |||
165 | int _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 | |||
198 | int _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 | |||
231 | int _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 | */ | ||
258 | char * _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 | */ | ||
278 | int _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 | |||
32 | void _gnutls_str_cpy (char *dest, size_t dest_tot_size, const char *src); | ||
33 | void _gnutls_mem_cpy (char *dest, size_t dest_tot_size, const char *src, | ||
34 | size_t src_size); | ||
35 | void _gnutls_str_cat (char *dest, size_t dest_tot_size, const char *src); | ||
36 | |||
37 | typedef 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 | |||
47 | void _gnutls_string_init (gnutls_string *, gnutls_alloc_function, | ||
48 | gnutls_realloc_function, gnutls_free_function); | ||
49 | void _gnutls_string_clear (gnutls_string *); | ||
50 | |||
51 | /* Beware, do not clear the string, after calling this | ||
52 | * function | ||
53 | */ | ||
54 | gnutls_datum_t _gnutls_string2datum (gnutls_string * str); | ||
55 | |||
56 | int _gnutls_string_copy_str (gnutls_string * dest, const char *src); | ||
57 | int _gnutls_string_append_str (gnutls_string *, const char *str); | ||
58 | int _gnutls_string_append_data (gnutls_string *, const void *data, | ||
59 | size_t data_size); | ||
60 | int _gnutls_string_append_printf (gnutls_string * dest, const char *fmt, ...); | ||
61 | |||
62 | char *_gnutls_bin2hex (const void *old, size_t oldlen, char *buffer, | ||
63 | size_t buffer_size); | ||
64 | int _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 | |||
53 | typedef int (*supp_recv_func) (gnutls_session_t session, | ||
54 | const opaque * data, size_t data_size); | ||
55 | typedef int (*supp_send_func) (gnutls_session_t session, gnutls_buffer * buf); | ||
56 | |||
57 | typedef 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 | |||
65 | gnutls_supplemental_entry _gnutls_supplemental[] = { | ||
66 | {0, 0, 0, 0} | ||
67 | }; | ||
68 | |||
69 | const char * | ||
70 | gnutls_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 | |||
81 | static supp_recv_func | ||
82 | get_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 | |||
93 | int | ||
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 | |||
150 | int | ||
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 | |||
27 | int _gnutls_parse_supplemental (gnutls_session_t session, | ||
28 | const uint8_t *data, | ||
29 | int data_size); | ||
30 | int _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 | **/ | ||
55 | void | ||
56 | gnutls_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 | **/ | ||
75 | int | ||
76 | gnutls_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 | **/ | ||
133 | int | ||
134 | gnutls_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 | **/ | ||
190 | int | ||
191 | gnutls_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 | **/ | ||
236 | int | ||
237 | gnutls_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 | **/ | ||
275 | int | ||
276 | gnutls_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 | **/ | ||
321 | int | ||
322 | gnutls_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 | **/ | ||
342 | int | ||
343 | gnutls_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 | **/ | ||
393 | const gnutls_datum_t * | ||
394 | gnutls_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 | **/ | ||
433 | const gnutls_datum_t * | ||
434 | gnutls_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 | **/ | ||
458 | int | ||
459 | gnutls_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 | **/ | ||
491 | int | ||
492 | gnutls_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 | **/ | ||
533 | void | ||
534 | gnutls_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 | **/ | ||
550 | void | ||
551 | gnutls_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 | **/ | ||
567 | void | ||
568 | gnutls_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 | **/ | ||
585 | void | ||
586 | gnutls_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 | **/ | ||
605 | void | ||
606 | gnutls_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 | **/ | ||
622 | void | ||
623 | gnutls_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 */ | ||
45 | static 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 | */ | ||
91 | int | ||
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 | |||
25 | int _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 | */ | ||
63 | inline static int | ||
64 | check_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 | -*/ | ||
102 | int | ||
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 | */ | ||
208 | static 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 | */ | ||
256 | static int | ||
257 | parse_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 | */ | ||
291 | static int | ||
292 | parse_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 | */ | ||
330 | static int | ||
331 | parse_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 | */ | ||
453 | static int | ||
454 | parse_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 | */ | ||
561 | static int | ||
562 | read_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 | |||
611 | int | ||
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 | |||
635 | cleanup: | ||
636 | |||
637 | for (i = 0; i < src->params_size; i++) | ||
638 | { | ||
639 | _gnutls_mpi_release (&dest->params[i]); | ||
640 | } | ||
641 | return ret; | ||
642 | } | ||
643 | |||
644 | void | ||
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 | |||
657 | int | ||
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 | */ | ||
704 | static int | ||
705 | read_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 | */ | ||
744 | static int | ||
745 | read_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 | */ | ||
770 | static int | ||
771 | read_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 | **/ | ||
820 | int | ||
821 | gnutls_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 | **/ | ||
862 | int | ||
863 | gnutls_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 | **/ | ||
951 | int | ||
952 | gnutls_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 | |||
978 | static int | ||
979 | generate_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 | */ | ||
1045 | int | ||
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 | |||
1100 | static int | ||
1101 | parse_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 | */ | ||
1198 | static int | ||
1199 | parse_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 | **/ | ||
1261 | int | ||
1262 | gnutls_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 | **/ | ||
1299 | int | ||
1300 | gnutls_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 | **/ | ||
1361 | int | ||
1362 | gnutls_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 | |||
1397 | static int | ||
1398 | parse_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 | */ | ||
1482 | static int | ||
1483 | parse_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 | */ | ||
1529 | static int | ||
1530 | read_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 | **/ | ||
1577 | int | ||
1578 | gnutls_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 | **/ | ||
1604 | int | ||
1605 | gnutls_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 | **/ | ||
1657 | int | ||
1658 | gnutls_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 | |||
1692 | static int | ||
1693 | parse_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 | |||
1837 | done: | ||
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 | **/ | ||
1876 | int | ||
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 | |||
1955 | done: | ||
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 | **/ | ||
1975 | void | ||
1976 | gnutls_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 | |||
27 | int _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 | |||
39 | int _gnutls_check_key_usage (const gnutls_cert * cert, | ||
40 | gnutls_kx_algorithm_t alg); | ||
41 | |||
42 | int _gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params); | ||
43 | int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params); | ||
44 | |||
45 | int _gnutls_x509_raw_privkey_to_gkey (gnutls_privkey * privkey, | ||
46 | const gnutls_datum_t * raw_key, | ||
47 | gnutls_x509_crt_fmt_t type); | ||
48 | int _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 | |||
3 | using namespace gnutls; | ||
4 | |||
5 | inline int RETWRAP_NET(int ret) | ||
6 | { | ||
7 | if (gnutls_error_is_fatal(ret)) throw(exception(ret)); | ||
8 | else return ret; | ||
9 | } | ||
10 | |||
11 | inline int RETWRAP(int ret) | ||
12 | { | ||
13 | if (ret < 0) throw(exception(ret)); | ||
14 | return ret; | ||
15 | } | ||
16 | |||
17 | session::session( gnutls_connection_end_t end) | ||
18 | { | ||
19 | RETWRAP(gnutls_init( &this->s, end)); | ||
20 | } | ||
21 | |||
22 | session::session( session& s) | ||
23 | { | ||
24 | this->s = s.s; | ||
25 | } | ||
26 | |||
27 | session::~session() | ||
28 | { | ||
29 | gnutls_deinit( this->s); | ||
30 | } | ||
31 | |||
32 | int session::bye( gnutls_close_request_t how) | ||
33 | { | ||
34 | return RETWRAP_NET( gnutls_bye( this->s, how)); | ||
35 | } | ||
36 | |||
37 | int session::handshake () | ||
38 | { | ||
39 | return RETWRAP_NET( gnutls_handshake( this->s)); | ||
40 | } | ||
41 | |||
42 | |||
43 | server_session::server_session() : session( GNUTLS_SERVER) | ||
44 | { | ||
45 | } | ||
46 | |||
47 | int server_session::rehandshake() | ||
48 | { | ||
49 | return RETWRAP_NET( gnutls_rehandshake( this->s)); | ||
50 | } | ||
51 | |||
52 | gnutls_alert_description_t session::get_alert() const | ||
53 | { | ||
54 | return gnutls_alert_get( this->s); | ||
55 | } | ||
56 | |||
57 | int 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 | |||
63 | int session::send_appropriate_alert (int err) | ||
64 | { | ||
65 | return RETWRAP_NET(gnutls_alert_send_appropriate( this->s, err)); | ||
66 | } | ||
67 | |||
68 | gnutls_cipher_algorithm_t session::get_cipher() const | ||
69 | { | ||
70 | return gnutls_cipher_get( this->s); | ||
71 | } | ||
72 | |||
73 | gnutls_kx_algorithm_t session::get_kx () const | ||
74 | { | ||
75 | return gnutls_kx_get( this->s); | ||
76 | } | ||
77 | |||
78 | gnutls_mac_algorithm_t session::get_mac () const | ||
79 | { | ||
80 | return gnutls_mac_get( this->s); | ||
81 | } | ||
82 | |||
83 | gnutls_compression_method_t session::get_compression() const | ||
84 | { | ||
85 | return gnutls_compression_get( this->s); | ||
86 | } | ||
87 | |||
88 | gnutls_certificate_type_t session::get_certificate_type() const | ||
89 | { | ||
90 | return gnutls_certificate_type_get( this->s); | ||
91 | } | ||
92 | |||
93 | void session::set_private_extensions ( bool allow) | ||
94 | { | ||
95 | gnutls_handshake_set_private_extensions( this->s, (int)allow); | ||
96 | } | ||
97 | |||
98 | gnutls_handshake_description_t session::get_handshake_last_out() const | ||
99 | { | ||
100 | return gnutls_handshake_get_last_out( this->s); | ||
101 | } | ||
102 | |||
103 | gnutls_handshake_description_t session::get_handshake_last_in() const | ||
104 | { | ||
105 | return gnutls_handshake_get_last_in( this->s); | ||
106 | } | ||
107 | |||
108 | ssize_t session::send (const void *data, size_t sizeofdata) | ||
109 | { | ||
110 | return RETWRAP_NET(gnutls_record_send( this->s, data, sizeofdata)); | ||
111 | } | ||
112 | |||
113 | ssize_t session::recv (void *data, size_t sizeofdata) | ||
114 | { | ||
115 | return RETWRAP_NET(gnutls_record_recv( this->s, data, sizeofdata)); | ||
116 | } | ||
117 | |||
118 | bool session::get_record_direction() const | ||
119 | { | ||
120 | return gnutls_record_get_direction(this->s); | ||
121 | } | ||
122 | |||
123 | // maximum packet size | ||
124 | size_t session::get_max_size () const | ||
125 | { | ||
126 | return gnutls_record_get_max_size( this->s); | ||
127 | } | ||
128 | |||
129 | void session::set_max_size(size_t size) | ||
130 | { | ||
131 | RETWRAP( gnutls_record_set_max_size( this->s, size)); | ||
132 | } | ||
133 | |||
134 | size_t session::check_pending () const | ||
135 | { | ||
136 | return gnutls_record_check_pending( this->s); | ||
137 | } | ||
138 | |||
139 | |||
140 | void 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 | |||
149 | void 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 | |||
157 | void session::set_cipher_priority (const int *list) | ||
158 | { | ||
159 | RETWRAP( gnutls_cipher_set_priority( this->s, list)); | ||
160 | } | ||
161 | |||
162 | void session::set_mac_priority (const int *list) | ||
163 | { | ||
164 | RETWRAP( gnutls_mac_set_priority( this->s, list)); | ||
165 | } | ||
166 | |||
167 | void session::set_compression_priority (const int *list) | ||
168 | { | ||
169 | RETWRAP( gnutls_compression_set_priority( this->s, list)); | ||
170 | } | ||
171 | |||
172 | void session::set_kx_priority (const int *list) | ||
173 | { | ||
174 | RETWRAP( gnutls_kx_set_priority( this->s, list)); | ||
175 | } | ||
176 | |||
177 | void session::set_protocol_priority (const int *list) | ||
178 | { | ||
179 | RETWRAP( gnutls_protocol_set_priority( this->s, list)); | ||
180 | } | ||
181 | |||
182 | void 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 | */ | ||
190 | void session::set_priority(const char* prio, const char** err_pos) | ||
191 | { | ||
192 | RETWRAP(gnutls_priority_set_direct( this->s, prio, err_pos)); | ||
193 | } | ||
194 | |||
195 | void session::set_priority(gnutls_priority_t p) | ||
196 | { | ||
197 | RETWRAP(gnutls_priority_set( this->s, p)); | ||
198 | } | ||
199 | |||
200 | gnutls_protocol_t session::get_protocol_version() const | ||
201 | { | ||
202 | return gnutls_protocol_get_version( this->s); | ||
203 | } | ||
204 | |||
205 | void 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 | |||
211 | void 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 | |||
217 | void 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 | |||
224 | void 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 | |||
230 | bool 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 | |||
239 | bool 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 | |||
254 | bool 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 | |||
262 | void session::get_our_certificate(gnutls_datum_t& cert) const | ||
263 | { | ||
264 | const 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 | |||
272 | time_t session::get_peers_certificate_activation_time() const | ||
273 | { | ||
274 | return gnutls_certificate_activation_time_peers( this->s); | ||
275 | } | ||
276 | |||
277 | time_t session::get_peers_certificate_expiration_time() const | ||
278 | { | ||
279 | return gnutls_certificate_expiration_time_peers( this->s); | ||
280 | } | ||
281 | void session::verify_peers_certificate( unsigned int& status) const | ||
282 | { | ||
283 | RETWRAP( gnutls_certificate_verify_peers2( this->s, &status)); | ||
284 | } | ||
285 | |||
286 | |||
287 | client_session::client_session() : session( GNUTLS_CLIENT) | ||
288 | { | ||
289 | } | ||
290 | |||
291 | // client session | ||
292 | void 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 | |||
298 | bool client_session::get_request_status() | ||
299 | { | ||
300 | return RETWRAP(gnutls_certificate_client_get_request_status (this->s)); | ||
301 | } | ||
302 | |||
303 | // server_session | ||
304 | void 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 | ||
311 | static 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 | |||
324 | const static gnutls_datum_t null_datum = { NULL, 0 }; | ||
325 | |||
326 | static 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 | |||
342 | static 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 | |||
355 | void 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 | |||
363 | void server_session::set_db_cache_expiration (unsigned int seconds) | ||
364 | { | ||
365 | gnutls_db_set_cache_expiration( this->s, seconds); | ||
366 | } | ||
367 | |||
368 | void server_session::db_remove () const | ||
369 | { | ||
370 | gnutls_db_remove_session( this->s); | ||
371 | } | ||
372 | |||
373 | bool 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 | |||
381 | void session::set_max_handshake_packet_length ( size_t max) | ||
382 | { | ||
383 | gnutls_handshake_set_max_packet_length( this->s, max); | ||
384 | } | ||
385 | |||
386 | void session::clear_credentials() | ||
387 | { | ||
388 | gnutls_credentials_clear( this->s); | ||
389 | } | ||
390 | |||
391 | void session::set_credentials( credentials &cred) | ||
392 | { | ||
393 | RETWRAP(gnutls_credentials_set( this->s, cred.get_type(), cred.ptr())); | ||
394 | } | ||
395 | |||
396 | const char* server_session::get_srp_username() const | ||
397 | { | ||
398 | return gnutls_srp_server_get_username( this->s); | ||
399 | } | ||
400 | |||
401 | const char* server_session::get_psk_username() const | ||
402 | { | ||
403 | return gnutls_psk_server_get_username( this->s); | ||
404 | } | ||
405 | |||
406 | |||
407 | void session::set_transport_ptr( gnutls_transport_ptr_t ptr) | ||
408 | { | ||
409 | gnutls_transport_set_ptr( this->s, ptr); | ||
410 | } | ||
411 | |||
412 | void 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 | |||
418 | gnutls_transport_ptr_t session::get_transport_ptr () const | ||
419 | { | ||
420 | return gnutls_transport_get_ptr (this->s); | ||
421 | } | ||
422 | |||
423 | void 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 | |||
429 | void session::set_transport_lowat( size_t num) | ||
430 | { | ||
431 | gnutls_transport_set_lowat (this->s, num); | ||
432 | } | ||
433 | |||
434 | void session::set_transport_push_function( gnutls_push_func push_func) | ||
435 | { | ||
436 | gnutls_transport_set_push_function ( this->s, push_func); | ||
437 | } | ||
438 | |||
439 | void session::set_transport_pull_function( gnutls_pull_func pull_func) | ||
440 | { | ||
441 | gnutls_transport_set_pull_function ( this->s, pull_func); | ||
442 | } | ||
443 | |||
444 | void session::set_user_ptr( void* ptr) | ||
445 | { | ||
446 | gnutls_session_set_ptr( this->s, ptr); | ||
447 | } | ||
448 | |||
449 | void* session::get_user_ptr( ) const | ||
450 | { | ||
451 | return gnutls_session_get_ptr(this->s); | ||
452 | } | ||
453 | |||
454 | void session::send_openpgp_cert( gnutls_openpgp_crt_status_t status) | ||
455 | { | ||
456 | gnutls_openpgp_send_cert(this->s, status); | ||
457 | } | ||
458 | |||
459 | |||
460 | void session::set_dh_prime_bits( unsigned int bits) | ||
461 | { | ||
462 | gnutls_dh_set_prime_bits( this->s, bits); | ||
463 | } | ||
464 | |||
465 | unsigned int session::get_dh_secret_bits() const | ||
466 | { | ||
467 | return RETWRAP( gnutls_dh_get_secret_bits( this->s)); | ||
468 | } | ||
469 | |||
470 | unsigned int session::get_dh_peers_public_bits() const | ||
471 | { | ||
472 | return RETWRAP(gnutls_dh_get_peers_public_bits( this->s)); | ||
473 | } | ||
474 | |||
475 | unsigned int session::get_dh_prime_bits() const | ||
476 | { | ||
477 | return RETWRAP( gnutls_dh_get_prime_bits( this->s)); | ||
478 | } | ||
479 | |||
480 | void 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 | |||
485 | void session::get_dh_pubkey( gnutls_datum_t & raw_key) const | ||
486 | { | ||
487 | RETWRAP(gnutls_dh_get_pubkey( this->s, &raw_key)); | ||
488 | } | ||
489 | |||
490 | void 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 | |||
495 | unsigned int session::get_rsa_export_modulus_bits() const | ||
496 | { | ||
497 | return RETWRAP(gnutls_rsa_export_get_modulus_bits( this->s)); | ||
498 | } | ||
499 | |||
500 | void 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 | |||
508 | gnutls_credentials_type_t session::get_auth_type() const | ||
509 | { | ||
510 | return gnutls_auth_get_type( this->s); | ||
511 | } | ||
512 | |||
513 | gnutls_credentials_type_t session::get_server_auth_type() const | ||
514 | { | ||
515 | return gnutls_auth_server_get_type( this->s); | ||
516 | } | ||
517 | |||
518 | gnutls_credentials_type_t session::get_client_auth_type() const | ||
519 | { | ||
520 | return gnutls_auth_client_get_type( this->s); | ||
521 | } | ||
522 | |||
523 | |||
524 | void* certificate_credentials::ptr() const | ||
525 | { | ||
526 | return this->cred; | ||
527 | } | ||
528 | |||
529 | void certificate_credentials::set_ptr(void* p) | ||
530 | { | ||
531 | this->cred = static_cast<gnutls_certificate_credentials_t> (p); | ||
532 | } | ||
533 | |||
534 | certificate_credentials::~certificate_credentials() | ||
535 | { | ||
536 | gnutls_certificate_free_credentials (this->cred); | ||
537 | } | ||
538 | |||
539 | certificate_credentials::certificate_credentials() : credentials(GNUTLS_CRD_CERTIFICATE) | ||
540 | { | ||
541 | RETWRAP(gnutls_certificate_allocate_credentials ( &this->cred)); | ||
542 | } | ||
543 | |||
544 | void certificate_server_credentials::set_params_function( gnutls_params_function* func) | ||
545 | { | ||
546 | gnutls_certificate_set_params_function( this->cred, func); | ||
547 | } | ||
548 | |||
549 | anon_server_credentials::anon_server_credentials() : credentials(GNUTLS_CRD_ANON) | ||
550 | { | ||
551 | RETWRAP(gnutls_anon_allocate_server_credentials( &this->cred)); | ||
552 | } | ||
553 | |||
554 | anon_server_credentials::~anon_server_credentials() | ||
555 | { | ||
556 | gnutls_anon_free_server_credentials( this->cred); | ||
557 | } | ||
558 | |||
559 | void 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 | |||
564 | void anon_server_credentials::set_params_function ( gnutls_params_function * func) | ||
565 | { | ||
566 | gnutls_anon_set_server_params_function ( this->cred, func); | ||
567 | } | ||
568 | |||
569 | anon_client_credentials::anon_client_credentials() : credentials(GNUTLS_CRD_ANON) | ||
570 | { | ||
571 | RETWRAP(gnutls_anon_allocate_client_credentials( &this->cred)); | ||
572 | } | ||
573 | |||
574 | anon_client_credentials::~anon_client_credentials() | ||
575 | { | ||
576 | gnutls_anon_free_client_credentials( this->cred); | ||
577 | } | ||
578 | |||
579 | void certificate_credentials::free_keys () | ||
580 | { | ||
581 | gnutls_certificate_free_keys( this->cred); | ||
582 | } | ||
583 | |||
584 | void certificate_credentials::free_cas () | ||
585 | { | ||
586 | gnutls_certificate_free_cas( this->cred); | ||
587 | } | ||
588 | |||
589 | void certificate_credentials::free_ca_names () | ||
590 | { | ||
591 | gnutls_certificate_free_ca_names( this->cred); | ||
592 | } | ||
593 | |||
594 | void certificate_credentials::free_crls () | ||
595 | { | ||
596 | gnutls_certificate_free_crls( this->cred); | ||
597 | } | ||
598 | |||
599 | |||
600 | void certificate_credentials::set_dh_params ( const dh_params& params) | ||
601 | { | ||
602 | gnutls_certificate_set_dh_params( this->cred, params.get_params_t()); | ||
603 | } | ||
604 | |||
605 | void 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 | |||
610 | void certificate_credentials::set_verify_flags ( unsigned int flags) | ||
611 | { | ||
612 | gnutls_certificate_set_verify_flags( this->cred, flags); | ||
613 | } | ||
614 | |||
615 | void 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 | |||
620 | void 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 | |||
625 | void 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 | |||
631 | void 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 | |||
636 | void 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 | |||
641 | void 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 | |||
646 | void 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 | |||
651 | void 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 | |||
657 | void 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 | |||
663 | void 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 | |||
668 | void 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 | |||
673 | void 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 | |||
678 | void 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 | |||
685 | srp_server_credentials::srp_server_credentials() : credentials(GNUTLS_CRD_SRP) | ||
686 | { | ||
687 | RETWRAP(gnutls_srp_allocate_server_credentials( &this->cred)); | ||
688 | } | ||
689 | |||
690 | srp_server_credentials::~srp_server_credentials() | ||
691 | { | ||
692 | gnutls_srp_free_server_credentials( this->cred); | ||
693 | } | ||
694 | |||
695 | void* srp_server_credentials::ptr() const | ||
696 | { | ||
697 | return this->cred; | ||
698 | } | ||
699 | |||
700 | void srp_server_credentials::set_ptr(void* p) | ||
701 | { | ||
702 | this->cred = static_cast<gnutls_srp_server_credentials_t> (p); | ||
703 | } | ||
704 | |||
705 | srp_client_credentials::srp_client_credentials() : credentials(GNUTLS_CRD_SRP) | ||
706 | { | ||
707 | RETWRAP(gnutls_srp_allocate_client_credentials( &this->cred)); | ||
708 | } | ||
709 | |||
710 | srp_client_credentials::~srp_client_credentials() | ||
711 | { | ||
712 | gnutls_srp_free_client_credentials( this->cred); | ||
713 | } | ||
714 | |||
715 | void* srp_client_credentials::ptr() const | ||
716 | { | ||
717 | return this->cred; | ||
718 | } | ||
719 | |||
720 | void srp_client_credentials::set_ptr(void* p) | ||
721 | { | ||
722 | this->cred = static_cast<gnutls_srp_client_credentials_t> (p); | ||
723 | } | ||
724 | |||
725 | void 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 | |||
730 | void 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 | |||
737 | void 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 | |||
742 | void 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 | |||
747 | credentials::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. */ | ||
755 | credentials::credentials( credentials& c) | ||
756 | { | ||
757 | this->type = c.type; | ||
758 | this->set_ptr( c.ptr()); | ||
759 | } | ||
760 | #endif | ||
761 | |||
762 | gnutls_credentials_type_t credentials::get_type() const | ||
763 | { | ||
764 | return type; | ||
765 | } | ||
766 | |||
767 | exception::exception( int x) | ||
768 | { | ||
769 | retcode = x; | ||
770 | } | ||
771 | |||
772 | int exception::get_code() | ||
773 | { | ||
774 | return retcode; | ||
775 | } | ||
776 | |||
777 | const char* exception::what() const throw() | ||
778 | { | ||
779 | return gnutls_strerror(retcode); | ||
780 | } | ||
781 | |||
782 | |||
783 | |||
784 | |||
785 | dh_params::dh_params() | ||
786 | { | ||
787 | RETWRAP(gnutls_dh_params_init( ¶ms)); | ||
788 | } | ||
789 | |||
790 | dh_params::~dh_params() | ||
791 | { | ||
792 | gnutls_dh_params_deinit(params); | ||
793 | } | ||
794 | |||
795 | void 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 | |||
801 | void 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 | |||
807 | void dh_params::generate( unsigned int bits) | ||
808 | { | ||
809 | RETWRAP(gnutls_dh_params_generate2( params, bits)); | ||
810 | } | ||
811 | |||
812 | void 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 | |||
817 | void 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 | |||
822 | gnutls_dh_params_t dh_params::get_params_t() const | ||
823 | { | ||
824 | return params; | ||
825 | } | ||
826 | |||
827 | dh_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 | |||
845 | rsa_params::rsa_params() | ||
846 | { | ||
847 | RETWRAP(gnutls_rsa_params_init( ¶ms)); | ||
848 | } | ||
849 | |||
850 | rsa_params::~rsa_params() | ||
851 | { | ||
852 | gnutls_rsa_params_deinit(params); | ||
853 | } | ||
854 | |||
855 | void 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 | |||
861 | void rsa_params::generate( unsigned int bits) | ||
862 | { | ||
863 | RETWRAP(gnutls_rsa_params_generate2( params, bits)); | ||
864 | } | ||
865 | |||
866 | void 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 | |||
871 | gnutls_rsa_params_t rsa_params::get_params_t() const | ||
872 | { | ||
873 | return params; | ||
874 | } | ||
875 | |||
876 | rsa_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 | |||
890 | void 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 | |||
902 | void 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 | |||
38 | extern int errno; | ||
39 | static int initialized_rand = 0; | ||
40 | |||
41 | #define INITIALIZE_RAND if (initialized_rand==0) {\ | ||
42 | srand(time(0)); \ | ||
43 | initialized_rand = 1; \ | ||
44 | } | ||
45 | static int | ||
46 | recv_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 | |||
62 | static int | ||
63 | send_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 | |||
3 | prefix=/home/lama/workbench/programming/c/gnunet/gnutls-2.2.3/build | ||
4 | exec_prefix=${prefix} | ||
5 | exec_prefix_set=no | ||
6 | |||
7 | gnutls_libs="-L${exec_prefix}/lib -lgnutls -L/usr/lib -ltasn1 -lgcrypt " | ||
8 | gnutls_cflags=" -I/usr/include -I${prefix}/include" | ||
9 | gnutls_la_file="${exec_prefix}/lib/libgnutls.la" | ||
10 | |||
11 | usage() | ||
12 | { | ||
13 | cat <<EOF | ||
14 | Usage: libgnutls-config [OPTIONS] | ||
15 | Options: | ||
16 | [--prefix[=DIR]] | ||
17 | [--exec-prefix[=DIR]] | ||
18 | [--version] | ||
19 | [--libs] | ||
20 | [--cflags] | ||
21 | EOF | ||
22 | exit $1 | ||
23 | } | ||
24 | |||
25 | if test $# -eq 0; then | ||
26 | usage 1 1>&2 | ||
27 | fi | ||
28 | |||
29 | while 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 | ||
73 | done | ||
74 | |||
75 | if test "$echo_prefix" = "yes"; then | ||
76 | echo $prefix | ||
77 | fi | ||
78 | |||
79 | if test "$echo_exec_prefix" = "yes"; then | ||
80 | echo $exec_prefix | ||
81 | fi | ||
82 | |||
83 | if 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 | ||
93 | fi | ||
94 | |||
95 | if test "$echo_la_file" = "yes"; then | ||
96 | echo ${gnutls_la_file} | ||
97 | fi | ||
98 | |||
99 | if test "$echo_libs" = "yes"; then | ||
100 | echo ${gnutls_libs} | ||
101 | fi | ||
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 @@ | |||
1 | dnl Autoconf macros for libgnutls | ||
2 | dnl $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 | |||
9 | dnl AM_PATH_LIBGNUTLS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) | ||
10 | dnl Test for libgnutls, and define LIBGNUTLS_CFLAGS and LIBGNUTLS_LIBS | ||
11 | dnl | ||
12 | AC_DEFUN([AM_PATH_LIBGNUTLS], | ||
13 | [dnl | ||
14 | dnl Get the cflags and libraries from the libgnutls-config script | ||
15 | dnl | ||
16 | AC_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" | ||
42 | dnl | ||
43 | dnl Now check if the installed libgnutls is sufficiently new. Also sanity | ||
44 | dnl checks the results of libgnutls-config to some extent | ||
45 | dnl | ||
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 | |||
53 | int | ||
54 | main () | ||
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 | |||
160 | dnl *-*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 | |||
23 | GNUTLS_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 | |||
23 | GNUTLS_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 | |||
2 | PKIX1 { } | ||
3 | |||
4 | DEFINITIONS IMPLICIT TAGS ::= | ||
5 | |||
6 | BEGIN | ||
7 | |||
8 | -- This contains both PKIX1Implicit88 and RFC2630 ASN.1 modules. | ||
9 | |||
10 | -- ISO arc for standard certificate and CRL extensions | ||
11 | |||
12 | id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} | ||
13 | |||
14 | |||
15 | -- authority key identifier OID and syntax | ||
16 | |||
17 | id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } | ||
18 | |||
19 | AuthorityKeyIdentifier ::= 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 | |||
26 | KeyIdentifier ::= OCTET STRING | ||
27 | |||
28 | -- subject key identifier OID and syntax | ||
29 | |||
30 | id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } | ||
31 | |||
32 | SubjectKeyIdentifier ::= KeyIdentifier | ||
33 | |||
34 | -- key usage extension OID and syntax | ||
35 | |||
36 | id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } | ||
37 | |||
38 | KeyUsage ::= 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 | |||
51 | id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 } | ||
52 | |||
53 | PrivateKeyUsagePeriod ::= 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 | |||
60 | id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } | ||
61 | |||
62 | CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation | ||
63 | |||
64 | PolicyInformation ::= SEQUENCE { | ||
65 | policyIdentifier CertPolicyId, | ||
66 | policyQualifiers SEQUENCE SIZE (1..MAX) OF | ||
67 | PolicyQualifierInfo OPTIONAL } | ||
68 | |||
69 | CertPolicyId ::= OBJECT IDENTIFIER | ||
70 | |||
71 | PolicyQualifierInfo ::= 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 | |||
78 | PolicyQualifierId ::= | ||
79 | OBJECT IDENTIFIER -- ( id-qt-cps | id-qt-unotice ) | ||
80 | |||
81 | -- CPS pointer qualifier | ||
82 | |||
83 | CPSuri ::= IA5String | ||
84 | |||
85 | -- user notice qualifier | ||
86 | |||
87 | UserNotice ::= SEQUENCE { | ||
88 | noticeRef NoticeReference OPTIONAL, | ||
89 | explicitText DisplayText OPTIONAL} | ||
90 | |||
91 | NoticeReference ::= SEQUENCE { | ||
92 | organization DisplayText, | ||
93 | noticeNumbers SEQUENCE OF INTEGER } | ||
94 | |||
95 | DisplayText ::= 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 | |||
102 | id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } | ||
103 | |||
104 | PolicyMappings ::= 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 | |||
112 | DirectoryString ::= 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 | |||
123 | id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } | ||
124 | |||
125 | SubjectAltName ::= GeneralNames | ||
126 | |||
127 | GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName | ||
128 | |||
129 | GeneralName ::= 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 | |||
144 | AnotherName ::= SEQUENCE { | ||
145 | type-id OBJECT IDENTIFIER, | ||
146 | value [0] EXPLICIT ANY DEFINED BY type-id } | ||
147 | |||
148 | EDIPartyName ::= SEQUENCE { | ||
149 | nameAssigner [0] DirectoryString OPTIONAL, | ||
150 | partyName [1] DirectoryString } | ||
151 | |||
152 | -- issuer alternative name extension OID and syntax | ||
153 | |||
154 | id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } | ||
155 | |||
156 | IssuerAltName ::= GeneralNames | ||
157 | |||
158 | id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } | ||
159 | |||
160 | SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute | ||
161 | |||
162 | -- basic constraints extension OID and syntax | ||
163 | |||
164 | id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } | ||
165 | |||
166 | BasicConstraints ::= SEQUENCE { | ||
167 | cA BOOLEAN DEFAULT FALSE, | ||
168 | pathLenConstraint INTEGER (0..MAX) OPTIONAL } | ||
169 | |||
170 | -- name constraints extension OID and syntax | ||
171 | |||
172 | id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } | ||
173 | |||
174 | NameConstraints ::= SEQUENCE { | ||
175 | permittedSubtrees [0] GeneralSubtrees OPTIONAL, | ||
176 | excludedSubtrees [1] GeneralSubtrees OPTIONAL } | ||
177 | |||
178 | GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree | ||
179 | |||
180 | GeneralSubtree ::= SEQUENCE { | ||
181 | base GeneralName, | ||
182 | minimum [0] BaseDistance DEFAULT 0, | ||
183 | maximum [1] BaseDistance OPTIONAL } | ||
184 | |||
185 | BaseDistance ::= INTEGER (0..MAX) | ||
186 | |||
187 | -- policy constraints extension OID and syntax | ||
188 | |||
189 | id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } | ||
190 | |||
191 | PolicyConstraints ::= SEQUENCE { | ||
192 | requireExplicitPolicy [0] SkipCerts OPTIONAL, | ||
193 | inhibitPolicyMapping [1] SkipCerts OPTIONAL } | ||
194 | |||
195 | SkipCerts ::= INTEGER (0..MAX) | ||
196 | |||
197 | -- CRL distribution points extension OID and syntax | ||
198 | |||
199 | id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31} | ||
200 | |||
201 | CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint | ||
202 | |||
203 | DistributionPoint ::= SEQUENCE { | ||
204 | distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL, | ||
205 | reasons [1] ReasonFlags OPTIONAL, | ||
206 | cRLIssuer [2] GeneralNames OPTIONAL | ||
207 | } | ||
208 | |||
209 | DistributionPointName ::= CHOICE { | ||
210 | fullName [0] GeneralNames, | ||
211 | nameRelativeToCRLIssuer [1] RelativeDistinguishedName | ||
212 | } | ||
213 | |||
214 | ReasonFlags ::= 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 | |||
227 | id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37} | ||
228 | |||
229 | ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId | ||
230 | |||
231 | KeyPurposeId ::= OBJECT IDENTIFIER | ||
232 | |||
233 | -- extended key purpose OIDs | ||
234 | id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } | ||
235 | id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } | ||
236 | id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } | ||
237 | id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } | ||
238 | id-kp-ipsecEndSystem OBJECT IDENTIFIER ::= { id-kp 5 } | ||
239 | id-kp-ipsecTunnel OBJECT IDENTIFIER ::= { id-kp 6 } | ||
240 | id-kp-ipsecUser OBJECT IDENTIFIER ::= { id-kp 7 } | ||
241 | id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } | ||
242 | |||
243 | -- authority info access | ||
244 | |||
245 | id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 } | ||
246 | |||
247 | AuthorityInfoAccessSyntax ::= | ||
248 | SEQUENCE SIZE (1..MAX) OF AccessDescription | ||
249 | |||
250 | AccessDescription ::= SEQUENCE { | ||
251 | accessMethod OBJECT IDENTIFIER, | ||
252 | accessLocation GeneralName } | ||
253 | |||
254 | -- CRL number extension OID and syntax | ||
255 | |||
256 | id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } | ||
257 | |||
258 | CRLNumber ::= INTEGER (0..MAX) | ||
259 | |||
260 | -- issuing distribution point extension OID and syntax | ||
261 | |||
262 | id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 } | ||
263 | |||
264 | IssuingDistributionPoint ::= 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 | |||
272 | id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 } | ||
273 | |||
274 | -- deltaCRLIndicator ::= BaseCRLNumber | ||
275 | |||
276 | BaseCRLNumber ::= CRLNumber | ||
277 | |||
278 | -- CRL reasons extension OID and syntax | ||
279 | |||
280 | id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 } | ||
281 | |||
282 | CRLReason ::= 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 | |||
294 | id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 } | ||
295 | |||
296 | CertificateIssuer ::= GeneralNames | ||
297 | |||
298 | -- hold instruction extension OID and syntax | ||
299 | |||
300 | id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 } | ||
301 | |||
302 | HoldInstructionCode ::= OBJECT IDENTIFIER | ||
303 | |||
304 | -- ANSI x9 holdinstructions | ||
305 | |||
306 | -- ANSI x9 arc holdinstruction arc | ||
307 | holdInstruction 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 | ||
311 | id-holdinstruction-none OBJECT IDENTIFIER ::= | ||
312 | {holdInstruction 1} -- deprecated | ||
313 | id-holdinstruction-callissuer OBJECT IDENTIFIER ::= | ||
314 | {holdInstruction 2} | ||
315 | id-holdinstruction-reject OBJECT IDENTIFIER ::= | ||
316 | {holdInstruction 3} | ||
317 | |||
318 | -- invalidity date CRL entry extension OID and syntax | ||
319 | |||
320 | id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 } | ||
321 | |||
322 | InvalidityDate ::= 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 | |||
332 | VisibleString ::= [UNIVERSAL 26] IMPLICIT OCTET STRING | ||
333 | |||
334 | NumericString ::= [UNIVERSAL 18] IMPLICIT OCTET STRING | ||
335 | |||
336 | IA5String ::= [UNIVERSAL 22] IMPLICIT OCTET STRING | ||
337 | |||
338 | TeletexString ::= [UNIVERSAL 20] IMPLICIT OCTET STRING | ||
339 | |||
340 | PrintableString ::= [UNIVERSAL 19] IMPLICIT OCTET STRING | ||
341 | |||
342 | UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING | ||
343 | -- UniversalString is defined in ASN.1:1993 | ||
344 | |||
345 | BMPString ::= [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 | |||
349 | UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING | ||
350 | -- The content of this type conforms to RFC 2279. | ||
351 | |||
352 | |||
353 | -- PKIX specific OIDs | ||
354 | |||
355 | id-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 | |||
361 | id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } | ||
362 | -- arc for private certificate extensions | ||
363 | id-qt OBJECT IDENTIFIER ::= { id-pkix 2 } | ||
364 | -- arc for policy qualifier types | ||
365 | id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } | ||
366 | -- arc for extended key purpose OIDS | ||
367 | id-ad OBJECT IDENTIFIER ::= { id-pkix 48 } | ||
368 | -- arc for access descriptors | ||
369 | |||
370 | -- policyQualifierIds for Internet policy qualifiers | ||
371 | |||
372 | id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 } | ||
373 | -- OID for CPS qualifier | ||
374 | id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 } | ||
375 | -- OID for user notice qualifier | ||
376 | |||
377 | -- access descriptor definitions | ||
378 | |||
379 | id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } | ||
380 | id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 } | ||
381 | |||
382 | -- attribute data types -- | ||
383 | |||
384 | Attribute ::= SEQUENCE { | ||
385 | type AttributeType, | ||
386 | values SET OF AttributeValue | ||
387 | -- at least one value is required -- | ||
388 | } | ||
389 | |||
390 | AttributeType ::= OBJECT IDENTIFIER | ||
391 | |||
392 | AttributeValue ::= ANY DEFINED BY type | ||
393 | |||
394 | AttributeTypeAndValue ::= 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 | ||
406 | id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} | ||
407 | |||
408 | -- Attributes of type NameDirectoryString | ||
409 | id-at-initials AttributeType ::= { id-at 43 } | ||
410 | X520initials ::= DirectoryString | ||
411 | |||
412 | id-at-generationQualifier AttributeType ::= { id-at 44 } | ||
413 | X520generationQualifier ::= DirectoryString | ||
414 | |||
415 | id-at-surname AttributeType ::= { id-at 4 } | ||
416 | X520surName ::= DirectoryString | ||
417 | |||
418 | id-at-givenName AttributeType ::= { id-at 42 } | ||
419 | X520givenName ::= DirectoryString | ||
420 | |||
421 | id-at-name AttributeType ::= { id-at 41 } | ||
422 | X520name ::= DirectoryString | ||
423 | |||
424 | id-at-commonName AttributeType ::= {id-at 3} | ||
425 | X520CommonName ::= DirectoryString | ||
426 | |||
427 | id-at-localityName AttributeType ::= {id-at 7} | ||
428 | X520LocalityName ::= DirectoryString | ||
429 | |||
430 | id-at-stateOrProvinceName AttributeType ::= {id-at 8} | ||
431 | X520StateOrProvinceName ::= DirectoryString | ||
432 | |||
433 | id-at-organizationName AttributeType ::= {id-at 10} | ||
434 | X520OrganizationName ::= DirectoryString | ||
435 | |||
436 | id-at-organizationalUnitName AttributeType ::= {id-at 11} | ||
437 | X520OrganizationalUnitName ::= DirectoryString | ||
438 | |||
439 | id-at-title AttributeType ::= {id-at 12} | ||
440 | X520Title ::= DirectoryString | ||
441 | |||
442 | id-at-description AttributeType ::= {id-at 13} | ||
443 | X520Description ::= DirectoryString | ||
444 | |||
445 | id-at-dnQualifier AttributeType ::= {id-at 46} | ||
446 | X520dnQualifier ::= PrintableString | ||
447 | |||
448 | id-at-countryName AttributeType ::= {id-at 6} | ||
449 | X520countryName ::= PrintableString (SIZE (2)) -- IS 3166 codes | ||
450 | |||
451 | id-at-serialNumber AttributeType ::= {id-at 5} | ||
452 | X520serialNumber ::= PrintableString | ||
453 | |||
454 | id-at-telephoneNumber AttributeType ::= {id-at 20} | ||
455 | X520telephoneNumber ::= PrintableString | ||
456 | |||
457 | id-at-facsimileTelephoneNumber AttributeType ::= {id-at 23} | ||
458 | X520facsimileTelephoneNumber ::= PrintableString | ||
459 | |||
460 | id-at-pseudonym AttributeType ::= {id-at 65} | ||
461 | X520pseudonym ::= DirectoryString | ||
462 | |||
463 | id-at-name AttributeType ::= {id-at 41} | ||
464 | X520name ::= DirectoryString | ||
465 | |||
466 | id-at-streetAddress AttributeType ::= {id-at 9} | ||
467 | X520streetAddress ::= DirectoryString | ||
468 | |||
469 | id-at-postalAddress AttributeType ::= {id-at 16} | ||
470 | X520postalAddress ::= PostalAddress | ||
471 | |||
472 | PostalAddress ::= SEQUENCE OF DirectoryString | ||
473 | |||
474 | |||
475 | -- Legacy attributes | ||
476 | |||
477 | pkcs OBJECT IDENTIFIER ::= | ||
478 | { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) } | ||
479 | |||
480 | pkcs-9 OBJECT IDENTIFIER ::= | ||
481 | { pkcs 9 } | ||
482 | |||
483 | |||
484 | emailAddress AttributeType ::= { pkcs-9 1 } | ||
485 | |||
486 | Pkcs9email ::= IA5String (SIZE (1..ub-emailaddress-length)) | ||
487 | |||
488 | -- naming data types -- | ||
489 | |||
490 | Name ::= CHOICE { -- only one possibility for now -- | ||
491 | rdnSequence RDNSequence } | ||
492 | |||
493 | RDNSequence ::= SEQUENCE OF RelativeDistinguishedName | ||
494 | |||
495 | DistinguishedName ::= RDNSequence | ||
496 | |||
497 | RelativeDistinguishedName ::= | ||
498 | SET SIZE (1 .. MAX) OF AttributeTypeAndValue | ||
499 | |||
500 | |||
501 | |||
502 | -- -------------------------------------------------------- | ||
503 | -- certificate and CRL specific structures begin here | ||
504 | -- -------------------------------------------------------- | ||
505 | |||
506 | Certificate ::= SEQUENCE { | ||
507 | tbsCertificate TBSCertificate, | ||
508 | signatureAlgorithm AlgorithmIdentifier, | ||
509 | signature BIT STRING } | ||
510 | |||
511 | TBSCertificate ::= 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 | |||
527 | Version ::= INTEGER { v1(0), v2(1), v3(2) } | ||
528 | |||
529 | CertificateSerialNumber ::= INTEGER | ||
530 | |||
531 | Validity ::= SEQUENCE { | ||
532 | notBefore Time, | ||
533 | notAfter Time } | ||
534 | |||
535 | Time ::= CHOICE { | ||
536 | utcTime UTCTime, | ||
537 | generalTime GeneralizedTime } | ||
538 | |||
539 | UniqueIdentifier ::= BIT STRING | ||
540 | |||
541 | SubjectPublicKeyInfo ::= SEQUENCE { | ||
542 | algorithm AlgorithmIdentifier, | ||
543 | subjectPublicKey BIT STRING } | ||
544 | |||
545 | Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension | ||
546 | |||
547 | Extension ::= SEQUENCE { | ||
548 | extnID OBJECT IDENTIFIER, | ||
549 | critical BOOLEAN DEFAULT FALSE, | ||
550 | extnValue OCTET STRING } | ||
551 | |||
552 | |||
553 | -- ------------------------------------------ | ||
554 | -- CRL structures | ||
555 | -- ------------------------------------------ | ||
556 | |||
557 | CertificateList ::= SEQUENCE { | ||
558 | tbsCertList TBSCertList, | ||
559 | signatureAlgorithm AlgorithmIdentifier, | ||
560 | signature BIT STRING } | ||
561 | |||
562 | TBSCertList ::= 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 | |||
582 | AlgorithmIdentifier ::= 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 | |||
591 | pkcs-1 OBJECT IDENTIFIER ::= { | ||
592 | pkcs 1 } | ||
593 | |||
594 | rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } | ||
595 | |||
596 | md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } | ||
597 | |||
598 | md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } | ||
599 | |||
600 | sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } | ||
601 | |||
602 | id-dsa-with-sha1 OBJECT IDENTIFIER ::= { | ||
603 | iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 } | ||
604 | |||
605 | Dss-Sig-Value ::= SEQUENCE { | ||
606 | r INTEGER, | ||
607 | s INTEGER | ||
608 | } | ||
609 | |||
610 | dhpublicnumber OBJECT IDENTIFIER ::= { | ||
611 | iso(1) member-body(2) us(840) ansi-x942(10046) number-type(2) 1 } | ||
612 | |||
613 | DomainParameters ::= 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 | |||
620 | ValidationParms ::= SEQUENCE { | ||
621 | seed BIT STRING, | ||
622 | pgenCounter INTEGER } | ||
623 | |||
624 | id-dsa OBJECT IDENTIFIER ::= { | ||
625 | iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 } | ||
626 | |||
627 | Dss-Parms ::= SEQUENCE { | ||
628 | p INTEGER, | ||
629 | q INTEGER, | ||
630 | g INTEGER } | ||
631 | |||
632 | -- x400 address syntax starts here | ||
633 | -- OR Names | ||
634 | |||
635 | ORAddress ::= 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 | |||
648 | BuiltInStandardAttributes ::= 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 | |||
664 | CountryName ::= [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 | |||
670 | AdministrationDomainName ::= [APPLICATION 2] EXPLICIT CHOICE { | ||
671 | numeric NumericString (SIZE (0..ub-domain-name-length)), | ||
672 | printable PrintableString (SIZE (0..ub-domain-name-length)) } | ||
673 | |||
674 | NetworkAddress ::= X121Address -- see also extended-network-address | ||
675 | |||
676 | X121Address ::= NumericString (SIZE (1..ub-x121-address-length)) | ||
677 | |||
678 | TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length)) | ||
679 | |||
680 | PrivateDomainName ::= CHOICE { | ||
681 | numeric NumericString (SIZE (1..ub-domain-name-length)), | ||
682 | printable PrintableString (SIZE (1..ub-domain-name-length)) } | ||
683 | |||
684 | OrganizationName ::= PrintableString | ||
685 | (SIZE (1..ub-organization-name-length)) | ||
686 | -- see also teletex-organization-name | ||
687 | |||
688 | NumericUserIdentifier ::= NumericString | ||
689 | (SIZE (1..ub-numeric-user-id-length)) | ||
690 | |||
691 | PersonalName ::= 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 | |||
700 | OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) | ||
701 | OF OrganizationalUnitName | ||
702 | -- see also teletex-organizational-unit-names | ||
703 | |||
704 | OrganizationalUnitName ::= PrintableString (SIZE | ||
705 | (1..ub-organizational-unit-name-length)) | ||
706 | |||
707 | -- Built-in Domain-defined Attributes | ||
708 | |||
709 | BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE | ||
710 | (1..ub-domain-defined-attributes) OF | ||
711 | BuiltInDomainDefinedAttribute | ||
712 | |||
713 | BuiltInDomainDefinedAttribute ::= 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 | |||
721 | ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF | ||
722 | ExtensionAttribute | ||
723 | |||
724 | ExtensionAttribute ::= 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 | |||
732 | common-name INTEGER ::= 1 | ||
733 | |||
734 | CommonName ::= PrintableString (SIZE (1..ub-common-name-length)) | ||
735 | |||
736 | teletex-common-name INTEGER ::= 2 | ||
737 | |||
738 | TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length)) | ||
739 | |||
740 | teletex-organization-name INTEGER ::= 3 | ||
741 | |||
742 | TeletexOrganizationName ::= | ||
743 | TeletexString (SIZE (1..ub-organization-name-length)) | ||
744 | |||
745 | teletex-personal-name INTEGER ::= 4 | ||
746 | |||
747 | TeletexPersonalName ::= 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 | |||
755 | teletex-organizational-unit-names INTEGER ::= 5 | ||
756 | |||
757 | TeletexOrganizationalUnitNames ::= SEQUENCE SIZE | ||
758 | (1..ub-organizational-units) OF TeletexOrganizationalUnitName | ||
759 | |||
760 | TeletexOrganizationalUnitName ::= TeletexString | ||
761 | (SIZE (1..ub-organizational-unit-name-length)) | ||
762 | |||
763 | pds-name INTEGER ::= 7 | ||
764 | |||
765 | PDSName ::= PrintableString (SIZE (1..ub-pds-name-length)) | ||
766 | |||
767 | physical-delivery-country-name INTEGER ::= 8 | ||
768 | |||
769 | PhysicalDeliveryCountryName ::= 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 | |||
774 | postal-code INTEGER ::= 9 | ||
775 | |||
776 | PostalCode ::= CHOICE { | ||
777 | numeric-code NumericString (SIZE (1..ub-postal-code-length)), | ||
778 | printable-code PrintableString (SIZE (1..ub-postal-code-length)) } | ||
779 | |||
780 | physical-delivery-office-name INTEGER ::= 10 | ||
781 | |||
782 | PhysicalDeliveryOfficeName ::= PDSParameter | ||
783 | |||
784 | physical-delivery-office-number INTEGER ::= 11 | ||
785 | |||
786 | PhysicalDeliveryOfficeNumber ::= PDSParameter | ||
787 | |||
788 | extension-OR-address-components INTEGER ::= 12 | ||
789 | |||
790 | ExtensionORAddressComponents ::= PDSParameter | ||
791 | |||
792 | physical-delivery-personal-name INTEGER ::= 13 | ||
793 | |||
794 | PhysicalDeliveryPersonalName ::= PDSParameter | ||
795 | |||
796 | physical-delivery-organization-name INTEGER ::= 14 | ||
797 | |||
798 | PhysicalDeliveryOrganizationName ::= PDSParameter | ||
799 | |||
800 | extension-physical-delivery-address-components INTEGER ::= 15 | ||
801 | |||
802 | ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter | ||
803 | |||
804 | unformatted-postal-address INTEGER ::= 16 | ||
805 | |||
806 | UnformattedPostalAddress ::= 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 | |||
812 | street-address INTEGER ::= 17 | ||
813 | |||
814 | StreetAddress ::= PDSParameter | ||
815 | |||
816 | post-office-box-address INTEGER ::= 18 | ||
817 | |||
818 | PostOfficeBoxAddress ::= PDSParameter | ||
819 | |||
820 | poste-restante-address INTEGER ::= 19 | ||
821 | |||
822 | PosteRestanteAddress ::= PDSParameter | ||
823 | |||
824 | unique-postal-name INTEGER ::= 20 | ||
825 | |||
826 | UniquePostalName ::= PDSParameter | ||
827 | |||
828 | local-postal-attributes INTEGER ::= 21 | ||
829 | |||
830 | LocalPostalAttributes ::= PDSParameter | ||
831 | |||
832 | PDSParameter ::= 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 | |||
838 | extended-network-address INTEGER ::= 22 | ||
839 | |||
840 | ExtendedNetworkAddress ::= 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 | |||
847 | PresentationAddress ::= 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 | |||
853 | terminal-type INTEGER ::= 23 | ||
854 | |||
855 | TerminalType ::= 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 | |||
865 | teletex-domain-defined-attributes INTEGER ::= 6 | ||
866 | |||
867 | TeletexDomainDefinedAttributes ::= SEQUENCE SIZE | ||
868 | (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute | ||
869 | |||
870 | TeletexDomainDefinedAttribute ::= 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 | ||
881 | ub-name INTEGER ::= 32768 | ||
882 | ub-common-name INTEGER ::= 64 | ||
883 | ub-locality-name INTEGER ::= 128 | ||
884 | ub-state-name INTEGER ::= 128 | ||
885 | ub-organization-name INTEGER ::= 64 | ||
886 | ub-organizational-unit-name INTEGER ::= 64 | ||
887 | ub-title INTEGER ::= 64 | ||
888 | ub-match INTEGER ::= 128 | ||
889 | |||
890 | ub-emailaddress-length INTEGER ::= 128 | ||
891 | |||
892 | ub-common-name-length INTEGER ::= 64 | ||
893 | ub-country-name-alpha-length INTEGER ::= 2 | ||
894 | ub-country-name-numeric-length INTEGER ::= 3 | ||
895 | ub-domain-defined-attributes INTEGER ::= 4 | ||
896 | ub-domain-defined-attribute-type-length INTEGER ::= 8 | ||
897 | ub-domain-defined-attribute-value-length INTEGER ::= 128 | ||
898 | ub-domain-name-length INTEGER ::= 16 | ||
899 | ub-extension-attributes INTEGER ::= 256 | ||
900 | ub-e163-4-number-length INTEGER ::= 15 | ||
901 | ub-e163-4-sub-address-length INTEGER ::= 40 | ||
902 | ub-generation-qualifier-length INTEGER ::= 3 | ||
903 | ub-given-name-length INTEGER ::= 16 | ||
904 | ub-initials-length INTEGER ::= 5 | ||
905 | ub-integer-options INTEGER ::= 256 | ||
906 | ub-numeric-user-id-length INTEGER ::= 32 | ||
907 | ub-organization-name-length INTEGER ::= 64 | ||
908 | ub-organizational-unit-name-length INTEGER ::= 32 | ||
909 | ub-organizational-units INTEGER ::= 4 | ||
910 | ub-pds-name-length INTEGER ::= 16 | ||
911 | ub-pds-parameter-length INTEGER ::= 30 | ||
912 | ub-pds-physical-address-lines INTEGER ::= 6 | ||
913 | ub-postal-code-length INTEGER ::= 16 | ||
914 | ub-surname-length INTEGER ::= 40 | ||
915 | ub-terminal-id-length INTEGER ::= 24 | ||
916 | ub-unformatted-address-length INTEGER ::= 180 | ||
917 | ub-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 | |||
936 | pkcs-7-ContentInfo ::= SEQUENCE { | ||
937 | contentType pkcs-7-ContentType, | ||
938 | content [0] EXPLICIT ANY DEFINED BY contentType } | ||
939 | |||
940 | pkcs-7-DigestInfo ::= SEQUENCE { | ||
941 | digestAlgorithm pkcs-7-DigestAlgorithmIdentifier, | ||
942 | digest pkcs-7-Digest | ||
943 | } | ||
944 | |||
945 | pkcs-7-Digest ::= OCTET STRING | ||
946 | |||
947 | pkcs-7-ContentType ::= OBJECT IDENTIFIER | ||
948 | |||
949 | pkcs-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 | |||
958 | pkcs-7-CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4) } | ||
959 | |||
960 | pkcs-7-DigestAlgorithmIdentifiers ::= SET OF pkcs-7-DigestAlgorithmIdentifier | ||
961 | |||
962 | pkcs-7-DigestAlgorithmIdentifier ::= AlgorithmIdentifier | ||
963 | |||
964 | pkcs-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. | ||
970 | pkcs-7-CertificateRevocationLists ::= SET OF ANY | ||
971 | |||
972 | pkcs-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 | |||
979 | pkcs-7-CertificateSet ::= SET OF pkcs-7-CertificateChoices | ||
980 | |||
981 | pkcs-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 | ||
988 | pkcs-10-CertificationRequestInfo ::= SEQUENCE { | ||
989 | version INTEGER { v1(0) }, | ||
990 | subject Name, | ||
991 | subjectPKInfo SubjectPublicKeyInfo, | ||
992 | attributes [0] Attributes | ||
993 | } | ||
994 | |||
995 | Attributes ::= SET OF Attribute | ||
996 | |||
997 | pkcs-10-CertificationRequest ::= SEQUENCE { | ||
998 | certificationRequestInfo pkcs-10-CertificationRequestInfo, | ||
999 | signatureAlgorithm AlgorithmIdentifier, | ||
1000 | signature BIT STRING | ||
1001 | } | ||
1002 | |||
1003 | -- stuff from PKCS#9 | ||
1004 | |||
1005 | pkcs-9-ub-challengePassword INTEGER ::= 255 | ||
1006 | |||
1007 | pkcs-9-certTypes OBJECT IDENTIFIER ::= {pkcs-9 22} | ||
1008 | pkcs-9-crlTypes OBJECT IDENTIFIER ::= {pkcs-9 23} | ||
1009 | |||
1010 | pkcs-9-at-challengePassword OBJECT IDENTIFIER ::= {pkcs-9 7} | ||
1011 | |||
1012 | pkcs-9-challengePassword ::= CHOICE { | ||
1013 | printableString PrintableString (SIZE (1..pkcs-9-ub-challengePassword)), | ||
1014 | utf8String UTF8String (SIZE (1..pkcs-9-ub-challengePassword)) } | ||
1015 | |||
1016 | pkcs-9-at-localKeyId OBJECT IDENTIFIER ::= {pkcs-9 21} | ||
1017 | |||
1018 | pkcs-9-localKeyId ::= OCTET STRING | ||
1019 | |||
1020 | pkcs-9-at-friendlyName OBJECT IDENTIFIER ::= {pkcs-9 20} | ||
1021 | |||
1022 | pkcs-9-friendlyName ::= BMPString (SIZE (1..255)) | ||
1023 | |||
1024 | -- PKCS #8 stuff | ||
1025 | |||
1026 | -- Private-key information syntax | ||
1027 | |||
1028 | pkcs-8-PrivateKeyInfo ::= SEQUENCE { | ||
1029 | version pkcs-8-Version, | ||
1030 | privateKeyAlgorithm AlgorithmIdentifier, | ||
1031 | privateKey pkcs-8-PrivateKey, | ||
1032 | attributes [0] Attributes OPTIONAL } | ||
1033 | |||
1034 | pkcs-8-Version ::= INTEGER {v1(0)} | ||
1035 | |||
1036 | pkcs-8-PrivateKey ::= OCTET STRING | ||
1037 | |||
1038 | pkcs-8-Attributes ::= SET OF Attribute | ||
1039 | |||
1040 | -- Encrypted private-key information syntax | ||
1041 | |||
1042 | pkcs-8-EncryptedPrivateKeyInfo ::= SEQUENCE { | ||
1043 | encryptionAlgorithm AlgorithmIdentifier, | ||
1044 | encryptedData pkcs-8-EncryptedData | ||
1045 | } | ||
1046 | |||
1047 | pkcs-8-EncryptedData ::= OCTET STRING | ||
1048 | |||
1049 | -- PKCS #5 stuff | ||
1050 | |||
1051 | pkcs-5 OBJECT IDENTIFIER ::= | ||
1052 | { pkcs 5 } | ||
1053 | |||
1054 | pkcs-5-encryptionAlgorithm OBJECT IDENTIFIER ::= | ||
1055 | { iso(1) member-body(2) us(840) rsadsi(113549) 3 } | ||
1056 | |||
1057 | pkcs-5-des-EDE3-CBC OBJECT IDENTIFIER ::= {pkcs-5-encryptionAlgorithm 7} | ||
1058 | |||
1059 | pkcs-5-des-EDE3-CBC-params ::= OCTET STRING (SIZE(8)) | ||
1060 | |||
1061 | pkcs-5-id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} | ||
1062 | |||
1063 | pkcs-5-PBES2-params ::= SEQUENCE { | ||
1064 | keyDerivationFunc AlgorithmIdentifier, | ||
1065 | encryptionScheme AlgorithmIdentifier } | ||
1066 | |||
1067 | -- PBKDF2 | ||
1068 | |||
1069 | pkcs-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 | |||
1076 | pkcs-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 | |||
1088 | pkcs-12 OBJECT IDENTIFIER ::= {pkcs 12} | ||
1089 | |||
1090 | pkcs-12-PFX ::= SEQUENCE { | ||
1091 | version INTEGER {v3(3)}, | ||
1092 | authSafe pkcs-7-ContentInfo, | ||
1093 | macData pkcs-12-MacData OPTIONAL | ||
1094 | } | ||
1095 | |||
1096 | pkcs-12-PbeParams ::= SEQUENCE { | ||
1097 | salt OCTET STRING, | ||
1098 | iterations INTEGER | ||
1099 | } | ||
1100 | |||
1101 | pkcs-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 | |||
1109 | pkcs-12-AuthenticatedSafe ::= SEQUENCE OF pkcs-7-ContentInfo | ||
1110 | -- Data if unencrypted | ||
1111 | -- EncryptedData if password-encrypted | ||
1112 | -- EnvelopedData if public key-encrypted | ||
1113 | |||
1114 | pkcs-12-SafeContents ::= SEQUENCE OF pkcs-12-SafeBag | ||
1115 | |||
1116 | pkcs-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 | |||
1125 | pkcs-12-bagtypes OBJECT IDENTIFIER ::= {pkcs-12 10 1} | ||
1126 | |||
1127 | pkcs-12-keyBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 1} | ||
1128 | pkcs-12-pkcs8ShroudedKeyBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 2} | ||
1129 | pkcs-12-certBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 3} | ||
1130 | pkcs-12-crlBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 4} | ||
1131 | |||
1132 | pkcs-12-KeyBag ::= pkcs-8-PrivateKeyInfo | ||
1133 | |||
1134 | -- Shrouded KeyBag | ||
1135 | |||
1136 | pkcs-12-PKCS8ShroudedKeyBag ::= pkcs-8-EncryptedPrivateKeyInfo | ||
1137 | |||
1138 | -- CertBag | ||
1139 | |||
1140 | pkcs-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 | |||
1148 | pkcs-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 | |||
1157 | pkcs-12-PKCS12Attribute ::= Attribute | ||
1158 | |||
1159 | -- PKCS #7 stuff (needed in PKCS 12) | ||
1160 | |||
1161 | pkcs-7-data OBJECT IDENTIFIER ::= { iso(1) member-body(2) | ||
1162 | us(840) rsadsi(113549) pkcs(1) pkcs7(7) 1 } | ||
1163 | |||
1164 | pkcs-7-encryptedData OBJECT IDENTIFIER ::= { iso(1) member-body(2) | ||
1165 | us(840) rsadsi(113549) pkcs(1) pkcs7(7) 6 } | ||
1166 | |||
1167 | pkcs-7-Data ::= OCTET STRING | ||
1168 | |||
1169 | pkcs-7-EncryptedData ::= SEQUENCE { | ||
1170 | version pkcs-7-CMSVersion, | ||
1171 | encryptedContentInfo pkcs-7-EncryptedContentInfo, | ||
1172 | unprotectedAttrs [1] IMPLICIT pkcs-7-UnprotectedAttributes OPTIONAL } | ||
1173 | |||
1174 | pkcs-7-EncryptedContentInfo ::= SEQUENCE { | ||
1175 | contentType pkcs-7-ContentType, | ||
1176 | contentEncryptionAlgorithm pkcs-7-ContentEncryptionAlgorithmIdentifier, | ||
1177 | encryptedContent [0] IMPLICIT pkcs-7-EncryptedContent OPTIONAL } | ||
1178 | |||
1179 | pkcs-7-ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier | ||
1180 | |||
1181 | pkcs-7-EncryptedContent ::= OCTET STRING | ||
1182 | |||
1183 | pkcs-7-UnprotectedAttributes ::= SET SIZE (1..MAX) OF Attribute | ||
1184 | |||
1185 | -- LDAP stuff | ||
1186 | -- may not be correct | ||
1187 | |||
1188 | id-at-ldap-DC AttributeType ::= { 0 9 2342 19200300 100 1 25 } | ||
1189 | |||
1190 | ldap-DC ::= IA5String | ||
1191 | |||
1192 | id-at-ldap-UID AttributeType ::= { 0 9 2342 19200300 100 1 1 } | ||
1193 | |||
1194 | ldap-UID ::= DirectoryString | ||
1195 | |||
1196 | -- rfc3039 | ||
1197 | |||
1198 | id-pda OBJECT IDENTIFIER ::= { id-pkix 9 } | ||
1199 | |||
1200 | id-pda-dateOfBirth AttributeType ::= { id-pda 1 } | ||
1201 | DateOfBirth ::= GeneralizedTime | ||
1202 | |||
1203 | id-pda-placeOfBirth AttributeType ::= { id-pda 2 } | ||
1204 | PlaceOfBirth ::= DirectoryString | ||
1205 | |||
1206 | id-pda-gender AttributeType ::= { id-pda 3 } | ||
1207 | Gender ::= PrintableString (SIZE(1)) | ||
1208 | -- "M", "F", "m" or "f" | ||
1209 | |||
1210 | id-pda-countryOfCitizenship AttributeType ::= { id-pda 4 } | ||
1211 | CountryOfCitizenship ::= PrintableString (SIZE (2)) | ||
1212 | -- ISO 3166 Country Code | ||
1213 | |||
1214 | id-pda-countryOfResidence AttributeType ::= { id-pda 5 } | ||
1215 | CountryOfResidence ::= PrintableString (SIZE (2)) | ||
1216 | -- ISO 3166 Country Code | ||
1217 | |||
1218 | -- rfc3820 | ||
1219 | |||
1220 | id-pe-proxyCertInfo OBJECT IDENTIFIER ::= { id-pe 14 } | ||
1221 | |||
1222 | id-ppl-inheritAll OBJECT IDENTIFIER ::= { id-pkix 21 1 } | ||
1223 | id-ppl-independent OBJECT IDENTIFIER ::= { id-pkix 21 2 } | ||
1224 | |||
1225 | ProxyCertInfo ::= SEQUENCE { | ||
1226 | pCPathLenConstraint INTEGER (0..MAX) OPTIONAL, | ||
1227 | proxyPolicy ProxyPolicy } | ||
1228 | |||
1229 | ProxyPolicy ::= SEQUENCE { | ||
1230 | policyLanguage OBJECT IDENTIFIER, | ||
1231 | policy OCTET STRING OPTIONAL } | ||
1232 | |||
1233 | -- rfc3920 section 5.1.1 | ||
1234 | |||
1235 | id-on OBJECT IDENTIFIER ::= { id-pkix 8 } -- other name forms | ||
1236 | |||
1237 | id-on-xmppAddr OBJECT IDENTIFIER ::= { id-on 5 } | ||
1238 | |||
1239 | XmppAddr ::= UTF8String | ||
1240 | |||
1241 | END | ||
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 | |||
7 | extern 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 | |||
33 | static const uint8_t b64table[] = | ||
34 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
35 | |||
36 | static 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 | |||
61 | inline static int | ||
62 | encode (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) | ||
109 | inline static int | ||
110 | decode (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 | */ | ||
144 | int | ||
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 | */ | ||
186 | int | ||
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 | **/ | ||
304 | int | ||
305 | gnutls_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 | **/ | ||
344 | int | ||
345 | gnutls_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 | */ | ||
368 | int | ||
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 | */ | ||
400 | inline static int | ||
401 | cpydata (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" | ||
426 | int | ||
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 | **/ | ||
536 | int | ||
537 | gnutls_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 | **/ | ||
580 | int | ||
581 | gnutls_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 | |||
25 | int _gnutls_base64_encode (const uint8_t * data, size_t data_size, | ||
26 | uint8_t ** result); | ||
27 | int _gnutls_fbase64_encode (const char *msg, const uint8_t * data, | ||
28 | int data_size, uint8_t ** result); | ||
29 | int _gnutls_base64_decode (const uint8_t * data, size_t data_size, | ||
30 | uint8_t ** result); | ||
31 | int _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)) | ||