mirror of
https://github.com/angt/secret
synced 2025-02-12 08:48:09 +01:00
Add base32 encoded TOTP
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
parent
edc05057fc
commit
6e1722c70e
2 changed files with 61 additions and 4 deletions
|
@ -158,6 +158,15 @@ Add a TOTP token:
|
||||||
Passphrase:
|
Passphrase:
|
||||||
$ 123456
|
$ 123456
|
||||||
|
|
||||||
|
Add a base32 encoded TOTP token:
|
||||||
|
|
||||||
|
$ echo JBSWY3DPEHPK3PXP | secret set test/totp32
|
||||||
|
Passphrase:
|
||||||
|
|
||||||
|
$ secret show test/totp32
|
||||||
|
Passphrase:
|
||||||
|
$ 123456
|
||||||
|
|
||||||
Derive a deterministic (a.k.a. unstored) secret:
|
Derive a deterministic (a.k.a. unstored) secret:
|
||||||
|
|
||||||
$ secret pass me@domain.com
|
$ secret pass me@domain.com
|
||||||
|
|
56
secret.c
56
secret.c
|
@ -491,13 +491,13 @@ s_sha1(uint8_t *digest, uint8_t *buf, size_t len)
|
||||||
static void
|
static void
|
||||||
s_totp(const char *secret, size_t len)
|
s_totp(const char *secret, size_t len)
|
||||||
{
|
{
|
||||||
|
if (!len || len > 64)
|
||||||
|
return;
|
||||||
|
|
||||||
uint8_t h[20];
|
uint8_t h[20];
|
||||||
uint8_t ki[64 + 8] = {0};
|
uint8_t ki[64 + 8] = {0};
|
||||||
uint8_t ko[64 + 20] = {0};
|
uint8_t ko[64 + 20] = {0};
|
||||||
|
|
||||||
if (!len || len > 64)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memcpy(ki, secret, len);
|
memcpy(ki, secret, len);
|
||||||
memcpy(ko, secret, len);
|
memcpy(ko, secret, len);
|
||||||
|
|
||||||
|
@ -519,6 +519,52 @@ s_totp(const char *secret, size_t len)
|
||||||
s_write(1, tmp, 6);
|
s_write(1, tmp, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
s_b32(char c)
|
||||||
|
{
|
||||||
|
if (c >= 'A' && c <= 'Z') {
|
||||||
|
return c - 'A';
|
||||||
|
} else if (c >= '2' && c <= '9') {
|
||||||
|
return c - '2' + ('Z' - 'A') + 1;
|
||||||
|
}
|
||||||
|
s_fatal("Invalid base32 character");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s_totp32(const char *secret, size_t len)
|
||||||
|
{
|
||||||
|
if (!len)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char out[64];
|
||||||
|
size_t outlen = 0;
|
||||||
|
unsigned buf = 0;
|
||||||
|
int bits = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
char c = secret[i];
|
||||||
|
|
||||||
|
if (!c || c == '=' || c == '\n')
|
||||||
|
break;
|
||||||
|
|
||||||
|
buf = (buf << 5) | s_b32(c);
|
||||||
|
bits += 5;
|
||||||
|
|
||||||
|
if (bits < 8)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (outlen == 64)
|
||||||
|
s_fatal("TOTP too big");
|
||||||
|
|
||||||
|
bits -= 8;
|
||||||
|
out[outlen++] = (buf >> bits) & 0xFF;
|
||||||
|
}
|
||||||
|
if (bits)
|
||||||
|
out[outlen++] = (buf << (8 - bits)) & 0xFF;
|
||||||
|
|
||||||
|
s_totp(out, outlen);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
s_show(int argc, char **argv, void *data)
|
s_show(int argc, char **argv, void *data)
|
||||||
{
|
{
|
||||||
|
@ -535,7 +581,9 @@ s_show(int argc, char **argv, void *data)
|
||||||
|
|
||||||
if (secret) {
|
if (secret) {
|
||||||
size_t len = load16_le(s.x.entry.slen);
|
size_t len = load16_le(s.x.entry.slen);
|
||||||
if (strstr(argv[1], "totp")) {
|
if (strstr(argv[1], "totp32")) {
|
||||||
|
s_totp32(secret, len);
|
||||||
|
} else if (strstr(argv[1], "totp")) {
|
||||||
s_totp(secret, len);
|
s_totp(secret, len);
|
||||||
} else {
|
} else {
|
||||||
s_write(1, secret, len);
|
s_write(1, secret, len);
|
||||||
|
|
Loading…
Add table
Reference in a new issue