blob: d05f6b56975003067eba69562551d3fa75341e5c (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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
}
|