forked from smallstep/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
auth.go
145 lines (116 loc) · 3.52 KB
/
auth.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package nacl
import (
"encoding/hex"
"fmt"
"io/ioutil"
"github.com/pkg/errors"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/utils"
"github.com/urfave/cli"
"golang.org/x/crypto/nacl/auth"
)
func authCommand() cli.Command {
return cli.Command{
Name: "auth",
Usage: "authenticates a message using a secret key",
UsageText: "step crypto nacl auth <subcommand> [arguments] [global-flags] [subcommand-flags]",
Description: `**step crypto nacl auth** command group uses secret key cryptography to
authenticate and verify messages using a secret key.
TODO
## EXAMPLES
Authenticate a message using a 256-bit key, a new nacl box private key can be
used as the secret:
'''
$ step crypto nacl auth digest auth.key
Write text to authenticate: ********
33c54aeb54077808fcfccadcd2f01971b120e314dffa61516b0738b74fdc8ff1
$ cat message.txt | step crypto nacl auth digest auth.key
33c54aeb54077808fcfccadcd2f01971b120e314dffa61516b0738b74fdc8ff1
'''
Verify the message with the hash:
'''
$ step crypto nacl auth verify auth.key 33c54aeb54077808fcfccadcd2f01971b120e314dffa61516b0738b74fdc8ff1
Write text to verify: ********
ok
$ cat message.txt | step crypto nacl auth verify auth.key 33c54aeb54077808fcfccadcd2f01971b120e314dffa61516b0738b74fdc8ff1
ok
'''`,
Subcommands: cli.Commands{
authDigestCommand(),
authVerifyCommand(),
},
}
}
func authDigestCommand() cli.Command {
return cli.Command{
Name: "digest",
Action: cli.ActionFunc(authDigestAction),
Usage: "generates a 32-byte digest for a message",
UsageText: "**step crypto nacl auth digest** <key-file>",
Description: `**step crypto nacl auth digest** creates a digest to authenticate of a message
using a secret key.
TODO
For examples, see **step help crypto nacl auth**.`,
}
}
func authVerifyCommand() cli.Command {
return cli.Command{
Name: "verify",
Action: cli.ActionFunc(authVerifyAction),
Usage: "checks digest is a valid for a message",
UsageText: "**step crypto nacl auth verify** <key-file> <digest>",
Description: `**step crypto nacl auth verify** verifies the digest of a message with a secret
key.
TODO
For examples, see **step help crypto nacl auth**.`,
}
}
func authDigestAction(ctx *cli.Context) error {
if err := errs.NumberOfArguments(ctx, 1); err != nil {
return err
}
keyFile := ctx.Args().Get(0)
key, err := ioutil.ReadFile(keyFile)
if err != nil {
return errs.FileError(err, keyFile)
} else if len(key) != auth.KeySize {
return errors.Errorf("invalid key file: key size is not %d bytes", auth.KeySize)
}
input, err := utils.ReadInput("Write text to digest: ")
if err != nil {
return errors.Wrap(err, "error reading input")
}
var k [32]byte
copy(k[:], key)
sum := auth.Sum(input, &k)
fmt.Println(hex.EncodeToString(sum[:]))
return nil
}
func authVerifyAction(ctx *cli.Context) error {
if err := errs.NumberOfArguments(ctx, 2); err != nil {
return err
}
args := ctx.Args()
keyFile, digest := args[0], args[1]
key, err := ioutil.ReadFile(keyFile)
if err != nil {
return errs.FileError(err, keyFile)
} else if len(key) != auth.KeySize {
return errors.Errorf("invalid key file: key size is not %d bytes", auth.KeySize)
}
sum, err := hex.DecodeString(digest)
if err != nil {
return errors.Wrap(err, "error decoding digest")
}
input, err := utils.ReadInput("Write text to verify: ")
if err != nil {
return errors.Wrap(err, "error reading input")
}
var k [32]byte
copy(k[:], key)
if auth.Verify(sum, input, &k) {
fmt.Println("ok")
return nil
}
return errors.New("fail")
}