EAP-TEAP (server): Allow Phase 2 skip based on client certificate
eap_teap_auth=2 can now be used to configure hostapd to skip Phase 2 if the peer can be authenticated based on client certificate during Phase 1. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
5196293926
commit
cd99a8c432
3 changed files with 23 additions and 5 deletions
|
@ -2555,7 +2555,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
} else if (os_strcmp(buf, "eap_teap_auth") == 0) {
|
} else if (os_strcmp(buf, "eap_teap_auth") == 0) {
|
||||||
int val = atoi(pos);
|
int val = atoi(pos);
|
||||||
|
|
||||||
if (val < 0 || val > 1) {
|
if (val < 0 || val > 2) {
|
||||||
wpa_printf(MSG_ERROR,
|
wpa_printf(MSG_ERROR,
|
||||||
"Line %d: Invalid eap_teap_auth value",
|
"Line %d: Invalid eap_teap_auth value",
|
||||||
line);
|
line);
|
||||||
|
|
|
@ -1229,6 +1229,8 @@ eap_server=0
|
||||||
# EAP-TEAP authentication type
|
# EAP-TEAP authentication type
|
||||||
# 0 = inner EAP (default)
|
# 0 = inner EAP (default)
|
||||||
# 1 = Basic-Password-Auth
|
# 1 = Basic-Password-Auth
|
||||||
|
# 2 = Do not require Phase 2 authentication if client can be authenticated
|
||||||
|
# during Phase 1
|
||||||
#eap_teap_auth=0
|
#eap_teap_auth=0
|
||||||
|
|
||||||
# EAP-TEAP authentication behavior when using PAC
|
# EAP-TEAP authentication behavior when using PAC
|
||||||
|
|
|
@ -64,7 +64,7 @@ struct eap_teap_data {
|
||||||
struct wpabuf *pending_phase2_resp;
|
struct wpabuf *pending_phase2_resp;
|
||||||
struct wpabuf *server_outer_tlvs;
|
struct wpabuf *server_outer_tlvs;
|
||||||
struct wpabuf *peer_outer_tlvs;
|
struct wpabuf *peer_outer_tlvs;
|
||||||
u8 *identity; /* from PAC-Opaque */
|
u8 *identity; /* from PAC-Opaque or client certificate */
|
||||||
size_t identity_len;
|
size_t identity_len;
|
||||||
int eap_seq;
|
int eap_seq;
|
||||||
int tnc_started;
|
int tnc_started;
|
||||||
|
@ -365,7 +365,9 @@ static void * eap_teap_init(struct eap_sm *sm)
|
||||||
data->teap_version = EAP_TEAP_VERSION;
|
data->teap_version = EAP_TEAP_VERSION;
|
||||||
data->state = START;
|
data->state = START;
|
||||||
|
|
||||||
if (eap_server_tls_ssl_init(sm, &data->ssl, 0, EAP_TYPE_TEAP)) {
|
if (eap_server_tls_ssl_init(sm, &data->ssl,
|
||||||
|
sm->cfg->eap_teap_auth == 2 ? 2 : 0,
|
||||||
|
EAP_TYPE_TEAP)) {
|
||||||
wpa_printf(MSG_INFO, "EAP-TEAP: Failed to initialize SSL.");
|
wpa_printf(MSG_INFO, "EAP-TEAP: Failed to initialize SSL.");
|
||||||
eap_teap_reset(sm, data);
|
eap_teap_reset(sm, data);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -502,6 +504,19 @@ static int eap_teap_phase1_done(struct eap_sm *sm, struct eap_teap_data *data)
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 1 done, starting Phase 2");
|
wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 1 done, starting Phase 2");
|
||||||
|
|
||||||
|
if (!data->identity && sm->cfg->eap_teap_auth == 2) {
|
||||||
|
const char *subject;
|
||||||
|
|
||||||
|
subject = tls_connection_get_peer_subject(data->ssl.conn);
|
||||||
|
if (subject) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"EAP-TEAP: Peer subject from Phase 1 client certificate: '%s'",
|
||||||
|
subject);
|
||||||
|
data->identity = (u8 *) os_strdup(subject);
|
||||||
|
data->identity_len = os_strlen(subject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data->tls_cs = tls_connection_get_cipher_suite(data->ssl.conn);
|
data->tls_cs = tls_connection_get_cipher_suite(data->ssl.conn);
|
||||||
wpa_printf(MSG_DEBUG, "EAP-TEAP: TLS cipher suite 0x%04x",
|
wpa_printf(MSG_DEBUG, "EAP-TEAP: TLS cipher suite 0x%04x",
|
||||||
data->tls_cs);
|
data->tls_cs);
|
||||||
|
@ -1775,9 +1790,10 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm,
|
||||||
next_vendor = EAP_VENDOR_IETF;
|
next_vendor = EAP_VENDOR_IETF;
|
||||||
next_type = EAP_TYPE_NONE;
|
next_type = EAP_TYPE_NONE;
|
||||||
eap_teap_state(data, PHASE2_METHOD);
|
eap_teap_state(data, PHASE2_METHOD);
|
||||||
} else if (sm->cfg->eap_teap_pac_no_inner) {
|
} else if (sm->cfg->eap_teap_pac_no_inner ||
|
||||||
|
sm->cfg->eap_teap_auth == 2) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"EAP-TEAP: Used PAC and identity already known - skip inner auth");
|
"EAP-TEAP: Used PAC or client certificate and identity already known - skip inner auth");
|
||||||
data->skipped_inner_auth = 1;
|
data->skipped_inner_auth = 1;
|
||||||
/* FIX: Need to derive CMK here. However, how is that
|
/* FIX: Need to derive CMK here. However, how is that
|
||||||
* supposed to be done? RFC 7170 does not tell that for
|
* supposed to be done? RFC 7170 does not tell that for
|
||||||
|
|
Loading…
Reference in a new issue