blob: 23d0b8156849f428a34c0e1957aa3e5a5a9906ce [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002 * TLS v1.0/v1.1/v1.2 server (RFC 2246, RFC 4346, RFC 5246)
Dmitry Shmidt818ea482014-03-10 13:15:21 -07003 * Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 */
8
9#include "includes.h"
10
11#include "common.h"
12#include "crypto/sha1.h"
13#include "crypto/tls.h"
14#include "tlsv1_common.h"
15#include "tlsv1_record.h"
16#include "tlsv1_server.h"
17#include "tlsv1_server_i.h"
18
19/* TODO:
20 * Support for a message fragmented across several records (RFC 2246, 6.2.1)
21 */
22
23
Dmitry Shmidt818ea482014-03-10 13:15:21 -070024void tlsv1_server_log(struct tlsv1_server *conn, const char *fmt, ...)
25{
26 va_list ap;
27 char *buf;
28 int buflen;
29
30 va_start(ap, fmt);
31 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
32 va_end(ap);
33
34 buf = os_malloc(buflen);
35 if (buf == NULL)
36 return;
37 va_start(ap, fmt);
38 vsnprintf(buf, buflen, fmt, ap);
39 va_end(ap);
40
41 wpa_printf(MSG_DEBUG, "TLSv1: %s", buf);
42 if (conn->log_cb)
43 conn->log_cb(conn->log_cb_ctx, buf);
44
45 os_free(buf);
46}
47
48
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070049void tlsv1_server_alert(struct tlsv1_server *conn, u8 level, u8 description)
50{
51 conn->alert_level = level;
52 conn->alert_description = description;
53}
54
55
56int tlsv1_server_derive_keys(struct tlsv1_server *conn,
57 const u8 *pre_master_secret,
58 size_t pre_master_secret_len)
59{
60 u8 seed[2 * TLS_RANDOM_LEN];
61 u8 key_block[TLS_MAX_KEY_BLOCK_LEN];
62 u8 *pos;
63 size_t key_block_len;
64
65 if (pre_master_secret) {
66 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: pre_master_secret",
67 pre_master_secret, pre_master_secret_len);
68 os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
69 os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
70 TLS_RANDOM_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080071 if (tls_prf(conn->rl.tls_version,
72 pre_master_secret, pre_master_secret_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070073 "master secret", seed, 2 * TLS_RANDOM_LEN,
74 conn->master_secret, TLS_MASTER_SECRET_LEN)) {
75 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive "
76 "master_secret");
77 return -1;
78 }
79 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret",
80 conn->master_secret, TLS_MASTER_SECRET_LEN);
81 }
82
83 os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
84 os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN);
85 key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len +
86 conn->rl.iv_size);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080087 if (tls_prf(conn->rl.tls_version,
88 conn->master_secret, TLS_MASTER_SECRET_LEN,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070089 "key expansion", seed, 2 * TLS_RANDOM_LEN,
90 key_block, key_block_len)) {
91 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block");
92 return -1;
93 }
94 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: key_block",
95 key_block, key_block_len);
96
97 pos = key_block;
98
99 /* client_write_MAC_secret */
100 os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size);
101 pos += conn->rl.hash_size;
102 /* server_write_MAC_secret */
103 os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size);
104 pos += conn->rl.hash_size;
105
106 /* client_write_key */
107 os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len);
108 pos += conn->rl.key_material_len;
109 /* server_write_key */
110 os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len);
111 pos += conn->rl.key_material_len;
112
113 /* client_write_IV */
114 os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size);
115 pos += conn->rl.iv_size;
116 /* server_write_IV */
117 os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size);
118 pos += conn->rl.iv_size;
119
120 return 0;
121}
122
123
124/**
125 * tlsv1_server_handshake - Process TLS handshake
126 * @conn: TLSv1 server connection data from tlsv1_server_init()
127 * @in_data: Input data from TLS peer
128 * @in_len: Input data length
129 * @out_len: Length of the output buffer.
130 * Returns: Pointer to output data, %NULL on failure
131 */
132u8 * tlsv1_server_handshake(struct tlsv1_server *conn,
133 const u8 *in_data, size_t in_len,
134 size_t *out_len)
135{
136 const u8 *pos, *end;
137 u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct;
138 size_t in_msg_len;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800139 int used;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700140
141 if (in_data == NULL || in_len == 0) {
142 wpa_printf(MSG_DEBUG, "TLSv1: No input data to server");
143 return NULL;
144 }
145
146 pos = in_data;
147 end = in_data + in_len;
148 in_msg = os_malloc(in_len);
149 if (in_msg == NULL)
150 return NULL;
151
152 /* Each received packet may include multiple records */
153 while (pos < end) {
154 in_msg_len = in_len;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800155 used = tlsv1_record_receive(&conn->rl, pos, end - pos,
156 in_msg, &in_msg_len, &alert);
157 if (used < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700158 wpa_printf(MSG_DEBUG, "TLSv1: Processing received "
159 "record failed");
160 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
161 goto failed;
162 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800163 if (used == 0) {
164 /* need more data */
165 wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
166 "yet supported");
167 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
168 goto failed;
169 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700170 ct = pos[0];
171
172 in_pos = in_msg;
173 in_end = in_msg + in_msg_len;
174
175 /* Each received record may include multiple messages of the
176 * same ContentType. */
177 while (in_pos < in_end) {
178 in_msg_len = in_end - in_pos;
179 if (tlsv1_server_process_handshake(conn, ct, in_pos,
180 &in_msg_len) < 0)
181 goto failed;
182 in_pos += in_msg_len;
183 }
184
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800185 pos += used;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700186 }
187
188 os_free(in_msg);
189 in_msg = NULL;
190
191 msg = tlsv1_server_handshake_write(conn, out_len);
192
193failed:
194 os_free(in_msg);
195 if (conn->alert_level) {
196 if (conn->state == FAILED) {
197 /* Avoid alert loops */
198 wpa_printf(MSG_DEBUG, "TLSv1: Drop alert loop");
199 os_free(msg);
200 return NULL;
201 }
202 conn->state = FAILED;
203 os_free(msg);
204 msg = tlsv1_server_send_alert(conn, conn->alert_level,
205 conn->alert_description,
206 out_len);
207 }
208
209 return msg;
210}
211
212
213/**
214 * tlsv1_server_encrypt - Encrypt data into TLS tunnel
215 * @conn: TLSv1 server connection data from tlsv1_server_init()
216 * @in_data: Pointer to plaintext data to be encrypted
217 * @in_len: Input buffer length
218 * @out_data: Pointer to output buffer (encrypted TLS data)
219 * @out_len: Maximum out_data length
220 * Returns: Number of bytes written to out_data, -1 on failure
221 *
222 * This function is used after TLS handshake has been completed successfully to
223 * send data in the encrypted tunnel.
224 */
225int tlsv1_server_encrypt(struct tlsv1_server *conn,
226 const u8 *in_data, size_t in_len,
227 u8 *out_data, size_t out_len)
228{
229 size_t rlen;
230
231 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
232 in_data, in_len);
233
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700234 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800235 out_data, out_len, in_data, in_len, &rlen) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700236 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
237 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
238 TLS_ALERT_INTERNAL_ERROR);
239 return -1;
240 }
241
242 return rlen;
243}
244
245
246/**
247 * tlsv1_server_decrypt - Decrypt data from TLS tunnel
248 * @conn: TLSv1 server connection data from tlsv1_server_init()
249 * @in_data: Pointer to input buffer (encrypted TLS data)
250 * @in_len: Input buffer length
251 * @out_data: Pointer to output buffer (decrypted data from TLS tunnel)
252 * @out_len: Maximum out_data length
253 * Returns: Number of bytes written to out_data, -1 on failure
254 *
255 * This function is used after TLS handshake has been completed successfully to
256 * receive data from the encrypted tunnel.
257 */
258int tlsv1_server_decrypt(struct tlsv1_server *conn,
259 const u8 *in_data, size_t in_len,
260 u8 *out_data, size_t out_len)
261{
262 const u8 *in_end, *pos;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800263 int used;
264 u8 alert, *out_end, *out_pos, ct;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700265 size_t olen;
266
267 pos = in_data;
268 in_end = in_data + in_len;
269 out_pos = out_data;
270 out_end = out_data + out_len;
271
272 while (pos < in_end) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800273 ct = pos[0];
274 olen = out_end - out_pos;
275 used = tlsv1_record_receive(&conn->rl, pos, in_end - pos,
276 out_pos, &olen, &alert);
277 if (used < 0) {
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700278 tlsv1_server_log(conn, "Record layer processing failed");
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800279 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
280 return -1;
281 }
282 if (used == 0) {
283 /* need more data */
284 wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
285 "yet supported");
286 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
287 return -1;
288 }
289
290 if (ct == TLS_CONTENT_TYPE_ALERT) {
291 if (olen < 2) {
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700292 tlsv1_server_log(conn, "Alert underflow");
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800293 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
294 TLS_ALERT_DECODE_ERROR);
295 return -1;
296 }
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700297 tlsv1_server_log(conn, "Received alert %d:%d",
298 out_pos[0], out_pos[1]);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800299 if (out_pos[0] == TLS_ALERT_LEVEL_WARNING) {
300 /* Continue processing */
301 pos += used;
302 continue;
303 }
304
305 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
306 out_pos[1]);
307 return -1;
308 }
309
310 if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700311 tlsv1_server_log(conn, "Unexpected content type 0x%x",
312 pos[0]);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700313 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
314 TLS_ALERT_UNEXPECTED_MESSAGE);
315 return -1;
316 }
317
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700318#ifdef CONFIG_TESTING_OPTIONS
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700319 if ((conn->test_flags &
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700320 (TLS_BREAK_VERIFY_DATA | TLS_BREAK_SRV_KEY_X_HASH |
321 TLS_BREAK_SRV_KEY_X_SIGNATURE)) &&
322 !conn->test_failure_reported) {
323 tlsv1_server_log(conn, "TEST-FAILURE: Client ApplData received after invalid handshake");
324 conn->test_failure_reported = 1;
325 }
326#endif /* CONFIG_TESTING_OPTIONS */
327
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700328 out_pos += olen;
329 if (out_pos > out_end) {
330 wpa_printf(MSG_DEBUG, "TLSv1: Buffer not large enough "
331 "for processing the received record");
332 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
333 TLS_ALERT_INTERNAL_ERROR);
334 return -1;
335 }
336
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800337 pos += used;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700338 }
339
340 return out_pos - out_data;
341}
342
343
344/**
345 * tlsv1_server_global_init - Initialize TLSv1 server
346 * Returns: 0 on success, -1 on failure
347 *
348 * This function must be called before using any other TLSv1 server functions.
349 */
350int tlsv1_server_global_init(void)
351{
352 return crypto_global_init();
353}
354
355
356/**
357 * tlsv1_server_global_deinit - Deinitialize TLSv1 server
358 *
359 * This function can be used to deinitialize the TLSv1 server that was
360 * initialized by calling tlsv1_server_global_init(). No TLSv1 server functions
361 * can be called after this before calling tlsv1_server_global_init() again.
362 */
363void tlsv1_server_global_deinit(void)
364{
365 crypto_global_deinit();
366}
367
368
369/**
370 * tlsv1_server_init - Initialize TLSv1 server connection
371 * @cred: Pointer to server credentials from tlsv1_server_cred_alloc()
372 * Returns: Pointer to TLSv1 server connection data or %NULL on failure
373 */
374struct tlsv1_server * tlsv1_server_init(struct tlsv1_credentials *cred)
375{
376 struct tlsv1_server *conn;
377 size_t count;
378 u16 *suites;
379
380 conn = os_zalloc(sizeof(*conn));
381 if (conn == NULL)
382 return NULL;
383
384 conn->cred = cred;
385
386 conn->state = CLIENT_HELLO;
387
388 if (tls_verify_hash_init(&conn->verify) < 0) {
389 wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize verify "
390 "hash");
391 os_free(conn);
392 return NULL;
393 }
394
395 count = 0;
396 suites = conn->cipher_suites;
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700397 suites[count++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
398 suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
399 suites[count++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700400 suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700401 suites[count++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
402 suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
403 suites[count++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700404 suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700405 suites[count++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700406 suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
407 suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
408 suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
409 conn->num_cipher_suites = count;
410
411 return conn;
412}
413
414
415static void tlsv1_server_clear_data(struct tlsv1_server *conn)
416{
417 tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
418 tlsv1_record_change_write_cipher(&conn->rl);
419 tlsv1_record_change_read_cipher(&conn->rl);
420 tls_verify_hash_free(&conn->verify);
421
422 crypto_public_key_free(conn->client_rsa_key);
423 conn->client_rsa_key = NULL;
424
425 os_free(conn->session_ticket);
426 conn->session_ticket = NULL;
427 conn->session_ticket_len = 0;
428 conn->use_session_ticket = 0;
429
430 os_free(conn->dh_secret);
431 conn->dh_secret = NULL;
432 conn->dh_secret_len = 0;
433}
434
435
436/**
437 * tlsv1_server_deinit - Deinitialize TLSv1 server connection
438 * @conn: TLSv1 server connection data from tlsv1_server_init()
439 */
440void tlsv1_server_deinit(struct tlsv1_server *conn)
441{
442 tlsv1_server_clear_data(conn);
443 os_free(conn);
444}
445
446
447/**
448 * tlsv1_server_established - Check whether connection has been established
449 * @conn: TLSv1 server connection data from tlsv1_server_init()
450 * Returns: 1 if connection is established, 0 if not
451 */
452int tlsv1_server_established(struct tlsv1_server *conn)
453{
454 return conn->state == ESTABLISHED;
455}
456
457
458/**
459 * tlsv1_server_prf - Use TLS-PRF to derive keying material
460 * @conn: TLSv1 server connection data from tlsv1_server_init()
461 * @label: Label (e.g., description of the key) for PRF
462 * @server_random_first: seed is 0 = client_random|server_random,
463 * 1 = server_random|client_random
464 * @out: Buffer for output data from TLS-PRF
465 * @out_len: Length of the output buffer
466 * Returns: 0 on success, -1 on failure
467 */
468int tlsv1_server_prf(struct tlsv1_server *conn, const char *label,
469 int server_random_first, u8 *out, size_t out_len)
470{
471 u8 seed[2 * TLS_RANDOM_LEN];
472
473 if (conn->state != ESTABLISHED)
474 return -1;
475
476 if (server_random_first) {
477 os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
478 os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random,
479 TLS_RANDOM_LEN);
480 } else {
481 os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
482 os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
483 TLS_RANDOM_LEN);
484 }
485
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800486 return tls_prf(conn->rl.tls_version,
487 conn->master_secret, TLS_MASTER_SECRET_LEN,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700488 label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
489}
490
491
492/**
493 * tlsv1_server_get_cipher - Get current cipher name
494 * @conn: TLSv1 server connection data from tlsv1_server_init()
495 * @buf: Buffer for the cipher name
496 * @buflen: buf size
497 * Returns: 0 on success, -1 on failure
498 *
499 * Get the name of the currently used cipher.
500 */
501int tlsv1_server_get_cipher(struct tlsv1_server *conn, char *buf,
502 size_t buflen)
503{
504 char *cipher;
505
506 switch (conn->rl.cipher_suite) {
507 case TLS_RSA_WITH_RC4_128_MD5:
508 cipher = "RC4-MD5";
509 break;
510 case TLS_RSA_WITH_RC4_128_SHA:
511 cipher = "RC4-SHA";
512 break;
513 case TLS_RSA_WITH_DES_CBC_SHA:
514 cipher = "DES-CBC-SHA";
515 break;
516 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
517 cipher = "DES-CBC3-SHA";
518 break;
519 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
520 cipher = "ADH-AES-128-SHA";
521 break;
522 case TLS_RSA_WITH_AES_256_CBC_SHA:
523 cipher = "AES-256-SHA";
524 break;
525 case TLS_RSA_WITH_AES_128_CBC_SHA:
526 cipher = "AES-128-SHA";
527 break;
528 default:
529 return -1;
530 }
531
532 if (os_strlcpy(buf, cipher, buflen) >= buflen)
533 return -1;
534 return 0;
535}
536
537
538/**
539 * tlsv1_server_shutdown - Shutdown TLS connection
540 * @conn: TLSv1 server connection data from tlsv1_server_init()
541 * Returns: 0 on success, -1 on failure
542 */
543int tlsv1_server_shutdown(struct tlsv1_server *conn)
544{
545 conn->state = CLIENT_HELLO;
546
547 if (tls_verify_hash_init(&conn->verify) < 0) {
548 wpa_printf(MSG_DEBUG, "TLSv1: Failed to re-initialize verify "
549 "hash");
550 return -1;
551 }
552
553 tlsv1_server_clear_data(conn);
554
555 return 0;
556}
557
558
559/**
560 * tlsv1_server_resumed - Was session resumption used
561 * @conn: TLSv1 server connection data from tlsv1_server_init()
562 * Returns: 1 if current session used session resumption, 0 if not
563 */
564int tlsv1_server_resumed(struct tlsv1_server *conn)
565{
566 return 0;
567}
568
569
570/**
571 * tlsv1_server_get_keys - Get master key and random data from TLS connection
572 * @conn: TLSv1 server connection data from tlsv1_server_init()
573 * @keys: Structure of key/random data (filled on success)
574 * Returns: 0 on success, -1 on failure
575 */
576int tlsv1_server_get_keys(struct tlsv1_server *conn, struct tls_keys *keys)
577{
578 os_memset(keys, 0, sizeof(*keys));
579 if (conn->state == CLIENT_HELLO)
580 return -1;
581
582 keys->client_random = conn->client_random;
583 keys->client_random_len = TLS_RANDOM_LEN;
584
585 if (conn->state != SERVER_HELLO) {
586 keys->server_random = conn->server_random;
587 keys->server_random_len = TLS_RANDOM_LEN;
588 keys->master_key = conn->master_secret;
589 keys->master_key_len = TLS_MASTER_SECRET_LEN;
590 }
591
592 return 0;
593}
594
595
596/**
597 * tlsv1_server_get_keyblock_size - Get TLS key_block size
598 * @conn: TLSv1 server connection data from tlsv1_server_init()
599 * Returns: Size of the key_block for the negotiated cipher suite or -1 on
600 * failure
601 */
602int tlsv1_server_get_keyblock_size(struct tlsv1_server *conn)
603{
604 if (conn->state == CLIENT_HELLO || conn->state == SERVER_HELLO)
605 return -1;
606
607 return 2 * (conn->rl.hash_size + conn->rl.key_material_len +
608 conn->rl.iv_size);
609}
610
611
612/**
613 * tlsv1_server_set_cipher_list - Configure acceptable cipher suites
614 * @conn: TLSv1 server connection data from tlsv1_server_init()
615 * @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers
616 * (TLS_CIPHER_*).
617 * Returns: 0 on success, -1 on failure
618 */
619int tlsv1_server_set_cipher_list(struct tlsv1_server *conn, u8 *ciphers)
620{
621 size_t count;
622 u16 *suites;
623
624 /* TODO: implement proper configuration of cipher suites */
625 if (ciphers[0] == TLS_CIPHER_ANON_DH_AES128_SHA) {
626 count = 0;
627 suites = conn->cipher_suites;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700628 suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700629 suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
630 suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
631 suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
632 suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700633 suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700634 suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
635 suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
636 suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
637 suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA;
638 conn->num_cipher_suites = count;
639 }
640
641 return 0;
642}
643
644
645int tlsv1_server_set_verify(struct tlsv1_server *conn, int verify_peer)
646{
647 conn->verify_peer = verify_peer;
648 return 0;
649}
650
651
652void tlsv1_server_set_session_ticket_cb(struct tlsv1_server *conn,
653 tlsv1_server_session_ticket_cb cb,
654 void *ctx)
655{
656 wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback set %p (ctx %p)",
657 cb, ctx);
658 conn->session_ticket_cb = cb;
659 conn->session_ticket_cb_ctx = ctx;
660}
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700661
662
663void tlsv1_server_set_log_cb(struct tlsv1_server *conn,
664 void (*cb)(void *ctx, const char *msg), void *ctx)
665{
666 conn->log_cb = cb;
667 conn->log_cb_ctx = ctx;
668}
669
670
671#ifdef CONFIG_TESTING_OPTIONS
672void tlsv1_server_set_test_flags(struct tlsv1_server *conn, u32 flags)
673{
674 conn->test_flags = flags;
675}
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700676
677
678static const u8 test_tls_prime15[1] = {
679 15
680};
681
682static const u8 test_tls_prime511b[64] = {
683 0x50, 0xfb, 0xf1, 0xae, 0x01, 0xf1, 0xfe, 0xe6,
684 0xe1, 0xae, 0xdc, 0x1e, 0xbe, 0xfb, 0x9e, 0x58,
685 0x9a, 0xd7, 0x54, 0x9d, 0x6b, 0xb3, 0x78, 0xe2,
686 0x39, 0x7f, 0x30, 0x01, 0x25, 0xa1, 0xf9, 0x7c,
687 0x55, 0x0e, 0xa1, 0x15, 0xcc, 0x36, 0x34, 0xbb,
688 0x6c, 0x8b, 0x64, 0x45, 0x15, 0x7f, 0xd3, 0xe7,
689 0x31, 0xc8, 0x8e, 0x56, 0x8e, 0x95, 0xdc, 0xea,
690 0x9e, 0xdf, 0xf7, 0x56, 0xdd, 0xb0, 0x34, 0xdb
691};
692
693static const u8 test_tls_prime767b[96] = {
694 0x4c, 0xdc, 0xb8, 0x21, 0x20, 0x9d, 0xe8, 0xa3,
695 0x53, 0xd9, 0x1c, 0x18, 0xc1, 0x3a, 0x58, 0x67,
696 0xa7, 0x85, 0xf9, 0x28, 0x9b, 0xce, 0xc0, 0xd1,
697 0x05, 0x84, 0x61, 0x97, 0xb2, 0x86, 0x1c, 0xd0,
698 0xd1, 0x96, 0x23, 0x29, 0x8c, 0xc5, 0x30, 0x68,
699 0x3e, 0xf9, 0x05, 0xba, 0x60, 0xeb, 0xdb, 0xee,
700 0x2d, 0xdf, 0x84, 0x65, 0x49, 0x87, 0x90, 0x2a,
701 0xc9, 0x8e, 0x34, 0x63, 0x6d, 0x9a, 0x2d, 0x32,
702 0x1c, 0x46, 0xd5, 0x4e, 0x20, 0x20, 0x90, 0xac,
703 0xd5, 0x48, 0x79, 0x99, 0x0c, 0xe6, 0xed, 0xbf,
704 0x79, 0xc2, 0x47, 0x50, 0x95, 0x38, 0x38, 0xbc,
705 0xde, 0xb0, 0xd2, 0xe8, 0x97, 0xcb, 0x22, 0xbb
706};
707
708static const u8 test_tls_prime58[128] = {
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724 0x03, 0xc1, 0xba, 0xc8, 0x25, 0xbe, 0x2d, 0xf3
725};
726
727static const u8 test_tls_non_prime[] = {
728 /*
729 * This is not a prime and the value has the following factors:
730 * 13736783488716579923 * 16254860191773456563 * 18229434976173670763 *
731 * 11112313018289079419 * 10260802278580253339 * 12394009491575311499 *
732 * 12419059668711064739 * 14317973192687985827 * 10498605410533203179 *
733 * 16338688760390249003 * 11128963991123878883 * 12990532258280301419 *
734 * 3
735 */
736 0x0C, 0x8C, 0x36, 0x9C, 0x6F, 0x71, 0x2E, 0xA7,
737 0xAB, 0x32, 0xD3, 0x0F, 0x68, 0x3D, 0xB2, 0x6D,
738 0x81, 0xDD, 0xC4, 0x84, 0x0D, 0x9C, 0x6E, 0x36,
739 0x29, 0x70, 0xF3, 0x1E, 0x9A, 0x42, 0x0B, 0x67,
740 0x82, 0x6B, 0xB1, 0xF2, 0xAF, 0x55, 0x28, 0xE7,
741 0xDB, 0x67, 0x6C, 0xF7, 0x6B, 0xAC, 0xAC, 0xE5,
742 0xF7, 0x9F, 0xD4, 0x63, 0x55, 0x70, 0x32, 0x7C,
743 0x70, 0xFB, 0xAF, 0xB8, 0xEB, 0x37, 0xCF, 0x3F,
744 0xFE, 0x94, 0x73, 0xF9, 0x7A, 0xC7, 0x12, 0x2E,
745 0x9B, 0xB4, 0x7D, 0x08, 0x60, 0x83, 0x43, 0x52,
746 0x83, 0x1E, 0xA5, 0xFC, 0xFA, 0x87, 0x12, 0xF4,
747 0x64, 0xE2, 0xCE, 0x71, 0x17, 0x72, 0xB6, 0xAB
748};
749
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700750#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700751
752
753void tlsv1_server_get_dh_p(struct tlsv1_server *conn, const u8 **dh_p,
754 size_t *dh_p_len)
755{
756 *dh_p = conn->cred->dh_p;
757 *dh_p_len = conn->cred->dh_p_len;
758
759#ifdef CONFIG_TESTING_OPTIONS
760 if (conn->test_flags & TLS_DHE_PRIME_511B) {
761 tlsv1_server_log(conn, "TESTING: Use short 511-bit prime with DHE");
762 *dh_p = test_tls_prime511b;
763 *dh_p_len = sizeof(test_tls_prime511b);
764 } else if (conn->test_flags & TLS_DHE_PRIME_767B) {
765 tlsv1_server_log(conn, "TESTING: Use short 767-bit prime with DHE");
766 *dh_p = test_tls_prime767b;
767 *dh_p_len = sizeof(test_tls_prime767b);
768 } else if (conn->test_flags & TLS_DHE_PRIME_15) {
769 tlsv1_server_log(conn, "TESTING: Use bogus 15 \"prime\" with DHE");
770 *dh_p = test_tls_prime15;
771 *dh_p_len = sizeof(test_tls_prime15);
772 } else if (conn->test_flags & TLS_DHE_PRIME_58B) {
773 tlsv1_server_log(conn, "TESTING: Use short 58-bit prime in long container with DHE");
774 *dh_p = test_tls_prime58;
775 *dh_p_len = sizeof(test_tls_prime58);
776 } else if (conn->test_flags & TLS_DHE_NON_PRIME) {
777 tlsv1_server_log(conn, "TESTING: Use claim non-prime as the DHE prime");
778 *dh_p = test_tls_non_prime;
779 *dh_p_len = sizeof(test_tls_non_prime);
780 }
781#endif /* CONFIG_TESTING_OPTIONS */
782}