@@ -19,8 +19,9 @@ import (
1919 "path/filepath"
2020 "runtime"
2121 "strings"
22+ "time"
2223
23- "golang.org/x/crypto/openpgp/packet "
24+ "golang.org/x/crypto/openpgp"
2425
2526 "github.com/arduino/arduino-create-agent/utilities"
2627 "github.com/blang/semver"
@@ -65,68 +66,64 @@ var publicKeyHex string = "99020D0452FAA2FA011000D0C5604932111750628F171E4E612D5
6566
6667func checkGPGSig (fileName string , sigFileName string ) error {
6768
68- // First, get the content of the file we have signed
69- fileContent , err := ioutil .ReadFile (fileName )
70- if err != nil {
71- return err
72- }
73-
7469 // Get a Reader for the signature file
7570 sigFile , err := os .Open (sigFileName )
7671 if err != nil {
7772 return err
7873 }
7974
80- defer func () {
81- if err := sigFile .Close (); err != nil {
82- panic (err )
83- }
84- }()
75+ defer sigFile .Close ()
8576
86- // Read the signature file
87- pack , err := packet . Read ( sigFile )
77+ // Get a Reader for the signature file
78+ file , err := os . Open ( fileName )
8879 if err != nil {
8980 return err
9081 }
9182
92- // Was it really a signature file ? If yes, get the Signature
93- signature , ok := pack .(* packet.Signature )
94- if ! ok {
95- return errors .New ("Not a valid signature file." )
96- }
83+ defer file .Close ()
9784
98- // For convenience, we have the key in hexadecimal, convert it to binary
9985 publicKeyBin , err := hex .DecodeString (publicKeyHex )
10086 if err != nil {
10187 return err
10288 }
10389
104- // Read the key
105- pack , err = packet .Read (bytes .NewReader (publicKeyBin ))
90+ keyring , _ := openpgp .ReadKeyRing (bytes .NewReader (publicKeyBin ))
91+
92+ _ , err = openpgp .CheckDetachedSignature (keyring , file , sigFile )
93+
94+ return err
95+ }
96+
97+ func (t * Tools ) DownloadPackageIndex (index_file , signature_file string ) error {
98+ // Fetch the index
99+ resp , err := http .Get (t .IndexURL )
106100 if err != nil {
107101 return err
108102 }
103+ defer resp .Body .Close ()
109104
110- // Was it really a public key file ? If yes, get the PublicKey
111- publicKey , ok := pack .( * packet. PublicKey )
112- if ! ok {
113- return errors . New ( "Invalid public key." )
105+ // Read the body
106+ body , err := ioutil . ReadAll ( resp . Body )
107+ if err != nil {
108+ return err
114109 }
115110
116- // Get the hash method used for the signature
117- hash := signature .Hash .New ()
118-
119- // Hash the content of the file (if the file is big, that's where you have to change the code to avoid getting the whole file in memory, by reading and writting in small chunks)
120- _ , err = hash .Write (fileContent )
111+ // Fetch the signature
112+ signature , err := http .Get (t .IndexURL + ".sig" )
121113 if err != nil {
122114 return err
123115 }
116+ defer signature .Body .Close ()
124117
125- // Check the signature
126- err = publicKey . VerifySignature ( hash , signature )
118+ // Read the body
119+ signature_body , err := ioutil . ReadAll ( signature . Body )
127120 if err != nil {
128121 return err
129122 }
123+ ioutil .WriteFile (index_file , body , 0644 )
124+ ioutil .WriteFile (signature_file , signature_body , 0644 )
125+
126+ t .LastRefresh = time .Now ()
130127
131128 return nil
132129}
@@ -147,35 +144,27 @@ func checkGPGSig(fileName string, sigFileName string) error {
147144// if it already exists.
148145func (t * Tools ) Download (name , version , behaviour string ) error {
149146
150- // Fetch the index
151- resp , err := http .Get (t .IndexURL )
152- if err != nil {
153- return err
154- }
155- defer resp .Body .Close ()
147+ index_file := path .Join (t .Directory , "package_index.json" )
148+ signature_file := path .Join (t .Directory , "package_index.json.sig" )
156149
157- // Read the body
158- body , err := ioutil .ReadAll (resp .Body )
159- if err != nil {
160- return err
150+ if _ , err := os .Stat (path .Join (t .Directory , "package_index.json" )); err != nil || time .Since (t .LastRefresh ) > 1 * time .Hour {
151+ // Download the file again and save it
152+ err = t .DownloadPackageIndex (index_file , signature_file )
153+ if err != nil {
154+ return err
155+ }
161156 }
162157
163- // Fetch the signature
164- signature , err := http .Get (t .IndexURL + ".sig" )
158+ err := checkGPGSig (index_file , signature_file )
165159 if err != nil {
166160 return err
167161 }
168- defer signature .Body .Close ()
169162
170- // Read the body
171- signature_body , err := ioutil .ReadAll (signature .Body )
163+ body , err := ioutil .ReadFile (index_file )
172164 if err != nil {
173165 return err
174166 }
175167
176- index_file , err := utilities .SaveFileonTempDir ("package_index.json" , bytes .NewReader (body ))
177- signature_file , err := utilities .SaveFileonTempDir ("package_index.json.sig" , bytes .NewReader (signature_body ))
178-
179168 var data index
180169 json .Unmarshal (body , & data )
181170
@@ -210,17 +199,9 @@ func (t *Tools) Download(name, version, behaviour string) error {
210199 }
211200 }
212201
213- err = checkGPGSig (index_file , signature_file )
214- // FIXME - try to understand why it fails
215- /*
216- if err != nil {
217- return err
218- }
219- */
220-
221202 // Download the tool
222203 t .Logger .Println ("Downloading tool " + name + " from " + correctSystem .URL )
223- resp , err = http .Get (correctSystem .URL )
204+ resp , err : = http .Get (correctSystem .URL )
224205 if err != nil {
225206 return err
226207 }
0 commit comments