...
1 package crypto
2
3 import (
4 "fmt"
5
6 "golang.org/x/crypto/bcrypt"
7
8 "edge-infra.dev/pkg/lib/crypto/randomizer"
9 "edge-infra.dev/pkg/lib/crypto/validation"
10 )
11
12 type bcryptCredential struct {
13 plainTextPwd string
14 hashedPwd []byte
15 }
16
17 func (pwd bcryptCredential) Salt() ([]byte, error) {
18 return []byte(""), fmt.Errorf("bcrypt generates the salt")
19 }
20
21 func (pwd bcryptCredential) Iterations() (int, error) {
22 return -1, fmt.Errorf("bcrypt implementation does not include iteration count")
23 }
24
25 func (pwd bcryptCredential) HashFunction() string {
26 return string(bcryptType)
27 }
28
29 func (pwd bcryptCredential) HashType() string {
30 return bcryptType.Type()
31 }
32
33 func (pwd bcryptCredential) Hashed() []byte {
34 return pwd.hashedPwd
35 }
36
37 func (pwd bcryptCredential) Plain() string {
38 return pwd.plainTextPwd
39 }
40
41
42 func GenerateRandomBcryptPassword(minLength, maxLength, cost int) (Credential, error) {
43 if err := validation.ValidatePwdBounds(minLength, maxLength); err != nil {
44 return nil, err
45 }
46
47 pwdLen, err := randomizer.RandomPassLength(minLength, maxLength)
48 if err != nil {
49 return nil, err
50 }
51
52 if err := validation.ValidateCost(cost); err != nil {
53 return nil, err
54 }
55
56 pwd, err := randomizer.GenerateRandomPlainPwd(pwdLen)
57 if err != nil {
58 return nil, err
59 }
60
61 hashedPwd, err := bcrypt.GenerateFromPassword([]byte(pwd), cost)
62 if err != nil {
63 return nil, err
64 }
65
66 return bcryptCredential{plainTextPwd: pwd, hashedPwd: hashedPwd}, nil
67 }
68
69 func CompareBcryptHashAndPassword(hashPwd []byte, current string) bool {
70 err := bcrypt.CompareHashAndPassword(hashPwd, []byte(current))
71 return err == nil
72 }
73
View as plain text