diff options
author | Ander Juaristi <a@juaristi.eus> | 2019-10-09 13:06:12 +0200 |
---|---|---|
committer | Ander Juaristi <a@juaristi.eus> | 2019-10-09 13:08:34 +0200 |
commit | f69dca5877829d2c4b2b6362d15791ed39feb635 (patch) | |
tree | 75ea73bcef1216c0c8b101847946b2f80369e7eb | |
parent | 4234e99b2a4296968b00ca69537f4577e109f975 (diff) | |
download | gnutls-ajuaristi-issue-386.tar.gz |
386: Initial importajuaristi-issue-386
Signed-off-by: Ander Juaristi <a@juaristi.eus>
-rw-r--r-- | lib/auth/psk_passwd.c | 64 | ||||
-rw-r--r-- | lib/ext/pre_shared_key.c | 9 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 3 | ||||
-rw-r--r-- | tests/psk.passwd | 1 |
4 files changed, 64 insertions, 13 deletions
diff --git a/lib/auth/psk_passwd.c b/lib/auth/psk_passwd.c index ec46ed3bf7..2b994e505d 100644 --- a/lib/auth/psk_passwd.c +++ b/lib/auth/psk_passwd.c @@ -20,7 +20,7 @@ * */ -/* Functions for operating in an PSK passwd file are included here */ +/* Functions for operating in a PSK passwd file are included here */ #include "gnutls_int.h" @@ -36,13 +36,39 @@ #include <num.h> #include <random.h> +static int read_prf_algo(const char *str, size_t len, gnutls_mac_algorithm_t *prf_algo) +{ + char algo_name[len + 1]; + gnutls_mac_algorithm_t prf; + + strncpy(algo_name, str, len); + algo_name[len] = '\0'; + + /* Some people are used to put dashes - make them happy */ + if (strcmp(algo_name, "SHA-1") == 0) + strcpy(algo_name, "SHA1"); + else if (strcmp(algo_name, "SHA-256") == 0) + strcpy(algo_name, "SHA256"); + else if (strcmp(algo_name, "SHA-512") == 0) + strcpy(algo_name, "SHA512"); + else if (strcmp(algo_name, "SHA-224") == 0) + strcpy(algo_name, "SHA224"); + else if (strcmp(algo_name, "SHA-384") == 0) + strcpy(algo_name, "SHA384"); + + if ((prf = gnutls_mac_get_id(algo_name)) == GNUTLS_MAC_UNKNOWN) + return GNUTLS_E_KEYFILE_ERROR; + + *prf_algo = prf; + return 0; +} /* this function parses passwd.psk file. Format is: * string(username):hex(passwd) */ -static int pwd_put_values(gnutls_datum_t * psk, char *str) +static int pwd_put_values(gnutls_datum_t * psk, gnutls_mac_algorithm_t *prf_algo, char *str) { - char *p; + char *p, *p2; int len, ret; gnutls_datum_t tmp; @@ -60,9 +86,12 @@ static int pwd_put_values(gnutls_datum_t * psk, char *str) /* read the key */ - len = strlen(p); - if (p[len - 1] == '\n' || p[len - 1] == ' ') - len--; + p2 = strchr(p, ':'); + + if (p2) + len = p2 - p; + else + len = strlen(p) - 1; tmp.data = (void*)p; tmp.size = len; @@ -72,6 +101,19 @@ static int pwd_put_values(gnutls_datum_t * psk, char *str) return ret; } + /* read the algorithm, if present and wanted by the user */ + if (p2 && prf_algo) { + len = strlen(++p2); + + if (p2[len - 1] == '\n' || p2[len - 1] == ' ') + len--; + + if ((ret = read_prf_algo(p2, len, prf_algo)) < 0) { + gnutls_assert(); + return ret; + } + } + return 0; } @@ -106,7 +148,8 @@ static int _randomize_psk(gnutls_datum_t * psk) */ int _gnutls_psk_pwd_find_entry(gnutls_session_t session, char *username, - gnutls_datum_t * psk) + gnutls_datum_t * psk, + gnutls_mac_algorithm_t *prf_algo) { gnutls_psk_server_credentials_t cred; FILE *fd; @@ -115,6 +158,9 @@ _gnutls_psk_pwd_find_entry(gnutls_session_t session, char *username, unsigned i, len; int ret; + if (prf_algo) + *prf_algo = GNUTLS_MAC_UNKNOWN; + cred = (gnutls_psk_server_credentials_t) _gnutls_get_cred(session, GNUTLS_CRD_PSK); if (cred == NULL) { @@ -126,7 +172,7 @@ _gnutls_psk_pwd_find_entry(gnutls_session_t session, char *username, * set, use it. */ if (cred->pwd_callback != NULL) { - ret = cred->pwd_callback(session, username, psk); + ret = cred->pwd_callback(session, username, psk, prf_algo); if (ret == 1) { /* the user does not exist */ ret = _randomize_psk(psk); @@ -170,7 +216,7 @@ _gnutls_psk_pwd_find_entry(gnutls_session_t session, char *username, } if (strncmp(username, line, MAX(i, len)) == 0) { - ret = pwd_put_values(psk, line); + ret = pwd_put_values(psk, prf_id, line); if (ret < 0) { gnutls_assert(); ret = GNUTLS_E_SRP_PWD_ERROR; diff --git a/lib/ext/pre_shared_key.c b/lib/ext/pre_shared_key.c index 436a426a87..2b1f023fc5 100644 --- a/lib/ext/pre_shared_key.c +++ b/lib/ext/pre_shared_key.c @@ -607,18 +607,21 @@ static int server_recv_params(gnutls_session_t session, psk.identity.size > 0 && psk.identity.size <= MAX_USERNAME_SIZE) { /* _gnutls_psk_pwd_find_entry() expects 0-terminated identities */ char identity_str[MAX_USERNAME_SIZE + 1]; - - prf = pskcred->binder_algo; + gnutls_mac_algorithm_t binder_algo_id; memcpy(identity_str, psk.identity.data, psk.identity.size); identity_str[psk.identity.size] = 0; /* this fails only on configuration errors; as such we always * return its error code in that case */ - ret = _gnutls_psk_pwd_find_entry(session, identity_str, &key); + ret = _gnutls_psk_pwd_find_entry(session, identity_str, &key, &binder_algo_id); if (ret < 0) return gnutls_assert_val(ret); + prf = (binder_algo_id == GNUTLS_MAC_UNKNOWN ? + pskcred->binder_algo : + mac_to_entry(binder_algo_id)); + resuming = 0; break; } diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index f5a5a66acb..0c335b66ba 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -2544,7 +2544,8 @@ gnutls_psk_set_server_credentials_function(gnutls_psk_server_credentials_t typedef int gnutls_psk_client_credentials_function(gnutls_session_t, char **username, - gnutls_datum_t * key); + gnutls_datum_t * key, + gnutls_mac_algorithm_t * prf); void gnutls_psk_set_client_credentials_function(gnutls_psk_client_credentials_t cred, diff --git a/tests/psk.passwd b/tests/psk.passwd index 3dd998e2dc..1919174082 100644 --- a/tests/psk.passwd +++ b/tests/psk.passwd @@ -1,2 +1,3 @@ jas:9e32cf7786321a828ef7668f09fb35db non-hex:9e32cf7786321a828ef7668f09fb35dbxx +explicitprf:9e32cf7786321a828ef7668f09fb35dbxx:sha-1 |