forked from veraison/go-cose
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cbor.go
84 lines (75 loc) · 2.16 KB
/
cbor.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
package cose
import (
"bytes"
"errors"
"io"
"github.com/fxamacker/cbor/v2"
)
// CBOR Tags for COSE signatures registered in the IANA "CBOR Tags" registry.
//
// Reference: https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml#tags
const (
CBORTagSignMessage = 98
CBORTagSign1Message = 18
)
// Pre-configured modes for CBOR encoding and decoding.
var (
encMode cbor.EncMode
decMode cbor.DecMode
decModeWithTagsForbidden cbor.DecMode
)
func init() {
var err error
// init encode mode
encOpts := cbor.EncOptions{
Sort: cbor.SortCanonical, // sort map keys
IndefLength: cbor.IndefLengthForbidden, // no streaming
}
encMode, err = encOpts.EncMode()
if err != nil {
panic(err)
}
// init decode mode
decOpts := cbor.DecOptions{
DupMapKey: cbor.DupMapKeyEnforcedAPF, // duplicated key not allowed
IndefLength: cbor.IndefLengthForbidden, // no streaming
IntDec: cbor.IntDecConvertSigned, // decode CBOR uint/int to Go int64
}
decMode, err = decOpts.DecMode()
if err != nil {
panic(err)
}
decOpts.TagsMd = cbor.TagsForbidden
decModeWithTagsForbidden, err = decOpts.DecMode()
if err != nil {
panic(err)
}
}
// byteString represents a "bstr / nil" type.
type byteString []byte
// UnmarshalCBOR decodes data into a "bstr / nil" type.
// It also ensures the data is of major type 2 since []byte can be alternatively
// interpreted as an array of bytes.
//
// Note: `github.com/fxamacker/cbor/v2` considers the primitive value
// `undefined` (major type 7, value 23) as nil, which is not recognized by COSE.
//
// Related Code: https://github.com/fxamacker/cbor/blob/v2.4.0/decode.go#L709
//
// Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-1.3
func (s *byteString) UnmarshalCBOR(data []byte) error {
if s == nil {
return errors.New("cbor: UnmarshalCBOR on nil byteString pointer")
}
if len(data) == 0 {
return io.EOF // same error as returned by cbor.Unmarshal()
}
if bytes.Equal(data, []byte{0xf6}) {
*s = nil
return nil
}
if data[0]>>5 != 2 { // major type 2: bstr
return errors.New("cbor: require bstr type")
}
return decModeWithTagsForbidden.Unmarshal(data, (*[]byte)(s))
}