From 3709c4a20b0fce5ddefc1c4b54133dfc716877c4 Mon Sep 17 00:00:00 2001 From: Hangkun Ung <hangkun.ung@gmail.com> Date: Sun, 20 Feb 2022 19:13:34 -0500 Subject: [PATCH] Add support for SHA256 and SHA512 --- .gitignore | 1 + README.md | 3 ++- gauth/gauth.go | 27 ++++++++++++++++++++++++--- gauth/testdata/encrypted.csv | Bin 64 -> 176 bytes gauth/testdata/plaintext.csv | 2 +- 5 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd5106f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_STORE diff --git a/README.md b/README.md index 08264de..5063022 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Usage Airbnb:abcd efgh ijkl mnop Google:a2b3c4d5e6f7ghij Github:234567qrstuvwxyz + otpauth://totp/testOrg:testuser?secret=AAAQEAYEAUDAOCAJ======&issuer=testOrg&algorithm=SHA512&digits=8&period=30 - Restrict access to your user: @@ -53,7 +54,7 @@ Encryption `gauth` will then prompt you for that password on every run: $ gauth - Encryption password: + Encryption password: prev curr next LastPass 915200 479333 408710 diff --git a/gauth/gauth.go b/gauth/gauth.go index 3b2af0a..bb26114 100644 --- a/gauth/gauth.go +++ b/gauth/gauth.go @@ -6,9 +6,12 @@ import ( "bytes" "crypto/aes" "crypto/cipher" + "crypto/sha1" "crypto/sha256" + "crypto/sha512" "errors" "fmt" + "hash" "io/ioutil" "strings" "time" @@ -24,6 +27,21 @@ func IndexNow() (uint64, int) { return uint64(time / 30), int(time % 30) } +// pickAlgorithm returns a constructor for the named hash function, or +// an error if the name is not a supported algorithm. +func pickAlgorithm(name string) (func() hash.Hash, error) { + switch name { + case "", "SHA1": + return sha1.New, nil + case "SHA256": + return sha256.New, nil + case "SHA512": + return sha512.New, nil + default: + return nil, fmt.Errorf("unsupported algorithm: %q", name) + } +} + // Codes returns the previous, current, and next codes from u. func Codes(u *otpauth.URL) (prev, curr, next string, _ error) { var ts uint64 @@ -40,11 +58,14 @@ func Codes(u *otpauth.URL) (prev, curr, next string, _ error) { func CodesAtTimeStep(u *otpauth.URL, timeStep uint64) (prev, curr, next string, _ error) { if u.Type != "totp" { return "", "", "", fmt.Errorf("unsupported type: %q", u.Type) - } else if u.Algorithm != "" && u.Algorithm != "SHA1" { - return "", "", "", fmt.Errorf("unsupported algorithm: %q", u.Algorithm) } - cfg := otp.Config{Digits: u.Digits} + alg, err := pickAlgorithm(u.Algorithm) + if err != nil { + return "", "", "", err + } + + cfg := otp.Config{Hash: alg, Digits: u.Digits} if err := cfg.ParseKey(u.RawSecret); err != nil { return "", "", "", fmt.Errorf("invalid secret: %v", err) } diff --git a/gauth/testdata/encrypted.csv b/gauth/testdata/encrypted.csv index 0185d1b96cf5e2719b74c59f1df8527df2e2d79c..ab8697f6d509c5a47349a1676e6f7547fe1521c7 100644 GIT binary patch literal 176 zcmV;h08jr@VQh3|WM5xp#JFzH%k`L@{D8=~18iQS(*RM}<eR1#BEK+|B4ij_g7AL_ z+&Y50;%p^NZaz1(LQrB4Ck*?qa?Q+pU(7^+h@R(H)iR0bxBS9K+GLQO%Lk=e3DJkq zTnJ2}Uq4P9SY=-kaDwFAwzdGwRs%`??*Qr3?9sG`NnlpA-5&KHCr@T_O7wJWgcsts e|63hQdZnD9Dm(lG5#`Rpwp;BTq@Q=rzCW>NrC8tq literal 64 zcmV-G0KflJVQh3|WM5w-G3q)M!zYxZ3(#$~4iEvv?1ke+)-pQY`Uu`$j~$OC)r(o5 W`4~(QDv{t5Q#$sSJ@}7H$lIQciyhzq diff --git a/gauth/testdata/plaintext.csv b/gauth/testdata/plaintext.csv index ec462d0..6da0364 100644 --- a/gauth/testdata/plaintext.csv +++ b/gauth/testdata/plaintext.csv @@ -1,3 +1,3 @@ test2:AEBAGBAFAYDQQCIK test1:AAAQEAYEAUDAOCAJ - +otpauth://totp/test3:testuser3?secret=AAAQEAYEAUDAOCAJ======&issuer=test3&algorithm=SHA512&digits=8&period=30