summaryrefslogtreecommitdiffstats
path: root/contrib/wpa_supplicant/eap_tls.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/wpa_supplicant/eap_tls.c')
-rw-r--r--contrib/wpa_supplicant/eap_tls.c91
1 files changed, 40 insertions, 51 deletions
diff --git a/contrib/wpa_supplicant/eap_tls.c b/contrib/wpa_supplicant/eap_tls.c
index 4b02cca..d1452df 100644
--- a/contrib/wpa_supplicant/eap_tls.c
+++ b/contrib/wpa_supplicant/eap_tls.c
@@ -38,8 +38,8 @@ static void * eap_tls_init(struct eap_sm *sm)
struct eap_tls_data *data;
struct wpa_ssid *config = eap_get_config(sm);
if (config == NULL ||
- (sm->init_phase2 ? config->private_key2 : config->private_key)
- == NULL) {
+ ((sm->init_phase2 ? config->private_key2 : config->private_key)
+ == NULL && config->engine == 0)) {
wpa_printf(MSG_INFO, "EAP-TLS: Private key not configured");
return NULL;
}
@@ -52,6 +52,18 @@ static void * eap_tls_init(struct eap_sm *sm)
if (eap_tls_ssl_init(sm, &data->ssl, config)) {
wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL.");
eap_tls_deinit(sm, data);
+ if (config->engine) {
+ wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting Smartcard "
+ "PIN");
+ eap_sm_request_pin(sm, config);
+ sm->ignore = TRUE;
+ } else if (config->private_key && !config->private_key_passwd)
+ {
+ wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting private "
+ "key passphrase");
+ eap_sm_request_passphrase(sm, config);
+ sm->ignore = TRUE;
+ }
return NULL;
}
@@ -72,61 +84,23 @@ static void eap_tls_deinit(struct eap_sm *sm, void *priv)
static u8 * eap_tls_process(struct eap_sm *sm, void *priv,
struct eap_method_ret *ret,
- u8 *reqData, size_t reqDataLen,
+ const u8 *reqData, size_t reqDataLen,
size_t *respDataLen)
{
- struct eap_hdr *req;
- int left, res;
- unsigned int tls_msg_len;
- u8 flags, *pos, *resp, id;
+ struct wpa_ssid *config = eap_get_config(sm);
+ const struct eap_hdr *req;
+ size_t left;
+ int res;
+ u8 flags, *resp, id;
+ const u8 *pos;
struct eap_tls_data *data = priv;
- if (tls_get_errors(sm->ssl_ctx)) {
- wpa_printf(MSG_INFO, "EAP-TLS: TLS errors detected");
- ret->ignore = TRUE;
- return NULL;
- }
-
- req = (struct eap_hdr *) reqData;
- pos = (u8 *) (req + 1);
- if (reqDataLen < sizeof(*req) + 2 || *pos != EAP_TYPE_TLS) {
- wpa_printf(MSG_INFO, "EAP-TLS: Invalid frame");
- ret->ignore = TRUE;
+ pos = eap_tls_process_init(sm, &data->ssl, EAP_TYPE_TLS, ret,
+ reqData, reqDataLen, &left, &flags);
+ if (pos == NULL)
return NULL;
- }
+ req = (const struct eap_hdr *) reqData;
id = req->identifier;
- pos++;
- flags = *pos++;
- left = be_to_host16(req->length) - sizeof(struct eap_hdr) - 2;
- wpa_printf(MSG_DEBUG, "EAP-TLS: Received packet(len=%lu) - "
- "Flags 0x%02x", (unsigned long) reqDataLen, flags);
- if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
- if (left < 4) {
- wpa_printf(MSG_INFO, "EAP-TLS: Short frame with TLS "
- "length");
- ret->ignore = TRUE;
- return NULL;
- }
- tls_msg_len = (pos[0] << 24) | (pos[1] << 16) | (pos[2] << 8) |
- pos[3];
- wpa_printf(MSG_DEBUG, "EAP-TLS: TLS Message Length: %d",
- tls_msg_len);
- if (data->ssl.tls_in_left == 0) {
- data->ssl.tls_in_total = tls_msg_len;
- data->ssl.tls_in_left = tls_msg_len;
- free(data->ssl.tls_in);
- data->ssl.tls_in = NULL;
- data->ssl.tls_in_len = 0;
- }
- pos += 4;
- left -= 4;
- }
-
- ret->ignore = FALSE;
-
- ret->methodState = METHOD_CONT;
- ret->decision = DECISION_COND_SUCC;
- ret->allowNotifications = TRUE;
if (flags & EAP_TLS_FLAGS_START) {
wpa_printf(MSG_DEBUG, "EAP-TLS: Start");
@@ -142,6 +116,11 @@ static u8 * eap_tls_process(struct eap_sm *sm, void *priv,
wpa_printf(MSG_DEBUG, "EAP-TLS: TLS processing failed");
ret->methodState = METHOD_MAY_CONT;
ret->decision = DECISION_FAIL;
+ if (resp) {
+ /* This is likely an alert message, so send it instead
+ * of just ACKing the error. */
+ return resp;
+ }
return eap_tls_build_ack(&data->ssl, respDataLen, id,
EAP_TYPE_TLS, 0);
}
@@ -166,6 +145,16 @@ static u8 * eap_tls_process(struct eap_sm *sm, void *priv,
return eap_tls_build_ack(&data->ssl, respDataLen, id,
EAP_TYPE_TLS, 0);
}
+
+ if (res == -1) {
+ /* The TLS handshake failed. So better forget the old PIN.
+ * It may be wrong, we can't be sure but trying the wrong one
+ * again might block it on the card - so better ask the user
+ * again */
+ free(config->pin);
+ config->pin = NULL;
+ }
+
return resp;
}
OpenPOWER on IntegriCloud