commit d2c2e549cfd016d1e2f7a748a55a1c2541ba2787 from: Omar Polo date: Sun May 21 15:50:35 2023 UTC totp: support other algorithms too commit - efd5f30cbef5c230de05502bcb840974b023afe1 commit + d2c2e549cfd016d1e2f7a748a55a1c2541ba2787 blob - 4c65b24145c830c58361cb9f2bbab8c1720ea7d5 blob + 1ce9cf076bd2dfab6a96bf08f741adad1ad34f62 --- totp.c +++ totp.c @@ -134,7 +134,7 @@ url_decode(char *url, char *dst) } static int -uri2secret(char *s, int *digits) +uri2secret(char *s, int *digits, const EVP_MD **alg) { char *q, *t, *f, *secret = NULL; @@ -155,6 +155,16 @@ uri2secret(char *s, int *digits) *digits = 8; else warnx("invalid number of digits; using 6"); + } else if (!strncmp(f, "algorithm=", 10)) { + f += 10; + if (!strcmp(f, "SHA1")) + *alg = EVP_sha1(); + else if (!strcmp(f, "SHA256")) + *alg = EVP_sha256(); + else if (!strcmp(f, "SHA512")) + *alg = EVP_sha512(); + else + warnx("unknown algorithm; using SHA1"); } } @@ -170,6 +180,7 @@ main(int argc, char **argv) { char buf[1024]; size_t buflen; + const EVP_MD *alg; unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; char *s, *q, *line = NULL; @@ -195,6 +206,8 @@ main(int argc, char **argv) if (argc != 0) usage(); + alg = EVP_sha1(); + linelen = getline(&line, &linesize, stdin); if (linelen == -1) { if (ferror(stdin)) @@ -213,7 +226,7 @@ main(int argc, char **argv) errx(1, "no secret provided"); if (!strncmp(line, "otpauth://", 10) && - uri2secret(line, &digits) == -1) + uri2secret(line, &digits, &alg) == -1) errx(1, "failed to decode otpauth URI"); if ((buflen = b32decode(line, buf, sizeof(buf))) == 0) @@ -221,8 +234,7 @@ main(int argc, char **argv) ct = htobe64(time(NULL) / 30); - HMAC(EVP_sha1(), buf, buflen, (unsigned char *)&ct, sizeof(ct), - md, &mdlen); + HMAC(alg, buf, buflen, (unsigned char *)&ct, sizeof(ct), md, &mdlen); off = md[mdlen - 1] & 0x0F;