aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2005-08-23 03:13:42 (GMT)
committerJouni Malinen <j@w1.fi>2005-08-23 03:13:42 (GMT)
commitefb47fa42fdff8679c2cc8627446c1e0ca91ec92 (patch)
tree54d8e63f039f9aeec489566d87b62deefda8719d
parentd2f6438e222962edcc3c1bac7236fa283329d038 (diff)
downloadhostap-history-efb47fa42fdff8679c2cc8627446c1e0ca91ec92.zip
hostap-history-efb47fa42fdff8679c2cc8627446c1e0ca91ec92.tar.gz
hostap-history-efb47fa42fdff8679c2cc8627446c1e0ca91ec92.tar.bz2
Modified TLS wrapper interface to use one function,
tls_connection_set_params() to set all certificate and private key parameters for TLS connections. The previous design worked fine with OpenSSL, but other TLS libraries, e.g., GnuTLS, may have different requirements and it is easier to implement the wrapper code if all this information is available at the same time. In addition, this allows OpenSSL engine specific parts of the TLS interface to be ignored in non-OpenSSL implementations.
-rw-r--r--wpa_supplicant/eap_tls_common.c121
-rw-r--r--wpa_supplicant/tls.h130
-rw-r--r--wpa_supplicant/tls_gnutls.c187
-rw-r--r--wpa_supplicant/tls_openssl.c101
4 files changed, 204 insertions, 335 deletions
diff --git a/wpa_supplicant/eap_tls_common.c b/wpa_supplicant/eap_tls_common.c
index 45cbb7e..e2d5a75 100644
--- a/wpa_supplicant/eap_tls_common.c
+++ b/wpa_supplicant/eap_tls_common.c
@@ -29,47 +29,37 @@
int eap_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
struct wpa_ssid *config)
{
- int ret = -1;
- char *ca_cert, *client_cert, *private_key, *private_key_passwd,
- *dh_file, *subject_match, *altsubject_match,
- *engine_id, **ppin, *key_id;
+ int ret = -1, res;
+ struct tls_connection_params params;
data->eap = sm;
data->phase2 = sm->init_phase2;
+ memset(&params, 0, sizeof(params));
+ params.engine = config->engine;
if (config == NULL) {
- ca_cert = NULL;
- client_cert = NULL;
- private_key = NULL;
- private_key_passwd = NULL;
- dh_file = NULL;
- subject_match = NULL;
- altsubject_match = NULL;
- engine_id = NULL;
- ppin = NULL;
- key_id = NULL;
} else if (data->phase2) {
- ca_cert = (char *) config->ca_cert2;
- client_cert = (char *) config->client_cert2;
- private_key = (char *) config->private_key2;
- private_key_passwd = (char *) config->private_key2_passwd;
- dh_file = (char *) config->dh_file2;
- subject_match = (char *) config->subject_match2;
- altsubject_match = (char *) config->altsubject_match2;
- engine_id = NULL;
- ppin = NULL;
- key_id = NULL;
+ params.ca_cert = (char *) config->ca_cert2;
+ params.client_cert = (char *) config->client_cert2;
+ params.private_key = (char *) config->private_key2;
+ params.private_key_passwd =
+ (char *) config->private_key2_passwd;
+ params.dh_file = (char *) config->dh_file2;
+ params.subject_match = (char *) config->subject_match2;
+ params.altsubject_match = (char *) config->altsubject_match2;
} else {
- ca_cert = (char *) config->ca_cert;
- client_cert = (char *) config->client_cert;
- private_key = (char *) config->private_key;
- private_key_passwd = (char *) config->private_key_passwd;
- dh_file = (char *) config->dh_file;
- subject_match = (char *) config->subject_match;
- altsubject_match = (char *) config->altsubject_match;
- engine_id = config->engine_id;
- ppin = &(config->pin);
- key_id = config->key_id;
+ params.ca_cert = (char *) config->ca_cert;
+ params.client_cert = (char *) config->client_cert;
+ params.private_key = (char *) config->private_key;
+ params.private_key_passwd =
+ (char *) config->private_key_passwd;
+ params.dh_file = (char *) config->dh_file;
+ params.subject_match = (char *) config->subject_match;
+ params.altsubject_match = (char *) config->altsubject_match;
+ params.engine_id = config->engine_id;
+ params.pin = config->pin;
+ params.key_id = config->key_id;
}
+
data->conn = tls_connection_init(sm->ssl_ctx);
if (data->conn == NULL) {
wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS "
@@ -77,52 +67,25 @@ int eap_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
goto done;
}
- if (tls_connection_set_subject_match(sm->ssl_ctx, data->conn,
- subject_match, altsubject_match))
- {
- wpa_printf(MSG_INFO, "TLS: Failed to set subject name "
- "matching");
- goto done;
- }
-
- if (tls_connection_ca_cert(sm->ssl_ctx, data->conn, ca_cert)) {
- wpa_printf(MSG_INFO, "TLS: Failed to load root certificate "
- "'%s'", ca_cert);
- goto done;
- }
-
- if (tls_connection_client_cert(sm->ssl_ctx, data->conn, client_cert)) {
- wpa_printf(MSG_INFO, "TLS: Failed to load client certificate "
- "'%s'", client_cert);
+ res = tls_connection_set_params(sm->ssl_ctx, data->conn, &params);
+ if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) {
+ /* At this point with the pkcs11 engine the PIN might be wrong.
+ * We reset the PIN in the configuration to be sure to not use
+ * it again and the calling function must request a new one */
+ free(config->pin);
+ config->pin = NULL;
+ } else if (res == TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED) {
+ wpa_printf(MSG_INFO,"TLS: Failed to load private key");
+ /* We don't know exactly but maybe the PIN was wrong,
+ * so ask for a new one. */
+ free(config->pin);
+ config->pin = NULL;
+ eap_sm_request_pin(sm, config);
+ sm->ignore = TRUE;
goto done;
- }
-
- if (config->engine) {
- wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine");
- if (tls_engine_init(data->conn, engine_id, ppin, key_id))
- goto done;
- if (tls_connection_engine_private_key(sm->ssl_ctx,
- data->conn)) {
- wpa_printf(MSG_INFO,"TLS: Failed to load private key");
- /* We don't know exactly but maybe the PIN was wrong,
- * so ask for a new one. */
- free(config->pin);
- config->pin = NULL;
- eap_sm_request_pin(sm, config);
- sm->ignore = TRUE;
- goto done;
- }
- } else if (tls_connection_private_key(sm->ssl_ctx, data->conn,
- private_key,
- private_key_passwd)) {
- wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'",
- private_key);
- goto done;
- }
-
- if (dh_file && tls_connection_dh(sm->ssl_ctx, data->conn, dh_file)) {
- wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
- dh_file);
+ } else if (res) {
+ wpa_printf(MSG_INFO, "TLS: Failed to set TLS connection "
+ "parameters");
goto done;
}
diff --git a/wpa_supplicant/tls.h b/wpa_supplicant/tls.h
index e5e11b8..a116e0f 100644
--- a/wpa_supplicant/tls.h
+++ b/wpa_supplicant/tls.h
@@ -33,6 +33,44 @@ struct tls_config {
};
/**
+ * struct tls_connection_params - Parameters for TLS connection
+ * @subject_match: String to match in the subject of the peer certificate or
+ * %NULL to allow all subjects
+ * @altsubject_match: String to match in the alternative subject of the peer
+ * certificate or %NULL to allow all alternative subjects
+ * @ca_cert: File name for CA certificate in PEM or DER format
+ * @client_cert: File name for client certificate in PEM or DER format
+ * @private_key: File name for client private key in PEM or DER format
+ * @private_key_passwd: Passphrase for decrypted private key, %NULL if no
+ * passphrase is used.
+ * @dh_file: File name for DH/DSA data in PEM format, or %NULL if not used
+ * @engine: 1 = use engine (e.g., a smartcard) for private key operations
+ * (this is OpenSSL specific for now)
+ * @engine_id: engine id string (this is OpenSSL specific for now)
+ * @ppin: pointer to the pin variable in the configuration
+ * (this is OpenSSL specific for now)
+ * @key_id: the private key's key id (this is OpenSSL specific for now)
+ *
+ * TLS connection parameters to be configured with tls_connection_set_params().
+ */
+struct tls_connection_params {
+ const char *ca_cert;
+ const char *subject_match;
+ const char *altsubject_match;
+ const char *client_cert;
+ const char *private_key;
+ const char *private_key_passwd;
+ const char *dh_file;
+
+ /* OpenSSL specific variables */
+ int engine;
+ const char *engine_id;
+ const char *pin;
+ const char *key_id;
+};
+
+
+/**
* tls_init - Initialize TLS library
* @conf: Configuration data for TLS library
* Returns: Context data to be used as tls_ctx in calls to other functions,
@@ -51,18 +89,6 @@ void * tls_init(const struct tls_config *conf);
void tls_deinit(void *tls_ctx);
/**
- * tls_engine_init - Initialize the engine
- * @conn: Connection context data from tls_connection_init()
- * @engine_id: engine id string
- * @ppin: pointer to the pin variable in the configuration
- * @key_id: the private key's key id
- *
- * Returns: 0 on success, -1 on failure.
-*/
-int tls_engine_init(struct tls_connection *conn, const char *engine_id,
- char **ppin, const char *key_id);
-
-/**
* tls_get_errors - Process pending errors
* @tls_ctx: TLS context data from tls_init()
*
@@ -112,16 +138,24 @@ int tls_connection_established(void *tls_ctx, struct tls_connection *conn);
*/
int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn);
+enum {
+ TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED = -3,
+ TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED = -2
+};
/**
- * tls_connection_ca_cert - Set trusted CA certificate for TLS connection
+ * tls_connection_set_params - Set TLS connection parameters
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
- * @ca_cert: File name for CA certificate in PEM or DER format
+ * @params: Connection parameters
*
- * Returns: 0 on success, -1 on failure
+ * Returns: 0 on success, -1 on failure,
+ * TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on possible PIN error causing
+ * PKCS#11 engine failure, or
+ * TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the
+ * PKCS#11 engine private key.
*/
-int tls_connection_ca_cert(void *tls_ctx, struct tls_connection *conn,
- const char *ca_cert);
+int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
+ const struct tls_connection_params *params);
/**
* tls_global_ca_cert - Set trusted CA certificate for all TLS connections
@@ -144,22 +178,6 @@ int tls_global_ca_cert(void *tls_ctx, const char *ca_cert);
int tls_global_set_verify(void *tls_ctx, int check_crl);
/**
- * tls_connection_set_subject_match - Set peer certificate subject matching
- * @tls_ctx: TLS context data from tls_init()
- * @conn: Connection context data from tls_connection_init()
- * @subject_match: String to match in the subject of the peer certificate or
- * @altsubject_match: String to match in the alt. subject of the peer
- * certificate or %NULL to allow all alt. subjects
- * %NULL to allow all subjects
- *
- * Returns: 0 on success, -1 on failure
- */
-int tls_connection_set_subject_match(void *tls_ctx,
- struct tls_connection *conn,
- const char *subject_match,
- const char *altsubject_match);
-
-/**
* tls_connection_set_verify - Set certificate verification options
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
@@ -171,17 +189,6 @@ int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
int verify_peer);
/**
- * tls_connection_client_cert - Set client certificate for TLS connection
- * @tls_ctx: TLS context data from tls_init()
- * @conn: Connection context data from tls_connection_init()
- * @client_cert: File name for client certificate in PEM or DER format
- *
- * Returns: 0 on success, -1 on failure
- */
-int tls_connection_client_cert(void *tls_ctx, struct tls_connection *conn,
- const char *client_cert);
-
-/**
* tls_global_client_cert - Set client certificate for all TLS connections
* @tls_ctx: TLS context data from tls_init()
* @client_cert: File name for client certificate in PEM or DER format
@@ -191,30 +198,6 @@ int tls_connection_client_cert(void *tls_ctx, struct tls_connection *conn,
int tls_global_client_cert(void *tls_ctx, const char *client_cert);
/**
- * tls_connection_private_key - Set private key for TLS connection
- * @tls_ctx: TLS context data from tls_init()
- * @conn: Connection context data from tls_connection_init()
- * @private_key: File name for client private key in PEM or DER format
- * @private_key_passwd: Passphrase for decrypted private key, %NULL if no
- * passphrase is used.
- *
- * Returns: 0 on success, -1 on failure
- */
-int tls_connection_private_key(void *tls_ctx, struct tls_connection *conn,
- const char *private_key,
- const char *private_key_passwd);
-
-/**
- * tls_connection_engine_private_key - Set private key for TLS connection
- * @tls_ctx: TLS context data from tls_init()
- * @conn: Connection context data from tls_connection_init()
- *
- * Returns: 0 on success, -1 on failure
- */
-int tls_connection_engine_private_key(void *tls_ctx,
- struct tls_connection *conn);
-
-/**
* tls_global_private_key - Set private key for all TLS connections
* @tls_ctx: TLS context data from tls_init()
* @private_key: File name for client private key in PEM or DER format
@@ -227,17 +210,6 @@ int tls_global_private_key(void *tls_ctx, const char *private_key,
const char *private_key_passwd);
/**
- * tls_connection_dh - Set DH/DSA parameters for TLS connection
- * @tls_ctx: TLS context data from tls_init()
- * @conn: Connection context data from tls_connection_init()
- * @dh_file: File name for DH/DSA data in PEM format.
- *
- * Returns: 0 on success, -1 on failure
- */
-int tls_connection_dh(void *tls_ctx, struct tls_connection *conn,
- const char *dh_file);
-
-/**
* tls_connection_get_keys - Get master key and random data from TLS connection
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
diff --git a/wpa_supplicant/tls_gnutls.c b/wpa_supplicant/tls_gnutls.c
index e1f8c34..965350a 100644
--- a/wpa_supplicant/tls_gnutls.c
+++ b/wpa_supplicant/tls_gnutls.c
@@ -73,8 +73,6 @@ struct tls_connection {
size_t push_buf_len, pull_buf_len;
gnutls_certificate_credentials_t xcred;
-
- char *client_cert, *private_key, *private_key_passwd;
};
@@ -146,18 +144,6 @@ void tls_deinit(void *ssl_ctx)
}
-int tls_engine_init(struct tls_connection *conn, const char *engine_id,
- char **ppin, const char *key_id)
-{
- return 0;
-}
-
-
-static void tls_engine_deinit(struct tls_connection *conn)
-{
-}
-
-
int tls_get_errors(void *ssl_ctx)
{
return 0;
@@ -239,11 +225,6 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
gnutls_certificate_allocate_credentials(&conn->xcred);
- /* TODO:
- * set ctx/app ptr back to conn
- * set TLSv1 only
- */
-
return conn;
}
@@ -255,14 +236,10 @@ void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
gnutls_certificate_free_credentials(conn->xcred);
gnutls_deinit(conn->session);
free(conn->pre_shared_secret);
- tls_engine_deinit(conn);
free(conn->subject_match);
free(conn->altsubject_match);
free(conn->push_buf);
free(conn->pull_buf);
- free(conn->client_cert);
- free(conn->private_key);
- free(conn->private_key_passwd);
free(conn);
}
@@ -389,38 +366,76 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
#endif
-int tls_connection_ca_cert(void *ssl_ctx, struct tls_connection *conn,
- const char *ca_cert)
+int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
+ const struct tls_connection_params *params)
{
int ret;
- if (conn == NULL)
+ if (conn == NULL || params == NULL)
return -1;
+ free(conn->subject_match);
+ conn->subject_match = NULL;
+ if (params->subject_match) {
+ conn->subject_match = strdup(params->subject_match);
+ if (conn->subject_match == NULL)
+ return -1;
+ }
+
+ free(conn->altsubject_match);
+ conn->altsubject_match = NULL;
+ if (params->altsubject_match) {
+ conn->altsubject_match = strdup(params->altsubject_match);
+ if (conn->altsubject_match == NULL)
+ return -1;
+ }
+
/* TODO: gnutls_certificate_set_verify_flags(xcred, flags);
* to force peer validation(?) */
- if (ca_cert) {
+ if (params->ca_cert) {
ret = gnutls_certificate_set_x509_trust_file(
- conn->xcred, ca_cert, GNUTLS_X509_FMT_PEM);
+ conn->xcred, params->ca_cert, GNUTLS_X509_FMT_PEM);
if (ret < 0) {
wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' "
- "in PEM format: %s", ca_cert,
+ "in PEM format: %s", params->ca_cert,
gnutls_strerror(ret));
ret = gnutls_certificate_set_x509_trust_file(
- conn->xcred, ca_cert, GNUTLS_X509_FMT_DER);
+ conn->xcred, params->ca_cert,
+ GNUTLS_X509_FMT_DER);
if (ret < 0) {
wpa_printf(MSG_DEBUG, "Failed to read CA cert "
- "'%s' in DER format: %s", ca_cert,
+ "'%s' in DER format: %s",
+ params->ca_cert,
gnutls_strerror(ret));
}
}
}
+ if (params->client_cert && params->private_key) {
+ /* TODO: private_key_passwd? */
+ ret = gnutls_certificate_set_x509_key_file(
+ conn->xcred, params->client_cert, params->private_key,
+ GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ wpa_printf(MSG_DEBUG, "Failed to read client cert/key "
+ "in PEM format: %s", gnutls_strerror(ret));
+ ret = gnutls_certificate_set_x509_key_file(
+ conn->xcred, params->client_cert,
+ params->private_key, GNUTLS_X509_FMT_DER);
+ if (ret < 0) {
+ wpa_printf(MSG_DEBUG, "Failed to read client "
+ "cert/key in DER format: %s",
+ gnutls_strerror(ret));
+ return ret;
+ }
+ }
+ }
+
ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE,
conn->xcred);
if (ret < 0) {
- wpa_printf(MSG_INFO, "Failed to configure CA cert: %s",
+ wpa_printf(MSG_INFO, "Failed to configure credentials: %s",
gnutls_strerror(ret));
}
@@ -442,34 +457,6 @@ int tls_global_set_verify(void *ssl_ctx, int check_crl)
}
-int tls_connection_set_subject_match(void *ssl_ctx,
- struct tls_connection *conn,
- const char *subject_match,
- const char *altsubject_match)
-{
- if (conn == NULL)
- return -1;
-
- free(conn->subject_match);
- conn->subject_match = NULL;
- if (subject_match) {
- conn->subject_match = strdup(subject_match);
- if (conn->subject_match == NULL)
- return -1;
- }
-
- free(conn->altsubject_match);
- conn->altsubject_match = NULL;
- if (altsubject_match) {
- conn->altsubject_match = strdup(altsubject_match);
- if (conn->altsubject_match == NULL)
- return -1;
- }
-
- return 0;
-}
-
-
int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
int verify_peer)
{
@@ -482,50 +469,6 @@ int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
}
-static int tls_connection_cert_key(struct tls_connection *conn)
-{
- int ret;
-
- /* TODO: private_key_passwd? */
- ret = gnutls_certificate_set_x509_key_file(
- conn->xcred, conn->client_cert, conn->private_key,
- GNUTLS_X509_FMT_PEM);
- if (ret < 0) {
- wpa_printf(MSG_DEBUG, "Failed to read client cert/key in PEM "
- "format: %s", gnutls_strerror(ret));
- return ret;
- }
-
- ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE,
- conn->xcred);
- if (ret < 0) {
- wpa_printf(MSG_INFO, "Failed to configure client cert/key: %s",
- gnutls_strerror(ret));
- }
-
- return 0;
-}
-
-
-int tls_connection_client_cert(void *ssl_ctx, struct tls_connection *conn,
- const char *client_cert)
-{
- if (client_cert == NULL)
- return 0;
- if (conn == NULL)
- return -1;
-
- free(conn->client_cert);
- conn->client_cert = NULL;
- if (client_cert)
- conn->client_cert = strdup(client_cert);
- if (conn->private_key && conn->client_cert)
- return tls_connection_cert_key(conn);
-
- return 0;
-}
-
-
int tls_global_client_cert(void *_ssl_ctx, const char *client_cert)
{
/* TODO */
@@ -533,34 +476,6 @@ int tls_global_client_cert(void *_ssl_ctx, const char *client_cert)
}
-int tls_connection_engine_private_key(void *_ssl_ctx,
- struct tls_connection *conn)
-{
- wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but "
- "engine support was not compiled in");
- return -1;
-}
-
-
-int tls_connection_private_key(void *_ssl_ctx, struct tls_connection *conn,
- const char *private_key,
- const char *private_key_passwd)
-{
- free(conn->private_key);
- conn->private_key = NULL;
- free(conn->private_key_passwd);
- conn->private_key_passwd = NULL;
- if (private_key)
- conn->private_key = strdup(private_key);
- if (private_key_passwd)
- conn->private_key_passwd = strdup(private_key_passwd);
- if (conn->private_key && conn->client_cert)
- return tls_connection_cert_key(conn);
-
- return 0;
-}
-
-
int tls_global_private_key(void *_ssl_ctx, const char *private_key,
const char *private_key_passwd)
{
@@ -569,14 +484,6 @@ int tls_global_private_key(void *_ssl_ctx, const char *private_key,
}
-int tls_connection_dh(void *ssl_ctx, struct tls_connection *conn,
- const char *dh_file)
-{
- /* TOOD */
- return -1;
-}
-
-
int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
struct tls_keys *keys)
{
diff --git a/wpa_supplicant/tls_openssl.c b/wpa_supplicant/tls_openssl.c
index dfc1800..e6af3a4 100644
--- a/wpa_supplicant/tls_openssl.c
+++ b/wpa_supplicant/tls_openssl.c
@@ -636,19 +636,16 @@ void tls_deinit(void *ssl_ctx)
}
-int tls_engine_init(struct tls_connection *conn, const char *engine_id,
- char **ppin, const char *key_id)
+static int tls_engine_init(struct tls_connection *conn, const char *engine_id,
+ const char *pin, const char *key_id)
{
#ifndef OPENSSL_NO_ENGINE
- if (ppin == NULL) {
- wpa_printf(MSG_DEBUG, "ENGINE: %s - ppin is NULL", __func__);
- return -1;
- }
+ int ret = -1;
if (engine_id == NULL) {
wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set");
return -1;
}
- if (*ppin == NULL) {
+ if (pin == NULL) {
wpa_printf(MSG_ERROR, "ENGINE: Smartcard PIN not set");
return -1;
}
@@ -684,11 +681,7 @@ int tls_engine_init(struct tls_connection *conn, const char *engine_id,
char *error = ERR_error_string(ERR_get_error(), NULL);
wpa_printf(MSG_ERROR, "ENGINE: can't load private key with id"
" '%s' [%s]", key_id, error);
- /* At this point with the pkcs11 engine the PIN might be wrong.
- * We reset the PIN in the configuration to be sure to not use
- * it again and the calling function must request a new one */
- free(*ppin);
- *ppin = NULL;
+ ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
goto err;
}
return 0;
@@ -704,7 +697,7 @@ err:
conn->private_key = NULL;
}
- return -1;
+ return ret;
#else /* OPENSSL_NO_ENGINE */
return 0;
#endif /* OPENSSL_NO_ENGINE */
@@ -918,12 +911,9 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
}
-int tls_connection_ca_cert(void *ssl_ctx, struct tls_connection *conn,
- const char *ca_cert)
+static int tls_connection_ca_cert(void *ssl_ctx, struct tls_connection *conn,
+ const char *ca_cert)
{
- if (conn == NULL)
- return -1;
-
if (ca_cert) {
if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
{
@@ -988,14 +978,11 @@ int tls_global_set_verify(void *ssl_ctx, int check_crl)
}
-int tls_connection_set_subject_match(void *ssl_ctx,
- struct tls_connection *conn,
- const char *subject_match,
- const char *altsubject_match)
+static int tls_connection_set_subject_match(void *ssl_ctx,
+ struct tls_connection *conn,
+ const char *subject_match,
+ const char *altsubject_match)
{
- if (conn == NULL)
- return -1;
-
free(conn->subject_match);
conn->subject_match = NULL;
if (subject_match) {
@@ -1036,13 +1023,12 @@ int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
}
-int tls_connection_client_cert(void *ssl_ctx, struct tls_connection *conn,
- const char *client_cert)
+static int tls_connection_client_cert(void *ssl_ctx,
+ struct tls_connection *conn,
+ const char *client_cert)
{
if (client_cert == NULL)
return 0;
- if (conn == NULL)
- return -1;
if (SSL_use_certificate_file(conn->ssl, client_cert,
SSL_FILETYPE_ASN1) != 1 &&
@@ -1183,8 +1169,8 @@ static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key,
}
-int tls_connection_engine_private_key(void *_ssl_ctx,
- struct tls_connection *conn)
+static int tls_connection_engine_private_key(void *_ssl_ctx,
+ struct tls_connection *conn)
{
#ifndef OPENSSL_NO_ENGINE
if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) {
@@ -1207,17 +1193,16 @@ int tls_connection_engine_private_key(void *_ssl_ctx,
}
-int tls_connection_private_key(void *_ssl_ctx, struct tls_connection *conn,
- const char *private_key,
- const char *private_key_passwd)
+static int tls_connection_private_key(void *_ssl_ctx,
+ struct tls_connection *conn,
+ const char *private_key,
+ const char *private_key_passwd)
{
SSL_CTX *ssl_ctx = _ssl_ctx;
char *passwd;
if (private_key == NULL)
return 0;
- if (conn == NULL)
- return -1;
if (private_key_passwd) {
passwd = strdup(private_key_passwd);
@@ -1299,7 +1284,7 @@ int tls_global_private_key(void *_ssl_ctx, const char *private_key,
}
-int tls_connection_dh(void *ssl_ctx, struct tls_connection *conn,
+static int tls_connection_dh(void *ssl_ctx, struct tls_connection *conn,
const char *dh_file)
{
#ifdef OPENSSL_NO_DH
@@ -1685,3 +1670,45 @@ int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
return -1;
return conn->write_alerts;
}
+
+
+int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
+ const struct tls_connection_params *params)
+{
+ int ret;
+
+ if (conn == NULL)
+ return -1;
+ if (tls_connection_set_subject_match(tls_ctx, conn,
+ params->subject_match,
+ params->altsubject_match))
+ return -1;
+ if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert))
+ return -1;
+ if (tls_connection_client_cert(tls_ctx, conn, params->client_cert))
+ return -1;
+
+ if (params->engine) {
+ wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine");
+ ret = tls_engine_init(conn, params->engine_id, params->pin,
+ params->key_id);
+ if (ret)
+ return ret;
+ if (tls_connection_engine_private_key(tls_ctx, conn))
+ return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
+ } else if (tls_connection_private_key(tls_ctx, conn,
+ params->private_key,
+ params->private_key_passwd)) {
+ wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'",
+ params->private_key);
+ return -1;
+ }
+
+ if (tls_connection_dh(tls_ctx, conn, params->dh_file)) {
+ wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
+ params->dh_file);
+ return -1;
+ }
+
+ return 0;
+}