aboutsummaryrefslogtreecommitdiffstats
path: root/src/eap_peer
diff options
context:
space:
mode:
authorVidyullatha Kanchanapally <vkanchan@qti.qualcomm.com>2017-03-22 10:40:05 (GMT)
committerJouni Malinen <j@w1.fi>2017-04-07 15:46:13 (GMT)
commit15def72fabd1116930f5ffdb09983cae1e8021a3 (patch)
treeaace82cd60f4461e286f5b65c950f6813880e8bf /src/eap_peer
parent42e69bda2aa0752a3a18714728d0d06bb20ad152 (diff)
downloadhostap-15def72fabd1116930f5ffdb09983cae1e8021a3.zip
hostap-15def72fabd1116930f5ffdb09983cae1e8021a3.tar.gz
hostap-15def72fabd1116930f5ffdb09983cae1e8021a3.tar.bz2
ERP: External control of ERP key information
This allows ERP keys to be managed by external entities, e.g., when offloading FILS shared key authentication to a driver. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'src/eap_peer')
-rw-r--r--src/eap_peer/eap.c87
-rw-r--r--src/eap_peer/eap.h5
2 files changed, 90 insertions, 2 deletions
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index bc90c7a..d0f305f 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -371,9 +371,8 @@ nak:
#ifdef CONFIG_ERP
-static char * eap_home_realm(struct eap_sm *sm)
+static char * eap_get_realm(struct eap_sm *sm, struct eap_peer_config *config)
{
- struct eap_peer_config *config = eap_get_config(sm);
char *realm;
size_t i, realm_len;
@@ -417,6 +416,12 @@ static char * eap_home_realm(struct eap_sm *sm)
}
+static char * eap_home_realm(struct eap_sm *sm)
+{
+ return eap_get_realm(sm, eap_get_config(sm));
+}
+
+
static struct eap_erp_key *
eap_erp_get_key(struct eap_sm *sm, const char *realm)
{
@@ -469,6 +474,84 @@ static void eap_erp_remove_keys_realm(struct eap_sm *sm, const char *realm)
}
}
+
+int eap_peer_update_erp_next_seq_num(struct eap_sm *sm, u16 next_seq_num)
+{
+ struct eap_erp_key *erp;
+ char *home_realm;
+
+ home_realm = eap_home_realm(sm);
+ if (!home_realm || os_strlen(home_realm) == 0) {
+ os_free(home_realm);
+ return -1;
+ }
+
+ erp = eap_erp_get_key(sm, home_realm);
+ if (!erp) {
+ wpa_printf(MSG_DEBUG,
+ "EAP: Failed to find ERP key for realm: %s",
+ home_realm);
+ os_free(home_realm);
+ return -1;
+ }
+
+ if ((u32) next_seq_num < erp->next_seq) {
+ /* Sequence number has wrapped around, clear this ERP
+ * info and do a full auth next time.
+ */
+ eap_peer_erp_free_key(erp);
+ } else {
+ erp->next_seq = (u32) next_seq_num;
+ }
+
+ os_free(home_realm);
+ return 0;
+}
+
+
+int eap_peer_get_erp_info(struct eap_sm *sm, struct eap_peer_config *config,
+ const u8 **username, size_t *username_len,
+ const u8 **realm, size_t *realm_len,
+ u16 *erp_next_seq_num, const u8 **rrk,
+ size_t *rrk_len)
+{
+ struct eap_erp_key *erp;
+ char *home_realm;
+ char *pos;
+
+ home_realm = eap_get_realm(sm, config);
+ if (!home_realm || os_strlen(home_realm) == 0) {
+ os_free(home_realm);
+ return -1;
+ }
+
+ erp = eap_erp_get_key(sm, home_realm);
+ os_free(home_realm);
+ if (!erp)
+ return -1;
+
+ if (erp->next_seq >= 65536)
+ return -1; /* SEQ has range of 0..65535 */
+
+ pos = os_strchr(erp->keyname_nai, '@');
+ *username_len = pos - erp->keyname_nai;
+ *username = (u8 *) erp->keyname_nai;
+
+ pos++;
+ *realm_len = os_strlen(pos);
+ *realm = (u8 *) pos;
+
+ *erp_next_seq_num = (u16) erp->next_seq;
+
+ *rrk_len = erp->rRK_len;
+ *rrk = erp->rRK;
+
+ if (*username_len == 0 || *realm_len == 0 || *rrk_len == 0)
+ return -1;
+
+ return 0;
+}
+
#endif /* CONFIG_ERP */
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index 932584f..883ba24 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -358,6 +358,11 @@ int eap_peer_was_failure_expected(struct eap_sm *sm);
void eap_peer_erp_free_keys(struct eap_sm *sm);
struct wpabuf * eap_peer_build_erp_reauth_start(struct eap_sm *sm, u8 eap_id);
void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr, size_t len);
+int eap_peer_get_erp_info(struct eap_sm *sm, struct eap_peer_config *config,
+ const u8 **username, size_t *username_len,
+ const u8 **realm, size_t *realm_len, u16 *erp_seq_num,
+ const u8 **rrk, size_t *rrk_len);
+int eap_peer_update_erp_next_seq_num(struct eap_sm *sm, u16 seq_num);
#endif /* IEEE8021X_EAPOL */