-
Notifications
You must be signed in to change notification settings - Fork 0
/
key.go
178 lines (160 loc) · 4.44 KB
/
key.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// Copyright 2022 - MinIO, Inc. All rights reserved.
// Use of this source code is governed by the AGPLv3
// license that can be found in the LICENSE file.
package kes
import (
"encoding/json"
"errors"
"io"
"time"
)
// DEK is a data encryption key. It has a plaintext
// and a ciphertext representation.
//
// Applications should use the plaintext for cryptographic
// operations and store the ciphertext at a durable
// location.
//
// If the DEK is used to e.g. encrypt some data then it's
// safe to store the DEK's ciphertext representation next
// to the encrypted data. The ciphertext representation
// does not need to stay secret.
type DEK struct {
Plaintext []byte
Ciphertext []byte
}
// CCP is a structure wrapping a ciphertext / decryption context
// pair.
//
// Its main purpose is to group a ciphertext and decryption
// context to improve API ergonomics.
type CCP struct {
Ciphertext []byte // Ciphertext bytes
Context []byte // Decryption context
}
// PCP is a structure wrapping a plaintext / encryption context
// pair.
//
// Its main purpose is to group a plaintext and encryption
// context to improve API ergonomics.
type PCP struct {
Plaintext []byte
Context []byte
}
// KeyInfo describes a cryptographic key at a KES server.
type KeyInfo struct {
Name string // Name of the cryptographic key
CreatedAt time.Time // Point in time when the key was created
CreatedBy Identity // Identity that created the key
}
// KeyIterator iterates over a stream of KeyInfo objects.
// Close the KeyIterator to release associated resources.
type KeyIterator struct {
decoder *json.Decoder
closer io.Closer
current KeyInfo
err error
closed bool
}
// Value returns the current KeyInfo. It returns
// the same KeyInfo until Next is called again.
//
// If KeyIterator has been closed or if Next has not been
// called once resp. once Next returns false then the
// behavior of Value is undefined.
func (i *KeyIterator) Value() KeyInfo { return i.current }
// Name returns the name of the current key. It is a
// short-hand for Value().Name.
func (i *KeyIterator) Name() string { return i.current.Name }
// CreatedAt returns the created-at timestamp of the current
// key. It is a short-hand for Value().CreatedAt.
func (i *KeyIterator) CreatedAt() time.Time { return i.current.CreatedAt }
// CreatedBy returns the identiy that created the current key.
// It is a short-hand for Value().CreatedBy.
func (i *KeyIterator) CreatedBy() Identity { return i.current.CreatedBy }
// Next returns true if there is another KeyInfo.
// It returns false if there are no more KeyInfo
// objects or when the KeyIterator encounters an
// error.
func (i *KeyIterator) Next() bool {
type Response struct {
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
CreatedBy Identity `json:"created_by"`
Err string `json:"error"`
}
if i.closed || i.err != nil {
return false
}
var resp Response
if err := i.decoder.Decode(&resp); err != nil {
if errors.Is(err, io.EOF) {
i.err = i.Close()
} else {
i.err = err
}
return false
}
if resp.Err != "" {
i.err = errors.New(resp.Err)
return false
}
i.current = KeyInfo{
Name: resp.Name,
CreatedAt: resp.CreatedAt,
CreatedBy: resp.CreatedBy,
}
return true
}
// WriteTo encodes and writes all remaining KeyInfos
// from its current iterator position to w. It returns
// the number of bytes written to w and the first error
// encounterred, if any.
func (i *KeyIterator) WriteTo(w io.Writer) (int64, error) {
type Response struct {
Name string `json:"name"`
CreatedAt time.Time `json:"created_at,omitempty"`
CreatedBy Identity `json:"created_by,omitempty"`
Err string `json:"error,omitempty"`
}
if i.err != nil {
return 0, i.err
}
if i.closed {
return 0, errors.New("kes: WriteTo called after Close")
}
cw := countWriter{W: w}
encoder := json.NewEncoder(&cw)
for {
var resp Response
if err := i.decoder.Decode(&resp); err != nil {
if errors.Is(err, io.EOF) {
i.err = i.Close()
} else {
i.err = err
}
return cw.N, i.err
}
if resp.Err != "" {
i.err = errors.New(resp.Err)
return cw.N, i.err
}
if err := encoder.Encode(resp); err != nil {
i.err = err
return cw.N, err
}
}
}
// Close closes the IdentityIterator and releases
// any associated resources.
func (i *KeyIterator) Close() error {
if !i.closed {
err := i.closer.Close()
if i.err == nil {
i.err = err
}
i.closed = true
return err
}
return i.err
}