ci / vet (pull_request) Failing after 12s
Full client-side crypto (PBKDF2/Argon2id master key, HKDF stretch, AES-256-CBC+HMAC encstrings), password grant with TOTP 2FA, sync, list/get/env/set/rm. Containerized (alpine, non-root), CI = gofmt/vet/ build/secret-scan, compose service ukrrs-secretsmgr-cli. Rust-era scripts archived. Live-validated against pwvault.turnsys.com. Ticket: https://projects.knownelement.com/issues/832
35 lines
829 B
Go
35 lines
829 B
Go
package main
|
|
|
|
// RFC 6238 TOTP (SHA1, 30s, 6 digits) for Bitwarden 2FA provider 0.
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha1"
|
|
"encoding/base32"
|
|
"encoding/binary"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func totpNow(secretB32 string, at time.Time) (string, error) {
|
|
secret := strings.ToUpper(strings.ReplaceAll(strings.ReplaceAll(secretB32, " ", ""), "-", ""))
|
|
pad := len(secret) % 8
|
|
if pad != 0 {
|
|
secret += strings.Repeat("=", 8-pad)
|
|
}
|
|
key, err := base32.StdEncoding.DecodeString(secret)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
counter := uint64(at.Unix()) / 30
|
|
var ctr [8]byte
|
|
binary.BigEndian.PutUint64(ctr[:], counter)
|
|
h := hmac.New(sha1.New, key)
|
|
h.Write(ctr[:])
|
|
sum := h.Sum(nil)
|
|
off := sum[len(sum)-1] & 0x0f
|
|
code := (binary.BigEndian.Uint32(sum[off:off+4]) & 0x7fffffff) % 1000000
|
|
return fmt.Sprintf("%06d", code), nil
|
|
}
|