EAP peer: Move certificate configuration params into shared struct

These parameters for certificate authentication are identical for the
Phase 1 (EAP-TLS alone) and Phase 2 (EAP-TLS inside a TLS tunnel).
Furthermore, yet another copy would be needed to support separate
machine credential in Phase 2. Clean this up by moving the shared
parameters into a separate data struct that can then be used for each
need without having to define separate struct members for each use.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2019-09-01 15:37:22 +03:00
parent 6e711e7ab3
commit b99c4cadb7
10 changed files with 250 additions and 428 deletions

View file

@ -299,7 +299,7 @@ int eap_example_peer_init(void)
eap_ctx.eap_config.identity_len = 4; eap_ctx.eap_config.identity_len = 4;
eap_ctx.eap_config.password = (u8 *) os_strdup("password"); eap_ctx.eap_config.password = (u8 *) os_strdup("password");
eap_ctx.eap_config.password_len = 8; eap_ctx.eap_config.password_len = 8;
eap_ctx.eap_config.ca_cert = os_strdup("ca.pem"); eap_ctx.eap_config.cert.ca_cert = os_strdup("ca.pem");
eap_ctx.eap_config.fragment_size = 1398; eap_ctx.eap_config.fragment_size = 1398;
os_memset(&eap_cb, 0, sizeof(eap_cb)); os_memset(&eap_cb, 0, sizeof(eap_cb));
@ -332,7 +332,7 @@ void eap_example_peer_deinit(void)
wpabuf_free(eap_ctx.eapReqData); wpabuf_free(eap_ctx.eapReqData);
os_free(eap_ctx.eap_config.identity); os_free(eap_ctx.eap_config.identity);
os_free(eap_ctx.eap_config.password); os_free(eap_ctx.eap_config.password);
os_free(eap_ctx.eap_config.ca_cert); os_free(eap_ctx.eap_config.cert.ca_cert);
} }

View file

@ -1,6 +1,6 @@
/* /*
* EAP peer state machines (RFC 4137) * EAP peer state machines (RFC 4137)
* Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi> * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
* *
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
@ -2688,7 +2688,7 @@ struct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config,
if (eap_allowed_phase2_type(vendor, method)) { if (eap_allowed_phase2_type(vendor, method)) {
if (vendor == EAP_VENDOR_IETF && if (vendor == EAP_VENDOR_IETF &&
method == EAP_TYPE_TLS && config && method == EAP_TYPE_TLS && config &&
config->private_key2 == NULL) !config->phase2_cert.private_key)
continue; continue;
buf[*count].vendor = vendor; buf[*count].vendor = vendor;
buf[*count].method = method; buf[*count].method = method;

View file

@ -1,6 +1,6 @@
/* /*
* EAP peer configuration data * EAP peer configuration data
* Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi> * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
* *
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
@ -10,96 +10,9 @@
#define EAP_CONFIG_H #define EAP_CONFIG_H
/** /**
* struct eap_peer_config - EAP peer configuration/credentials * struct eap_peer_cert_config - EAP peer certificate configuration/credential
*/ */
struct eap_peer_config { struct eap_peer_cert_config {
/**
* identity - EAP Identity
*
* This field is used to set the real user identity or NAI (for
* EAP-PSK/PAX/SAKE/GPSK).
*/
u8 *identity;
/**
* identity_len - EAP Identity length
*/
size_t identity_len;
/**
* anonymous_identity - Anonymous EAP Identity
*
* This field is used for unencrypted use with EAP types that support
* different tunnelled identity, e.g., EAP-TTLS, in order to reveal the
* real identity (identity field) only to the authentication server.
*
* If not set, the identity field will be used for both unencrypted and
* protected fields.
*
* This field can also be used with EAP-SIM/AKA/AKA' to store the
* pseudonym identity.
*/
u8 *anonymous_identity;
/**
* anonymous_identity_len - Length of anonymous_identity
*/
size_t anonymous_identity_len;
u8 *imsi_identity;
size_t imsi_identity_len;
/**
* machine_identity - EAP Identity for machine credential
*
* This field is used to set the machine identity or NAI for cases where
* and explicit machine credential (instead of or in addition to a user
* credential (from %identity) is needed.
*/
u8 *machine_identity;
/**
* machine_identity_len - EAP Identity length for machine credential
*/
size_t machine_identity_len;
/**
* password - Password string for EAP
*
* This field can include either the plaintext password (default
* option) or a NtPasswordHash (16-byte MD4 hash of the unicode
* presentation of the password) if flags field has
* EAP_CONFIG_FLAGS_PASSWORD_NTHASH bit set to 1. NtPasswordHash can
* only be used with authentication mechanism that use this hash as the
* starting point for operation: MSCHAP and MSCHAPv2 (EAP-MSCHAPv2,
* EAP-TTLS/MSCHAPv2, EAP-TTLS/MSCHAP, LEAP).
*
* In addition, this field is used to configure a pre-shared key for
* EAP-PSK/PAX/SAKE/GPSK. The length of the PSK must be 16 for EAP-PSK
* and EAP-PAX and 32 for EAP-SAKE. EAP-GPSK can use a variable length
* PSK.
*/
u8 *password;
/**
* password_len - Length of password field
*/
size_t password_len;
/**
* machine_password - Password string for EAP machine credential
*
* This field is used when machine credential based on username/password
* is needed instead of a user credential (from %password). See
* %password for more details on the format.
*/
u8 *machine_password;
/**
* machine_password_len - Length of machine credential password field
*/
size_t machine_password_len;
/** /**
* ca_cert - File path to CA certificate file (PEM/DER) * ca_cert - File path to CA certificate file (PEM/DER)
* *
@ -258,14 +171,6 @@ struct eap_peer_config {
*/ */
char *check_cert_subject; char *check_cert_subject;
/**
* check_cert_subject2 - Constraint for server certificate subject fields
*
* This field is like check_cert_subject, but used for phase 2 (inside
* EAP-TTLS/PEAP/FAST tunnel) authentication.
*/
char *check_cert_subject2;
/** /**
* altsubject_match - Constraint for server certificate alt. subject * altsubject_match - Constraint for server certificate alt. subject
* *
@ -327,115 +232,163 @@ struct eap_peer_config {
char *domain_match; char *domain_match;
/** /**
* ca_cert2 - File path to CA certificate file (PEM/DER) (Phase 2) * pin - PIN for USIM, GSM SIM, and smartcards
* *
* This file can have one or more trusted CA certificates. If ca_cert2 * This field is used to configure PIN for SIM and smartcards for
* and ca_path2 are not included, server certificate will not be * EAP-SIM and EAP-AKA. In addition, this is used with EAP-TLS if a
* verified. This is insecure and a trusted CA certificate should * smartcard is used for private key operations.
* always be configured. Full path to the file should be used since
* working directory may change when wpa_supplicant is run in the
* background.
* *
* This field is like ca_cert, but used for phase 2 (inside * If left out, this will be asked through control interface.
* EAP-TTLS/PEAP/FAST tunnel) authentication.
*
* Alternatively, a named configuration blob can be used by setting
* this to blob://blob_name.
*/ */
char *ca_cert2; char *pin;
/** /**
* ca_path2 - Directory path for CA certificate files (PEM) (Phase 2) * engine - Enable OpenSSL engine (e.g., for smartcard access)
* *
* This path may contain multiple CA certificates in OpenSSL format. * This is used if private key operations for EAP-TLS are performed
* Common use for this is to point to system trusted CA list which is * using a smartcard.
* often installed into directory like /etc/ssl/certs. If configured,
* these certificates are added to the list of trusted CAs. ca_cert
* may also be included in that case, but it is not required.
*
* This field is like ca_path, but used for phase 2 (inside
* EAP-TTLS/PEAP/FAST tunnel) authentication.
*/ */
char *ca_path2; int engine;
/** /**
* client_cert2 - File path to client certificate file * engine_id - Engine ID for OpenSSL engine
* *
* This field is like client_cert, but used for phase 2 (inside * "opensc" to select OpenSC engine or "pkcs11" to select PKCS#11
* EAP-TTLS/PEAP/FAST tunnel) authentication. Full path to the * engine.
* file should be used since working directory may change when
* wpa_supplicant is run in the background.
* *
* Alternatively, a named configuration blob can be used by setting * This is used if private key operations for EAP-TLS are performed
* this to blob://blob_name. * using a smartcard.
*/ */
char *client_cert2; char *engine_id;
/** /**
* private_key2 - File path to client private key file * key_id - Key ID for OpenSSL engine
* *
* This field is like private_key, but used for phase 2 (inside * This is used if private key operations for EAP-TLS are performed
* EAP-TTLS/PEAP/FAST tunnel) authentication. Full path to the * using a smartcard.
* file should be used since working directory may change when
* wpa_supplicant is run in the background.
*
* Alternatively, a named configuration blob can be used by setting
* this to blob://blob_name.
*/ */
char *private_key2; char *key_id;
/** /**
* private_key2_passwd - Password for private key file * cert_id - Cert ID for OpenSSL engine
* *
* This field is like private_key_passwd, but used for phase 2 (inside * This is used if the certificate operations for EAP-TLS are performed
* EAP-TTLS/PEAP/FAST tunnel) authentication. * using a smartcard.
*/ */
char *private_key2_passwd; char *cert_id;
/** /**
* dh_file2 - File path to DH/DSA parameters file (in PEM format) * ca_cert_id - CA Cert ID for OpenSSL engine
* *
* This field is like dh_file, but used for phase 2 (inside * This is used if the CA certificate for EAP-TLS is on a smartcard.
* EAP-TTLS/PEAP/FAST tunnel) authentication. Full path to the
* file should be used since working directory may change when
* wpa_supplicant is run in the background.
*
* Alternatively, a named configuration blob can be used by setting
* this to blob://blob_name.
*/ */
char *dh_file2; char *ca_cert_id;
};
/**
* struct eap_peer_config - EAP peer configuration/credentials
*/
struct eap_peer_config {
/**
* identity - EAP Identity
*
* This field is used to set the real user identity or NAI (for
* EAP-PSK/PAX/SAKE/GPSK).
*/
u8 *identity;
/** /**
* subject_match2 - Constraint for server certificate subject * identity_len - EAP Identity length
*
* This field is like subject_match, but used for phase 2 (inside
* EAP-TTLS/PEAP/FAST tunnel) authentication.
*/ */
char *subject_match2; size_t identity_len;
/** /**
* altsubject_match2 - Constraint for server certificate alt. subject * anonymous_identity - Anonymous EAP Identity
* *
* This field is like altsubject_match, but used for phase 2 (inside * This field is used for unencrypted use with EAP types that support
* EAP-TTLS/PEAP/FAST tunnel) authentication. * different tunnelled identity, e.g., EAP-TTLS, in order to reveal the
* real identity (identity field) only to the authentication server.
*
* If not set, the identity field will be used for both unencrypted and
* protected fields.
*
* This field can also be used with EAP-SIM/AKA/AKA' to store the
* pseudonym identity.
*/ */
char *altsubject_match2; u8 *anonymous_identity;
/** /**
* domain_suffix_match2 - Constraint for server domain name * anonymous_identity_len - Length of anonymous_identity
*
* This field is like domain_suffix_match, but used for phase 2 (inside
* EAP-TTLS/PEAP/FAST tunnel) authentication.
*/ */
char *domain_suffix_match2; size_t anonymous_identity_len;
u8 *imsi_identity;
size_t imsi_identity_len;
/** /**
* domain_match2 - Constraint for server domain name * machine_identity - EAP Identity for machine credential
* *
* This field is like domain_match, but used for phase 2 (inside * This field is used to set the machine identity or NAI for cases where
* EAP-TTLS/PEAP/FAST tunnel) authentication. * and explicit machine credential (instead of or in addition to a user
* credential (from %identity) is needed.
*/ */
char *domain_match2; u8 *machine_identity;
/**
* machine_identity_len - EAP Identity length for machine credential
*/
size_t machine_identity_len;
/**
* password - Password string for EAP
*
* This field can include either the plaintext password (default
* option) or a NtPasswordHash (16-byte MD4 hash of the unicode
* presentation of the password) if flags field has
* EAP_CONFIG_FLAGS_PASSWORD_NTHASH bit set to 1. NtPasswordHash can
* only be used with authentication mechanism that use this hash as the
* starting point for operation: MSCHAP and MSCHAPv2 (EAP-MSCHAPv2,
* EAP-TTLS/MSCHAPv2, EAP-TTLS/MSCHAP, LEAP).
*
* In addition, this field is used to configure a pre-shared key for
* EAP-PSK/PAX/SAKE/GPSK. The length of the PSK must be 16 for EAP-PSK
* and EAP-PAX and 32 for EAP-SAKE. EAP-GPSK can use a variable length
* PSK.
*/
u8 *password;
/**
* password_len - Length of password field
*/
size_t password_len;
/**
* machine_password - Password string for EAP machine credential
*
* This field is used when machine credential based on username/password
* is needed instead of a user credential (from %password). See
* %password for more details on the format.
*/
u8 *machine_password;
/**
* machine_password_len - Length of machine credential password field
*/
size_t machine_password_len;
/**
* cert - Certificate parameters for Phase 1
*/
struct eap_peer_cert_config cert;
/**
* phase2_cert - Certificate parameters for Phase 2
*
* This is like cert, but used for Phase 2 (inside
* EAP-TTLS/PEAP/FAST/TEAP tunnel) authentication.
*/
struct eap_peer_cert_config phase2_cert;
/** /**
* eap_methods - Allowed EAP methods * eap_methods - Allowed EAP methods
@ -534,123 +487,6 @@ struct eap_peer_config {
*/ */
char *pcsc; char *pcsc;
/**
* pin - PIN for USIM, GSM SIM, and smartcards
*
* This field is used to configure PIN for SIM and smartcards for
* EAP-SIM and EAP-AKA. In addition, this is used with EAP-TLS if a
* smartcard is used for private key operations.
*
* If left out, this will be asked through control interface.
*/
char *pin;
/**
* engine - Enable OpenSSL engine (e.g., for smartcard access)
*
* This is used if private key operations for EAP-TLS are performed
* using a smartcard.
*/
int engine;
/**
* engine_id - Engine ID for OpenSSL engine
*
* "opensc" to select OpenSC engine or "pkcs11" to select PKCS#11
* engine.
*
* This is used if private key operations for EAP-TLS are performed
* using a smartcard.
*/
char *engine_id;
/**
* engine2 - Enable OpenSSL engine (e.g., for smartcard) (Phase 2)
*
* This is used if private key operations for EAP-TLS are performed
* using a smartcard.
*
* This field is like engine, but used for phase 2 (inside
* EAP-TTLS/PEAP/FAST tunnel) authentication.
*/
int engine2;
/**
* pin2 - PIN for USIM, GSM SIM, and smartcards (Phase 2)
*
* This field is used to configure PIN for SIM and smartcards for
* EAP-SIM and EAP-AKA. In addition, this is used with EAP-TLS if a
* smartcard is used for private key operations.
*
* This field is like pin2, but used for phase 2 (inside
* EAP-TTLS/PEAP/FAST tunnel) authentication.
*
* If left out, this will be asked through control interface.
*/
char *pin2;
/**
* engine2_id - Engine ID for OpenSSL engine (Phase 2)
*
* "opensc" to select OpenSC engine or "pkcs11" to select PKCS#11
* engine.
*
* This is used if private key operations for EAP-TLS are performed
* using a smartcard.
*
* This field is like engine_id, but used for phase 2 (inside
* EAP-TTLS/PEAP/FAST tunnel) authentication.
*/
char *engine2_id;
/**
* key_id - Key ID for OpenSSL engine
*
* This is used if private key operations for EAP-TLS are performed
* using a smartcard.
*/
char *key_id;
/**
* cert_id - Cert ID for OpenSSL engine
*
* This is used if the certificate operations for EAP-TLS are performed
* using a smartcard.
*/
char *cert_id;
/**
* ca_cert_id - CA Cert ID for OpenSSL engine
*
* This is used if the CA certificate for EAP-TLS is on a smartcard.
*/
char *ca_cert_id;
/**
* key2_id - Key ID for OpenSSL engine (phase2)
*
* This is used if private key operations for EAP-TLS are performed
* using a smartcard.
*/
char *key2_id;
/**
* cert2_id - Cert ID for OpenSSL engine (phase2)
*
* This is used if the certificate operations for EAP-TLS are performed
* using a smartcard.
*/
char *cert2_id;
/**
* ca_cert2_id - CA Cert ID for OpenSSL engine (phase2)
*
* This is used if the CA certificate for EAP-TLS is on a smartcard.
*/
char *ca_cert2_id;
/** /**
* otp - One-time-password * otp - One-time-password
* *

View file

@ -169,7 +169,7 @@ static void * eap_teap_init(struct eap_sm *sm)
eap_teap_parse_phase1(data, config->phase1); eap_teap_parse_phase1(data, config->phase1);
if ((data->provisioning_allowed & EAP_TEAP_PROV_AUTH) && if ((data->provisioning_allowed & EAP_TEAP_PROV_AUTH) &&
!config->ca_cert && !config->ca_path) { !config->cert.ca_cert && !config->cert.ca_path) {
/* Prevent PAC provisioning without mutual authentication /* Prevent PAC provisioning without mutual authentication
* (either by validating server certificate or by suitable * (either by validating server certificate or by suitable
* inner EAP method). */ * inner EAP method). */

View file

@ -1,6 +1,6 @@
/* /*
* EAP peer method: EAP-TLS (RFC 2716) * EAP peer method: EAP-TLS (RFC 2716)
* Copyright (c) 2004-2008, 2012-2015, Jouni Malinen <j@w1.fi> * Copyright (c) 2004-2008, 2012-2019, Jouni Malinen <j@w1.fi>
* *
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
@ -34,9 +34,10 @@ static void * eap_tls_init(struct eap_sm *sm)
struct eap_tls_data *data; struct eap_tls_data *data;
struct eap_peer_config *config = eap_get_config(sm); struct eap_peer_config *config = eap_get_config(sm);
if (config == NULL || if (config == NULL ||
((sm->init_phase2 ? config->private_key2 : config->private_key) ((sm->init_phase2 ? config->phase2_cert.private_key :
== NULL && config->cert.private_key) == NULL &&
(sm->init_phase2 ? config->engine2 : config->engine) == 0)) { (sm->init_phase2 ? config->phase2_cert.engine :
config->cert.engine) == 0)) {
wpa_printf(MSG_INFO, "EAP-TLS: Private key not configured"); wpa_printf(MSG_INFO, "EAP-TLS: Private key not configured");
return NULL; return NULL;
} }
@ -51,13 +52,13 @@ static void * eap_tls_init(struct eap_sm *sm)
if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TLS)) { if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TLS)) {
wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL."); wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL.");
eap_tls_deinit(sm, data); eap_tls_deinit(sm, data);
if (config->engine) { if (config->cert.engine) {
wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting Smartcard " wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting Smartcard "
"PIN"); "PIN");
eap_sm_request_pin(sm); eap_sm_request_pin(sm);
sm->ignore = TRUE; sm->ignore = TRUE;
} else if (config->private_key && !config->private_key_passwd) } else if (config->cert.private_key &&
{ !config->cert.private_key_passwd) {
wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting private " wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting private "
"key passphrase"); "key passphrase");
eap_sm_request_passphrase(sm); eap_sm_request_passphrase(sm);

View file

@ -105,8 +105,8 @@ static void eap_tls_params_flags(struct tls_connection_params *params,
} }
static void eap_tls_params_from_conf1(struct tls_connection_params *params, static void eap_tls_cert_params_from_conf(struct tls_connection_params *params,
struct eap_peer_config *config) struct eap_peer_cert_config *config)
{ {
params->ca_cert = config->ca_cert; params->ca_cert = config->ca_cert;
params->ca_path = config->ca_path; params->ca_path = config->ca_path;
@ -125,6 +125,13 @@ static void eap_tls_params_from_conf1(struct tls_connection_params *params,
params->key_id = config->key_id; params->key_id = config->key_id;
params->cert_id = config->cert_id; params->cert_id = config->cert_id;
params->ca_cert_id = config->ca_cert_id; params->ca_cert_id = config->ca_cert_id;
}
static void eap_tls_params_from_conf1(struct tls_connection_params *params,
struct eap_peer_config *config)
{
eap_tls_cert_params_from_conf(params, &config->cert);
eap_tls_params_flags(params, config->phase1); eap_tls_params_flags(params, config->phase1);
} }
@ -132,23 +139,7 @@ static void eap_tls_params_from_conf1(struct tls_connection_params *params,
static void eap_tls_params_from_conf2(struct tls_connection_params *params, static void eap_tls_params_from_conf2(struct tls_connection_params *params,
struct eap_peer_config *config) struct eap_peer_config *config)
{ {
params->ca_cert = config->ca_cert2; eap_tls_cert_params_from_conf(params, &config->phase2_cert);
params->ca_path = config->ca_path2;
params->client_cert = config->client_cert2;
params->private_key = config->private_key2;
params->private_key_passwd = config->private_key2_passwd;
params->dh_file = config->dh_file2;
params->subject_match = config->subject_match2;
params->altsubject_match = config->altsubject_match2;
params->check_cert_subject = config->check_cert_subject2;
params->suffix_match = config->domain_suffix_match2;
params->domain_match = config->domain_match2;
params->engine = config->engine2;
params->engine_id = config->engine2_id;
params->pin = config->pin2;
params->key_id = config->key2_id;
params->cert_id = config->cert2_id;
params->ca_cert_id = config->ca_cert2_id;
eap_tls_params_flags(params, config->phase2); eap_tls_params_flags(params, config->phase2);
} }
@ -264,8 +255,8 @@ static int eap_tls_init_connection(struct eap_sm *sm,
*/ */
wpa_printf(MSG_INFO, wpa_printf(MSG_INFO,
"TLS: Bad PIN provided, requesting a new one"); "TLS: Bad PIN provided, requesting a new one");
os_free(config->pin); os_free(config->cert.pin);
config->pin = NULL; config->cert.pin = NULL;
eap_sm_request_pin(sm); eap_sm_request_pin(sm);
sm->ignore = TRUE; sm->ignore = TRUE;
} else if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) { } else if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) {

View file

@ -1,6 +1,6 @@
/* /*
* WPA Supplicant / Configuration parser and common functions * WPA Supplicant / Configuration parser and common functions
* Copyright (c) 2003-2018, Jouni Malinen <j@w1.fi> * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
* *
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
@ -2279,23 +2279,24 @@ static char * wpa_config_write_peerkey(const struct parse_data *data,
/* STR: Define a string variable for an ASCII string; f = field name */ /* STR: Define a string variable for an ASCII string; f = field name */
#ifdef NO_CONFIG_WRITE #ifdef NO_CONFIG_WRITE
#define _STR(f) #f, wpa_config_parse_str, OFFSET(f) #define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
#define _STRe(f) #f, wpa_config_parse_str, OFFSET(eap.f) #define _STRe(f, m) #f, wpa_config_parse_str, OFFSET(eap.m)
#else /* NO_CONFIG_WRITE */ #else /* NO_CONFIG_WRITE */
#define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f) #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
#define _STRe(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(eap.f) #define _STRe(f, m) #f, wpa_config_parse_str, wpa_config_write_str, \
OFFSET(eap.m)
#endif /* NO_CONFIG_WRITE */ #endif /* NO_CONFIG_WRITE */
#define STR(f) _STR(f), NULL, NULL, NULL, 0 #define STR(f) _STR(f), NULL, NULL, NULL, 0
#define STRe(f) _STRe(f), NULL, NULL, NULL, 0 #define STRe(f, m) _STRe(f, m), NULL, NULL, NULL, 0
#define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1 #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
#define STR_KEYe(f) _STRe(f), NULL, NULL, NULL, 1 #define STR_KEYe(f, m) _STRe(f, m), NULL, NULL, NULL, 1
/* STR_LEN: Define a string variable with a separate variable for storing the /* STR_LEN: Define a string variable with a separate variable for storing the
* data length. Unlike STR(), this can be used to store arbitrary binary data * data length. Unlike STR(), this can be used to store arbitrary binary data
* (i.e., even nul termination character). */ * (i.e., even nul termination character). */
#define _STR_LEN(f) _STR(f), OFFSET(f ## _len) #define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
#define _STR_LENe(f) _STRe(f), OFFSET(eap.f ## _len) #define _STR_LENe(f, m) _STRe(f, m), OFFSET(eap.m ## _len)
#define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0 #define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
#define STR_LENe(f) _STR_LENe(f), NULL, NULL, 0 #define STR_LENe(f, m) _STR_LENe(f, m), NULL, NULL, 0
#define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1 #define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
/* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
@ -2306,17 +2307,17 @@ static char * wpa_config_write_peerkey(const struct parse_data *data,
#ifdef NO_CONFIG_WRITE #ifdef NO_CONFIG_WRITE
#define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0 #define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0
#define _INTe(f) #f, wpa_config_parse_int, OFFSET(eap.f), (void *) 0 #define _INTe(f, m) #f, wpa_config_parse_int, OFFSET(eap.m), (void *) 0
#else /* NO_CONFIG_WRITE */ #else /* NO_CONFIG_WRITE */
#define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \ #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
OFFSET(f), (void *) 0 OFFSET(f), (void *) 0
#define _INTe(f) #f, wpa_config_parse_int, wpa_config_write_int, \ #define _INTe(f, m) #f, wpa_config_parse_int, wpa_config_write_int, \
OFFSET(eap.f), (void *) 0 OFFSET(eap.m), (void *) 0
#endif /* NO_CONFIG_WRITE */ #endif /* NO_CONFIG_WRITE */
/* INT: Define an integer variable */ /* INT: Define an integer variable */
#define INT(f) _INT(f), NULL, NULL, 0 #define INT(f) _INT(f), NULL, NULL, 0
#define INTe(f) _INTe(f), NULL, NULL, 0 #define INTe(f, m) _INTe(f, m), NULL, NULL, 0
/* INT_RANGE: Define an integer variable with allowed value range */ /* INT_RANGE: Define an integer variable with allowed value range */
#define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0 #define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
@ -2384,53 +2385,53 @@ static const struct parse_data ssid_fields[] = {
{ INT(vht_center_freq2) }, { INT(vht_center_freq2) },
#ifdef IEEE8021X_EAPOL #ifdef IEEE8021X_EAPOL
{ FUNC(eap) }, { FUNC(eap) },
{ STR_LENe(identity) }, { STR_LENe(identity, identity) },
{ STR_LENe(anonymous_identity) }, { STR_LENe(anonymous_identity, anonymous_identity) },
{ STR_LENe(imsi_identity) }, { STR_LENe(imsi_identity, imsi_identity) },
{ STR_LENe(machine_identity) }, { STR_LENe(machine_identity, machine_identity) },
{ FUNC_KEY(password) }, { FUNC_KEY(password) },
{ FUNC_KEY(machine_password) }, { FUNC_KEY(machine_password) },
{ STRe(ca_cert) }, { STRe(ca_cert, cert.ca_cert) },
{ STRe(ca_path) }, { STRe(ca_path, cert.ca_path) },
{ STRe(client_cert) }, { STRe(client_cert, cert.client_cert) },
{ STRe(private_key) }, { STRe(private_key, cert.private_key) },
{ STR_KEYe(private_key_passwd) }, { STR_KEYe(private_key_passwd, cert.private_key_passwd) },
{ STRe(dh_file) }, { STRe(dh_file, cert.dh_file) },
{ STRe(subject_match) }, { STRe(subject_match, cert.subject_match) },
{ STRe(check_cert_subject) }, { STRe(check_cert_subject, cert.check_cert_subject) },
{ STRe(altsubject_match) }, { STRe(altsubject_match, cert.altsubject_match) },
{ STRe(domain_suffix_match) }, { STRe(domain_suffix_match, cert.domain_suffix_match) },
{ STRe(domain_match) }, { STRe(domain_match, cert.domain_match) },
{ STRe(ca_cert2) }, { STRe(ca_cert2, phase2_cert.ca_cert) },
{ STRe(ca_path2) }, { STRe(ca_path2, phase2_cert.ca_path) },
{ STRe(client_cert2) }, { STRe(client_cert2, phase2_cert.client_cert) },
{ STRe(private_key2) }, { STRe(private_key2, phase2_cert.private_key) },
{ STR_KEYe(private_key2_passwd) }, { STR_KEYe(private_key2_passwd, phase2_cert.private_key_passwd) },
{ STRe(dh_file2) }, { STRe(dh_file2, phase2_cert.dh_file) },
{ STRe(subject_match2) }, { STRe(subject_match2, phase2_cert.subject_match) },
{ STRe(check_cert_subject2) }, { STRe(check_cert_subject2, phase2_cert.check_cert_subject) },
{ STRe(altsubject_match2) }, { STRe(altsubject_match2, phase2_cert.altsubject_match) },
{ STRe(domain_suffix_match2) }, { STRe(domain_suffix_match2, phase2_cert.domain_suffix_match) },
{ STRe(domain_match2) }, { STRe(domain_match2, phase2_cert.domain_match) },
{ STRe(phase1) }, { STRe(phase1, phase1) },
{ STRe(phase2) }, { STRe(phase2, phase2) },
{ STRe(pcsc) }, { STRe(pcsc, pcsc) },
{ STR_KEYe(pin) }, { STR_KEYe(pin, cert.pin) },
{ STRe(engine_id) }, { STRe(engine_id, cert.engine_id) },
{ STRe(key_id) }, { STRe(key_id, cert.key_id) },
{ STRe(cert_id) }, { STRe(cert_id, cert.cert_id) },
{ STRe(ca_cert_id) }, { STRe(ca_cert_id, cert.ca_cert_id) },
{ STR_KEYe(pin2) }, { STR_KEYe(pin2, phase2_cert.pin) },
{ STRe(engine2_id) }, { STRe(engine_id2, phase2_cert.engine_id) },
{ STRe(key2_id) }, { STRe(key_id2, phase2_cert.key_id) },
{ STRe(cert2_id) }, { STRe(cert_id2, phase2_cert.cert_id) },
{ STRe(ca_cert2_id) }, { STRe(ca_cert_id2, phase2_cert.ca_cert_id) },
{ INTe(engine) }, { INTe(engine, cert.engine) },
{ INTe(engine2) }, { INTe(engine2, phase2_cert.engine) },
{ INT(eapol_flags) }, { INT(eapol_flags) },
{ INTe(sim_num) }, { INTe(sim_num, sim_num) },
{ STRe(openssl_ciphers) }, { STRe(openssl_ciphers, openssl_ciphers) },
{ INTe(erp) }, { INTe(erp, erp) },
#endif /* IEEE8021X_EAPOL */ #endif /* IEEE8021X_EAPOL */
{ FUNC_KEY(wep_key0) }, { FUNC_KEY(wep_key0) },
{ FUNC_KEY(wep_key1) }, { FUNC_KEY(wep_key1) },
@ -2440,9 +2441,9 @@ static const struct parse_data ssid_fields[] = {
{ INT(priority) }, { INT(priority) },
#ifdef IEEE8021X_EAPOL #ifdef IEEE8021X_EAPOL
{ INT(eap_workaround) }, { INT(eap_workaround) },
{ STRe(pac_file) }, { STRe(pac_file, pac_file) },
{ INTe(fragment_size) }, { INTe(fragment_size, fragment_size) },
{ INTe(ocsp) }, { INTe(ocsp, ocsp) },
#endif /* IEEE8021X_EAPOL */ #endif /* IEEE8021X_EAPOL */
#ifdef CONFIG_MESH #ifdef CONFIG_MESH
{ INT_RANGE(mode, 0, 5) }, { INT_RANGE(mode, 0, 5) },
@ -2654,6 +2655,28 @@ int wpa_config_update_prio_list(struct wpa_config *config)
#ifdef IEEE8021X_EAPOL #ifdef IEEE8021X_EAPOL
static void eap_peer_config_free_cert(struct eap_peer_cert_config *cert)
{
os_free(cert->ca_cert);
os_free(cert->ca_path);
os_free(cert->client_cert);
os_free(cert->private_key);
str_clear_free(cert->private_key_passwd);
os_free(cert->dh_file);
os_free(cert->subject_match);
os_free(cert->check_cert_subject);
os_free(cert->altsubject_match);
os_free(cert->domain_suffix_match);
os_free(cert->domain_match);
str_clear_free(cert->pin);
os_free(cert->engine_id);
os_free(cert->key_id);
os_free(cert->cert_id);
os_free(cert->ca_cert_id);
}
static void eap_peer_config_free(struct eap_peer_config *eap) static void eap_peer_config_free(struct eap_peer_config *eap)
{ {
os_free(eap->eap_methods); os_free(eap->eap_methods);
@ -2663,41 +2686,11 @@ static void eap_peer_config_free(struct eap_peer_config *eap)
os_free(eap->machine_identity); os_free(eap->machine_identity);
bin_clear_free(eap->password, eap->password_len); bin_clear_free(eap->password, eap->password_len);
bin_clear_free(eap->machine_password, eap->machine_password_len); bin_clear_free(eap->machine_password, eap->machine_password_len);
os_free(eap->ca_cert); eap_peer_config_free_cert(&eap->cert);
os_free(eap->ca_path); eap_peer_config_free_cert(&eap->phase2_cert);
os_free(eap->client_cert);
os_free(eap->private_key);
str_clear_free(eap->private_key_passwd);
os_free(eap->dh_file);
os_free(eap->subject_match);
os_free(eap->check_cert_subject);
os_free(eap->altsubject_match);
os_free(eap->domain_suffix_match);
os_free(eap->domain_match);
os_free(eap->ca_cert2);
os_free(eap->ca_path2);
os_free(eap->client_cert2);
os_free(eap->private_key2);
str_clear_free(eap->private_key2_passwd);
os_free(eap->dh_file2);
os_free(eap->subject_match2);
os_free(eap->check_cert_subject2);
os_free(eap->altsubject_match2);
os_free(eap->domain_suffix_match2);
os_free(eap->domain_match2);
os_free(eap->phase1); os_free(eap->phase1);
os_free(eap->phase2); os_free(eap->phase2);
os_free(eap->pcsc); os_free(eap->pcsc);
str_clear_free(eap->pin);
os_free(eap->engine_id);
os_free(eap->key_id);
os_free(eap->cert_id);
os_free(eap->ca_cert_id);
os_free(eap->key2_id);
os_free(eap->cert2_id);
os_free(eap->ca_cert2_id);
str_clear_free(eap->pin2);
os_free(eap->engine2_id);
os_free(eap->otp); os_free(eap->otp);
os_free(eap->pending_req_otp); os_free(eap->pending_req_otp);
os_free(eap->pac_file); os_free(eap->pac_file);
@ -2705,6 +2698,7 @@ static void eap_peer_config_free(struct eap_peer_config *eap)
str_clear_free(eap->external_sim_resp); str_clear_free(eap->external_sim_resp);
os_free(eap->openssl_ciphers); os_free(eap->openssl_ciphers);
} }
#endif /* IEEE8021X_EAPOL */ #endif /* IEEE8021X_EAPOL */

View file

@ -1,6 +1,6 @@
/* /*
* WPA Supplicant / Configuration backend: text file * WPA Supplicant / Configuration backend: text file
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi> * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
* *
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
@ -745,9 +745,9 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
#define STR(t) write_str(f, #t, ssid) #define STR(t) write_str(f, #t, ssid)
#define INT(t) write_int(f, #t, ssid->t, 0) #define INT(t) write_int(f, #t, ssid->t, 0)
#define INTe(t) write_int(f, #t, ssid->eap.t, 0) #define INTe(t, m) write_int(f, #t, ssid->eap.m, 0)
#define INT_DEF(t, def) write_int(f, #t, ssid->t, def) #define INT_DEF(t, def) write_int(f, #t, ssid->t, def)
#define INT_DEFe(t, def) write_int(f, #t, ssid->eap.t, def) #define INT_DEFe(t, m, def) write_int(f, #t, ssid->eap.m, def)
STR(ssid); STR(ssid);
INT(scan_ssid); INT(scan_ssid);
@ -812,11 +812,11 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
STR(engine2_id); STR(engine2_id);
STR(cert2_id); STR(cert2_id);
STR(ca_cert2_id); STR(ca_cert2_id);
INTe(engine); INTe(engine, cert.engine);
INTe(engine2); INTe(engine2, phase2_cert.engine);
INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS); INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
STR(openssl_ciphers); STR(openssl_ciphers);
INTe(erp); INTe(erp, erp);
#endif /* IEEE8021X_EAPOL */ #endif /* IEEE8021X_EAPOL */
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
write_wep_key(f, i, ssid); write_wep_key(f, i, ssid);
@ -825,9 +825,9 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
#ifdef IEEE8021X_EAPOL #ifdef IEEE8021X_EAPOL
INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND); INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
STR(pac_file); STR(pac_file);
INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE); INT_DEFe(fragment_size, fragment_size, DEFAULT_FRAGMENT_SIZE);
INTe(ocsp); INTe(ocsp, ocsp);
INT_DEFe(sim_num, DEFAULT_USER_SELECTED_SIM); INT_DEFe(sim_num, sim_num, DEFAULT_USER_SELECTED_SIM);
#endif /* IEEE8021X_EAPOL */ #endif /* IEEE8021X_EAPOL */
INT(mode); INT(mode);
INT(no_auto_peer); INT(no_auto_peer);

View file

@ -1,6 +1,6 @@
/* /*
* WPA Supplicant / Configuration backend: Windows registry * WPA Supplicant / Configuration backend: Windows registry
* Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
* *
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
@ -868,9 +868,9 @@ static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
#define STR(t) write_str(netw, #t, ssid) #define STR(t) write_str(netw, #t, ssid)
#define INT(t) write_int(netw, #t, ssid->t, 0) #define INT(t) write_int(netw, #t, ssid->t, 0)
#define INTe(t) write_int(netw, #t, ssid->eap.t, 0) #define INTe(t, m) write_int(netw, #t, ssid->eap.m, 0)
#define INT_DEF(t, def) write_int(netw, #t, ssid->t, def) #define INT_DEF(t, def) write_int(netw, #t, ssid->t, def)
#define INT_DEFe(t, def) write_int(netw, #t, ssid->eap.t, def) #define INT_DEFe(t, m, def) write_int(netw, #t, ssid->eap.m, def)
STR(ssid); STR(ssid);
INT(scan_ssid); INT(scan_ssid);
@ -920,8 +920,8 @@ static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
STR(engine2_id); STR(engine2_id);
STR(cert2_id); STR(cert2_id);
STR(ca_cert2_id); STR(ca_cert2_id);
INTe(engine); INTe(engine, cert.engine);
INTe(engine2); INTe(engine2, phase2_cert.engine);
INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS); INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
#endif /* IEEE8021X_EAPOL */ #endif /* IEEE8021X_EAPOL */
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
@ -931,7 +931,7 @@ static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
#ifdef IEEE8021X_EAPOL #ifdef IEEE8021X_EAPOL
INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND); INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
STR(pac_file); STR(pac_file);
INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE); INT_DEFe(fragment_size, fragment_size, DEFAULT_FRAGMENT_SIZE);
#endif /* IEEE8021X_EAPOL */ #endif /* IEEE8021X_EAPOL */
INT(mode); INT(mode);
write_int(netw, "proactive_key_caching", ssid->proactive_key_caching, write_int(netw, "proactive_key_caching", ssid->proactive_key_caching,

View file

@ -6918,8 +6918,8 @@ int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
wpa_s->reassociate = 1; wpa_s->reassociate = 1;
break; break;
case WPA_CTRL_REQ_EAP_PIN: case WPA_CTRL_REQ_EAP_PIN:
str_clear_free(eap->pin); str_clear_free(eap->cert.pin);
eap->pin = os_strdup(value); eap->cert.pin = os_strdup(value);
eap->pending_req_pin = 0; eap->pending_req_pin = 0;
if (ssid == wpa_s->current_ssid) if (ssid == wpa_s->current_ssid)
wpa_s->reassociate = 1; wpa_s->reassociate = 1;
@ -6933,8 +6933,8 @@ int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
eap->pending_req_otp_len = 0; eap->pending_req_otp_len = 0;
break; break;
case WPA_CTRL_REQ_EAP_PASSPHRASE: case WPA_CTRL_REQ_EAP_PASSPHRASE:
str_clear_free(eap->private_key_passwd); str_clear_free(eap->cert.private_key_passwd);
eap->private_key_passwd = os_strdup(value); eap->cert.private_key_passwd = os_strdup(value);
eap->pending_req_passphrase = 0; eap->pending_req_passphrase = 0;
if (ssid == wpa_s->current_ssid) if (ssid == wpa_s->current_ssid)
wpa_s->reassociate = 1; wpa_s->reassociate = 1;