aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/tls/auth_dh_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/tls/auth_dh_common.c')
-rw-r--r--src/daemon/https/tls/auth_dh_common.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/daemon/https/tls/auth_dh_common.c b/src/daemon/https/tls/auth_dh_common.c
index 0957f81b..8fc6e391 100644
--- a/src/daemon/https/tls/auth_dh_common.c
+++ b/src/daemon/https/tls/auth_dh_common.c
@@ -50,3 +50,278 @@ MHD_gtls_free_dh_info (MHD_gtls_dh_info_st * dh)
50 MHD__gnutls_free_datum (&dh->public_key); 50 MHD__gnutls_free_datum (&dh->public_key);
51} 51}
52 52
53int
54MHD_gtls_proc_dh_common_client_kx (MHD_gtls_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 = MHD_gtls_read_uint16 (&data[0]);
66 _n_Y = n_Y;
67
68 DECR_LEN (data_size, n_Y);
69 if (MHD_gtls_mpi_scan_nz (&session->key->client_Y, &data[2], &_n_Y))
70 {
71 MHD_gnutls_assert ();
72 return GNUTLS_E_MPI_SCAN_FAILED;
73 }
74
75 MHD_gtls_dh_set_peer_public (session, session->key->client_Y);
76
77 session->key->KEY =
78 MHD_gtls_calc_dh_key (session->key->client_Y, session->key->dh_secret, p);
79
80 if (session->key->KEY == NULL)
81 {
82 MHD_gnutls_assert ();
83 return GNUTLS_E_MEMORY_ERROR;
84 }
85
86 MHD_gtls_mpi_release (&session->key->client_Y);
87 MHD_gtls_mpi_release (&session->key->dh_secret);
88
89 ret = MHD_gtls_mpi_dprint (&session->key->key, session->key->KEY);
90
91 MHD_gtls_mpi_release (&session->key->KEY);
92
93 if (ret < 0)
94 {
95 return ret;
96 }
97
98 return 0;
99}
100
101int
102MHD_gtls_gen_dh_common_client_kx (MHD_gtls_session_t session, opaque ** data)
103{
104 mpi_t x = NULL, X = NULL;
105 size_t n_X;
106 int ret;
107
108 *data = NULL;
109
110 X = MHD_gtls_calc_dh_secret (&x, session->key->client_g,
111 session->key->client_p);
112 if (X == NULL || x == NULL)
113 {
114 MHD_gnutls_assert ();
115 ret = GNUTLS_E_MEMORY_ERROR;
116 goto error;
117 }
118
119 MHD_gtls_dh_set_secret_bits (session, MHD__gnutls_mpi_get_nbits (x));
120
121 MHD_gtls_mpi_print (NULL, &n_X, X);
122 (*data) = MHD_gnutls_malloc (n_X + 2);
123 if (*data == NULL)
124 {
125 ret = GNUTLS_E_MEMORY_ERROR;
126 goto error;
127 }
128
129 MHD_gtls_mpi_print (&(*data)[2], &n_X, X);
130 MHD_gtls_mpi_release (&X);
131
132 MHD_gtls_write_uint16 (n_X, &(*data)[0]);
133
134 /* calculate the key after calculating the message */
135 session->key->KEY =
136 MHD_gtls_calc_dh_key (session->key->client_Y, x, session->key->client_p);
137
138 MHD_gtls_mpi_release (&x);
139 if (session->key->KEY == NULL)
140 {
141 MHD_gnutls_assert ();
142 ret = GNUTLS_E_MEMORY_ERROR;
143 goto error;
144 }
145
146 /* THESE SHOULD BE DISCARDED */
147 MHD_gtls_mpi_release (&session->key->client_Y);
148 MHD_gtls_mpi_release (&session->key->client_p);
149 MHD_gtls_mpi_release (&session->key->client_g);
150
151 ret = MHD_gtls_mpi_dprint (&session->key->key, session->key->KEY);
152
153 MHD_gtls_mpi_release (&session->key->KEY);
154
155 if (ret < 0)
156 {
157 MHD_gnutls_assert ();
158 goto error;
159 }
160
161 return n_X + 2;
162
163error:
164 MHD_gtls_mpi_release (&x);
165 MHD_gtls_mpi_release (&X);
166 MHD_gnutls_free (*data);
167 *data = NULL;
168 return ret;
169}
170
171int
172MHD_gtls_proc_dh_common_server_kx (MHD_gtls_session_t session,
173 opaque * data, size_t _data_size, int psk)
174{
175 uint16_t n_Y, n_g, n_p;
176 size_t _n_Y, _n_g, _n_p;
177 uint8_t *data_p;
178 uint8_t *data_g;
179 uint8_t *data_Y;
180 int i, bits, psk_size, ret;
181 ssize_t data_size = _data_size;
182
183 i = 0;
184
185 if (psk != 0)
186 {
187 DECR_LEN (data_size, 2);
188 psk_size = MHD_gtls_read_uint16 (&data[i]);
189 DECR_LEN (data_size, psk_size);
190 i += 2 + psk_size;
191 }
192
193 DECR_LEN (data_size, 2);
194 n_p = MHD_gtls_read_uint16 (&data[i]);
195 i += 2;
196
197 DECR_LEN (data_size, n_p);
198 data_p = &data[i];
199 i += n_p;
200
201 DECR_LEN (data_size, 2);
202 n_g = MHD_gtls_read_uint16 (&data[i]);
203 i += 2;
204
205 DECR_LEN (data_size, n_g);
206 data_g = &data[i];
207 i += n_g;
208
209 DECR_LEN (data_size, 2);
210 n_Y = MHD_gtls_read_uint16 (&data[i]);
211 i += 2;
212
213 DECR_LEN (data_size, n_Y);
214 data_Y = &data[i];
215 i += n_Y;
216
217 _n_Y = n_Y;
218 _n_g = n_g;
219 _n_p = n_p;
220
221 if (MHD_gtls_mpi_scan_nz (&session->key->client_Y, data_Y, &_n_Y) != 0)
222 {
223 MHD_gnutls_assert ();
224 return GNUTLS_E_MPI_SCAN_FAILED;
225 }
226
227 if (MHD_gtls_mpi_scan_nz (&session->key->client_g, data_g, &_n_g) != 0)
228 {
229 MHD_gnutls_assert ();
230 return GNUTLS_E_MPI_SCAN_FAILED;
231 }
232 if (MHD_gtls_mpi_scan_nz (&session->key->client_p, data_p, &_n_p) != 0)
233 {
234 MHD_gnutls_assert ();
235 return GNUTLS_E_MPI_SCAN_FAILED;
236 }
237
238 bits = MHD_gtls_dh_get_allowed_prime_bits (session);
239 if (bits < 0)
240 {
241 MHD_gnutls_assert ();
242 return bits;
243 }
244
245 if (MHD__gnutls_mpi_get_nbits (session->key->client_p) < (size_t) bits)
246 {
247 /* the prime used by the peer is not acceptable
248 */
249 MHD_gnutls_assert ();
250 return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
251 }
252
253 MHD_gtls_dh_set_group (session, session->key->client_g,
254 session->key->client_p);
255 MHD_gtls_dh_set_peer_public (session, session->key->client_Y);
256
257 ret = n_Y + n_p + n_g + 6;
258 if (psk != 0)
259 ret += 2;
260
261 return ret;
262}
263
264/* If the psk flag is set, then an empty psk_identity_hint will
265 * be inserted */
266int
267MHD_gtls_dh_common_print_server_kx (MHD_gtls_session_t session,
268 mpi_t g, mpi_t p, opaque ** data, int psk)
269{
270 mpi_t x, X;
271 size_t n_X, n_g, n_p;
272 int ret, data_size, pos;
273 uint8_t *pdata;
274
275 X = MHD_gtls_calc_dh_secret (&x, g, p);
276 if (X == NULL || x == NULL)
277 {
278 MHD_gnutls_assert ();
279 return GNUTLS_E_MEMORY_ERROR;
280 }
281
282 session->key->dh_secret = x;
283 MHD_gtls_dh_set_secret_bits (session, MHD__gnutls_mpi_get_nbits (x));
284
285 MHD_gtls_mpi_print (NULL, &n_g, g);
286 MHD_gtls_mpi_print (NULL, &n_p, p);
287 MHD_gtls_mpi_print (NULL, &n_X, X);
288
289 data_size = n_g + n_p + n_X + 6;
290 if (psk != 0)
291 data_size += 2;
292
293 (*data) = MHD_gnutls_malloc (data_size);
294 if (*data == NULL)
295 {
296 MHD_gtls_mpi_release (&X);
297 return GNUTLS_E_MEMORY_ERROR;
298 }
299
300 pos = 0;
301 pdata = *data;
302
303 if (psk != 0)
304 {
305 MHD_gtls_write_uint16 (0, &pdata[pos]);
306 pos += 2;
307 }
308
309 MHD_gtls_mpi_print (&pdata[pos + 2], &n_p, p);
310 MHD_gtls_write_uint16 (n_p, &pdata[pos]);
311
312 pos += n_p + 2;
313
314 MHD_gtls_mpi_print (&pdata[pos + 2], &n_g, g);
315 MHD_gtls_write_uint16 (n_g, &pdata[pos]);
316
317 pos += n_g + 2;
318
319 MHD_gtls_mpi_print (&pdata[pos + 2], &n_X, X);
320 MHD_gtls_mpi_release (&X);
321
322 MHD_gtls_write_uint16 (n_X, &pdata[pos]);
323
324 ret = data_size;
325
326 return ret;
327}