@@ -19,8 +19,9 @@ import (
19
19
"path/filepath"
20
20
"runtime"
21
21
"strings"
22
+ "time"
22
23
23
- "golang.org/x/crypto/openpgp/packet "
24
+ "golang.org/x/crypto/openpgp"
24
25
25
26
"github.com/arduino/arduino-create-agent/utilities"
26
27
"github.com/blang/semver"
@@ -65,68 +66,64 @@ var publicKeyHex string = "99020D0452FAA2FA011000D0C5604932111750628F171E4E612D5
65
66
66
67
func checkGPGSig (fileName string , sigFileName string ) error {
67
68
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
-
74
69
// Get a Reader for the signature file
75
70
sigFile , err := os .Open (sigFileName )
76
71
if err != nil {
77
72
return err
78
73
}
79
74
80
- defer func () {
81
- if err := sigFile .Close (); err != nil {
82
- panic (err )
83
- }
84
- }()
75
+ defer sigFile .Close ()
85
76
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 )
88
79
if err != nil {
89
80
return err
90
81
}
91
82
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 ()
97
84
98
- // For convenience, we have the key in hexadecimal, convert it to binary
99
85
publicKeyBin , err := hex .DecodeString (publicKeyHex )
100
86
if err != nil {
101
87
return err
102
88
}
103
89
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 )
106
100
if err != nil {
107
101
return err
108
102
}
103
+ defer resp .Body .Close ()
109
104
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
114
109
}
115
110
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" )
121
113
if err != nil {
122
114
return err
123
115
}
116
+ defer signature .Body .Close ()
124
117
125
- // Check the signature
126
- err = publicKey . VerifySignature ( hash , signature )
118
+ // Read the body
119
+ signature_body , err := ioutil . ReadAll ( signature . Body )
127
120
if err != nil {
128
121
return err
129
122
}
123
+ ioutil .WriteFile (index_file , body , 0644 )
124
+ ioutil .WriteFile (signature_file , signature_body , 0644 )
125
+
126
+ t .LastRefresh = time .Now ()
130
127
131
128
return nil
132
129
}
@@ -147,35 +144,27 @@ func checkGPGSig(fileName string, sigFileName string) error {
147
144
// if it already exists.
148
145
func (t * Tools ) Download (name , version , behaviour string ) error {
149
146
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" )
156
149
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
+ }
161
156
}
162
157
163
- // Fetch the signature
164
- signature , err := http .Get (t .IndexURL + ".sig" )
158
+ err := checkGPGSig (index_file , signature_file )
165
159
if err != nil {
166
160
return err
167
161
}
168
- defer signature .Body .Close ()
169
162
170
- // Read the body
171
- signature_body , err := ioutil .ReadAll (signature .Body )
163
+ body , err := ioutil .ReadFile (index_file )
172
164
if err != nil {
173
165
return err
174
166
}
175
167
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
-
179
168
var data index
180
169
json .Unmarshal (body , & data )
181
170
@@ -210,17 +199,9 @@ func (t *Tools) Download(name, version, behaviour string) error {
210
199
}
211
200
}
212
201
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
-
221
202
// Download the tool
222
203
t .Logger .Println ("Downloading tool " + name + " from " + correctSystem .URL )
223
- resp , err = http .Get (correctSystem .URL )
204
+ resp , err : = http .Get (correctSystem .URL )
224
205
if err != nil {
225
206
return err
226
207
}
0 commit comments