summaryrefslogtreecommitdiffstats
path: root/contrib/hostapd/tls_openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/hostapd/tls_openssl.c')
-rw-r--r--contrib/hostapd/tls_openssl.c418
1 files changed, 296 insertions, 122 deletions
diff --git a/contrib/hostapd/tls_openssl.c b/contrib/hostapd/tls_openssl.c
index 08d5a80..c8d941f 100644
--- a/contrib/hostapd/tls_openssl.c
+++ b/contrib/hostapd/tls_openssl.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / SSL/TLS interface functions for openssl
- * Copyright (c) 2004-2006, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
*
* 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
@@ -12,9 +12,7 @@
* See README and COPYING for more details.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
+#include "includes.h"
#ifndef CONFIG_SMARTCARD
#ifndef OPENSSL_NO_ENGINE
@@ -235,7 +233,7 @@ static int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from,
goto err;
}
- if (hash_size != flen) {
+ if ((int) hash_size != flen) {
wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)",
(unsigned) hash_size, flen);
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
@@ -248,7 +246,7 @@ static int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from,
}
len = RSA_size(rsa);
- buf = malloc(len);
+ buf = os_malloc(len);
if (buf == NULL) {
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
goto err;
@@ -264,7 +262,7 @@ static int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from,
ret = len;
err:
- free(buf);
+ os_free(buf);
CryptDestroyHash(hash);
return ret;
@@ -287,14 +285,14 @@ static void cryptoapi_free_data(struct cryptoapi_rsa_data *priv)
CryptReleaseContext(priv->crypt_prov, 0);
if (priv->cert)
CertFreeCertificateContext(priv->cert);
- free(priv);
+ os_free(priv);
}
static int cryptoapi_finish(RSA *rsa)
{
cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data);
- free((void *) rsa->meth);
+ os_free((void *) rsa->meth);
rsa->meth = NULL;
return 1;
}
@@ -315,8 +313,7 @@ static const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store)
if (strncmp(name, "cert://", 7) == 0) {
unsigned short wbuf[255];
- MultiByteToWideChar(CP_ACP, 0, name + 7, -1,
- wbuf, sizeof(wbuf));
+ MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255);
ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING |
PKCS_7_ASN_ENCODING,
0, CERT_FIND_SUBJECT_STR,
@@ -327,8 +324,8 @@ static const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store)
const char *hash = name + 7;
unsigned char *buf;
- len = strlen(hash) / 2;
- buf = malloc(len);
+ len = os_strlen(hash) / 2;
+ buf = os_malloc(len);
if (buf && hexstr2bin(hash, buf, len) == 0) {
blob.cbData = len;
blob.pbData = buf;
@@ -338,7 +335,7 @@ static const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store)
0, CERT_FIND_HASH,
&blob, NULL);
}
- free(buf);
+ os_free(buf);
}
CertCloseStore(cs, 0);
@@ -359,17 +356,15 @@ static int tls_cryptoapi_cert(SSL *ssl, const char *name)
strncmp(name, "hash://", 7) != 0))
return -1;
- priv = malloc(sizeof(*priv));
- rsa_meth = malloc(sizeof(*rsa_meth));
+ priv = os_zalloc(sizeof(*priv));
+ rsa_meth = os_zalloc(sizeof(*rsa_meth));
if (priv == NULL || rsa_meth == NULL) {
wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory "
"for CryptoAPI RSA method");
- free(priv);
- free(rsa_meth);
+ os_free(priv);
+ os_free(rsa_meth);
return -1;
}
- memset(priv, 0, sizeof(*priv));
- memset(rsa_meth, 0, sizeof(*rsa_meth));
priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER);
if (priv->cert == NULL) {
@@ -419,8 +414,11 @@ static int tls_cryptoapi_cert(SSL *ssl, const char *name)
goto err;
}
- if (!SSL_use_certificate(ssl, cert))
+ if (!SSL_use_certificate(ssl, cert)) {
+ RSA_free(rsa);
+ rsa = NULL;
goto err;
+ }
pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
X509_free(cert);
cert = NULL;
@@ -442,7 +440,7 @@ err:
if (rsa)
RSA_free(rsa);
else {
- free(rsa_meth);
+ os_free(rsa_meth);
cryptoapi_free_data(priv);
}
return -1;
@@ -455,6 +453,10 @@ static int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name)
PCCERT_CONTEXT ctx = NULL;
X509 *cert;
char buf[128];
+ const char *store;
+#ifdef UNICODE
+ WCHAR *wstore;
+#endif /* UNICODE */
if (mingw_load_crypto_func())
return -1;
@@ -462,10 +464,20 @@ static int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name)
if (name == NULL || strncmp(name, "cert_store://", 13) != 0)
return -1;
- cs = CertOpenSystemStore(0, name + 13);
+ store = name + 13;
+#ifdef UNICODE
+ wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR));
+ if (wstore == NULL)
+ return -1;
+ wsprintf(wstore, L"%S", store);
+ cs = CertOpenSystemStore(0, wstore);
+ os_free(wstore);
+#else /* UNICODE */
+ cs = CertOpenSystemStore(0, store);
+#endif /* UNICODE */
if (cs == NULL) {
wpa_printf(MSG_DEBUG, "%s: failed to open system cert store "
- "'%s': error=%d", __func__, name + 13,
+ "'%s': error=%d", __func__, store,
(int) GetLastError());
return -1;
}
@@ -643,21 +655,25 @@ static int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path,
{
char *engine_id = "pkcs11";
const char *pre_cmd[] = {
- "SO_PATH", pkcs11_so_path,
- "ID", engine_id,
+ "SO_PATH", NULL /* pkcs11_so_path */,
+ "ID", NULL /* engine_id */,
"LIST_ADD", "1",
/* "NO_VCHECK", "1", */
"LOAD", NULL,
NULL, NULL
};
const char *post_cmd[] = {
- "MODULE_PATH", pkcs11_module_path,
+ "MODULE_PATH", NULL /* pkcs11_module_path */,
NULL, NULL
};
if (!pkcs11_so_path || !pkcs11_module_path)
return 0;
+ pre_cmd[1] = pkcs11_so_path;
+ pre_cmd[3] = engine_id;
+ post_cmd[1] = pkcs11_module_path;
+
wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s",
pkcs11_so_path);
@@ -673,8 +689,8 @@ static int tls_engine_load_dynamic_opensc(const char *opensc_so_path)
{
char *engine_id = "opensc";
const char *pre_cmd[] = {
- "SO_PATH", opensc_so_path,
- "ID", engine_id,
+ "SO_PATH", NULL /* opensc_so_path */,
+ "ID", NULL /* engine_id */,
"LIST_ADD", "1",
"LOAD", NULL,
NULL, NULL
@@ -683,6 +699,9 @@ static int tls_engine_load_dynamic_opensc(const char *opensc_so_path)
if (!opensc_so_path)
return 0;
+ pre_cmd[1] = opensc_so_path;
+ pre_cmd[3] = engine_id;
+
wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s",
opensc_so_path);
@@ -853,15 +872,14 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
SSL_CTX *ssl = ssl_ctx;
struct tls_connection *conn;
- conn = malloc(sizeof(*conn));
+ conn = os_zalloc(sizeof(*conn));
if (conn == NULL)
return NULL;
- memset(conn, 0, sizeof(*conn));
conn->ssl = SSL_new(ssl);
if (conn->ssl == NULL) {
tls_show_errors(MSG_INFO, __func__,
"Failed to initialize new SSL connection");
- free(conn);
+ os_free(conn);
return NULL;
}
@@ -875,7 +893,7 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
tls_show_errors(MSG_INFO, __func__,
"Failed to create a new BIO for ssl_in");
SSL_free(conn->ssl);
- free(conn);
+ os_free(conn);
return NULL;
}
@@ -885,7 +903,7 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
"Failed to create a new BIO for ssl_out");
SSL_free(conn->ssl);
BIO_free(conn->ssl_in);
- free(conn);
+ os_free(conn);
return NULL;
}
@@ -899,12 +917,12 @@ void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
{
if (conn == NULL)
return;
- free(conn->pre_shared_secret);
+ os_free(conn->pre_shared_secret);
SSL_free(conn->ssl);
tls_engine_deinit(conn);
- free(conn->subject_match);
- free(conn->altsubject_match);
- free(conn);
+ os_free(conn->subject_match);
+ os_free(conn->altsubject_match);
+ os_free(conn);
}
@@ -928,55 +946,71 @@ int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
}
-static int tls_match_altsubject(X509 *cert, const char *match)
+static int tls_match_altsubject_component(X509 *cert, int type,
+ const char *value, size_t len)
{
GENERAL_NAME *gen;
- char *field, *tmp;
void *ext;
int i, found = 0;
- size_t len;
ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
gen = sk_GENERAL_NAME_value(ext, i);
- switch (gen->type) {
- case GEN_EMAIL:
- field = "EMAIL";
- break;
- case GEN_DNS:
- field = "DNS";
- break;
- case GEN_URI:
- field = "URI";
- break;
- default:
- field = NULL;
- wpa_printf(MSG_DEBUG, "TLS: altSubjectName: "
- "unsupported type=%d", gen->type);
- break;
- }
-
- if (!field)
- continue;
-
- wpa_printf(MSG_DEBUG, "TLS: altSubjectName: %s:%s",
- field, gen->d.ia5->data);
- len = strlen(field) + 1 + strlen((char *) gen->d.ia5->data) +
- 1;
- tmp = malloc(len);
- if (tmp == NULL)
+ if (gen->type != type)
continue;
- snprintf(tmp, len, "%s:%s", field, gen->d.ia5->data);
- if (strstr(tmp, match))
+ if (os_strlen((char *) gen->d.ia5->data) == len &&
+ os_memcmp(value, gen->d.ia5->data, len) == 0)
found++;
- free(tmp);
}
return found;
}
+static int tls_match_altsubject(X509 *cert, const char *match)
+{
+ int type;
+ const char *pos, *end;
+ size_t len;
+
+ pos = match;
+ do {
+ if (os_strncmp(pos, "EMAIL:", 6) == 0) {
+ type = GEN_EMAIL;
+ pos += 6;
+ } else if (os_strncmp(pos, "DNS:", 4) == 0) {
+ type = GEN_DNS;
+ pos += 4;
+ } else if (os_strncmp(pos, "URI:", 4) == 0) {
+ type = GEN_URI;
+ pos += 4;
+ } else {
+ wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName "
+ "match '%s'", pos);
+ return 0;
+ }
+ end = os_strchr(pos, ';');
+ while (end) {
+ if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
+ os_strncmp(end + 1, "DNS:", 4) == 0 ||
+ os_strncmp(end + 1, "URI:", 4) == 0)
+ break;
+ end = os_strchr(end + 1, ';');
+ }
+ if (end)
+ len = end - pos;
+ else
+ len = os_strlen(pos);
+ if (tls_match_altsubject_component(cert, type, pos, len) > 0)
+ return 1;
+ pos = end + 1;
+ } while (end);
+
+ return 0;
+}
+
+
static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
char buf[256];
@@ -1006,7 +1040,7 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
"preverify_ok=%d err=%d (%s) depth=%d buf='%s'",
preverify_ok, err,
X509_verify_cert_error_string(err), depth, buf);
- if (depth == 0 && match && strstr(buf, match) == NULL) {
+ if (depth == 0 && match && os_strstr(buf, match) == NULL) {
wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not "
"match with '%s'", buf, match);
preverify_ok = 0;
@@ -1071,11 +1105,20 @@ static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn,
}
if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) {
+ unsigned long err = ERR_peek_error();
tls_show_errors(MSG_WARNING, __func__,
"Failed to add ca_cert_blob to "
"certificate store");
- X509_free(cert);
- return -1;
+ if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
+ ERR_GET_REASON(err) ==
+ X509_R_CERT_ALREADY_IN_HASH_TABLE) {
+ wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
+ "cert already in hash table error",
+ __func__);
+ } else {
+ X509_free(cert);
+ return -1;
+ }
}
X509_free(cert);
wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob "
@@ -1128,9 +1171,8 @@ static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn,
}
-int tls_global_ca_cert(void *_ssl_ctx, const char *ca_cert)
+static int tls_global_ca_cert(SSL_CTX *ssl_ctx, const char *ca_cert)
{
- SSL_CTX *ssl_ctx = _ssl_ctx;
if (ca_cert) {
if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
{
@@ -1174,23 +1216,22 @@ int tls_global_set_verify(void *ssl_ctx, int check_crl)
}
-static int tls_connection_set_subject_match(void *ssl_ctx,
- struct tls_connection *conn,
+static int tls_connection_set_subject_match(struct tls_connection *conn,
const char *subject_match,
const char *altsubject_match)
{
- free(conn->subject_match);
+ os_free(conn->subject_match);
conn->subject_match = NULL;
if (subject_match) {
- conn->subject_match = strdup(subject_match);
+ conn->subject_match = os_strdup(subject_match);
if (conn->subject_match == NULL)
return -1;
}
- free(conn->altsubject_match);
+ os_free(conn->altsubject_match);
conn->altsubject_match = NULL;
if (altsubject_match) {
- conn->altsubject_match = strdup(altsubject_match);
+ conn->altsubject_match = os_strdup(altsubject_match);
if (conn->altsubject_match == NULL)
return -1;
}
@@ -1219,8 +1260,7 @@ int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
}
-static int tls_connection_client_cert(void *ssl_ctx,
- struct tls_connection *conn,
+static int tls_connection_client_cert(struct tls_connection *conn,
const char *client_cert,
const u8 *client_cert_blob,
size_t client_cert_blob_len)
@@ -1270,10 +1310,9 @@ static int tls_connection_client_cert(void *ssl_ctx,
}
-int tls_global_client_cert(void *_ssl_ctx, const char *client_cert)
+static int tls_global_client_cert(SSL_CTX *ssl_ctx, const char *client_cert)
{
#ifndef OPENSSL_NO_STDIO
- SSL_CTX *ssl_ctx = _ssl_ctx;
if (client_cert == NULL)
return 0;
@@ -1300,9 +1339,9 @@ static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
if (password == NULL) {
return 0;
}
- strncpy(buf, (char *) password, size);
+ os_strncpy(buf, (char *) password, size);
buf[size - 1] = '\0';
- return strlen(buf);
+ return os_strlen(buf);
}
@@ -1322,6 +1361,7 @@ static int tls_parse_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, PKCS12 *p12,
if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
tls_show_errors(MSG_DEBUG, __func__,
"Failed to parse PKCS12 file");
+ PKCS12_free(p12);
return -1;
}
wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data");
@@ -1388,7 +1428,7 @@ static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key,
FILE *f;
PKCS12 *p12;
- f = fopen(private_key, "r");
+ f = fopen(private_key, "rb");
if (f == NULL)
return -1;
@@ -1434,8 +1474,7 @@ static int tls_read_pkcs12_blob(SSL_CTX *ssl_ctx, SSL *ssl,
}
-static int tls_connection_engine_private_key(void *_ssl_ctx,
- struct tls_connection *conn)
+static int tls_connection_engine_private_key(struct tls_connection *conn)
{
#ifndef OPENSSL_NO_ENGINE
if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) {
@@ -1472,7 +1511,7 @@ static int tls_connection_private_key(void *_ssl_ctx,
return 0;
if (private_key_passwd) {
- passwd = strdup(private_key_passwd);
+ passwd = os_strdup(private_key_passwd);
if (passwd == NULL)
return -1;
} else
@@ -1582,13 +1621,13 @@ static int tls_connection_private_key(void *_ssl_ctx,
if (!ok) {
wpa_printf(MSG_INFO, "OpenSSL: Failed to load private key");
- free(passwd);
+ os_free(passwd);
ERR_clear_error();
return -1;
}
ERR_clear_error();
SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
- free(passwd);
+ os_free(passwd);
if (!SSL_check_private_key(conn->ssl)) {
tls_show_errors(MSG_INFO, __func__, "Private key failed "
@@ -1601,17 +1640,16 @@ static int tls_connection_private_key(void *_ssl_ctx,
}
-int tls_global_private_key(void *_ssl_ctx, const char *private_key,
- const char *private_key_passwd)
+static int tls_global_private_key(SSL_CTX *ssl_ctx, const char *private_key,
+ const char *private_key_passwd)
{
- SSL_CTX *ssl_ctx = _ssl_ctx;
char *passwd;
if (private_key == NULL)
return 0;
if (private_key_passwd) {
- passwd = strdup(private_key_passwd);
+ passwd = os_strdup(private_key_passwd);
if (passwd == NULL)
return -1;
} else
@@ -1629,11 +1667,11 @@ int tls_global_private_key(void *_ssl_ctx, const char *private_key,
tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) {
tls_show_errors(MSG_INFO, __func__,
"Failed to load private key");
- free(passwd);
+ os_free(passwd);
ERR_clear_error();
return -1;
}
- free(passwd);
+ os_free(passwd);
ERR_clear_error();
SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
@@ -1647,8 +1685,7 @@ int tls_global_private_key(void *_ssl_ctx, const char *private_key,
}
-static int tls_connection_dh(void *ssl_ctx, struct tls_connection *conn,
- const char *dh_file)
+static int tls_connection_dh(struct tls_connection *conn, const char *dh_file)
{
#ifdef OPENSSL_NO_DH
if (dh_file == NULL)
@@ -1733,7 +1770,7 @@ int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL)
return -1;
- memset(keys, 0, sizeof(*keys));
+ os_memset(keys, 0, sizeof(*keys));
keys->master_key = ssl->session->master_key;
keys->master_key_len = ssl->session->master_key_length;
keys->client_random = ssl->s3->client_random;
@@ -1745,13 +1782,25 @@ int tls_connection_get_keys(void *ssl_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)
+{
+ return -1;
+}
+
+
u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
const u8 *in_data, size_t in_len,
- size_t *out_len)
+ size_t *out_len, u8 **appl_data,
+ size_t *appl_data_len)
{
int res;
u8 *out_data;
+ if (appl_data)
+ *appl_data = NULL;
+
/*
* Give TLS handshake data from the server (if available) to OpenSSL
* for processing.
@@ -1782,7 +1831,7 @@ u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
/* Get the TLS handshake data to be sent to the server */
res = BIO_ctrl_pending(conn->ssl_out);
wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
- out_data = malloc(res == 0 ? 1 : res);
+ out_data = os_malloc(res == 0 ? 1 : res);
if (out_data == NULL) {
wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
"handshake output (%d bytes)", res);
@@ -1805,6 +1854,26 @@ u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
return NULL;
}
*out_len = res;
+
+ if (SSL_is_init_finished(conn->ssl) && appl_data) {
+ *appl_data = os_malloc(in_len);
+ if (*appl_data) {
+ res = SSL_read(conn->ssl, *appl_data, in_len);
+ if (res < 0) {
+ tls_show_errors(MSG_INFO, __func__,
+ "Failed to read possible "
+ "Application Data");
+ os_free(*appl_data);
+ *appl_data = NULL;
+ } else {
+ *appl_data_len = res;
+ wpa_hexdump_key(MSG_MSGDUMP, "SSL: Application"
+ " Data in Finish message",
+ *appl_data, *appl_data_len);
+ }
+ }
+ }
+
return out_data;
}
@@ -1833,7 +1902,7 @@ u8 * tls_connection_server_handshake(void *ssl_ctx,
res = BIO_ctrl_pending(conn->ssl_out);
wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
- out_data = malloc(res == 0 ? 1 : res);
+ out_data = os_malloc(res == 0 ? 1 : res);
if (out_data == NULL) {
wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
"handshake output (%d bytes)", res);
@@ -1930,7 +1999,7 @@ int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
}
-#ifdef EAP_FAST
+#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC)
/* Pre-shared secred requires a patch to openssl, so this function is
* commented out unless explicitly needed for EAP-FAST in order to be able to
* build this file with unmodified openssl. */
@@ -1944,7 +2013,8 @@ static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
if (conn == NULL || conn->pre_shared_secret == 0)
return 0;
- memcpy(secret, conn->pre_shared_secret, conn->pre_shared_secret_len);
+ os_memcpy(secret, conn->pre_shared_secret,
+ conn->pre_shared_secret_len);
*secret_len = conn->pre_shared_secret_len;
return 1;
@@ -1957,14 +2027,14 @@ int tls_connection_set_master_key(void *ssl_ctx, struct tls_connection *conn,
if (conn == NULL || key_len > SSL_MAX_MASTER_KEY_LENGTH)
return -1;
- free(conn->pre_shared_secret);
+ os_free(conn->pre_shared_secret);
conn->pre_shared_secret = NULL;
conn->pre_shared_secret_len = 0;
if (key) {
- conn->pre_shared_secret = malloc(key_len);
+ conn->pre_shared_secret = os_malloc(key_len);
if (conn->pre_shared_secret) {
- memcpy(conn->pre_shared_secret, key, key_len);
+ os_memcpy(conn->pre_shared_secret, key, key_len);
conn->pre_shared_secret_len = key_len;
}
if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
@@ -1977,17 +2047,58 @@ int tls_connection_set_master_key(void *ssl_ctx, struct tls_connection *conn,
return 0;
}
-#endif /* EAP_FAST */
+#endif /* EAP_FAST || EAP_FAST_DYNAMIC */
-int tls_connection_set_anon_dh(void *ssl_ctx, struct tls_connection *conn)
+int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
+ u8 *ciphers)
{
- if (conn == NULL || conn->ssl == NULL)
+ char buf[100], *pos, *end;
+ u8 *c;
+ int ret;
+
+ if (conn == NULL || conn->ssl == NULL || ciphers == NULL)
return -1;
- if (SSL_set_cipher_list(conn->ssl, "ADH-AES128-SHA") != 1) {
+ buf[0] = '\0';
+ pos = buf;
+ end = pos + sizeof(buf);
+
+ c = ciphers;
+ while (*c != TLS_CIPHER_NONE) {
+ const char *suite;
+
+ switch (*c) {
+ case TLS_CIPHER_RC4_SHA:
+ suite = "RC4-SHA";
+ break;
+ case TLS_CIPHER_AES128_SHA:
+ suite = "AES128-SHA";
+ break;
+ case TLS_CIPHER_RSA_DHE_AES128_SHA:
+ suite = "DHE-RSA-AES128-SHA";
+ break;
+ case TLS_CIPHER_ANON_DH_AES128_SHA:
+ suite = "ADH-AES128-SHA";
+ break;
+ default:
+ wpa_printf(MSG_DEBUG, "TLS: Unsupported "
+ "cipher selection: %d", *c);
+ return -1;
+ }
+ ret = os_snprintf(pos, end - pos, ":%s", suite);
+ if (ret < 0 || ret >= end - pos)
+ break;
+ pos += ret;
+
+ c++;
+ }
+
+ wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1);
+
+ if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
tls_show_errors(MSG_INFO, __func__,
- "Anon DH configuration failed");
+ "Cipher suite configuration failed");
return -1;
}
@@ -2006,7 +2117,8 @@ int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
if (name == NULL)
return -1;
- snprintf(buf, buflen, "%s", name);
+ os_snprintf(buf, buflen, "%s", name);
+ buf[buflen - 1] = '\0';
return 0;
}
@@ -2020,7 +2132,7 @@ int tls_connection_enable_workaround(void *ssl_ctx,
}
-#ifdef EAP_FAST
+#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC)
/* ClientHello TLS extensions require a patch to openssl, so this function is
* commented out unless explicitly needed for EAP-FAST in order to be able to
* build this file with unmodified openssl. */
@@ -2037,7 +2149,7 @@ int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
return 0;
}
-#endif /* EAP_FAST */
+#endif /* EAP_FAST || EAP_FAST_DYNAMIC */
int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
@@ -2078,7 +2190,7 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
__func__, ERR_error_string(err, NULL));
}
- if (tls_connection_set_subject_match(tls_ctx, conn,
+ if (tls_connection_set_subject_match(conn,
params->subject_match,
params->altsubject_match))
return -1;
@@ -2087,7 +2199,7 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
params->ca_cert_blob_len,
params->ca_path))
return -1;
- if (tls_connection_client_cert(tls_ctx, conn, params->client_cert,
+ if (tls_connection_client_cert(conn, params->client_cert,
params->client_cert_blob,
params->client_cert_blob_len))
return -1;
@@ -2098,7 +2210,7 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
params->key_id);
if (ret)
return ret;
- if (tls_connection_engine_private_key(tls_ctx, conn))
+ if (tls_connection_engine_private_key(conn))
return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
} else if (tls_connection_private_key(tls_ctx, conn,
params->private_key,
@@ -2110,7 +2222,7 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
return -1;
}
- if (tls_connection_dh(tls_ctx, conn, params->dh_file)) {
+ if (tls_connection_dh(conn, params->dh_file)) {
wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
params->dh_file);
return -1;
@@ -2122,6 +2234,31 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
}
+int tls_global_set_params(void *tls_ctx,
+ const struct tls_connection_params *params)
+{
+ SSL_CTX *ssl_ctx = tls_ctx;
+ unsigned long err;
+
+ while ((err = ERR_get_error())) {
+ wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
+ __func__, ERR_error_string(err, NULL));
+ }
+
+ if (tls_global_ca_cert(ssl_ctx, params->ca_cert))
+ return -1;
+
+ if (tls_global_client_cert(ssl_ctx, params->client_cert))
+ return -1;
+
+ if (tls_global_private_key(ssl_ctx, params->private_key,
+ params->private_key_passwd))
+ return -1;
+
+ return 0;
+}
+
+
int tls_connection_get_keyblock_size(void *tls_ctx,
struct tls_connection *conn)
{
@@ -2141,3 +2278,40 @@ int tls_connection_get_keyblock_size(void *tls_ctx,
EVP_MD_size(h) +
EVP_CIPHER_iv_length(c));
}
+
+
+unsigned int tls_capabilities(void *tls_ctx)
+{
+ return 0;
+}
+
+
+int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn,
+ int tls_ia)
+{
+ return -1;
+}
+
+
+int tls_connection_ia_send_phase_finished(void *tls_ctx,
+ struct tls_connection *conn,
+ int final,
+ u8 *out_data, size_t out_len)
+{
+ return -1;
+}
+
+
+int tls_connection_ia_final_phase_finished(void *tls_ctx,
+ 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)
+{
+ return -1;
+}
OpenPOWER on IntegriCloud