summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2020-10-30 16:53:47 +0100
committerDaiki Ueno <ueno@gnu.org>2020-10-31 16:18:34 +0100
commit9728b396db737987bbd3a1d1e4a17449b6b928fc (patch)
treea6ec2e2464c0addb5377e7fb605bc64dd6f5c186
parentcc89b3c82a13fc88a6fbfb1e4d47278bebcf913a (diff)
downloadgnutls-9728b396db737987bbd3a1d1e4a17449b6b928fc.tar.gz
psktool: Fix hex-encoding logic of username
The previous code didn't modify the pointer to the realloc'ed region nor check overflow before calling realloc. Spotted by Anderson Sasaki in: <https://gitlab.com/gnutls/gnutls/-/merge_requests/1345#note_439063374>. Signed-off-by: Daiki Ueno <ueno@gnu.org>
-rw-r--r--src/psk.c15
-rwxr-xr-xtests/psktool.sh32
2 files changed, 41 insertions, 6 deletions
diff --git a/src/psk.c b/src/psk.c
index b79401cf16..4b8a62957a 100644
--- a/src/psk.c
+++ b/src/psk.c
@@ -58,6 +58,7 @@ int main(int argc, char **argv)
#include <minmax.h>
#include "close-stream.h"
#include "getpass.h"
+#include "xsize.h"
static int write_key(const char *username,
const unsigned char *key, size_t key_size,
@@ -217,6 +218,7 @@ write_key(const char *username, const unsigned char *key, size_t key_size,
/* encode username if it contains special characters */
if (strcspn(username, ":\n") != strlen(username)) {
char *new_data;
+ size_t new_size;
tmp.data = (void *)username;
tmp.size = strlen(username);
@@ -229,16 +231,21 @@ write_key(const char *username, const unsigned char *key, size_t key_size,
}
/* prepend '#' */
- new_data = gnutls_realloc(_username.data, _username.size + 2);
+ new_size = xsum(_username.size, 2);
+ if (size_overflow_p(new_size)) {
+ ret = -1;
+ goto out;
+ }
+ new_data = gnutls_realloc(_username.data, new_size);
if (!new_data) {
ret = -1;
goto out;
}
- memmove(_username.data + 1, _username.data, _username.size);
+ memmove(new_data + 1, new_data, _username.size);
new_data[0] = '#';
- new_data[_username.size] = '\0';
+ new_data[_username.size + 1] = '\0';
_username.data = (void *)new_data;
- _username.size += 1;
+ _username.size = new_size - 1;
} else {
_username.data = (void *)strdup(username);
_username.size = strlen(username);
diff --git a/tests/psktool.sh b/tests/psktool.sh
index 9e81d01718..9d0e081296 100755
--- a/tests/psktool.sh
+++ b/tests/psktool.sh
@@ -41,7 +41,7 @@ fi
echo "Checking PSK tool basic operations"
# echo create a user and check whether a key is available
-"${PSKTOOL}" -p ${TMPFILE} -u test
+${VALGRIND} "${PSKTOOL}" -p ${TMPFILE} -u test
if test $? != 0;then
echo "password generation failed..."
exit 1
@@ -63,7 +63,7 @@ fi
# Create second user and check whether both exist
-"${PSKTOOL}" -p ${TMPFILE} -u user2
+${VALGRIND} "${PSKTOOL}" -p ${TMPFILE} -u user2
if test $? != 0;then
echo "password generation failed..."
exit 1
@@ -81,6 +81,34 @@ if test $? != 0;then
exit 1
fi
+# Create third user with a special character in username
+
+${VALGRIND} "${PSKTOOL}" -p ${TMPFILE} -u user:3
+if test $? != 0;then
+ echo "password generation failed..."
+ exit 1
+fi
+
+grep '#757365723a33:' ${TMPFILE} >/dev/null 2>&1
+if test $? != 0;then
+ echo "could not find third generated user..."
+ exit 1
+fi
+
+# Modify the third user password
+
+${VALGRIND} "${PSKTOOL}" -p ${TMPFILE} -u user:3
+if test $? != 0;then
+ echo "password generation failed..."
+ exit 1
+fi
+
+matches=`grep '#757365723a33:' ${TMPFILE} 2>/dev/null | wc -l`
+if test $matches != 1;then
+ echo "duplicate entry for third generated user..."
+ exit 1
+fi
+
rm -f $TMPFILE
exit 0