From patchwork Fri Apr 5 17:55:54 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Stewart X-Patchwork-Id: 234271 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) by ozlabs.org (Postfix) with ESMTP id AE7512C010E for ; Sat, 6 Apr 2013 07:15:40 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 37D7E9D237; Fri, 5 Apr 2013 16:15:38 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ZB-gvVehChqU; Fri, 5 Apr 2013 16:15:37 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 9C6D79D262; Fri, 5 Apr 2013 16:15:33 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id B17D39D262 for ; Fri, 5 Apr 2013 16:15:32 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6h-+1j6S+pXy for ; Fri, 5 Apr 2013 16:15:28 -0400 (EDT) Received: from mail-oa0-f74.google.com (mail-oa0-f74.google.com [209.85.219.74]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority" (not verified)) by maxx.maxx.shmoo.com (Postfix) with ESMTPS id 86AE49D237 for ; Fri, 5 Apr 2013 16:15:28 -0400 (EDT) Received: by mail-oa0-f74.google.com with SMTP id k14so990417oag.3 for ; Fri, 05 Apr 2013 13:15:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:in-reply-to:references:from:date:subject:to:message-id :x-gm-message-state; bh=N4g/8iDYFV3SJcs8JFrSYDs6riyNLeD3+3/XCH28+rs=; b=Igq8wJn1ZBW57ifBGYdqLEFeyS2IJA1AZfu8poIOA0McxIxkrbJkVh3ak8+tZx8/HW 4QqbiJp28FHQ3OvqDwZW6Qxff+92ovs+KVrzAsmXBxndQPzkFWdwkJRZ4p6/87Op2jxK 3gdtkHVyPK2Xr7l0ELypDT2h63EFNF7OQAt4pj0uVzNm7X0KrhQPUzY7uyEv756FUvR0 Axfn7ZqjmPt7VVY0pf/1/jdm0YepKJZLogWnnseZxbp7GuF0imLEgp56BukOw6dNARHO 7uLjh6H7jwM2ucK/bnCOqVa9GeXnwJxizbjasUnS+vKc6RoBeqCtPWC/0up7Y+kybl29 Up3g== X-Received: by 10.50.65.69 with SMTP id v5mr468752igs.1.1365192927900; Fri, 05 Apr 2013 13:15:27 -0700 (PDT) Received: from corp2gmr1-2.hot.corp.google.com (corp2gmr1-2.hot.corp.google.com [172.24.189.93]) by gmr-mx.google.com with ESMTPS id ex5si463700igc.1.2013.04.05.13.15.27 (version=TLSv1.1 cipher=AES128-SHA bits=128/128); Fri, 05 Apr 2013 13:15:27 -0700 (PDT) Received: from clearcreek.mtv.corp.google.com (clearcreek.mtv.corp.google.com [172.22.73.104]) by corp2gmr1-2.hot.corp.google.com (Postfix) with ESMTP id 47D935A41C6 for ; Fri, 5 Apr 2013 13:15:27 -0700 (PDT) Received: by clearcreek.mtv.corp.google.com (Postfix, from userid 110058) id D2F862003A0; Fri, 5 Apr 2013 13:15:26 -0700 (PDT) In-Reply-To: <20130405181242.72044200550@clearcreek.mtv.corp.google.com> References: <20130405181242.72044200550@clearcreek.mtv.corp.google.com> From: Paul Stewart Date: Fri, 5 Apr 2013 10:55:54 -0700 Subject: [PATCHv2] tls_openssl: Store TLS context per-connection To: hostap@lists.shmoo.com Message-Id: <20130405201526.D2F862003A0@clearcreek.mtv.corp.google.com> X-Gm-Message-State: ALoCoQmoEYwcSzAJMHxe502hSAHl+uGTBXFeOIjuvV3PJf9wzLozJWXN+U7Ejvtzs+cyXPdnqfJiFUmYBTOdWld5M0O16VfEku8TUyTT8a/i+mi5SmzJQU467Xm4M4ySgytu56gTiQAHKEvK098DejeEqrL4kkKUL6NpiteyLolSTCeC5E2FU12RFrgUUEEkrlr8lvAv6j7urjpMA/hmSaZJ8cRdZG8gHA== X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.11 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com Store context for each tls_init() caller, so events are generated for the correct wpa_s instance. The tls_global variable is retained for older OpenSSL implementations that may not have app-data for SSL_CTX. Signed-hostap: Paul Stewart --- src/crypto/tls_openssl.c | 84 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 23 deletions(-) diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 2c3db47..d7c87f8 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -37,6 +37,10 @@ #define OPENSSL_d2i_TYPE unsigned char ** #endif +#if defined(SSL_CTX_get_app_data) && defined(SSL_CTX_set_app_data) +#define OPENSSL_SUPPORTS_CTX_APP_DATA +#endif + #ifdef SSL_F_SSL_SET_SESSION_TICKET_EXT #ifdef SSL_OP_NO_TICKET /* @@ -49,17 +53,18 @@ static int tls_openssl_ref_count = 0; -struct tls_global { +struct tls_context { void (*event_cb)(void *ctx, enum tls_event ev, union tls_event_data *data); void *cb_ctx; int cert_in_cb; }; -static struct tls_global *tls_global = NULL; +static struct tls_context *tls_global = NULL; struct tls_connection { + struct tls_context *context; SSL *ssl; BIO *ssl_in, *ssl_out; #ifndef OPENSSL_NO_ENGINE @@ -86,6 +91,19 @@ struct tls_connection { }; +static struct tls_context *tls_context_new(const struct tls_config *conf) +{ + struct tls_context *context = os_zalloc(sizeof(*context)); + if (context == NULL) + return NULL; + if (conf) { + context->event_cb = conf->event_cb; + context->cb_ctx = conf->cb_ctx; + context->cert_in_cb = conf->cert_in_cb; + } + return context; +} + #ifdef CONFIG_NO_STDOUT_DEBUG static void _tls_show_errors(void) @@ -511,6 +529,7 @@ static void ssl_info_cb(const SSL *ssl, int where, int ret) wpa_printf(MSG_DEBUG, "SSL: %s:%s", str, SSL_state_string_long(ssl)); } else if (where & SSL_CB_ALERT) { + struct tls_connection *conn = SSL_get_app_data((SSL *) ssl); wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s", where & SSL_CB_READ ? "read (remote end reported an error)" : @@ -518,21 +537,19 @@ static void ssl_info_cb(const SSL *ssl, int where, int ret) SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret)); if ((ret >> 8) == SSL3_AL_FATAL) { - struct tls_connection *conn = - SSL_get_app_data((SSL *) ssl); if (where & SSL_CB_READ) conn->read_alerts++; else conn->write_alerts++; } - if (tls_global->event_cb != NULL) { + if (conn->context->event_cb != NULL) { union tls_event_data ev; + struct tls_context *context = conn->context; os_memset(&ev, 0, sizeof(ev)); ev.alert.is_local = !(where & SSL_CB_READ); ev.alert.type = SSL_alert_type_string_long(ret); ev.alert.description = SSL_alert_desc_string_long(ret); - tls_global->event_cb(tls_global->cb_ctx, TLS_ALERT, - &ev); + context->event_cb(context->cb_ctx, TLS_ALERT, &ev); } } else if (where & SSL_CB_EXIT && ret <= 0) { wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s", @@ -690,17 +707,12 @@ static int tls_engine_load_dynamic_opensc(const char *opensc_so_path) void * tls_init(const struct tls_config *conf) { SSL_CTX *ssl; + struct tls_context *context; if (tls_openssl_ref_count == 0) { - tls_global = os_zalloc(sizeof(*tls_global)); - if (tls_global == NULL) + tls_global = context = tls_context_new(conf); + if (context == NULL) return NULL; - if (conf) { - tls_global->event_cb = conf->event_cb; - tls_global->cb_ctx = conf->cb_ctx; - tls_global->cert_in_cb = conf->cert_in_cb; - } - #ifdef CONFIG_FIPS #ifdef OPENSSL_FIPS if (conf && conf->fips_mode) { @@ -746,6 +758,13 @@ void * tls_init(const struct tls_config *conf) #endif /* OPENSSL_NO_RC2 */ PKCS12_PBE_add(); #endif /* PKCS12_FUNCS */ +#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA + } else { + /* Newer OpenSSL can store app-data per-SSL */ + context = tls_context_new(conf); + if (context == NULL) + return NULL; +#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */ } tls_openssl_ref_count++; @@ -754,6 +773,9 @@ void * tls_init(const struct tls_config *conf) return NULL; SSL_CTX_set_info_callback(ssl, ssl_info_cb); +#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA + SSL_CTX_set_app_data(ssl, context); +#endif #ifndef OPENSSL_NO_ENGINE if (conf && @@ -779,6 +801,13 @@ void * tls_init(const struct tls_config *conf) void tls_deinit(void *ssl_ctx) { SSL_CTX *ssl = ssl_ctx; +#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA + struct tls_context *context = + (struct tls_context *)SSL_CTX_get_app_data(ssl); + if (context != tls_global) { + os_free(context); + } +#endif SSL_CTX_free(ssl); tls_openssl_ref_count--; @@ -915,6 +944,10 @@ struct tls_connection * tls_connection_init(void *ssl_ctx) SSL_CTX *ssl = ssl_ctx; struct tls_connection *conn; long options; + struct tls_context *context = tls_global; +#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA + context = (struct tls_context *)SSL_CTX_get_app_data(ssl); +#endif conn = os_zalloc(sizeof(*conn)); if (conn == NULL) @@ -927,6 +960,7 @@ struct tls_connection * tls_connection_init(void *ssl_ctx) return NULL; } + conn->context = context; SSL_set_app_data(conn->ssl, conn); options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE; @@ -1122,8 +1156,9 @@ static void openssl_tls_fail_event(struct tls_connection *conn, { union tls_event_data ev; struct wpabuf *cert = NULL; + struct tls_context *context = conn->context; - if (tls_global->event_cb == NULL) + if (context->event_cb == NULL) return; cert = get_x509_cert(err_cert); @@ -1134,7 +1169,7 @@ static void openssl_tls_fail_event(struct tls_connection *conn, ev.cert_fail.subject = subject; ev.cert_fail.reason_txt = err_str; ev.cert_fail.cert = cert; - tls_global->event_cb(tls_global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); + context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); wpabuf_free(cert); } @@ -1145,15 +1180,16 @@ static void openssl_tls_cert_event(struct tls_connection *conn, { struct wpabuf *cert = NULL; union tls_event_data ev; + struct tls_context *context = conn->context; #ifdef CONFIG_SHA256 u8 hash[32]; #endif /* CONFIG_SHA256 */ - if (tls_global->event_cb == NULL) + if (context->event_cb == NULL) return; os_memset(&ev, 0, sizeof(ev)); - if (conn->cert_probe || tls_global->cert_in_cb) { + if (conn->cert_probe || context->cert_in_cb) { cert = get_x509_cert(err_cert); ev.peer_cert.cert = cert; } @@ -1171,7 +1207,7 @@ static void openssl_tls_cert_event(struct tls_connection *conn, #endif /* CONFIG_SHA256 */ ev.peer_cert.depth = depth; ev.peer_cert.subject = subject; - tls_global->event_cb(tls_global->cb_ctx, TLS_PEER_CERTIFICATE, &ev); + context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev); wpabuf_free(cert); } @@ -1183,6 +1219,7 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) int err, depth; SSL *ssl; struct tls_connection *conn; + struct tls_context *context; char *match, *altmatch; const char *err_str; @@ -1196,6 +1233,7 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) conn = SSL_get_app_data(ssl); if (conn == NULL) return 0; + context = conn->context; match = conn->subject_match; altmatch = conn->altsubject_match; @@ -1278,9 +1316,9 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) TLS_FAIL_SERVER_CHAIN_PROBE); } - if (preverify_ok && tls_global->event_cb != NULL) - tls_global->event_cb(tls_global->cb_ctx, - TLS_CERT_CHAIN_SUCCESS, NULL); + if (preverify_ok && context->event_cb != NULL) + context->event_cb(context->cb_ctx, + TLS_CERT_CHAIN_SUCCESS, NULL); return preverify_ok; }