2 * WPA Supplicant / SSL/TLS interface functions for openssl
3 * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
18 #include <openssl/ssl.h>
19 #include <openssl/err.h>
20 #include <openssl/pkcs12.h>
26 struct tls_connection {
28 BIO *ssl_in, *ssl_out;
33 static void ssl_info_cb(const SSL *ssl, int where, int ret)
38 wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret);
39 w = where & ~SSL_ST_MASK;
40 if (w & SSL_ST_CONNECT)
42 else if (w & SSL_ST_ACCEPT)
47 if (where & SSL_CB_LOOP) {
48 wpa_printf(MSG_DEBUG, "SSL: %s:%s",
49 str, SSL_state_string_long(ssl));
50 } else if (where & SSL_CB_ALERT) {
51 wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s",
53 "read (authentication server reported an error)" :
54 "write (local SSL3 detected an error)",
55 SSL_alert_type_string_long(ret),
56 SSL_alert_desc_string_long(ret));
57 } else if (where & SSL_CB_EXIT && ret <= 0) {
58 wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s",
59 str, ret == 0 ? "failed" : "error",
60 SSL_state_string_long(ssl));
69 SSL_load_error_strings();
71 /* TODO: if /dev/urandom is available, PRNG is seeded automatically.
72 * If this is not the case, random data should be added here. */
76 #endif /* PKCS12_FUNCS */
78 ssl = SSL_CTX_new(TLSv1_method());
82 SSL_CTX_set_info_callback(ssl, ssl_info_cb);
88 void tls_deinit(void *ssl_ctx)
90 SSL_CTX *ssl = ssl_ctx;
97 int tls_get_errors(void *ssl_ctx)
102 while ((err = ERR_get_error())) {
103 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
104 ERR_error_string(err, NULL));
111 struct tls_connection * tls_connection_init(void *ssl_ctx)
113 SSL_CTX *ssl = ssl_ctx;
114 struct tls_connection *conn;
116 conn = malloc(sizeof(*conn));
119 memset(conn, 0, sizeof(*conn));
120 conn->ssl = SSL_new(ssl);
121 if (conn->ssl == NULL) {
122 wpa_printf(MSG_INFO, "TLS: Failed to initialize new SSL "
124 ERR_error_string(ERR_get_error(), NULL));
129 SSL_set_options(conn->ssl,
130 SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
131 SSL_OP_SINGLE_DH_USE);
133 conn->ssl_in = BIO_new(BIO_s_mem());
135 wpa_printf(MSG_INFO, "SSL: Failed to create a new BIO for "
137 ERR_error_string(ERR_get_error(), NULL));
143 conn->ssl_out = BIO_new(BIO_s_mem());
144 if (!conn->ssl_out) {
145 wpa_printf(MSG_INFO, "SSL: Failed to create a new BIO for "
147 ERR_error_string(ERR_get_error(), NULL));
149 BIO_free(conn->ssl_in);
154 SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out);
160 void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
165 free(conn->subject_match);
170 int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
172 return conn ? SSL_is_init_finished(conn->ssl) : 0;
176 int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
181 /* Shutdown previous TLS connection without notifying the peer
182 * because the connection was already terminated in practice
183 * and "close notify" shutdown alert would confuse AS. */
184 SSL_set_quiet_shutdown(conn->ssl, 1);
185 SSL_shutdown(conn->ssl);
190 static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
196 struct tls_connection *conn;
199 err_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
200 err = X509_STORE_CTX_get_error(x509_ctx);
201 depth = X509_STORE_CTX_get_error_depth(x509_ctx);
202 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
203 SSL_get_ex_data_X509_STORE_CTX_idx());
204 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
206 conn = SSL_get_app_data(ssl);
207 match = conn ? conn->subject_match : NULL;
210 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed,"
211 " error %d (%s) depth %d for '%s'", err,
212 X509_verify_cert_error_string(err), depth, buf);
214 wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - "
215 "preverify_ok=%d err=%d (%s) depth=%d buf='%s'",
217 X509_verify_cert_error_string(err), depth, buf);
218 if (depth == 0 && match && strstr(buf, match) == NULL) {
219 wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not "
220 "match with '%s'", buf, match);
229 int tls_connection_ca_cert(void *ssl_ctx, struct tls_connection *conn,
230 const char *ca_cert, const char *subject_match)
235 free(conn->subject_match);
236 conn->subject_match = NULL;
238 conn->subject_match = strdup(subject_match);
239 if (conn->subject_match == NULL)
244 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
246 wpa_printf(MSG_WARNING, "TLS: Failed to load root "
248 ERR_error_string(ERR_get_error(), NULL));
251 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
252 "certificate(s) loaded");
253 tls_get_errors(ssl_ctx);
255 SSL_set_app_data(conn->ssl, conn);
256 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
258 /* No ca_cert configured - do not try to verify server
260 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
267 int tls_global_ca_cert(void *_ssl_ctx, const char *ca_cert)
269 SSL_CTX *ssl_ctx = _ssl_ctx;
271 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
273 wpa_printf(MSG_WARNING, "TLS: Failed to load root "
275 ERR_error_string(ERR_get_error(), NULL));
278 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
279 "certificate(s) loaded");
287 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
288 int verify_peer, const char *subject_match)
293 free(conn->subject_match);
294 conn->subject_match = NULL;
296 conn->subject_match = strdup(subject_match);
297 if (conn->subject_match == NULL)
302 SSL_set_app_data(conn->ssl, conn);
303 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
304 SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
305 SSL_VERIFY_CLIENT_ONCE, tls_verify_cb);
307 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
310 SSL_set_accept_state(conn->ssl);
316 int tls_connection_client_cert(void *ssl_ctx, struct tls_connection *conn,
317 const char *client_cert)
319 if (client_cert == NULL)
324 if (SSL_use_certificate_file(conn->ssl, client_cert,
325 SSL_FILETYPE_ASN1) != 1 &&
326 SSL_use_certificate_file(conn->ssl, client_cert,
327 SSL_FILETYPE_PEM) != 1) {
328 wpa_printf(MSG_INFO, "TLS: Failed to load client "
330 ERR_error_string(ERR_get_error(), NULL));
337 int tls_global_client_cert(void *_ssl_ctx, const char *client_cert)
339 SSL_CTX *ssl_ctx = _ssl_ctx;
340 if (client_cert == NULL)
343 if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
344 SSL_FILETYPE_ASN1) != 1 &&
345 SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
346 SSL_FILETYPE_PEM) != 1) {
347 wpa_printf(MSG_INFO, "TLS: Failed to load client "
349 ERR_error_string(ERR_get_error(), NULL));
356 static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
358 if (password == NULL) {
361 strncpy(buf, (char *) password, size);
362 buf[size - 1] = '\0';
367 static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key,
377 f = fopen(private_key, "r");
381 p12 = d2i_PKCS12_fp(f, NULL);
383 wpa_printf(MSG_DEBUG, "TLS: Failed to read PKCS12 file '%s'",
392 if (!PKCS12_parse(p12, passwd, &pkey, &cert, NULL)) {
393 wpa_printf(MSG_DEBUG, "TLS: Failed to parse PKCS12 file '%s': "
395 ERR_error_string(ERR_get_error(), NULL));
398 wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 file '%s'",
402 wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12");
404 if (SSL_use_certificate(ssl, cert) != 1)
407 if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1)
414 wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12");
416 if (SSL_use_PrivateKey(ssl, pkey) != 1)
419 if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1)
428 #else /* PKCS12_FUNCS */
429 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read "
432 #endif /* PKCS12_FUNCS */
436 int tls_connection_private_key(void *_ssl_ctx, struct tls_connection *conn,
437 const char *private_key,
438 const char *private_key_passwd)
440 SSL_CTX *ssl_ctx = _ssl_ctx;
443 if (private_key == NULL)
448 if (private_key_passwd) {
449 passwd = strdup(private_key_passwd);
455 SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
456 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
457 if (SSL_use_PrivateKey_file(conn->ssl, private_key,
458 SSL_FILETYPE_ASN1) != 1 &&
459 SSL_use_PrivateKey_file(conn->ssl, private_key,
460 SSL_FILETYPE_PEM) != 1 &&
461 tls_read_pkcs12(ssl_ctx, conn->ssl, private_key, passwd)) {
462 wpa_printf(MSG_INFO, "SSL: Failed to load private key: %s",
463 ERR_error_string(ERR_get_error(), NULL));
470 SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
472 if (!SSL_check_private_key(conn->ssl)) {
473 wpa_printf(MSG_INFO, "SSL: Private key failed "
475 ERR_error_string(ERR_get_error(), NULL));
483 int tls_global_private_key(void *_ssl_ctx, const char *private_key,
484 const char *private_key_passwd)
486 SSL_CTX *ssl_ctx = _ssl_ctx;
489 if (private_key == NULL)
492 if (private_key_passwd) {
493 passwd = strdup(private_key_passwd);
499 SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
500 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
501 if (SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
502 SSL_FILETYPE_ASN1) != 1 &&
503 SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
504 SSL_FILETYPE_PEM) != 1 &&
505 tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) {
506 wpa_printf(MSG_INFO, "SSL: Failed to load private key: %s",
507 ERR_error_string(ERR_get_error(), NULL));
514 SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
516 if (!SSL_CTX_check_private_key(ssl_ctx)) {
517 wpa_printf(MSG_INFO, "SSL: Private key failed "
519 ERR_error_string(ERR_get_error(), NULL));
527 int tls_connection_dh(void *ssl_ctx, struct tls_connection *conn,
533 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
534 "dh_file specified");
536 #else /* OPENSSL_NO_DH */
545 bio = BIO_new_file(dh_file, "r");
547 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
548 dh_file, ERR_error_string(ERR_get_error(), NULL));
551 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
553 #ifndef OPENSSL_NO_DSA
556 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
557 " trying to parse as DSA params", dh_file,
558 ERR_error_string(ERR_get_error(), NULL));
559 bio = BIO_new_file(dh_file, "r");
562 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
565 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
567 ERR_error_string(ERR_get_error(), NULL));
571 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
572 dh = DSA_dup_DH(dsa);
575 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
576 "params into DH params");
581 #endif /* !OPENSSL_NO_DSA */
583 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
588 if (SSL_set_tmp_dh(conn->ssl, dh) != 1) {
589 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
591 ERR_error_string(ERR_get_error(), NULL));
597 #endif /* OPENSSL_NO_DH */
601 int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
602 struct tls_keys *keys)
606 if (conn == NULL || keys == NULL)
609 if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL)
612 keys->master_key = ssl->session->master_key;
613 keys->master_key_len = ssl->session->master_key_length;
614 keys->client_random = ssl->s3->client_random;
615 keys->client_random_len = SSL3_RANDOM_SIZE;
616 keys->server_random = ssl->s3->server_random;
617 keys->server_random_len = SSL3_RANDOM_SIZE;
623 u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
624 const u8 *in_data, size_t in_len,
631 BIO_write(conn->ssl_in, in_data, in_len) < 0) {
632 wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_write: %s",
633 ERR_error_string(ERR_get_error(), NULL));
637 res = SSL_connect(conn->ssl);
639 int err = SSL_get_error(conn->ssl, res);
640 if (err == SSL_ERROR_WANT_READ)
641 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want "
643 else if (err == SSL_ERROR_WANT_WRITE)
644 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to "
647 wpa_printf(MSG_INFO, "SSL: SSL_connect: %s",
648 ERR_error_string(ERR_get_error(), NULL));
653 res = BIO_ctrl_pending(conn->ssl_out);
654 wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
655 out_data = malloc(res == 0 ? 1 : res);
656 if (out_data == NULL) {
657 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
658 "handshake output (%d bytes)", res);
659 BIO_reset(conn->ssl_out);
663 res = res == 0 ? 0 : BIO_read(conn->ssl_out, out_data, res);
665 wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_read: %s",
666 ERR_error_string(ERR_get_error(), NULL));
667 BIO_reset(conn->ssl_out);
676 u8 * tls_connection_server_handshake(void *ssl_ctx,
677 struct tls_connection *conn,
678 const u8 *in_data, size_t in_len,
686 BIO_write(conn->ssl_in, in_data, in_len) < 0) {
687 wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_write: %s",
688 ERR_error_string(ERR_get_error(), NULL));
692 res = SSL_read(conn->ssl, buf, sizeof(buf));
694 wpa_printf(MSG_DEBUG, "SSL: Unexpected data from SSL_read "
698 res = BIO_ctrl_pending(conn->ssl_out);
699 wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
700 out_data = malloc(res == 0 ? 1 : res);
701 if (out_data == NULL) {
702 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
703 "handshake output (%d bytes)", res);
704 BIO_reset(conn->ssl_out);
708 res = res == 0 ? 0 : BIO_read(conn->ssl_out, out_data, res);
710 wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_read: %s",
711 ERR_error_string(ERR_get_error(), NULL));
712 BIO_reset(conn->ssl_out);
721 int tls_connection_encrypt(void *ssl_ctx, struct tls_connection *conn,
722 u8 *in_data, size_t in_len,
723 u8 *out_data, size_t out_len)
730 BIO_reset(conn->ssl_in);
731 BIO_reset(conn->ssl_out);
732 res = SSL_write(conn->ssl, in_data, in_len);
734 wpa_printf(MSG_INFO, "TLS: Encryption failed - SSL_write: %s",
735 ERR_error_string(ERR_get_error(), NULL));
739 res = BIO_read(conn->ssl_out, out_data, out_len);
741 wpa_printf(MSG_INFO, "TLS: Encryption failed - BIO_read: %s",
742 ERR_error_string(ERR_get_error(), NULL));
750 int tls_connection_decrypt(void *ssl_ctx, struct tls_connection *conn,
751 u8 *in_data, size_t in_len,
752 u8 *out_data, size_t out_len)
756 res = BIO_write(conn->ssl_in, in_data, in_len);
758 wpa_printf(MSG_INFO, "TLS: Decryption failed - BIO_write: %s",
759 ERR_error_string(ERR_get_error(), NULL));
762 BIO_reset(conn->ssl_out);
764 res = SSL_read(conn->ssl, out_data, out_len);
766 wpa_printf(MSG_INFO, "TLS: Decryption failed - SSL_read: %s",
767 ERR_error_string(ERR_get_error(), NULL));
775 int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
777 return conn ? conn->ssl->hit : 0;
781 int tls_connection_set_master_key(void *ssl_ctx, struct tls_connection *conn,
782 const u8 *key, size_t key_len)
786 if (conn == NULL || key == NULL || key_len > SSL_MAX_MASTER_KEY_LENGTH)
789 if (ssl == NULL || ssl->session == NULL)
792 memcpy(ssl->session->master_key, key, key_len);
793 ssl->session->master_key_length = key_len;
799 int tls_connection_set_anon_dh(void *ssl_ctx, struct tls_connection *conn)
801 if (conn == NULL || conn->ssl == NULL)
804 if (SSL_set_cipher_list(conn->ssl, "ADH-AES128-SHA") != 1) {
805 wpa_printf(MSG_INFO, "TLS: Anon DH configuration failed - %s",
806 ERR_error_string(ERR_get_error(), NULL));
814 int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
815 char *buf, size_t buflen)
818 if (conn == NULL || conn->ssl == NULL)
821 name = SSL_get_cipher(conn->ssl);
825 snprintf(buf, buflen, "%s", name);
830 int tls_connection_enable_workaround(void *ssl_ctx,
831 struct tls_connection *conn)
833 SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
840 /* ClientHello TLS extensions require a patch to openssl, so this function is
841 * commented out unless explicitly needed for EAP-FAST in order to be able to
842 * build this file with unmodified openssl. */
843 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
844 int ext_type, const u8 *data,
853 if (conn == NULL || conn->ssl == NULL)
855 OPENSSL_free(conn->ssl->hello_extension);
857 conn->ssl->hello_extension = NULL;
858 conn->ssl->hello_extension_len = 0;
862 conn->ssl->hello_extension = OPENSSL_malloc(1);
863 conn->ssl->hello_extension_len = 0;
866 conn->ssl->hello_extension = OPENSSL_malloc(sizeof(*hdr) + data_len);
867 if (conn->ssl->hello_extension == NULL)
870 hdr = (struct tls_ext_hdr *) conn->ssl->hello_extension;
871 hdr->extensions_len = host_to_be16(sizeof(*hdr) - 2 + data_len);
872 hdr->extension_type = host_to_be16(ext_type);
873 hdr->extension_len = host_to_be16(data_len);
874 memcpy(hdr + 1, data, data_len);
875 conn->ssl->hello_extension_len = sizeof(*hdr) + data_len;
879 #endif /* EAP_FAST */