2 * TLS v1.0/v1.1/v1.2 client (RFC 2246, RFC 4346, RFC 5246)
3 * Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "crypto/sha1.h"
13 #include "crypto/tls.h"
14 #include "tlsv1_common.h"
15 #include "tlsv1_record.h"
16 #include "tlsv1_client.h"
17 #include "tlsv1_client_i.h"
20 * Support for a message fragmented across several records (RFC 2246, 6.2.1)
24 void tls_alert(struct tlsv1_client
*conn
, u8 level
, u8 description
)
26 conn
->alert_level
= level
;
27 conn
->alert_description
= description
;
31 void tlsv1_client_free_dh(struct tlsv1_client
*conn
)
36 conn
->dh_p
= conn
->dh_g
= conn
->dh_ys
= NULL
;
40 int tls_derive_pre_master_secret(u8
*pre_master_secret
)
42 WPA_PUT_BE16(pre_master_secret
, TLS_VERSION
);
43 if (os_get_random(pre_master_secret
+ 2,
44 TLS_PRE_MASTER_SECRET_LEN
- 2))
50 int tls_derive_keys(struct tlsv1_client
*conn
,
51 const u8
*pre_master_secret
, size_t pre_master_secret_len
)
53 u8 seed
[2 * TLS_RANDOM_LEN
];
54 u8 key_block
[TLS_MAX_KEY_BLOCK_LEN
];
58 if (pre_master_secret
) {
59 wpa_hexdump_key(MSG_MSGDUMP
, "TLSv1: pre_master_secret",
60 pre_master_secret
, pre_master_secret_len
);
61 os_memcpy(seed
, conn
->client_random
, TLS_RANDOM_LEN
);
62 os_memcpy(seed
+ TLS_RANDOM_LEN
, conn
->server_random
,
64 if (tls_prf(conn
->rl
.tls_version
,
65 pre_master_secret
, pre_master_secret_len
,
66 "master secret", seed
, 2 * TLS_RANDOM_LEN
,
67 conn
->master_secret
, TLS_MASTER_SECRET_LEN
)) {
68 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to derive "
72 wpa_hexdump_key(MSG_MSGDUMP
, "TLSv1: master_secret",
73 conn
->master_secret
, TLS_MASTER_SECRET_LEN
);
76 os_memcpy(seed
, conn
->server_random
, TLS_RANDOM_LEN
);
77 os_memcpy(seed
+ TLS_RANDOM_LEN
, conn
->client_random
, TLS_RANDOM_LEN
);
78 key_block_len
= 2 * (conn
->rl
.hash_size
+ conn
->rl
.key_material_len
);
79 if (conn
->rl
.tls_version
== TLS_VERSION_1
)
80 key_block_len
+= 2 * conn
->rl
.iv_size
;
81 if (tls_prf(conn
->rl
.tls_version
,
82 conn
->master_secret
, TLS_MASTER_SECRET_LEN
,
83 "key expansion", seed
, 2 * TLS_RANDOM_LEN
,
84 key_block
, key_block_len
)) {
85 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to derive key_block");
88 wpa_hexdump_key(MSG_MSGDUMP
, "TLSv1: key_block",
89 key_block
, key_block_len
);
93 /* client_write_MAC_secret */
94 os_memcpy(conn
->rl
.write_mac_secret
, pos
, conn
->rl
.hash_size
);
95 pos
+= conn
->rl
.hash_size
;
96 /* server_write_MAC_secret */
97 os_memcpy(conn
->rl
.read_mac_secret
, pos
, conn
->rl
.hash_size
);
98 pos
+= conn
->rl
.hash_size
;
100 /* client_write_key */
101 os_memcpy(conn
->rl
.write_key
, pos
, conn
->rl
.key_material_len
);
102 pos
+= conn
->rl
.key_material_len
;
103 /* server_write_key */
104 os_memcpy(conn
->rl
.read_key
, pos
, conn
->rl
.key_material_len
);
105 pos
+= conn
->rl
.key_material_len
;
107 if (conn
->rl
.tls_version
== TLS_VERSION_1
) {
108 /* client_write_IV */
109 os_memcpy(conn
->rl
.write_iv
, pos
, conn
->rl
.iv_size
);
110 pos
+= conn
->rl
.iv_size
;
111 /* server_write_IV */
112 os_memcpy(conn
->rl
.read_iv
, pos
, conn
->rl
.iv_size
);
113 pos
+= conn
->rl
.iv_size
;
116 * Use IV field to set the mask value for TLS v1.1. A fixed
117 * mask of zero is used per the RFC 4346, 6.2.3.2 CBC Block
120 os_memset(conn
->rl
.write_iv
, 0, conn
->rl
.iv_size
);
128 * tlsv1_client_handshake - Process TLS handshake
129 * @conn: TLSv1 client connection data from tlsv1_client_init()
130 * @in_data: Input data from TLS peer
131 * @in_len: Input data length
132 * @out_len: Length of the output buffer.
133 * @appl_data: Pointer to application data pointer, or %NULL if dropped
134 * @appl_data_len: Pointer to variable that is set to appl_data length
135 * @need_more_data: Set to 1 if more data would be needed to complete
137 * Returns: Pointer to output data, %NULL on failure
139 u8
* tlsv1_client_handshake(struct tlsv1_client
*conn
,
140 const u8
*in_data
, size_t in_len
,
141 size_t *out_len
, u8
**appl_data
,
142 size_t *appl_data_len
, int *need_more_data
)
145 u8
*msg
= NULL
, *in_msg
= NULL
, *in_pos
, *in_end
, alert
, ct
;
153 if (conn
->state
== CLIENT_HELLO
) {
156 return tls_send_client_hello(conn
, out_len
);
159 if (conn
->partial_input
) {
160 if (wpabuf_resize(&conn
->partial_input
, in_len
) < 0) {
161 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to allocate "
162 "memory for pending record");
163 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
164 TLS_ALERT_INTERNAL_ERROR
);
167 wpabuf_put_data(conn
->partial_input
, in_data
, in_len
);
168 in_data
= wpabuf_head(conn
->partial_input
);
169 in_len
= wpabuf_len(conn
->partial_input
);
172 if (in_data
== NULL
|| in_len
== 0)
176 end
= in_data
+ in_len
;
177 in_msg
= os_malloc(in_len
);
181 /* Each received packet may include multiple records */
184 used
= tlsv1_record_receive(&conn
->rl
, pos
, end
- pos
,
185 in_msg
, &in_msg_len
, &alert
);
187 wpa_printf(MSG_DEBUG
, "TLSv1: Processing received "
189 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, alert
);
193 struct wpabuf
*partial
;
194 wpa_printf(MSG_DEBUG
, "TLSv1: Need more data");
195 partial
= wpabuf_alloc_copy(pos
, end
- pos
);
196 wpabuf_free(conn
->partial_input
);
197 conn
->partial_input
= partial
;
198 if (conn
->partial_input
== NULL
) {
199 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to "
200 "allocate memory for pending "
202 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
203 TLS_ALERT_INTERNAL_ERROR
);
214 in_end
= in_msg
+ in_msg_len
;
216 /* Each received record may include multiple messages of the
217 * same ContentType. */
218 while (in_pos
< in_end
) {
219 in_msg_len
= in_end
- in_pos
;
220 if (tlsv1_client_process_handshake(conn
, ct
, in_pos
,
225 in_pos
+= in_msg_len
;
234 no_appl_data
= appl_data
== NULL
|| *appl_data
== NULL
;
235 msg
= tlsv1_client_handshake_write(conn
, out_len
, no_appl_data
);
239 if (conn
->alert_level
) {
240 wpabuf_free(conn
->partial_input
);
241 conn
->partial_input
= NULL
;
242 conn
->state
= FAILED
;
244 msg
= tlsv1_client_send_alert(conn
, conn
->alert_level
,
245 conn
->alert_description
,
247 } else if (msg
== NULL
) {
252 if (need_more_data
== NULL
|| !(*need_more_data
)) {
253 wpabuf_free(conn
->partial_input
);
254 conn
->partial_input
= NULL
;
262 * tlsv1_client_encrypt - Encrypt data into TLS tunnel
263 * @conn: TLSv1 client connection data from tlsv1_client_init()
264 * @in_data: Pointer to plaintext data to be encrypted
265 * @in_len: Input buffer length
266 * @out_data: Pointer to output buffer (encrypted TLS data)
267 * @out_len: Maximum out_data length
268 * Returns: Number of bytes written to out_data, -1 on failure
270 * This function is used after TLS handshake has been completed successfully to
271 * send data in the encrypted tunnel.
273 int tlsv1_client_encrypt(struct tlsv1_client
*conn
,
274 const u8
*in_data
, size_t in_len
,
275 u8
*out_data
, size_t out_len
)
279 wpa_hexdump_key(MSG_MSGDUMP
, "TLSv1: Plaintext AppData",
282 if (tlsv1_record_send(&conn
->rl
, TLS_CONTENT_TYPE_APPLICATION_DATA
,
283 out_data
, out_len
, in_data
, in_len
, &rlen
) < 0) {
284 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to create a record");
285 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
286 TLS_ALERT_INTERNAL_ERROR
);
295 * tlsv1_client_decrypt - Decrypt data from TLS tunnel
296 * @conn: TLSv1 client connection data from tlsv1_client_init()
297 * @in_data: Pointer to input buffer (encrypted TLS data)
298 * @in_len: Input buffer length
299 * @need_more_data: Set to 1 if more data would be needed to complete
301 * Returns: Decrypted data or %NULL on failure
303 * This function is used after TLS handshake has been completed successfully to
304 * receive data from the encrypted tunnel.
306 struct wpabuf
* tlsv1_client_decrypt(struct tlsv1_client
*conn
,
307 const u8
*in_data
, size_t in_len
,
310 const u8
*in_end
, *pos
;
312 u8 alert
, *out_pos
, ct
;
314 struct wpabuf
*buf
= NULL
;
319 if (conn
->partial_input
) {
320 if (wpabuf_resize(&conn
->partial_input
, in_len
) < 0) {
321 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to allocate "
322 "memory for pending record");
323 alert
= TLS_ALERT_INTERNAL_ERROR
;
326 wpabuf_put_data(conn
->partial_input
, in_data
, in_len
);
327 in_data
= wpabuf_head(conn
->partial_input
);
328 in_len
= wpabuf_len(conn
->partial_input
);
332 in_end
= in_data
+ in_len
;
334 while (pos
< in_end
) {
336 if (wpabuf_resize(&buf
, in_end
- pos
) < 0) {
337 alert
= TLS_ALERT_INTERNAL_ERROR
;
340 out_pos
= wpabuf_put(buf
, 0);
341 olen
= wpabuf_tailroom(buf
);
342 used
= tlsv1_record_receive(&conn
->rl
, pos
, in_end
- pos
,
343 out_pos
, &olen
, &alert
);
345 wpa_printf(MSG_DEBUG
, "TLSv1: Record layer processing "
350 struct wpabuf
*partial
;
351 wpa_printf(MSG_DEBUG
, "TLSv1: Need more data");
352 partial
= wpabuf_alloc_copy(pos
, in_end
- pos
);
353 wpabuf_free(conn
->partial_input
);
354 conn
->partial_input
= partial
;
355 if (conn
->partial_input
== NULL
) {
356 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to "
357 "allocate memory for pending "
359 alert
= TLS_ALERT_INTERNAL_ERROR
;
367 if (ct
== TLS_CONTENT_TYPE_ALERT
) {
369 wpa_printf(MSG_DEBUG
, "TLSv1: Alert "
371 alert
= TLS_ALERT_DECODE_ERROR
;
374 wpa_printf(MSG_DEBUG
, "TLSv1: Received alert %d:%d",
375 out_pos
[0], out_pos
[1]);
376 if (out_pos
[0] == TLS_ALERT_LEVEL_WARNING
) {
377 /* Continue processing */
386 if (ct
!= TLS_CONTENT_TYPE_APPLICATION_DATA
) {
387 wpa_printf(MSG_DEBUG
, "TLSv1: Unexpected content type "
388 "0x%x when decrypting application data",
390 alert
= TLS_ALERT_UNEXPECTED_MESSAGE
;
394 wpabuf_put(buf
, olen
);
399 wpabuf_free(conn
->partial_input
);
400 conn
->partial_input
= NULL
;
405 wpabuf_free(conn
->partial_input
);
406 conn
->partial_input
= NULL
;
407 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, alert
);
413 * tlsv1_client_global_init - Initialize TLSv1 client
414 * Returns: 0 on success, -1 on failure
416 * This function must be called before using any other TLSv1 client functions.
418 int tlsv1_client_global_init(void)
420 return crypto_global_init();
425 * tlsv1_client_global_deinit - Deinitialize TLSv1 client
427 * This function can be used to deinitialize the TLSv1 client that was
428 * initialized by calling tlsv1_client_global_init(). No TLSv1 client functions
429 * can be called after this before calling tlsv1_client_global_init() again.
431 void tlsv1_client_global_deinit(void)
433 crypto_global_deinit();
438 * tlsv1_client_init - Initialize TLSv1 client connection
439 * Returns: Pointer to TLSv1 client connection data or %NULL on failure
441 struct tlsv1_client
* tlsv1_client_init(void)
443 struct tlsv1_client
*conn
;
447 conn
= os_zalloc(sizeof(*conn
));
451 conn
->state
= CLIENT_HELLO
;
453 if (tls_verify_hash_init(&conn
->verify
) < 0) {
454 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to initialize verify "
461 suites
= conn
->cipher_suites
;
462 suites
[count
++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
;
463 suites
[count
++] = TLS_RSA_WITH_AES_256_CBC_SHA256
;
464 suites
[count
++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA
;
465 suites
[count
++] = TLS_RSA_WITH_AES_256_CBC_SHA
;
466 suites
[count
++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
;
467 suites
[count
++] = TLS_RSA_WITH_AES_128_CBC_SHA256
;
468 suites
[count
++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA
;
469 suites
[count
++] = TLS_RSA_WITH_AES_128_CBC_SHA
;
470 suites
[count
++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
;
471 suites
[count
++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA
;
472 suites
[count
++] = TLS_RSA_WITH_RC4_128_SHA
;
473 suites
[count
++] = TLS_RSA_WITH_RC4_128_MD5
;
474 conn
->num_cipher_suites
= count
;
476 conn
->rl
.tls_version
= TLS_VERSION
;
483 * tlsv1_client_deinit - Deinitialize TLSv1 client connection
484 * @conn: TLSv1 client connection data from tlsv1_client_init()
486 void tlsv1_client_deinit(struct tlsv1_client
*conn
)
488 crypto_public_key_free(conn
->server_rsa_key
);
489 tlsv1_record_set_cipher_suite(&conn
->rl
, TLS_NULL_WITH_NULL_NULL
);
490 tlsv1_record_change_write_cipher(&conn
->rl
);
491 tlsv1_record_change_read_cipher(&conn
->rl
);
492 tls_verify_hash_free(&conn
->verify
);
493 os_free(conn
->client_hello_ext
);
494 tlsv1_client_free_dh(conn
);
495 tlsv1_cred_free(conn
->cred
);
496 wpabuf_free(conn
->partial_input
);
502 * tlsv1_client_established - Check whether connection has been established
503 * @conn: TLSv1 client connection data from tlsv1_client_init()
504 * Returns: 1 if connection is established, 0 if not
506 int tlsv1_client_established(struct tlsv1_client
*conn
)
508 return conn
->state
== ESTABLISHED
;
513 * tlsv1_client_prf - Use TLS-PRF to derive keying material
514 * @conn: TLSv1 client connection data from tlsv1_client_init()
515 * @label: Label (e.g., description of the key) for PRF
516 * @server_random_first: seed is 0 = client_random|server_random,
517 * 1 = server_random|client_random
518 * @out: Buffer for output data from TLS-PRF
519 * @out_len: Length of the output buffer
520 * Returns: 0 on success, -1 on failure
522 int tlsv1_client_prf(struct tlsv1_client
*conn
, const char *label
,
523 int server_random_first
, u8
*out
, size_t out_len
)
525 u8 seed
[2 * TLS_RANDOM_LEN
];
527 if (conn
->state
!= ESTABLISHED
)
530 if (server_random_first
) {
531 os_memcpy(seed
, conn
->server_random
, TLS_RANDOM_LEN
);
532 os_memcpy(seed
+ TLS_RANDOM_LEN
, conn
->client_random
,
535 os_memcpy(seed
, conn
->client_random
, TLS_RANDOM_LEN
);
536 os_memcpy(seed
+ TLS_RANDOM_LEN
, conn
->server_random
,
540 return tls_prf(conn
->rl
.tls_version
,
541 conn
->master_secret
, TLS_MASTER_SECRET_LEN
,
542 label
, seed
, 2 * TLS_RANDOM_LEN
, out
, out_len
);
547 * tlsv1_client_get_cipher - Get current cipher name
548 * @conn: TLSv1 client connection data from tlsv1_client_init()
549 * @buf: Buffer for the cipher name
551 * Returns: 0 on success, -1 on failure
553 * Get the name of the currently used cipher.
555 int tlsv1_client_get_cipher(struct tlsv1_client
*conn
, char *buf
,
560 switch (conn
->rl
.cipher_suite
) {
561 case TLS_RSA_WITH_RC4_128_MD5
:
564 case TLS_RSA_WITH_RC4_128_SHA
:
567 case TLS_RSA_WITH_DES_CBC_SHA
:
568 cipher
= "DES-CBC-SHA";
570 case TLS_RSA_WITH_3DES_EDE_CBC_SHA
:
571 cipher
= "DES-CBC3-SHA";
573 case TLS_DHE_RSA_WITH_DES_CBC_SHA
:
574 cipher
= "DHE-RSA-DES-CBC-SHA";
576 case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
:
577 cipher
= "DHE-RSA-DES-CBC3-SHA";
579 case TLS_DH_anon_WITH_RC4_128_MD5
:
580 cipher
= "ADH-RC4-MD5";
582 case TLS_DH_anon_WITH_DES_CBC_SHA
:
583 cipher
= "ADH-DES-SHA";
585 case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
:
586 cipher
= "ADH-DES-CBC3-SHA";
588 case TLS_RSA_WITH_AES_128_CBC_SHA
:
589 cipher
= "AES-128-SHA";
591 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA
:
592 cipher
= "DHE-RSA-AES-128-SHA";
594 case TLS_DH_anon_WITH_AES_128_CBC_SHA
:
595 cipher
= "ADH-AES-128-SHA";
597 case TLS_RSA_WITH_AES_256_CBC_SHA
:
598 cipher
= "AES-256-SHA";
600 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA
:
601 cipher
= "DHE-RSA-AES-256-SHA";
603 case TLS_DH_anon_WITH_AES_256_CBC_SHA
:
604 cipher
= "ADH-AES-256-SHA";
606 case TLS_RSA_WITH_AES_128_CBC_SHA256
:
607 cipher
= "AES-128-SHA256";
609 case TLS_RSA_WITH_AES_256_CBC_SHA256
:
610 cipher
= "AES-256-SHA256";
612 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
:
613 cipher
= "DHE-RSA-AES-128-SHA256";
615 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
:
616 cipher
= "DHE-RSA-AES-256-SHA256";
618 case TLS_DH_anon_WITH_AES_128_CBC_SHA256
:
619 cipher
= "ADH-AES-128-SHA256";
621 case TLS_DH_anon_WITH_AES_256_CBC_SHA256
:
622 cipher
= "ADH-AES-256-SHA256";
628 if (os_strlcpy(buf
, cipher
, buflen
) >= buflen
)
635 * tlsv1_client_shutdown - Shutdown TLS connection
636 * @conn: TLSv1 client connection data from tlsv1_client_init()
637 * Returns: 0 on success, -1 on failure
639 int tlsv1_client_shutdown(struct tlsv1_client
*conn
)
641 conn
->state
= CLIENT_HELLO
;
643 if (tls_verify_hash_init(&conn
->verify
) < 0) {
644 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to re-initialize verify "
649 tlsv1_record_set_cipher_suite(&conn
->rl
, TLS_NULL_WITH_NULL_NULL
);
650 tlsv1_record_change_write_cipher(&conn
->rl
);
651 tlsv1_record_change_read_cipher(&conn
->rl
);
653 conn
->certificate_requested
= 0;
654 crypto_public_key_free(conn
->server_rsa_key
);
655 conn
->server_rsa_key
= NULL
;
656 conn
->session_resumed
= 0;
663 * tlsv1_client_resumed - Was session resumption used
664 * @conn: TLSv1 client connection data from tlsv1_client_init()
665 * Returns: 1 if current session used session resumption, 0 if not
667 int tlsv1_client_resumed(struct tlsv1_client
*conn
)
669 return !!conn
->session_resumed
;
674 * tlsv1_client_hello_ext - Set TLS extension for ClientHello
675 * @conn: TLSv1 client connection data from tlsv1_client_init()
676 * @ext_type: Extension type
677 * @data: Extension payload (%NULL to remove extension)
678 * @data_len: Extension payload length
679 * Returns: 0 on success, -1 on failure
681 int tlsv1_client_hello_ext(struct tlsv1_client
*conn
, int ext_type
,
682 const u8
*data
, size_t data_len
)
686 conn
->session_ticket_included
= 0;
687 os_free(conn
->client_hello_ext
);
688 conn
->client_hello_ext
= NULL
;
689 conn
->client_hello_ext_len
= 0;
691 if (data
== NULL
|| data_len
== 0)
694 pos
= conn
->client_hello_ext
= os_malloc(6 + data_len
);
698 WPA_PUT_BE16(pos
, 4 + data_len
);
700 WPA_PUT_BE16(pos
, ext_type
);
702 WPA_PUT_BE16(pos
, data_len
);
704 os_memcpy(pos
, data
, data_len
);
705 conn
->client_hello_ext_len
= 6 + data_len
;
707 if (ext_type
== TLS_EXT_PAC_OPAQUE
) {
708 conn
->session_ticket_included
= 1;
709 wpa_printf(MSG_DEBUG
, "TLSv1: Using session ticket");
717 * tlsv1_client_get_keys - Get master key and random data from TLS connection
718 * @conn: TLSv1 client connection data from tlsv1_client_init()
719 * @keys: Structure of key/random data (filled on success)
720 * Returns: 0 on success, -1 on failure
722 int tlsv1_client_get_keys(struct tlsv1_client
*conn
, struct tls_keys
*keys
)
724 os_memset(keys
, 0, sizeof(*keys
));
725 if (conn
->state
== CLIENT_HELLO
)
728 keys
->client_random
= conn
->client_random
;
729 keys
->client_random_len
= TLS_RANDOM_LEN
;
731 if (conn
->state
!= SERVER_HELLO
) {
732 keys
->server_random
= conn
->server_random
;
733 keys
->server_random_len
= TLS_RANDOM_LEN
;
734 keys
->master_key
= conn
->master_secret
;
735 keys
->master_key_len
= TLS_MASTER_SECRET_LEN
;
743 * tlsv1_client_get_keyblock_size - Get TLS key_block size
744 * @conn: TLSv1 client connection data from tlsv1_client_init()
745 * Returns: Size of the key_block for the negotiated cipher suite or -1 on
748 int tlsv1_client_get_keyblock_size(struct tlsv1_client
*conn
)
750 if (conn
->state
== CLIENT_HELLO
|| conn
->state
== SERVER_HELLO
)
753 return 2 * (conn
->rl
.hash_size
+ conn
->rl
.key_material_len
+
759 * tlsv1_client_set_cipher_list - Configure acceptable cipher suites
760 * @conn: TLSv1 client connection data from tlsv1_client_init()
761 * @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers
763 * Returns: 0 on success, -1 on failure
765 int tlsv1_client_set_cipher_list(struct tlsv1_client
*conn
, u8
*ciphers
)
770 /* TODO: implement proper configuration of cipher suites */
771 if (ciphers
[0] == TLS_CIPHER_ANON_DH_AES128_SHA
) {
773 suites
= conn
->cipher_suites
;
774 suites
[count
++] = TLS_DH_anon_WITH_AES_256_CBC_SHA256
;
775 suites
[count
++] = TLS_DH_anon_WITH_AES_256_CBC_SHA
;
776 suites
[count
++] = TLS_DH_anon_WITH_AES_128_CBC_SHA256
;
777 suites
[count
++] = TLS_DH_anon_WITH_AES_128_CBC_SHA
;
778 suites
[count
++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
;
779 suites
[count
++] = TLS_DH_anon_WITH_RC4_128_MD5
;
780 suites
[count
++] = TLS_DH_anon_WITH_DES_CBC_SHA
;
783 * Cisco AP (at least 350 and 1200 series) local authentication
784 * server does not know how to search cipher suites from the
785 * list and seem to require that the last entry in the list is
786 * the one that it wants to use. However, TLS specification
787 * requires the list to be in the client preference order. As a
788 * workaround, add anon-DH AES-128-SHA1 again at the end of the
789 * list to allow the Cisco code to find it.
791 suites
[count
++] = TLS_DH_anon_WITH_AES_128_CBC_SHA
;
792 conn
->num_cipher_suites
= count
;
800 * tlsv1_client_set_cred - Set client credentials
801 * @conn: TLSv1 client connection data from tlsv1_client_init()
802 * @cred: Credentials from tlsv1_cred_alloc()
803 * Returns: 0 on success, -1 on failure
805 * On success, the client takes ownership of the credentials block and caller
806 * must not free it. On failure, caller is responsible for freeing the
809 int tlsv1_client_set_cred(struct tlsv1_client
*conn
,
810 struct tlsv1_credentials
*cred
)
812 tlsv1_cred_free(conn
->cred
);
818 void tlsv1_client_set_time_checks(struct tlsv1_client
*conn
, int enabled
)
820 conn
->disable_time_checks
= !enabled
;
824 void tlsv1_client_set_session_ticket_cb(struct tlsv1_client
*conn
,
825 tlsv1_client_session_ticket_cb cb
,
828 wpa_printf(MSG_DEBUG
, "TLSv1: SessionTicket callback set %p (ctx %p)",
830 conn
->session_ticket_cb
= cb
;
831 conn
->session_ticket_cb_ctx
= ctx
;