cryptutils

Cryptographic Software Utilities
git clone http://git.omkov.net/cryptutils
Log | Tree | Refs | README | LICENCE | Download

AuthorJamozed <[email protected]>
Date2021-02-21 10:43:50
Commit3275b9a753ccf3022037d481b71e18f3f652a4a2
Parent0737d9ea7e64133bd878ae025ad44c1fc8efd3bb

otp: Use Base32 for secret input

Use Base32 format for secret input as this is most commonly used for HOTP and TOTP keys.

Diffstat

M src/otp.c | 53 +++++++++++++----------------------------------------

1 files changed, 13 insertions, 40 deletions

diff --git a/src/otp.c b/src/otp.c
index d9841e2..f4b5fc5 100644
--- a/src/otp.c
+++ b/src/otp.c
@@ -1,4 +1,4 @@
-// otp.c, version 0.1.0
+// otp.c, version 0.2.0
 // OMKOV cryptutils otp
 // Copyright (C) 2020, Jakob Wakeling
 // All rights reserved.
@@ -30,12 +30,10 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-/*
-	TODO Switch to base32 for secret input, as this is more commonly used.
-*/
-
+#include "lib/base32.h"
 #include "lib/error.c"
 #include "lib/optget.h"
+#include "lib/strconv.h"
 
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
@@ -44,7 +42,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 #include <stdint.h>
 #include <stdio.h>
 
-#define VERSION "0.1.0"
+#define VERSION "0.2.0"
 
 static struct lop lops[] = {
 	{ "help",    ARG_NUL, 256 },
@@ -52,10 +50,7 @@ static struct lop lops[] = {
 	{ NULL, 0, 0 }
 };
 
-static const uint8_t B16D[];
-
 static inline uint32_t hotp(uint8_t *K, size_t Klen, uint64_t C);
-static uint8_t *b16d(char *s, size_t l);
 
 static void hlp(void);
 static void ver(void);
@@ -74,18 +69,16 @@ int main(int ac, char *av[]) { A0 = av[0];
 
 	if (opt.ind == ac - 1) { c = time(NULL) / 30; }
 	else {
-		register uint64_t d; register char *p = av[opt.ind + 1];
-		for (c = 0; *p >= '0' && *p <= '9'; ++p) {
-			d = (uint64_t)*p - '0';
-			if (c > (UINT64_MAX - d) / 10) { break; }
-			c = c * 10 + d;
-		}
-		
-		if (*p) { error(1, "invalid counter"); }
+		char *ep; c = strtou64(av[opt.ind + 1], &ep, 10);
+		if (*ep) { error(1, "invalid counter"); }
 	}
 
-	if (!(k = b16d(av[opt.ind], l))) { error(1, "invalid secret"); }
-	printf("%06u\n", hotp(k, l / 2, c)); free(k); return 0;
+	k = (uint8_t *)malloc(B32DLEN(l) * sizeof (*k));
+	if (!k) { error(1, "%s", serr()); }
+	
+	size_t kl = b32decode(k, (uint8_t *)av[opt.ind], l);
+	
+	printf("%06u\n", hotp(k, kl, c)); free(k); return 0;
 }
 
 /* Compute HOTP token with a key and counter */
@@ -111,17 +104,6 @@ static inline uint32_t hotp(uint8_t *K, size_t Klen, uint64_t C) {
 	return dt % (uint32_t)pow(10, 6/*Token length*/);
 }
 
-/* Decode base16 to an array */
-static uint8_t *b16d(char *s, size_t l) {
-	if (l % 2) { return NULL; }
-	
-	uint8_t *a = (uint8_t *)malloc((l / 2) * sizeof (*a));
-	
-	for (uint8_t *i = a; *s; ++i, s += 2) {
-		*i = (B16D[s[0]] << 4) | B16D[s[1]];
-	} return a;
-}
-
 /* Print help information */
 static void hlp(void) {
 	puts("otp - compute hotp or totp tokens\n");
@@ -140,13 +122,3 @@ static void ver(void) {
 	puts("OMKOV Permissive Licence (https://www.omkov.net/OLPE)");
 	return;
 }
-
-static const uint8_t B16D[] = {
-	0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0,  1,  2,  3,  4,  5,  6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
-	0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 10, 11, 12, 13, 14, 15, 0
-};