X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=blobdiff_plain;f=libeap%2Fsrc%2Fcrypto%2Ftls_internal.c;h=704751d308fcf9f080de1a5f2aeab086573ff096;hp=64124d8a8e3ef74c8bbaa4709d6ea208189bbb27;hb=4f319dde67a76fe0aaf33f6d2788968012584ada;hpb=ed09b5e64dd485851310307979d5eed14678087b diff --git a/libeap/src/crypto/tls_internal.c b/libeap/src/crypto/tls_internal.c index 64124d8..704751d 100644 --- a/libeap/src/crypto/tls_internal.c +++ b/libeap/src/crypto/tls_internal.c @@ -1,15 +1,9 @@ /* * TLS interface functions and an internal TLS implementation - * Copyright (c) 2004-2009, Jouni Malinen + * Copyright (c) 2004-2011, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. * * This file interface functions for hostapd/wpa_supplicant to use the * integrated TLSv1 implementation. @@ -34,6 +28,7 @@ struct tls_global { struct tls_connection { struct tlsv1_client *client; struct tlsv1_server *server; + struct tls_global *global; }; @@ -91,6 +86,7 @@ struct tls_connection * tls_connection_init(void *tls_ctx) conn = os_zalloc(sizeof(*conn)); if (conn == NULL) return NULL; + conn->global = global; #ifdef CONFIG_TLS_INTERNAL_CLIENT if (!global->server) { @@ -115,6 +111,28 @@ struct tls_connection * tls_connection_init(void *tls_ctx) } +#ifdef CONFIG_TESTING_OPTIONS +#ifdef CONFIG_TLS_INTERNAL_SERVER +void tls_connection_set_test_flags(struct tls_connection *conn, u32 flags) +{ + if (conn->server) + tlsv1_server_set_test_flags(conn->server, flags); +} +#endif /* CONFIG_TLS_INTERNAL_SERVER */ +#endif /* CONFIG_TESTING_OPTIONS */ + + +void tls_connection_set_log_cb(struct tls_connection *conn, + void (*log_cb)(void *ctx, const char *msg), + void *ctx) +{ +#ifdef CONFIG_TLS_INTERNAL_SERVER + if (conn->server) + tlsv1_server_set_log_cb(conn->server, log_cb, ctx); +#endif /* CONFIG_TLS_INTERNAL_SERVER */ +} + + void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) { if (conn == NULL) @@ -172,6 +190,36 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, if (cred == NULL) return -1; + if (params->subject_match) { + wpa_printf(MSG_INFO, "TLS: subject_match not supported"); + tlsv1_cred_free(cred); + return -1; + } + + if (params->altsubject_match) { + wpa_printf(MSG_INFO, "TLS: altsubject_match not supported"); + tlsv1_cred_free(cred); + return -1; + } + + if (params->suffix_match) { + wpa_printf(MSG_INFO, "TLS: suffix_match not supported"); + tlsv1_cred_free(cred); + return -1; + } + + if (params->domain_match) { + wpa_printf(MSG_INFO, "TLS: domain_match not supported"); + tlsv1_cred_free(cred); + return -1; + } + + if (params->openssl_ciphers) { + wpa_printf(MSG_INFO, "TLS: openssl_ciphers not supported"); + tlsv1_cred_free(cred); + return -1; + } + if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob, params->ca_cert_blob_len, params->ca_path)) { @@ -211,6 +259,9 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, return -1; } + tlsv1_client_set_time_checks( + conn->client, !(params->flags & TLS_CONN_DISABLE_TIME_CHECKS)); + return 0; #else /* CONFIG_TLS_INTERNAL_CLIENT */ return -1; @@ -277,7 +328,8 @@ int tls_global_set_verify(void *tls_ctx, int check_crl) int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, - int verify_peer) + int verify_peer, unsigned int flags, + const u8 *session_ctx, size_t session_ctx_len) { #ifdef CONFIG_TLS_INTERNAL_SERVER if (conn->server) @@ -287,23 +339,30 @@ int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, } -int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn, - int tls_ia) +int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, + struct tls_random *data) { +#ifdef CONFIG_TLS_INTERNAL_CLIENT + if (conn->client) + return tlsv1_client_get_random(conn->client, data); +#endif /* CONFIG_TLS_INTERNAL_CLIENT */ +#ifdef CONFIG_TLS_INTERNAL_SERVER + if (conn->server) + return tlsv1_server_get_random(conn->server, data); +#endif /* CONFIG_TLS_INTERNAL_SERVER */ return -1; } -int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn, - struct tls_keys *keys) +static int tls_get_keyblock_size(struct tls_connection *conn) { #ifdef CONFIG_TLS_INTERNAL_CLIENT if (conn->client) - return tlsv1_client_get_keys(conn->client, keys); + return tlsv1_client_get_keyblock_size(conn->client); #endif /* CONFIG_TLS_INTERNAL_CLIENT */ #ifdef CONFIG_TLS_INTERNAL_SERVER if (conn->server) - return tlsv1_server_get_keys(conn->server, keys); + return tlsv1_server_get_keyblock_size(conn->server); #endif /* CONFIG_TLS_INTERNAL_SERVER */ return -1; } @@ -311,23 +370,41 @@ int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn, int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, const char *label, int server_random_first, - u8 *out, size_t out_len) -{ + int skip_keyblock, u8 *out, size_t out_len) +{ + int ret = -1, skip = 0; + u8 *tmp_out = NULL; + u8 *_out = out; + + if (skip_keyblock) { + skip = tls_get_keyblock_size(conn); + if (skip < 0) + return -1; + tmp_out = os_malloc(skip + out_len); + if (!tmp_out) + return -1; + _out = tmp_out; + } + #ifdef CONFIG_TLS_INTERNAL_CLIENT if (conn->client) { - return tlsv1_client_prf(conn->client, label, - server_random_first, - out, out_len); + ret = tlsv1_client_prf(conn->client, label, + server_random_first, + _out, out_len); } #endif /* CONFIG_TLS_INTERNAL_CLIENT */ #ifdef CONFIG_TLS_INTERNAL_SERVER if (conn->server) { - return tlsv1_server_prf(conn->server, label, - server_random_first, - out, out_len); + ret = tlsv1_server_prf(conn->server, label, + server_random_first, + _out, out_len); } #endif /* CONFIG_TLS_INTERNAL_SERVER */ - return -1; + if (ret == 0 && skip_keyblock) + os_memcpy(out, _out + skip, out_len); + bin_clear_free(tmp_out, skip); + + return ret; } @@ -336,6 +413,17 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx, const struct wpabuf *in_data, struct wpabuf **appl_data) { + return tls_connection_handshake2(tls_ctx, conn, in_data, appl_data, + NULL); +} + + +struct wpabuf * tls_connection_handshake2(void *tls_ctx, + struct tls_connection *conn, + const struct wpabuf *in_data, + struct wpabuf **appl_data, + int *need_more_data) +{ #ifdef CONFIG_TLS_INTERNAL_CLIENT u8 *res, *ad; size_t res_len, ad_len; @@ -348,7 +436,7 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx, res = tlsv1_client_handshake(conn->client, in_data ? wpabuf_head(in_data) : NULL, in_data ? wpabuf_len(in_data) : 0, - &res_len, &ad, &ad_len); + &res_len, &ad, &ad_len, need_more_data); if (res == NULL) return NULL; out = wpabuf_alloc_ext_data(res, res_len); @@ -459,23 +547,23 @@ struct wpabuf * tls_connection_decrypt(void *tls_ctx, struct tls_connection *conn, const struct wpabuf *in_data) { + return tls_connection_decrypt2(tls_ctx, conn, in_data, NULL); +} + + +struct wpabuf * tls_connection_decrypt2(void *tls_ctx, + struct tls_connection *conn, + const struct wpabuf *in_data, + int *need_more_data) +{ + if (need_more_data) + *need_more_data = 0; + #ifdef CONFIG_TLS_INTERNAL_CLIENT if (conn->client) { - struct wpabuf *buf; - int res; - buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); - if (buf == NULL) - return NULL; - res = tlsv1_client_decrypt(conn->client, wpabuf_head(in_data), - wpabuf_len(in_data), - wpabuf_mhead(buf), - wpabuf_size(buf)); - if (res < 0) { - wpabuf_free(buf); - return NULL; - } - wpabuf_put(buf, res); - return buf; + return tlsv1_client_decrypt(conn->client, wpabuf_head(in_data), + wpabuf_len(in_data), + need_more_data); } #endif /* CONFIG_TLS_INTERNAL_CLIENT */ #ifdef CONFIG_TLS_INTERNAL_SERVER @@ -530,6 +618,14 @@ int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, } +int tls_get_version(void *ssl_ctx, struct tls_connection *conn, + char *buf, size_t buflen) +{ + /* TODO */ + return -1; +} + + int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, char *buf, size_t buflen) { @@ -587,65 +683,51 @@ int tls_connection_get_write_alerts(void *tls_ctx, } -int tls_connection_get_keyblock_size(void *tls_ctx, - struct tls_connection *conn) +int tls_connection_set_session_ticket_cb(void *tls_ctx, + struct tls_connection *conn, + tls_session_ticket_cb cb, + void *ctx) { #ifdef CONFIG_TLS_INTERNAL_CLIENT - if (conn->client) - return tlsv1_client_get_keyblock_size(conn->client); + if (conn->client) { + tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx); + return 0; + } #endif /* CONFIG_TLS_INTERNAL_CLIENT */ #ifdef CONFIG_TLS_INTERNAL_SERVER - if (conn->server) - return tlsv1_server_get_keyblock_size(conn->server); + if (conn->server) { + tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx); + return 0; + } #endif /* CONFIG_TLS_INTERNAL_SERVER */ return -1; } -unsigned int tls_capabilities(void *tls_ctx) +int tls_get_library_version(char *buf, size_t buf_len) { - return 0; + return os_snprintf(buf, buf_len, "internal"); } -struct wpabuf * tls_connection_ia_send_phase_finished( - void *tls_ctx, struct tls_connection *conn, int final) +void tls_connection_set_success_data(struct tls_connection *conn, + struct wpabuf *data) { - return NULL; } -int tls_connection_ia_final_phase_finished(void *tls_ctx, - struct tls_connection *conn) +void tls_connection_set_success_data_resumed(struct tls_connection *conn) { - return -1; } -int tls_connection_ia_permute_inner_secret(void *tls_ctx, - struct tls_connection *conn, - const u8 *key, size_t key_len) +const struct wpabuf * +tls_connection_get_success_data(struct tls_connection *conn) { - return -1; + return NULL; } -int tls_connection_set_session_ticket_cb(void *tls_ctx, - struct tls_connection *conn, - tls_session_ticket_cb cb, - void *ctx) +void tls_connection_remove_session(struct tls_connection *conn) { -#ifdef CONFIG_TLS_INTERNAL_CLIENT - if (conn->client) { - tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx); - return 0; - } -#endif /* CONFIG_TLS_INTERNAL_CLIENT */ -#ifdef CONFIG_TLS_INTERNAL_SERVER - if (conn->server) { - tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx); - return 0; - } -#endif /* CONFIG_TLS_INTERNAL_SERVER */ - return -1; }