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: 234239 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 A354B2C00FF for ; Sat, 6 Apr 2013 05:12:57 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id C9F1F9C196; Fri, 5 Apr 2013 14:12:54 -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 YR4P3YGXOs2d; Fri, 5 Apr 2013 14:12:54 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 745D69C19C; Fri, 5 Apr 2013 14:12:50 -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 73BF69C196 for ; Fri, 5 Apr 2013 14:12:48 -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 os0FZ1THwhf8 for ; Fri, 5 Apr 2013 14:12:44 -0400 (EDT) Received: from mail-ia0-f201.google.com (mail-ia0-f201.google.com [209.85.210.201]) (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 46C879C13E for ; Fri, 5 Apr 2013 14:12:44 -0400 (EDT) Received: by mail-ia0-f201.google.com with SMTP id t4so960463iag.4 for ; Fri, 05 Apr 2013 11:12:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:date:subject:to:message-id:x-gm-message-state; bh=v1KWG9GwEaSJq/98/4anPM+7OFS7gbwoRHWXl917kmw=; b=KP9PmBO+yNlym4Ai6Py2XsFgXQDAaek6uriC784tIKYjQKWrbXLj7VI5YbORVPoN4k 27l3a+l3xOcwfVbMSstsdMgKhqRjKG3wCLXajJUIEheitNvTZAIpIUqQZAaC3jmg79mO 1C76AnGGO4rOrJ5fVFnhtNuZjIR4vYRTHXXVVst5XrXe5MHPh9uyYzJTecvT5futMWw+ LNHj7cVOqfqfv4c/h9k8VJNOYn4URgfPrDuZ9syeLB03UDl8nkEUsTAMvey+t8iBLb5B +wC/CHYbgL0ujRgvma5+FXVjndQ7eVMkmissifSqG3YMqa3dYrpq5g9kE5HLUD0QdlJC brjA== X-Received: by 10.42.55.19 with SMTP id t19mr8411197icg.31.1365185563528; Fri, 05 Apr 2013 11:12:43 -0700 (PDT) Received: from corp2gmr1-1.hot.corp.google.com (corp2gmr1-1.hot.corp.google.com [172.24.189.92]) by gmr-mx.google.com with ESMTPS id hn12si419978igb.3.2013.04.05.11.12.43 (version=TLSv1.1 cipher=AES128-SHA bits=128/128); Fri, 05 Apr 2013 11:12:43 -0700 (PDT) Received: from clearcreek.mtv.corp.google.com (clearcreek.mtv.corp.google.com [172.22.73.104]) by corp2gmr1-1.hot.corp.google.com (Postfix) with ESMTP id DF16E31C10E for ; Fri, 5 Apr 2013 11:12:42 -0700 (PDT) Received: by clearcreek.mtv.corp.google.com (Postfix, from userid 110058) id 72044200550; Fri, 5 Apr 2013 11:12:42 -0700 (PDT) From: Paul Stewart Date: Fri, 5 Apr 2013 10:55:54 -0700 Subject: [PATCH] tls_openssl: Store TLS context per-connection To: hostap@lists.shmoo.com Message-Id: <20130405181242.72044200550@clearcreek.mtv.corp.google.com> X-Gm-Message-State: ALoCoQkH25cDQAbBDT/36N1GNAW3Jx50B/Uo4jO9FzfoWSVBL2shl+ZsFiRrm19FKgiZcjI+9QSh2nwUAxWNGHochZVwzrG547u6ePfwQMCQ436vdLnNHBzEe8cjDyu6rPXEjok8eeC5Ln2AKpm+wf1f9WS4P0koweWHkHbt3/zKjCegROxHlG0XLwmwSaauw/4FybGACksuBdhqS/ue58RGdI4tPWRVsw== 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. --- 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..cb845a8 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 (OPENSSL_VERSION_NUMBER >= 0x1000103fL) +#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; }