/
interface.go
214 lines (195 loc) · 8.56 KB
/
interface.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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
package jwe
import (
"github.com/lestrrat-go/iter/mapiter"
"github.com/lestrrat-go/jwx/v2/internal/iter"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwe/internal/keygen"
)
// KeyEncrypter is an interface for object that can encrypt a
// content encryption key.
//
// You can use this in place of a regular key (i.e. in jwe.WithKey())
// to encrypt the content encryption key in a JWE message without
// having to expose the secret key in memory, for example, when you
// want to use hardware security modules (HSMs) to encrypt the key.
//
// This API is experimental and may change without notice, even
// in minor releases.
type KeyEncrypter interface {
// Algorithm returns the algorithm used to encrypt the key.
Algorithm() jwa.KeyEncryptionAlgorithm
// EncryptKey encrypts the given content encryption key.
EncryptKey([]byte) ([]byte, error)
}
// KeyIDer is an interface for things that can return a key ID.
//
// As of this writing, this is solely used to identify KeyEncrypter
// objects that also carry a key ID on its own.
type KeyIDer interface {
KeyID() string
}
// KeyDecrypter is an interface for objects that can decrypt a content
// encryption key.
//
// You can use this in place of a regular key (i.e. in jwe.WithKey())
// to decrypt the encrypted key in a JWE message without having to
// expose the secret key in memory, for example, when you want to use
// hardware security modules (HSMs) to decrypt the key.
//
// This API is experimental and may change without notice, even
// in minor releases.
type KeyDecrypter interface {
// Decrypt decrypts the encrypted key of a JWE message.
//
// Make sure you understand how JWE messages are structured.
//
// For example, while in most circumstances a JWE message will only have one recipient,
// a JWE message may contain multiple recipients, each with their own
// encrypted key. This method will be called for each recipient, instead of
// just once for a message.
//
// Also, header values could be found in either protected/unprotected headers
// of a JWE message, as well as in protected/unprotected headers for each recipient.
// When checking a header value, you can decide to use either one, or both, but you
// must be aware that there are multiple places to look for.
DecryptKey(alg jwa.KeyEncryptionAlgorithm, encryptedKey []byte, recipient Recipient, message *Message) ([]byte, error)
}
// Recipient holds the encrypted key and hints to decrypt the key
type Recipient interface {
Headers() Headers
EncryptedKey() []byte
SetHeaders(Headers) error
SetEncryptedKey([]byte) error
}
type stdRecipient struct {
// Comments on each field are taken from https://datatracker.ietf.org/doc/html/rfc7516
//
// header
// The "header" member MUST be present and contain the value JWE Per-
// Recipient Unprotected Header when the JWE Per-Recipient
// Unprotected Header value is non-empty; otherwise, it MUST be
// absent. This value is represented as an unencoded JSON object,
// rather than as a string. These Header Parameter values are not
// integrity protected.
//
// At least one of the "header", "protected", and "unprotected" members
// MUST be present so that "alg" and "enc" Header Parameter values are
// conveyed for each recipient computation.
//
// JWX note: see Message.unprotectedHeaders
headers Headers
// encrypted_key
// The "encrypted_key" member MUST be present and contain the value
// BASE64URL(JWE Encrypted Key) when the JWE Encrypted Key value is
// non-empty; otherwise, it MUST be absent.
encryptedKey []byte
}
// Message contains the entire encrypted JWE message. You should not
// expect to use Message for anything other than inspecting the
// state of an encrypted message. This is because encryption is
// highly context sensitive, and once we parse the original payload
// into an object, we may not always be able to recreate the exact
// context in which the encryption happened.
//
// For example, it is totally valid for if the protected header's
// integrity was calculated using a non-standard line breaks:
//
// {"a dummy":
// "protected header"}
//
// Once parsed, though, we can only serialize the protected header as:
//
// {"a dummy":"protected header"}
//
// which would obviously result in a contradicting integrity value
// if we tried to re-calculate it from a parsed message.
//
//nolint:govet
type Message struct {
// Comments on each field are taken from https://datatracker.ietf.org/doc/html/rfc7516
//
// protected
// The "protected" member MUST be present and contain the value
// BASE64URL(UTF8(JWE Protected Header)) when the JWE Protected
// Header value is non-empty; otherwise, it MUST be absent. These
// Header Parameter values are integrity protected.
protectedHeaders Headers
// unprotected
// The "unprotected" member MUST be present and contain the value JWE
// Shared Unprotected Header when the JWE Shared Unprotected Header
// value is non-empty; otherwise, it MUST be absent. This value is
// represented as an unencoded JSON object, rather than as a string.
// These Header Parameter values are not integrity protected.
//
// JWX note: This field is NOT mutually exclusive with per-recipient
// headers within the implmentation because... it's too much work.
// It is _never_ populated (we don't provide a way to do this) upon encryption.
// When decrypting, if present its values are always merged with
// per-recipient header.
unprotectedHeaders Headers
// iv
// The "iv" member MUST be present and contain the value
// BASE64URL(JWE Initialization Vector) when the JWE Initialization
// Vector value is non-empty; otherwise, it MUST be absent.
initializationVector []byte
// aad
// The "aad" member MUST be present and contain the value
// BASE64URL(JWE AAD)) when the JWE AAD value is non-empty;
// otherwise, it MUST be absent. A JWE AAD value can be included to
// supply a base64url-encoded value to be integrity protected but not
// encrypted.
authenticatedData []byte
// ciphertext
// The "ciphertext" member MUST be present and contain the value
// BASE64URL(JWE Ciphertext).
cipherText []byte
// tag
// The "tag" member MUST be present and contain the value
// BASE64URL(JWE Authentication Tag) when the JWE Authentication Tag
// value is non-empty; otherwise, it MUST be absent.
tag []byte
// recipients
// The "recipients" member value MUST be an array of JSON objects.
// Each object contains information specific to a single recipient.
// This member MUST be present with exactly one array element per
// recipient, even if some or all of the array element values are the
// empty JSON object "{}" (which can happen when all Header Parameter
// values are shared between all recipients and when no encrypted key
// is used, such as when doing Direct Encryption).
//
// Some Header Parameters, including the "alg" parameter, can be shared
// among all recipient computations. Header Parameters in the JWE
// Protected Header and JWE Shared Unprotected Header values are shared
// among all recipients.
//
// The Header Parameter values used when creating or validating per-
// recipient ciphertext and Authentication Tag values are the union of
// the three sets of Header Parameter values that may be present: (1)
// the JWE Protected Header represented in the "protected" member, (2)
// the JWE Shared Unprotected Header represented in the "unprotected"
// member, and (3) the JWE Per-Recipient Unprotected Header represented
// in the "header" member of the recipient's array element. The union
// of these sets of Header Parameters comprises the JOSE Header. The
// Header Parameter names in the three locations MUST be disjoint.
recipients []Recipient
// TODO: Additional members can be present in both the JSON objects defined
// above; if not understood by implementations encountering them, they
// MUST be ignored.
// privateParams map[string]interface{}
// These two fields below are not available for the public consumers of this object.
// rawProtectedHeaders stores the original protected header buffer
rawProtectedHeaders []byte
// storeProtectedHeaders is a hint to be used in UnmarshalJSON().
// When this flag is true, UnmarshalJSON() will populate the
// rawProtectedHeaders field
storeProtectedHeaders bool
}
// populater is an interface for things that may modify the
// JWE header. e.g. ByteWithECPrivateKey
type populater interface {
Populate(keygen.Setter) error
}
type Visitor = iter.MapVisitor
type VisitorFunc = iter.MapVisitorFunc
type HeaderPair = mapiter.Pair
type Iterator = mapiter.Iterator