-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnode.go
More file actions
164 lines (139 loc) · 3.12 KB
/
node.go
File metadata and controls
164 lines (139 loc) · 3.12 KB
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package vcrypt
import (
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"errors"
"io"
"github.com/vcrypt/vcrypt/cryptex"
"github.com/vcrypt/vcrypt/secret"
)
// NodeType marks the type of data held by a Node.
type NodeType int
const (
// CryptexNode contains a marshaled cryptex.
CryptexNode NodeType = iota + 1
// SecretNode holds a marshaled secret.
SecretNode
// MarkerNode marks material data.
MarkerNode
)
// NewCryptexNode constructs a node with the marshaled cryptex data.
func NewCryptexNode(cptx cryptex.Cryptex, inputs [][]byte) (*Node, error) {
env, err := cryptex.Wrap(cptx)
if err != nil {
return nil, err
}
nonce := make([]byte, 24)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
return &Node{
Nonce: nonce,
Inputs: inputs,
cryptex: env,
}, nil
}
// NewSecretNode constructs a node with the marshaled secret data.
func NewSecretNode(sec secret.Secret) (*Node, error) {
env, err := secret.Wrap(sec)
if err != nil {
return nil, err
}
nonce := make([]byte, 24)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
return &Node{
Nonce: nonce,
secret: env,
}, nil
}
// NewMarkerNode constructs a node with a marker for material data.
func NewMarkerNode(mrkr *Marker) (*Node, error) {
nonce := make([]byte, 24)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
return &Node{
Nonce: nonce,
Marker: mrkr,
}, nil
}
// Cryptex returns the unmarshaled cryptex held by the node.
func (n *Node) Cryptex() (cryptex.Cryptex, error) {
if n.cryptex == nil {
return nil, nil
}
return n.cryptex.Cryptex()
}
// Secret returns the unmarshaled secret held by the node.
func (n *Node) Secret() (secret.Secret, error) {
if n.secret == nil {
return nil, nil
}
return n.secret.Secret()
}
// Comment string
func (n *Node) Comment() (string, error) {
switch {
case n.cryptex != nil:
cptx, err := n.cryptex.Cryptex()
if err != nil {
return "", err
}
return cptx.Comment(), nil
case n.secret != nil:
sec, err := n.secret.Secret()
if err != nil {
return "", err
}
return sec.Comment(), nil
case n.Marker != nil:
return n.Marker.Comment, nil
default:
return "", errors.New("invalid Node, nil members")
}
}
// Digest returns a unique series of bytes that identify the node.
func (n *Node) Digest() ([]byte, error) {
// HMAC(Nonce,Inputs[*]|(Cryptex||Secret||Marker))
hash := hmac.New(sha256.New, n.Nonce)
for _, input := range n.Inputs {
if _, err := hash.Write(input); err != nil {
return nil, err
}
}
var (
data []byte
err error
)
switch {
case n.cryptex != nil:
data, err = n.cryptex.Marshal()
case n.secret != nil:
data, err = n.secret.Marshal()
case n.Marker != nil:
data, err = n.Marker.Marshal()
}
if err != nil {
return nil, err
}
if _, err := hash.Write(data); err != nil {
return nil, err
}
return hash.Sum(nil), nil
}
// Type of Node
func (n *Node) Type() NodeType {
switch {
case n.cryptex != nil:
return CryptexNode
case n.secret != nil:
return SecretNode
case n.Marker != nil:
return MarkerNode
default:
panic("unrecognizable Node type")
}
}