Module Name:    src
Committed By:   nia
Date:           Tue Oct 12 09:40:39 UTC 2021

Modified Files:
        src/lib/libcrypt: crypt-argon2.c

Log Message:
crypt-argon2: improve resilience of the parser.

Allow the version number to be unspecified as in the argon2 upstream
test suite, properly defaulting to a version if the v= block is
entirely missing, and treating the remaining block as parameters.

Fix a null pointer derefence when the encoded password is unspecified
in the settings string.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/lib/libcrypt/crypt-argon2.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libcrypt/crypt-argon2.c
diff -u src/lib/libcrypt/crypt-argon2.c:1.2 src/lib/libcrypt/crypt-argon2.c:1.3
--- src/lib/libcrypt/crypt-argon2.c:1.2	Thu May 14 08:34:19 2020
+++ src/lib/libcrypt/crypt-argon2.c	Tue Oct 12 09:40:38 2021
@@ -95,15 +95,24 @@ static int decode_option(argon2_context 
 
 	a = strsep(&inp, "$");
 
-	if ((getnum(a, &tmp))<0) { /* on error, default to current */
-				/* should start thinking about aborting */
-		ctx->version = ARGON2_VERSION_NUMBER;
+	/* parse the version number of the hash, if it's there */
+	if (strncmp(a, "v=", 2) == 0) {
+		a += 2;
+		if ((getnum(a, &tmp))<0) { /* on error, default to current */
+			/* should start thinking about aborting */
+			ctx->version = ARGON2_VERSION_NUMBER;
+		} else {
+			ctx->version = tmp;
+		}
+		a = strsep(&inp, "$");
 	} else {
-		ctx->version = tmp;
+		/*
+		 * This is a parameter list, not a version number, use the
+		 * default version.
+		 */
+		ctx->version = ARGON2_VERSION_NUMBER;
 	}
 
-	a = strsep(&inp, "$");
-
 	/* parse labelled argon2 params */
 	/* m_cost (m)
 	 * t_cost (t)
@@ -143,12 +152,12 @@ static int decode_option(argon2_context 
 
 	a = strsep(&inp, "$");
 
-	snprintf((char *)ctx->salt,ctx->saltlen, "%s", a);
+	snprintf((char *)ctx->salt, ctx->saltlen, "%s", a);
 
 	a = strsep(&inp, "$");
 
-	if (*a) {
-		snprintf((char *)ctx->pwd,ctx->pwdlen, "%s", a);
+	if (a) {
+		snprintf((char *)ctx->pwd, ctx->pwdlen, "%s", a);
 	} else {
 		/* don't care if passwd hash is missing */
 		/* if missing, most likely coming from */
@@ -212,7 +221,7 @@ __crypt_argon2(const char *pw, const cha
 	rc = decode_option(&ctx, &atype, salt);
 
 	if (rc < 0) {
-	/* unable to parse input params */
+		/* unable to parse input params */
 		return 0;
 	}
 
@@ -221,7 +230,8 @@ __crypt_argon2(const char *pw, const cha
 		ebuf, sizeof(ebuf), encodebuf, sizeof(encodebuf), atype, ctx.version);
 
 	if (rc != ARGON2_OK) {
-		fprintf(stderr, "Failed: %s\n", argon2_error_message(rc));
+		fprintf(stderr, "argon2: failed: %s\n",
+		    argon2_error_message(rc));
 		return 0;
 	}
 

Reply via email to