@@ -3,32 +3,95 @@ package main
33import (
44 "crypto/aes"
55 "crypto/sha256"
6+ "encoding/base64"
7+ "encoding/json"
8+ "fmt"
69 "gaen/export"
710 "io"
11+ "io/ioutil"
812 "strconv"
913 "strings"
1014 "time"
1115
1216 "golang.org/x/crypto/hkdf"
17+ "google.golang.org/protobuf/proto"
1318)
1419
15- // DecodeFromTEK ..
16- func DecodeFromTEK (tek * export.TemporaryExposureKey ) []RollingProximityIdentifier {
17- rpis := make ([]RollingProximityIdentifier , 0 )
20+ func DecodeFromFile (filename string ) error {
21+ export , err := UnmarshalExportFile (filename )
22+ if err != nil {
23+ return err
24+ }
25+ teks := DecodeExport (export )
26+
27+ // print something
28+ fmt .Printf ("\n TEK: [%s] - [%s]\n " , base64 .StdEncoding .EncodeToString (teks [0 ].ID ), teks [0 ].IDBytes )
29+ b , _ := json .MarshalIndent (teks [0 ].RPIs [0 ], "" , "\t " )
30+ fmt .Printf ("\n RPI:\n %v\n " , string (b ))
31+
32+ return nil
33+ }
34+
35+ func UnmarshalExportFile (filename string ) (* export.TemporaryExposureKeyExport , error ) {
36+ in , err := ioutil .ReadFile (filename )
37+ if err != nil {
38+ return nil , err
39+ }
40+ in = in [16 :]
41+
42+ export := & export.TemporaryExposureKeyExport {}
43+ if err := proto .Unmarshal (in , export ); err != nil {
44+ return nil , err
45+ }
46+ return export , nil
47+ }
48+
49+ func DecodeExport (export * export.TemporaryExposureKeyExport ) []TemporaryExposureKey {
50+ teks := make ([]TemporaryExposureKey , 0 )
1851
19- hkdfReader := hkdf .New (sha256 .New , tek .KeyData , nil , []byte ("EN-RPIK" ))
52+ for _ , tek := range export .Keys {
53+ tek := NewTemporaryExposureKeyFromGaenTEK (tek )
54+ tek .RPIs = DecodeTEK (tek )
55+ teks = append (teks , tek )
56+ }
57+
58+ return teks
59+ }
60+
61+ // DecodeFromTEK ..
62+ func DecodeTEK (tek TemporaryExposureKey ) []RollingProximityIdentifier {
63+ hkdfReader := hkdf .New (sha256 .New , tek .ID , nil , []byte ("EN-RPIK" ))
2064 rpiKey := make ([]byte , 16 )
2165 io .ReadFull (hkdfReader , rpiKey )
2266
23- for rp := 0 ; rp < int (* tek .RollingPeriod ); rp ++ {
24- interval := rp + int (* tek .RollingStartIntervalNumber )
67+ rpis := make ([]RollingProximityIdentifier , 0 )
68+ for rp := 0 ; rp < tek .RollingPeriod ; rp ++ {
69+ interval := rp + tek .RollingStartInterval
2570 newRpi := NewRollingProximityIdentifier (rpiKey , interval )
2671 rpis = append (rpis , newRpi )
2772 }
2873
2974 return rpis
3075}
3176
77+ type TemporaryExposureKey struct {
78+ ID []byte `json:"id"`
79+ IDBytes string `json:"id_bytes"`
80+ RollingPeriod int
81+ RollingStartInterval int
82+ RPIs []RollingProximityIdentifier `json:"rpis"`
83+ }
84+
85+ func NewTemporaryExposureKeyFromGaenTEK (tek * export.TemporaryExposureKey ) TemporaryExposureKey {
86+ return TemporaryExposureKey {
87+ ID : tek .KeyData ,
88+ IDBytes : encodeToHexString (tek .KeyData ),
89+ RollingPeriod : int (* tek .RollingPeriod ),
90+ RollingStartInterval : int (* tek .RollingStartIntervalNumber ),
91+ RPIs : make ([]RollingProximityIdentifier , 0 ),
92+ }
93+ }
94+
3295// RollingProximityIdentifier ..
3396type RollingProximityIdentifier struct {
3497 ID []byte `json:"id"`
0 commit comments