Mercurial > trustbridge
comparison common/binverify.c @ 774:44fa5de02b52
(issue43) Finalize and verify binary verification for linux.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Fri, 11 Jul 2014 16:20:27 +0200 |
parents | 2798f1869eee |
children | 698b6a9bd75e |
comparison
equal
deleted
inserted
replaced
773:2c69298b4188 | 774:44fa5de02b52 |
---|---|
8 | 8 |
9 #include "binverify.h" | 9 #include "binverify.h" |
10 | 10 |
11 #include "strhelp.h" | 11 #include "strhelp.h" |
12 #include "logging.h" | 12 #include "logging.h" |
13 | |
14 #ifdef RELEASE_BUILD | 13 #ifdef RELEASE_BUILD |
15 #include "pubkey-release.h" | 14 #include "pubkey-release.h" |
16 #else | 15 #else |
17 #include "pubkey-test.h" | 16 #include "pubkey-test.h" |
18 #endif | 17 #endif |
230 #pragma GCC diagnostic ignored "-Wconversion" | 229 #pragma GCC diagnostic ignored "-Wconversion" |
231 /* Polarssl mh.h contains a conversion which gcc warns about */ | 230 /* Polarssl mh.h contains a conversion which gcc warns about */ |
232 #include <polarssl/pk.h> | 231 #include <polarssl/pk.h> |
233 #include <polarssl/base64.h> | 232 #include <polarssl/base64.h> |
234 #include <polarssl/sha256.h> | 233 #include <polarssl/sha256.h> |
234 #include <polarssl/error.h> | |
235 #include <polarssl/x509_crt.h> | |
235 #pragma GCC diagnostic pop | 236 #pragma GCC diagnostic pop |
236 | 237 |
237 bin_verify_result | 238 bin_verify_result |
238 verify_binary_linux(const char *filename, size_t name_len) | 239 verify_binary_linux(const char *filename, size_t name_len) |
239 { | 240 { |
245 sig_size = TRUSTBRIDGE_RSA_KEY_SIZE / 8; | 246 sig_size = TRUSTBRIDGE_RSA_KEY_SIZE / 8; |
246 unsigned char signature[sig_size], | 247 unsigned char signature[sig_size], |
247 hash[32]; | 248 hash[32]; |
248 | 249 |
249 bin_verify_result retval = VerifyUnknownError; | 250 bin_verify_result retval = VerifyUnknownError; |
250 pk_context pub_key_ctx; | 251 x509_crt codesign_cert; |
251 | 252 |
252 if (strnlen(filename, name_len + 1) != name_len || name_len == 0) | 253 if (strnlen(filename, name_len + 1) != name_len || name_len == 0) |
253 { | 254 { |
254 ERRORPRINTF ("Invalid call to verify_binary_linux\n"); | 255 ERRORPRINTF ("Invalid call to verify_binary_linux\n"); |
255 return VerifyUnknownError; | 256 return VerifyUnknownError; |
262 ERRORPRINTF ("Read file failed with error: %i\n", ret); | 263 ERRORPRINTF ("Read file failed with error: %i\n", ret); |
263 return VerifyReadFailed; | 264 return VerifyReadFailed; |
264 } | 265 } |
265 | 266 |
266 /* Fetch the signature from the end of data */ | 267 /* Fetch the signature from the end of data */ |
267 if (data_size < sig_b64_size + 4) | 268 if (data_size < sig_b64_size + 5) |
268 { | 269 { |
269 ERRORPRINTF ("File to small to contain a signature.\n"); | 270 ERRORPRINTF ("File to small to contain a signature.\n"); |
270 retval = VerifyInvalidSignature; | 271 retval = VerifyInvalidSignature; |
271 goto done; | 272 goto done; |
272 } | 273 } |
273 | 274 |
274 if (data[data_size - sig_b64_size - 1] != ':' || | 275 if (data[data_size - sig_b64_size - 2] != ':' || |
275 data[data_size - sig_b64_size - 2] != 'S' || | 276 data[data_size - sig_b64_size - 3] != 'S' || |
276 data[data_size - sig_b64_size - 3] != '\n'|| | 277 data[data_size - sig_b64_size - 4] != '\n'|| |
277 data[data_size - sig_b64_size - 4] != '\r') | 278 data[data_size - sig_b64_size - 5] != '\r') |
278 { | 279 { |
279 ERRORPRINTF ("Failed to find valid signature line.\n"); | 280 ERRORPRINTF ("Failed to find valid signature line.\n"); |
280 retval = VerifyInvalidSignature; | 281 retval = VerifyInvalidSignature; |
281 goto done; | 282 goto done; |
282 } | 283 } |
283 | 284 |
284 strncpy(signature_b64, data - sig_b64_size, sig_b64_size); | 285 strncpy(signature_b64, data + (data_size - sig_b64_size - 1), sig_b64_size); |
285 signature_b64[sig_b64_size] = '\0'; | 286 signature_b64[sig_b64_size] = '\0'; |
286 | 287 |
287 ret = base64_decode(signature, &sig_size, | 288 ret = base64_decode(signature, &sig_size, |
288 (unsigned char *)signature_b64, sig_b64_size); | 289 (unsigned char *)signature_b64, sig_b64_size); |
289 | 290 |
290 if (ret != 0 || sig_size != TRUSTBRIDGE_RSA_KEY_SIZE / 8) | 291 if (ret != 0 || sig_size != TRUSTBRIDGE_RSA_KEY_SIZE / 8) |
291 { | 292 { |
293 ERRORPRINTF ("Base 64 decode failed with error: %i\n", ret); | |
292 goto done; | 294 goto done; |
293 } | 295 } |
294 | 296 |
295 /* Hash is calculated over the data without the signature at the end. */ | 297 /* 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); | 298 sha256((unsigned char *)data, data_size - sig_b64_size - 5, hash, 0); |
297 | 299 |
298 pk_init(&pub_key_ctx); | 300 x509_crt_init(&codesign_cert); |
299 | 301 |
300 ret = pk_parse_public_key(&pub_key_ctx, public_key_codesign_pem, | 302 /* Parse the pinned certificate */ |
301 public_key_codesign_pem_size); | 303 ret = x509_crt_parse(&codesign_cert, |
304 public_key_codesign_pem, | |
305 public_key_codesign_pem_size); | |
302 if (ret != 0) | 306 if (ret != 0) |
303 { | 307 { |
304 ERRORPRINTF ("pk_parse_public_key failed with -0x%04x\n\n", -ret); | 308 char errbuf[1020]; |
305 pk_free(&pub_key_ctx); | 309 polarssl_strerror(ret, errbuf, 1020); |
310 errbuf[1019] = '\0'; /* Just to be sure */ | |
311 ERRORPRINTF ("x509_crt_parse failed with -0x%04x\n%s\n", -ret, errbuf); | |
312 x509_crt_free(&codesign_cert); | |
306 return VerifyUnknownError; | 313 return VerifyUnknownError; |
307 } | 314 } |
308 | 315 |
309 ret = pk_verify(&pub_key_ctx, POLARSSL_MD_SHA256, hash, 0, | 316 ret = pk_verify(&codesign_cert.pk, POLARSSL_MD_SHA256, hash, 0, |
310 signature, sig_size); | 317 signature, sig_size); |
311 | 318 |
312 if (ret != 0) | 319 if (ret != 0) |
313 { | 320 { |
314 ERRORPRINTF ("pk_verify failed with -0x%04x\n\n", -ret); | 321 char errbuf[1020]; |
315 } | 322 polarssl_strerror(ret, errbuf, 1020); |
316 pk_free(&pub_key_ctx); | 323 errbuf[1019] = '\0'; /* Just to be sure */ |
317 | 324 ERRORPRINTF ("pk_verify failed with -0x%04x\n %s\n", -ret, errbuf); |
318 return VerifyValid; | 325 x509_crt_free(&codesign_cert); |
326 retval = VerifyInvalidSignature; | |
327 goto done; | |
328 } | |
329 x509_crt_free(&codesign_cert); | |
330 | |
331 retval = VerifyValid; | |
319 | 332 |
320 done: | 333 done: |
321 xfree (data); | 334 xfree (data); |
322 return retval; | 335 return retval; |
323 } | 336 } |