Mercurial > trustbridge
comparison common/binverify.c @ 771:2798f1869eee
(issue43) Add first draft of signature verification for GNU/Linux
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Thu, 10 Jul 2014 19:15:22 +0200 |
parents | be30d50bc4f0 |
children | 44fa5de02b52 |
comparison
equal
deleted
inserted
replaced
770:7861950f7637 | 771:2798f1869eee |
---|---|
17 #include "pubkey-test.h" | 17 #include "pubkey-test.h" |
18 #endif | 18 #endif |
19 | 19 |
20 bin_verify_result | 20 bin_verify_result |
21 verify_binary(const char *filename, size_t name_len) { | 21 verify_binary(const char *filename, size_t name_len) { |
22 if (!filename || !name_len) | |
23 return VerifyUnknownError; | |
22 #ifdef WIN32 | 24 #ifdef WIN32 |
23 return verify_binary_win(filename, name_len); | 25 return verify_binary_win(filename, name_len); |
24 #else | 26 #else |
25 /* TODO */ | 27 return verify_binary_linux(filename, name_len); |
26 if (filename && name_len) | |
27 return VerifyValid; | |
28 return VerifyUnknownError; | |
29 #endif | 28 #endif |
30 } | 29 } |
31 | 30 |
32 #ifdef WIN32 | 31 #ifdef WIN32 |
33 | 32 |
222 { | 221 { |
223 CryptMsgClose(hMsg); | 222 CryptMsgClose(hMsg); |
224 } | 223 } |
225 return retval; | 224 return retval; |
226 } | 225 } |
226 #else /* WIN32 */ | |
227 | |
228 #include "listutil.h" | |
229 | |
230 #pragma GCC diagnostic ignored "-Wconversion" | |
231 /* Polarssl mh.h contains a conversion which gcc warns about */ | |
232 #include <polarssl/pk.h> | |
233 #include <polarssl/base64.h> | |
234 #include <polarssl/sha256.h> | |
235 #pragma GCC diagnostic pop | |
236 | |
237 bin_verify_result | |
238 verify_binary_linux(const char *filename, size_t name_len) | |
239 { | |
240 int ret = -1; | |
241 const size_t sig_b64_size = TRUSTBRIDGE_RSA_KEY_SIZE / 8 * 4 / 3; | |
242 char *data = NULL, | |
243 signature_b64[sig_b64_size + 1]; | |
244 size_t data_size = 0, | |
245 sig_size = TRUSTBRIDGE_RSA_KEY_SIZE / 8; | |
246 unsigned char signature[sig_size], | |
247 hash[32]; | |
248 | |
249 bin_verify_result retval = VerifyUnknownError; | |
250 pk_context pub_key_ctx; | |
251 | |
252 if (strnlen(filename, name_len + 1) != name_len || name_len == 0) | |
253 { | |
254 ERRORPRINTF ("Invalid call to verify_binary_linux\n"); | |
255 return VerifyUnknownError; | |
256 } | |
257 | |
258 ret = read_file(filename, &data, &data_size, MAX_VALID_BIN_SIZE); | |
259 | |
260 if (ret != 0) | |
261 { | |
262 ERRORPRINTF ("Read file failed with error: %i\n", ret); | |
263 return VerifyReadFailed; | |
264 } | |
265 | |
266 /* Fetch the signature from the end of data */ | |
267 if (data_size < sig_b64_size + 4) | |
268 { | |
269 ERRORPRINTF ("File to small to contain a signature.\n"); | |
270 retval = VerifyInvalidSignature; | |
271 goto done; | |
272 } | |
273 | |
274 if (data[data_size - sig_b64_size - 1] != ':' || | |
275 data[data_size - sig_b64_size - 2] != 'S' || | |
276 data[data_size - sig_b64_size - 3] != '\n'|| | |
277 data[data_size - sig_b64_size - 4] != '\r') | |
278 { | |
279 ERRORPRINTF ("Failed to find valid signature line.\n"); | |
280 retval = VerifyInvalidSignature; | |
281 goto done; | |
282 } | |
283 | |
284 strncpy(signature_b64, data - sig_b64_size, sig_b64_size); | |
285 signature_b64[sig_b64_size] = '\0'; | |
286 | |
287 ret = base64_decode(signature, &sig_size, | |
288 (unsigned char *)signature_b64, sig_b64_size); | |
289 | |
290 if (ret != 0 || sig_size != TRUSTBRIDGE_RSA_KEY_SIZE / 8) | |
291 { | |
292 goto done; | |
293 } | |
294 | |
295 /* Hash is calculated over the data without the signature at the end. */ | |
296 sha256((unsigned char *)data, data_size - sig_b64_size - 4, hash, 0); | |
297 | |
298 pk_init(&pub_key_ctx); | |
299 | |
300 ret = pk_parse_public_key(&pub_key_ctx, public_key_codesign_pem, | |
301 public_key_codesign_pem_size); | |
302 if (ret != 0) | |
303 { | |
304 ERRORPRINTF ("pk_parse_public_key failed with -0x%04x\n\n", -ret); | |
305 pk_free(&pub_key_ctx); | |
306 return VerifyUnknownError; | |
307 } | |
308 | |
309 ret = pk_verify(&pub_key_ctx, POLARSSL_MD_SHA256, hash, 0, | |
310 signature, sig_size); | |
311 | |
312 if (ret != 0) | |
313 { | |
314 ERRORPRINTF ("pk_verify failed with -0x%04x\n\n", -ret); | |
315 } | |
316 pk_free(&pub_key_ctx); | |
317 | |
318 return VerifyValid; | |
319 | |
320 done: | |
321 xfree (data); | |
322 return retval; | |
323 } | |
324 | |
227 #endif /* WIN32 */ | 325 #endif /* WIN32 */ |