-
Notifications
You must be signed in to change notification settings - Fork 13
/
secret.go
98 lines (79 loc) · 1.88 KB
/
secret.go
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package vault
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"errors"
"strings"
)
const vaultHeader = "$ANSIBLE_VAULT;1.1;AES256"
type secret struct {
salt []byte
hmac []byte
data []byte
}
func decodeSecret(input string) (*secret, error) {
lines := strings.SplitN(input, "\n", 3)
if len(lines) != 3 {
return nil, errors.New("invalid secret")
}
salt, err := hex.DecodeString(lines[0])
if err != nil {
return nil, err
}
hmac, err := hex.DecodeString(lines[1])
if err != nil {
return nil, err
}
data, err := hex.DecodeString(lines[2])
if err != nil {
return nil, err
}
return &secret{salt, hmac, data}, nil
}
func encodeSecret(secret *secret, key *key) (string, error) {
hmacEncrypt := hmac.New(sha256.New, key.hmacKey)
hmacEncrypt.Write(secret.data)
hexSalt := hex.EncodeToString(secret.salt)
hexHmac := hmacEncrypt.Sum(nil)
hexCipher := hex.EncodeToString(secret.data)
combined := strings.Join([]string{
string(hexSalt),
hex.EncodeToString([]byte(hexHmac)),
string(hexCipher),
}, "\n")
result := strings.Join([]string{
vaultHeader,
wrapText(hex.EncodeToString([]byte(combined))),
}, "\n")
return result, nil
}
func checkDigest(secret *secret, key *key) error {
hash := hmac.New(sha256.New, key.hmacKey)
hash.Write(secret.data)
if !hmac.Equal(hash.Sum(nil), secret.hmac) {
return errors.New("invalid password")
}
return nil
}
func wrapText(text string) string {
src := []byte(text)
result := []byte{}
for i := 0; i < len(src); i++ {
if i > 0 && i%80 == 0 {
result = append(result, '\n')
}
result = append(result, src[i])
}
return string(result)
}
func hexDecode(input string) (string, error) {
input = strings.TrimSpace(input)
input = strings.Replace(input, "\r", "", -1)
input = strings.Replace(input, "\n", "", -1)
decoded, err := hex.DecodeString(input)
if err != nil {
return "", err
}
return string(decoded), nil
}