diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2025-10-23 21:02:22 -0700 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2025-10-23 21:02:22 -0700 |
| commit | 3c2c07a69daf75d377ba196c28524c0fc6a16db6 (patch) | |
| tree | 83a1c9ea49bc8c0927f8de2ed9f3b933f29759f0 /pwhash.go | |
| parent | c241eeb8ad4baafa75691ffb140029ec54cb349e (diff) | |
| download | sym-3c2c07a69daf75d377ba196c28524c0fc6a16db6.tar.zst | |
Move sym files into the root directory
Diffstat (limited to 'pwhash.go')
| -rw-r--r-- | pwhash.go | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/pwhash.go b/pwhash.go new file mode 100644 index 0000000..d05f6b5 --- /dev/null +++ b/pwhash.go @@ -0,0 +1,51 @@ +package sym + +import ( + "crypto/pbkdf2" + "crypto/sha256" + "fmt" + "os" + + "golang.org/x/term" +) + +const defaultPBKDF2Iters = 35_000_000 + +//go:generate go tool stringer -type=pwHash -linecomment +type pwHash int8 + +const ( + pwHashInvalid pwHash = iota + pwHashPBKDF2_HMAC_SHA256 // PBKDF2-HMAC-SHA256 +) + +type hashMetadata struct { + PasswordHashType pwHash + Iterations int32 + SaltSize int8 +} + +func (h *hashMetadata) validate() error { + if h.PasswordHashType != pwHashPBKDF2_HMAC_SHA256 { + return fmt.Errorf("invalid hash type %q", h.PasswordHashType) + } + if h.Iterations <= 0 || h.Iterations > defaultPBKDF2Iters { + return fmt.Errorf("too many iterations") + } + if h.SaltSize <= 0 || h.SaltSize > defaultSaltSize { + return fmt.Errorf("salt size too long") + } + return nil +} + +func (h *hashMetadata) hashPassword(password string, salt []byte) ([]byte, error) { + return pbkdf2.Key(sha256.New, password, salt, int(h.Iterations), 32) +} + +func termReadPassword() (string, error) { + pw, err := term.ReadPassword(int(os.Stdin.Fd())) + if err != nil { + return "", err + } + return string(pw), nil +} |
