EAP-pwd peer: Add support for hashed password
This extends EAP-pwd peer support to allow NtHash version of password storage in addition to full plaintext password. In addition, this allows the server to request hashed version even if the plaintext password is available on the client. Furthermore, unsupported password preparation requests are now rejected rather than allowing the authentication attempt to continue. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
e4840b381c
commit
3e808b831c
1 changed files with 60 additions and 6 deletions
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "crypto/sha256.h"
|
||||
#include "crypto/ms_funcs.h"
|
||||
#include "eap_peer/eap_i.h"
|
||||
#include "eap_common/eap_pwd_common.h"
|
||||
|
||||
|
@ -25,6 +26,7 @@ struct eap_pwd_data {
|
|||
size_t id_server_len;
|
||||
u8 *password;
|
||||
size_t password_len;
|
||||
int password_hash;
|
||||
u16 group_num;
|
||||
EAP_PWD_group *grp;
|
||||
|
||||
|
@ -86,8 +88,9 @@ static void * eap_pwd_init(struct eap_sm *sm)
|
|||
const u8 *identity, *password;
|
||||
size_t identity_len, password_len;
|
||||
int fragment_size;
|
||||
int pwhash;
|
||||
|
||||
password = eap_get_config_password(sm, &password_len);
|
||||
password = eap_get_config_password2(sm, &password_len, &pwhash);
|
||||
if (password == NULL) {
|
||||
wpa_printf(MSG_INFO, "EAP-PWD: No password configured!");
|
||||
return NULL;
|
||||
|
@ -129,6 +132,7 @@ static void * eap_pwd_init(struct eap_sm *sm)
|
|||
}
|
||||
os_memcpy(data->password, password, password_len);
|
||||
data->password_len = password_len;
|
||||
data->password_hash = pwhash;
|
||||
|
||||
data->out_frag_pos = data->in_frag_pos = 0;
|
||||
data->inbuf = data->outbuf = NULL;
|
||||
|
@ -216,6 +220,10 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
|
|||
const u8 *payload, size_t payload_len)
|
||||
{
|
||||
struct eap_pwd_id *id;
|
||||
const u8 *password;
|
||||
size_t password_len;
|
||||
u8 pwhashhash[16];
|
||||
int res;
|
||||
|
||||
if (data->state != PWD_ID_Req) {
|
||||
ret->ignore = TRUE;
|
||||
|
@ -231,6 +239,9 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
|
|||
|
||||
id = (struct eap_pwd_id *) payload;
|
||||
data->group_num = be_to_host16(id->group_num);
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-PWD: Server EAP-pwd-ID proposal: group=%u random=%u prf=%u prep=%u",
|
||||
data->group_num, id->random_function, id->prf, id->prep);
|
||||
if ((id->random_function != EAP_PWD_DEFAULT_RAND_FUNC) ||
|
||||
(id->prf != EAP_PWD_DEFAULT_PRF)) {
|
||||
ret->ignore = TRUE;
|
||||
|
@ -238,6 +249,22 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
|
|||
return;
|
||||
}
|
||||
|
||||
if (id->prep != EAP_PWD_PREP_NONE &&
|
||||
id->prep != EAP_PWD_PREP_MS) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-PWD: Unsupported password pre-processing technique (Prep=%u)",
|
||||
id->prep);
|
||||
eap_pwd_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (id->prep == EAP_PWD_PREP_NONE && data->password_hash) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-PWD: Unhashed password not available");
|
||||
eap_pwd_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-PWD (peer): using group %d",
|
||||
data->group_num);
|
||||
|
||||
|
@ -260,12 +287,39 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
|
|||
return;
|
||||
}
|
||||
|
||||
if (id->prep == EAP_PWD_PREP_MS) {
|
||||
if (data->password_hash) {
|
||||
res = hash_nt_password_hash(data->password, pwhashhash);
|
||||
} else {
|
||||
u8 pwhash[16];
|
||||
|
||||
res = nt_password_hash(data->password,
|
||||
data->password_len, pwhash);
|
||||
if (res == 0)
|
||||
res = hash_nt_password_hash(pwhash, pwhashhash);
|
||||
os_memset(pwhash, 0, sizeof(pwhash));
|
||||
}
|
||||
|
||||
if (res) {
|
||||
eap_pwd_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
password = pwhashhash;
|
||||
password_len = sizeof(pwhashhash);
|
||||
} else {
|
||||
password = data->password;
|
||||
password_len = data->password_len;
|
||||
}
|
||||
|
||||
/* compute PWE */
|
||||
if (compute_password_element(data->grp, data->group_num,
|
||||
data->password, data->password_len,
|
||||
data->id_server, data->id_server_len,
|
||||
data->id_peer, data->id_peer_len,
|
||||
id->token)) {
|
||||
res = compute_password_element(data->grp, data->group_num,
|
||||
password, password_len,
|
||||
data->id_server, data->id_server_len,
|
||||
data->id_peer, data->id_peer_len,
|
||||
id->token);
|
||||
os_memset(pwhashhash, 0, sizeof(pwhashhash));
|
||||
if (res) {
|
||||
wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute PWE");
|
||||
eap_pwd_state(data, FAILURE);
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue