/
cose.go
59 lines (49 loc) · 1.33 KB
/
cose.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
package cose
import (
"bytes"
"fmt"
"github.com/ugorji/go/codec"
)
// Errors
var (
ErrMissingKeyType = fmt.Errorf("cose: missing key type")
ErrMissingAlgorithm = fmt.Errorf("cose: missing algorithm")
ErrUnsupportedKeyType = fmt.Errorf("cose: unsupported key type")
ErrUnsupportedAlgorithm = fmt.Errorf("cose: unsupported algorithm")
ErrInvalidFormat = fmt.Errorf("cose: invalid format")
)
// ParseCOSE parses a raw COSE key into a public key, either *ecdsa.PublicKey or *rsa.PublicKey.
func ParseCOSE(buf []byte) (interface{}, error) {
m := make(map[int]interface{})
cbor := codec.CborHandle{}
if err := codec.NewDecoder(bytes.NewReader(buf), &cbor).Decode(&m); err != nil {
return nil, err
}
return ParseCOSEMap(m)
}
// ParseCOSEMap parses a COSE key that has been decoded from it's CBOR format to a dictionary.
func ParseCOSEMap(m map[int]interface{}) (interface{}, error) {
rawKty, ok := m[1]
if !ok {
return nil, ErrMissingKeyType
}
kty, ok := rawKty.(uint64)
if !ok {
return nil, ErrMissingKeyType
}
rawAlg, ok := m[3]
if !ok {
return nil, ErrMissingAlgorithm
}
alg, ok := rawAlg.(int64)
if !ok {
return nil, ErrMissingAlgorithm
}
// https://tools.ietf.org/html/rfc8152#section-13
switch kty {
case 2: // EC2
return parseECDSA(alg, m)
default:
return nil, ErrUnsupportedKeyType
}
}