-
Notifications
You must be signed in to change notification settings - Fork 0
/
key.go
127 lines (108 loc) · 3.03 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
// (c) 2022-2022, LDC Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package key
import (
"encoding/hex"
"encoding/json"
)
// Key represents a COSE_Key object.
//
// Reference https://datatracker.ietf.org/doc/html/rfc9052#section-7
type Key IntMap
// Kty returns the key type.
// If the key is nil, it returns KtyReserved.
//
// Reference https://www.iana.org/assignments/cose/cose.xhtml#key-type
func (k Key) Kty() Kty {
if k == nil {
return KtyReserved
}
v, _ := k.GetSmallInt(ParamKty)
return Kty(v)
}
// Kid returns the key identifier.
// If the key identifier is not present, or the underlying value's Kind is not []byte, it returns nil.
func (k Key) Kid() ByteStr {
v, _ := k.GetBytes(ParamKid)
return v
}
// Alg returns the key algorithm.
// If It is elliptic-curves key and algorithm is not present,
// it will return the algorithm that matched the curve.
// Reference https://www.iana.org/assignments/cose/cose.xhtml#algorithms
func (k Key) Alg() Alg {
v, err := k.GetSmallInt(ParamAlg)
if err == nil && v == 0 {
// alg is optional, try lookup it by crv
if c, err := k.GetSmallInt(ParamCrv); err == nil {
return Crv(c).Alg()
}
}
return Alg(v)
}
// Ops returns the key operations, or nil.
//
// Reference https://www.iana.org/assignments/cose/cose.xhtml#key-common-parameters
func (k Key) Ops() Ops {
if v, ok := k[ParamOps]; ok {
switch x := v.(type) {
case Ops:
return x
case []any:
ops := make(Ops, len(x))
for i, v := range x {
op, err := SmallInt(v)
if err != nil {
return nil
}
ops[i] = IntKey(op)
}
return ops
}
}
return nil
}
// BaseIV returns the base IV to be XORed with Partial IVs.
//
// Reference https://www.iana.org/assignments/cose/cose.xhtml#key-common-parameters
func (k Key) BaseIV() ByteStr {
v, _ := k.GetBytes(ParamBaseIV)
return v
}
// Has returns true if the key has the given parameter.
func (k Key) Has(p IntKey) bool {
return IntMap(k).Has(p)
}
// GetSmallInt returns the value of the given parameter as a small integer, or a error.
func (k Key) GetSmallInt(p IntKey) (int, error) {
return IntMap(k).GetSmallInt(p)
}
// GetBytes returns the value of the given parameter as a slice of bytes, or a error.
func (k Key) GetBytes(p IntKey) ([]byte, error) {
return IntMap(k).GetBytes(p)
}
// MarshalJSON implements the json.Marshaler interface for Key.
func (k Key) MarshalJSON() ([]byte, error) {
m := make(map[string]any, len(k))
for n, v := range k {
if b, ok := v.(interface{ String() string }); ok {
m[k.ParamString(n)] = b.String()
} else if b, ok := v.([]byte); ok {
m[k.ParamString(n)] = hex.EncodeToString(b)
} else {
m[k.ParamString(n)] = v
}
}
return json.Marshal(m)
}
// Bytesify returns a CBOR-encoded byte slice.
// It returns nil if MarshalCBOR failed.
func (k Key) Bytesify() []byte {
b, _ := IntMap(k).MarshalCBOR()
return b
}
// MarshalCBOR implements the CBOR Marshaler interface for Key.
// It is the same as IntMap.MarshalCBOR.
func (k Key) MarshalCBOR() ([]byte, error) {
return IntMap(k).MarshalCBOR()
}