-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecode.go
90 lines (74 loc) · 2.06 KB
/
decode.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
// SPDX-FileCopyrightText: 2024 Comcast Cable Communications Management, LLC
// SPDX-License-Identifier: Apache-2.0
package securly
import (
"github.com/lestrrat-go/jwx/v2/jws"
"github.com/xmidt-org/jwskeychain"
)
// Decode converts a slice of bytes into a *Message if possible. Depending on
// the options provided, the function may also verify the signature of the
// message.
//
// This function defaults secure, so it will verify the signature of the
// message. If you want to skip this verification, you can pass the
// NoVerification() option.
func Decode(buf []byte, opts ...DecoderOption) (*Message, error) {
p, err := newDecoder(opts...)
if err != nil {
return nil, err
}
return p.decode(buf)
}
// decoder contains the configuration for decoding a set of messages.
type decoder struct {
noVerification bool
opts []jwskeychain.Option
provider *jwskeychain.Provider
}
// newDecoder converts a slice of bytes plus options into a Message.
func newDecoder(opts ...DecoderOption) (*decoder, error) {
var p decoder
vadors := []DecoderOption{
createTrust(),
validateRoots(),
}
opts = append(opts, vadors...)
for _, opt := range opts {
err := opt.apply(&p)
if err != nil {
return nil, err
}
}
return &p, nil
}
// decode converts a slice of bytes into a *Message if possible.
func (p *decoder) decode(buf []byte) (*Message, error) {
JWS, err := decompress(buf)
if err != nil {
return nil, err
}
var payload []byte
// Verify the JWS signature if possible.
if p.noVerification {
var trusted *jws.Message
if trusted, err = jws.Parse(JWS, jws.WithCompact()); err == nil {
payload = trusted.Payload()
}
} else {
payload, err = jws.Verify(JWS, jws.WithKeyProvider(p.provider))
}
if err != nil {
return nil, err
}
// Unmarshal the inner payload
var msg Message
if _, err = msg.UnmarshalMsg(payload); err != nil {
return nil, err
}
// The encryption algorithm must be safe to send in the clear, or this
// message is invalid.
if err := msg.Response.safeInTheClear(); err != nil {
return nil, err
}
return &msg, nil
}