# HG changeset patch # User Andre Heinecke # Date 1405088427 -7200 # Node ID 44fa5de02b52b028fcb1c533e555eb0d7b76ea87 # Parent 2c69298b418837eb02db957307c7bfe51d2b7f69 (issue43) Finalize and verify binary verification for linux. diff -r 2c69298b4188 -r 44fa5de02b52 common/binverify.c --- a/common/binverify.c Thu Jul 10 19:16:21 2014 +0200 +++ b/common/binverify.c Fri Jul 11 16:20:27 2014 +0200 @@ -10,7 +10,6 @@ #include "strhelp.h" #include "logging.h" - #ifdef RELEASE_BUILD #include "pubkey-release.h" #else @@ -232,6 +231,8 @@ #include #include #include +#include +#include #pragma GCC diagnostic pop bin_verify_result @@ -247,7 +248,7 @@ hash[32]; bin_verify_result retval = VerifyUnknownError; - pk_context pub_key_ctx; + x509_crt codesign_cert; if (strnlen(filename, name_len + 1) != name_len || name_len == 0) { @@ -264,24 +265,24 @@ } /* Fetch the signature from the end of data */ - if (data_size < sig_b64_size + 4) + if (data_size < sig_b64_size + 5) { ERRORPRINTF ("File to small to contain a signature.\n"); retval = VerifyInvalidSignature; goto done; } - if (data[data_size - sig_b64_size - 1] != ':' || - data[data_size - sig_b64_size - 2] != 'S' || - data[data_size - sig_b64_size - 3] != '\n'|| - data[data_size - sig_b64_size - 4] != '\r') + if (data[data_size - sig_b64_size - 2] != ':' || + data[data_size - sig_b64_size - 3] != 'S' || + data[data_size - sig_b64_size - 4] != '\n'|| + data[data_size - sig_b64_size - 5] != '\r') { ERRORPRINTF ("Failed to find valid signature line.\n"); retval = VerifyInvalidSignature; goto done; } - strncpy(signature_b64, data - sig_b64_size, sig_b64_size); + strncpy(signature_b64, data + (data_size - sig_b64_size - 1), sig_b64_size); signature_b64[sig_b64_size] = '\0'; ret = base64_decode(signature, &sig_size, @@ -289,33 +290,45 @@ if (ret != 0 || sig_size != TRUSTBRIDGE_RSA_KEY_SIZE / 8) { + ERRORPRINTF ("Base 64 decode failed with error: %i\n", ret); goto done; } /* Hash is calculated over the data without the signature at the end. */ - sha256((unsigned char *)data, data_size - sig_b64_size - 4, hash, 0); + sha256((unsigned char *)data, data_size - sig_b64_size - 5, hash, 0); - pk_init(&pub_key_ctx); + x509_crt_init(&codesign_cert); - ret = pk_parse_public_key(&pub_key_ctx, public_key_codesign_pem, - public_key_codesign_pem_size); + /* Parse the pinned certificate */ + ret = x509_crt_parse(&codesign_cert, + public_key_codesign_pem, + public_key_codesign_pem_size); if (ret != 0) { - ERRORPRINTF ("pk_parse_public_key failed with -0x%04x\n\n", -ret); - pk_free(&pub_key_ctx); + char errbuf[1020]; + polarssl_strerror(ret, errbuf, 1020); + errbuf[1019] = '\0'; /* Just to be sure */ + ERRORPRINTF ("x509_crt_parse failed with -0x%04x\n%s\n", -ret, errbuf); + x509_crt_free(&codesign_cert); return VerifyUnknownError; } - ret = pk_verify(&pub_key_ctx, POLARSSL_MD_SHA256, hash, 0, + ret = pk_verify(&codesign_cert.pk, POLARSSL_MD_SHA256, hash, 0, signature, sig_size); if (ret != 0) { - ERRORPRINTF ("pk_verify failed with -0x%04x\n\n", -ret); + char errbuf[1020]; + polarssl_strerror(ret, errbuf, 1020); + errbuf[1019] = '\0'; /* Just to be sure */ + ERRORPRINTF ("pk_verify failed with -0x%04x\n %s\n", -ret, errbuf); + x509_crt_free(&codesign_cert); + retval = VerifyInvalidSignature; + goto done; } - pk_free(&pub_key_ctx); + x509_crt_free(&codesign_cert); - return VerifyValid; + retval = VerifyValid; done: xfree (data); diff -r 2c69298b4188 -r 44fa5de02b52 common/binverify.h --- a/common/binverify.h Thu Jul 10 19:16:21 2014 +0200 +++ b/common/binverify.h Fri Jul 11 16:20:27 2014 +0200 @@ -43,10 +43,12 @@ * embedded PKCS 7 "authenticode" signatures embedded into the * file. * - * On Linux the last pattern of \r\nS: (0x0d0a533A) is looked up and - * afterwards a 3072 Bit Base64 encoded RSA signature is expected. + * On Linux the file is epxected to and with the pattern of + * \r\nS: (0x0d0a533A) followed by a 3072 Bit Base64 encoded RSA + * signature. * The signature is verified against the built in codesigning key in * the same certificate that is used for windows verification. + * If the pattern is not found the verification fails. * * @param[in] filename absolute null terminated UTF-8 encoded path to the file. * @param[in] name_len length of the filename. diff -r 2c69298b4188 -r 44fa5de02b52 ui/tests/CMakeLists.txt --- a/ui/tests/CMakeLists.txt Thu Jul 10 19:16:21 2014 +0200 +++ b/ui/tests/CMakeLists.txt Fri Jul 11 16:20:27 2014 +0200 @@ -121,31 +121,19 @@ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/append-sig.sh ${CMAKE_CURRENT_SOURCE_DIR}/data/codesign/codesigning.key ${CMAKE_CURRENT_BINARY_DIR}/fakeinst ${CMAKE_CURRENT_BINARY_DIR}/fakeinst-signed ) -# add_custom_command( -# TARGET binverifytest -# POST_BUILD -# COMMAND ${OSSLSIGNCODE_EXECUTABLE} sign -certs ${CMAKE_CURRENT_SOURCE_DIR}/data/codesign/codesigning.pem -# -key ${CMAKE_CURRENT_SOURCE_DIR}/data/codesign/codesigning-other.key -# -h sha256 -in ${CMAKE_CURRENT_BINARY_DIR}/fakeinst.exe -# -out ${CMAKE_CURRENT_BINARY_DIR}/fakeinst-other-key.exe -# ) -# add_custom_command( -# TARGET binverifytest -# POST_BUILD -# COMMAND ${OSSLSIGNCODE_EXECUTABLE} sign -certs ${CMAKE_CURRENT_SOURCE_DIR}/data/codesign/codesigning-other.pem -# -key ${CMAKE_CURRENT_SOURCE_DIR}/data/codesign/codesigning-other.key -# -h sha256 -in ${CMAKE_CURRENT_BINARY_DIR}/fakeinst.exe -# -out ${CMAKE_CURRENT_BINARY_DIR}/fakeinst-other-cert.exe -# ) -# add_custom_command( -# TARGET binverifytest -# POST_BUILD -# COMMAND ${OSSLSIGNCODE_EXECUTABLE} sign -certs ${CMAKE_CURRENT_SOURCE_DIR}/data/codesign/codesigning.pem -# -key ${CMAKE_CURRENT_SOURCE_DIR}/data/codesign/codesigning.key -# -h sha256 -in ${CMAKE_CURRENT_BINARY_DIR}/fakeinst.exe -# -out ${CMAKE_CURRENT_BINARY_DIR}/fakeinst-invalid.exe && -# ${CMAKE_STRIP} ${CMAKE_CURRENT_BINARY_DIR}/fakeinst-invalid.exe -# ) + add_custom_command( + TARGET binverifytest + POST_BUILD + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/append-sig.sh ${CMAKE_CURRENT_SOURCE_DIR}/data/codesign/codesigning-other.key + ${CMAKE_CURRENT_BINARY_DIR}/fakeinst ${CMAKE_CURRENT_BINARY_DIR}/fakeinst-other-key + ) + add_custom_command( + TARGET binverifytest + POST_BUILD + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/append-sig.sh ${CMAKE_CURRENT_SOURCE_DIR}/data/codesign/codesigning.key + ${CMAKE_CURRENT_BINARY_DIR}/fakeinst ${CMAKE_CURRENT_BINARY_DIR}/fakeinst-invalid && + sed -i s/Fakeinstaller/Bakeinstaller/g ${CMAKE_CURRENT_BINARY_DIR}/fakeinst-invalid + ) endif() endif () diff -r 2c69298b4188 -r 44fa5de02b52 ui/tests/append-sig.sh --- a/ui/tests/append-sig.sh Thu Jul 10 19:16:21 2014 +0200 +++ b/ui/tests/append-sig.sh Fri Jul 11 16:20:27 2014 +0200 @@ -1,3 +1,3 @@ #!/bin/bash cp $2 $3 -echo \\r\\nS:$(openssl dgst -sha256 -sign $1 < $2 | base64 -w0) >> $3 +echo -e \\r\\nS:$(openssl dgst -sha256 -sign $1 < $2 | base64 -w0) >> $3 diff -r 2c69298b4188 -r 44fa5de02b52 ui/tests/binverifytest.cpp --- a/ui/tests/binverifytest.cpp Thu Jul 10 19:16:21 2014 +0200 +++ b/ui/tests/binverifytest.cpp Fri Jul 11 16:20:27 2014 +0200 @@ -47,12 +47,15 @@ strlen("fakeinst-invalid" EXE_SUFFIX))); } -/* Check that a signature with a different (valid) certificate is not validated */ +#ifdef Q_OS_WIN +/* Check that a signature with a different (valid) certificate is not validated + * on Linux only the key is checked not the certificate */ void BinVerifyTest::testOtherCert() { QVERIFY(VerifyInvalidCertificate == verify_binary ("fakeinst-other-cert" EXE_SUFFIX, strlen("fakeinst-other-cert" EXE_SUFFIX))); } +#endif /* Check that no signature is not validated */ void BinVerifyTest::testNoSignature() diff -r 2c69298b4188 -r 44fa5de02b52 ui/tests/binverifytest.h --- a/ui/tests/binverifytest.h Thu Jul 10 19:16:21 2014 +0200 +++ b/ui/tests/binverifytest.h Fri Jul 11 16:20:27 2014 +0200 @@ -19,7 +19,9 @@ void testMiscErrors(); void testValidBinary(); void testOtherKey(); +#ifdef Q_OS_WIN void testOtherCert(); +#endif void testInvalidSig(); }; #endif