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 }

http://wald.intevation.org/projects/trustbridge/