summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnder Juaristi <a@juaristi.eus>2019-10-09 13:06:12 +0200
committerAnder Juaristi <a@juaristi.eus>2019-10-09 13:08:34 +0200
commitf69dca5877829d2c4b2b6362d15791ed39feb635 (patch)
tree75ea73bcef1216c0c8b101847946b2f80369e7eb
parent4234e99b2a4296968b00ca69537f4577e109f975 (diff)
downloadgnutls-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.c64
-rw-r--r--lib/ext/pre_shared_key.c9
-rw-r--r--lib/includes/gnutls/gnutls.h.in3
-rw-r--r--tests/psk.passwd1
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