-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdcc-parser.go
69 lines (56 loc) · 1.64 KB
/
dcc-parser.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
package dcc
import (
"errors"
"io/ioutil"
"strings"
"github.com/dasio/base45"
"github.com/fxamacker/cbor/v2"
"github.com/veraison/go-cose"
)
var dccPrefix = "HC1:"
// ParseQR parses a Vaccine Passport, it reads the image file at 'path', decoding the QR code and returns the Pass Payload and Raw COSE message containing headers, payload and signatures
func ParseQR(path string) (payload *DCC, messageRaw *cose.Sign1Message, err error) {
err = errors.New("QRCode parsing not yet implemented")
return
}
// Parse parses a Vaccine Passport, it reads the file at 'path' and returns the Pass Payload and Raw COSE message containing headers, payload and signatures
func Parse(path string) (payload *DCC, messageRaw *cose.Sign1Message, err error) {
// Read vaccine pass
fileBytes, err := ioutil.ReadFile(path)
if err != nil {
return
}
// remove magic header : HC1: (Health Certificate Version 1)
dccBase45 := string(fileBytes)
if !strings.HasPrefix(dccBase45, dccPrefix) {
err = errors.New("data does not appear to be EU DCC / Vaccine Passport")
return
}
dccBase45 = strings.Split(dccBase45, dccPrefix)[1]
// Decode base45
dccCOSECompressed, err := base45.DecodeString(dccBase45)
if err != nil {
return
}
// Decompress Binary COSE Data with zlib
dccCOSE, err := zlibDecompress(dccCOSECompressed)
if err != nil {
return
}
// Unmarshal COSE
msg := cose.NewSign1Message()
err = msg.UnmarshalCBOR(dccCOSE)
if err != nil {
return
}
// Read CBOR DCC Payload into JSON Struct
dcc := &DCC{}
err = cbor.Unmarshal(msg.Payload, dcc)
if err != nil {
return
}
// We got the goods! Return them
payload = dcc
messageRaw = msg
return
}