aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/tls/auth_dhe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/tls/auth_dhe.c')
-rw-r--r--src/daemon/https/tls/auth_dhe.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/src/daemon/https/tls/auth_dhe.c b/src/daemon/https/tls/auth_dhe.c
new file mode 100644
index 00000000..fa535e55
--- /dev/null
+++ b/src/daemon/https/tls/auth_dhe.c
@@ -0,0 +1,277 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains everything for the Ephemeral Diffie Hellman (DHE)
26 * key exchange. This is used in the handshake procedure of the certificate
27 * authentication.
28 */
29
30#include "gnutls_int.h"
31#include "gnutls_auth_int.h"
32#include "gnutls_errors.h"
33#include "gnutls_dh.h"
34#include "gnutls_num.h"
35#include "gnutls_sig.h"
36#include <gnutls_datum.h>
37#include <auth_cert.h>
38#include <gnutls_x509.h>
39#include <gnutls_state.h>
40#include <auth_dh_common.h>
41
42static int gen_dhe_server_kx (MHD_gtls_session_t, opaque **);
43static int proc_dhe_server_kx (MHD_gtls_session_t, opaque *, size_t);
44static int proc_dhe_client_kx (MHD_gtls_session_t, opaque *, size_t);
45
46const MHD_gtls_mod_auth_st MHD_gtls_dhe_rsa_auth_struct = {
47 "DHE_RSA",
48 MHD_gtls_gen_cert_server_certificate,
49 MHD_gtls_gen_cert_client_certificate,
50 gen_dhe_server_kx,
51 MHD_gtls_gen_dh_common_client_kx,
52 MHD_gtls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
53 MHD_gtls_gen_cert_server_cert_req, /* server cert request */
54
55 MHD_gtls_proc_cert_server_certificate,
56 MHD__gnutls_proc_cert_client_certificate,
57 proc_dhe_server_kx,
58 proc_dhe_client_kx,
59 MHD_gtls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
60 MHD_gtls_proc_cert_cert_req /* proc server cert request */
61};
62
63const MHD_gtls_mod_auth_st MHD_gtls_dhe_dss_auth_struct = {
64 "DHE_DSS",
65 MHD_gtls_gen_cert_server_certificate,
66 MHD_gtls_gen_cert_client_certificate,
67 gen_dhe_server_kx,
68 MHD_gtls_gen_dh_common_client_kx,
69 MHD_gtls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
70 MHD_gtls_gen_cert_server_cert_req, /* server cert request */
71
72 MHD_gtls_proc_cert_server_certificate,
73 MHD__gnutls_proc_cert_client_certificate,
74 proc_dhe_server_kx,
75 proc_dhe_client_kx,
76 MHD_gtls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
77 MHD_gtls_proc_cert_cert_req /* proc server cert request */
78};
79
80
81static int
82gen_dhe_server_kx (MHD_gtls_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 MHD_gnutls_cert *apr_cert_list;
89 MHD_gnutls_privkey *apr_pkey;
90 int apr_cert_list_length;
91 MHD_gnutls_datum_t signature, ddata;
92 MHD_gtls_cert_credentials_t cred;
93 MHD_gtls_dh_params_t dh_params;
94
95 cred = (MHD_gtls_cert_credentials_t)
96 MHD_gtls_get_cred (session->key, MHD_GNUTLS_CRD_CERTIFICATE, NULL);
97 if (cred == NULL)
98 {
99 MHD_gnutls_assert ();
100 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
101 }
102
103 bits = MHD_gtls_dh_get_allowed_prime_bits (session);
104
105 /* find the appropriate certificate */
106 if ((ret =
107 MHD_gtls_get_selected_cert (session, &apr_cert_list,
108 &apr_cert_list_length, &apr_pkey)) < 0)
109 {
110 MHD_gnutls_assert ();
111 return ret;
112 }
113
114 dh_params =
115 MHD_gtls_get_dh_params (cred->dh_params, cred->params_func, session);
116 mpis = MHD_gtls_dh_params_to_mpi (dh_params);
117 if (mpis == NULL)
118 {
119 MHD_gnutls_assert ();
120 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
121 }
122
123 p = mpis[0];
124 g = mpis[1];
125
126 if ((ret = MHD_gtls_auth_info_set (session, MHD_GNUTLS_CRD_CERTIFICATE,
127 sizeof (cert_auth_info_st), 0)) < 0)
128 {
129 MHD_gnutls_assert ();
130 return ret;
131 }
132
133 MHD_gtls_dh_set_group (session, g, p);
134
135 ret = MHD_gtls_dh_common_print_server_kx (session, g, p, data, 0);
136 if (ret < 0)
137 {
138 MHD_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 MHD_gtls_tls_sign_params (session, &apr_cert_list[0],
152 apr_pkey, &ddata, &signature)) < 0)
153 {
154 MHD_gnutls_assert ();
155 MHD_gnutls_free (*data);
156 return ret;
157 }
158 }
159 else
160 {
161 MHD_gnutls_assert ();
162 return data_size; /* do not put a signature - ILLEGAL! */
163 }
164
165 *data = MHD_gtls_realloc_fast (*data, data_size + signature.size + 2);
166 if (*data == NULL)
167 {
168 MHD__gnutls_free_datum (&signature);
169 MHD_gnutls_assert ();
170 return GNUTLS_E_MEMORY_ERROR;
171 }
172
173 MHD_gtls_write_datum16 (&(*data)[data_size], signature);
174 data_size += signature.size + 2;
175
176 MHD__gnutls_free_datum (&signature);
177
178 return data_size;
179}
180
181static int
182proc_dhe_server_kx (MHD_gtls_session_t session, opaque * data,
183 size_t _data_size)
184{
185 int sigsize;
186 MHD_gnutls_datum_t vparams, signature;
187 int ret;
188 cert_auth_info_t info = MHD_gtls_get_auth_info (session);
189 ssize_t data_size = _data_size;
190 MHD_gnutls_cert peer_cert;
191
192 if (info == NULL || info->ncerts == 0)
193 {
194 MHD_gnutls_assert ();
195 /* we need this in order to get peer's certificate */
196 return GNUTLS_E_INTERNAL_ERROR;
197 }
198
199 ret = MHD_gtls_proc_dh_common_server_kx (session, data, _data_size, 0);
200 if (ret < 0)
201 {
202 MHD_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 = MHD_gtls_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 MHD_gtls_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 MHD_gnutls_assert ();
225 return ret;
226 }
227
228 ret =
229 MHD_gtls_verify_sig_params (session, &peer_cert, &vparams, &signature);
230
231 MHD_gtls_gcert_deinit (&peer_cert);
232 if (ret < 0)
233 {
234 MHD_gnutls_assert ();
235 return ret;
236 }
237
238 return ret;
239}
240
241
242
243static int
244proc_dhe_client_kx (MHD_gtls_session_t session, opaque * data,
245 size_t _data_size)
246{
247 MHD_gtls_cert_credentials_t cred;
248 int ret;
249 mpi_t p, g;
250 const mpi_t *mpis;
251 MHD_gtls_dh_params_t dh_params;
252
253 cred = (MHD_gtls_cert_credentials_t)
254 MHD_gtls_get_cred (session->key, MHD_GNUTLS_CRD_CERTIFICATE, NULL);
255 if (cred == NULL)
256 {
257 MHD_gnutls_assert ();
258 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
259 }
260
261 dh_params =
262 MHD_gtls_get_dh_params (cred->dh_params, cred->params_func, session);
263 mpis = MHD_gtls_dh_params_to_mpi (dh_params);
264 if (mpis == NULL)
265 {
266 MHD_gnutls_assert ();
267 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
268 }
269
270 p = mpis[0];
271 g = mpis[1];
272
273 ret = MHD_gtls_proc_dh_common_client_kx (session, data, _data_size, g, p);
274
275 return ret;
276
277}