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
99
100
101
102
103
|
diff --git a/spectre.go b/spectre.go
index 4f5ba3d5e7c8fb5e803c12093d7390c9ce25f5e1..b640fbf763656b6d73d3ee5ba25a06f45c93f7cc 100644
--- a/spectre.go
+++ b/spectre.go
@@ -1,12 +1,5 @@
package spectre
-import (
- "crypto/hmac"
- "crypto/sha256"
- "golang.org/x/crypto/scrypt"
- "strings"
-)
-
// Spectre is a spectre client
type Spectre struct {
name string
@@ -26,7 +19,7 @@ }
for _, opt := range opts {
opt(s)
}
- s.key, err = s.userKey()
+ s.key, err = userKey(s.name, s.secret, s.scoper)
return
}
@@ -40,75 +33,9 @@ s.scoper = scoper
}
}
-func (s *Spectre) userKey() ([]byte, error) {
- nameBytes := []byte(s.name)
- secretBytes := []byte(s.secret)
- keyScope := []byte(s.scoper.Scope(Authentication))
-
- nameBytesLen := len(nameBytes)
- keySalt := append(keyScope,
- byte(nameBytesLen>>24),
- byte(nameBytesLen>>16),
- byte(nameBytesLen>>8),
- byte(nameBytesLen),
- )
- keySalt = append(keySalt, nameBytes...)
-
- return scrypt.Key(secretBytes, keySalt, 32768, 8, 2, 64)
-}
-
-func (s *Spectre) siteKey(name string, counter int, scope Scope) []byte {
- nameBytes := []byte(name)
- scopeBytes := []byte(s.scoper.Scope(scope))
-
- nameBytesLen := len(nameBytes)
- keySalt := append(scopeBytes,
- byte(nameBytesLen>>24),
- byte(nameBytesLen>>16),
- byte(nameBytesLen>>8),
- byte(nameBytesLen),
- )
- keySalt = append(keySalt, nameBytes...)
- keySalt = append(keySalt,
- byte(counter>>24),
- byte(counter>>16),
- byte(counter>>8),
- byte(counter),
- )
-
- sign := hmac.New(sha256.New, s.key)
- sign.Write(keySalt)
-
- return sign.Sum(nil)
-}
-
// Site returns a site password based on Options
func (s *Spectre) Site(siteName string, opts ...SiteOption) string {
- siteOpts := &options{
- template: "",
- counter: 1,
- scope: Authentication,
- }
- for _, opt := range opts {
- opt(siteOpts)
- }
-
- if siteOpts.template == "" {
- siteOpts.template = siteOpts.scope.DefaultTemplate()
- }
-
- siteKey := s.siteKey(siteName, siteOpts.counter, siteOpts.scope)
-
- templateSet := templates[siteOpts.template]
- template := templateSet[int(siteKey[0])%len(templateSet)]
-
- var out strings.Builder
- for idx, b := range template {
- chars := characters[string(b)]
- char := chars[int(siteKey[idx+1])%len(chars)]
- out.WriteByte(char)
- }
- return out.String()
+ return site(s.key, s.scoper, siteName, opts...)
}
type options struct {
|