changeset 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 2c69298b4188
children d2996be40de4
files common/binverify.c common/binverify.h ui/tests/CMakeLists.txt ui/tests/append-sig.sh ui/tests/binverifytest.cpp ui/tests/binverifytest.h
diffstat 6 files changed, 55 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- 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 <polarssl/pk.h>
 #include <polarssl/base64.h>
 #include <polarssl/sha256.h>
+#include <polarssl/error.h>
+#include <polarssl/x509_crt.h>
 #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);
--- 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.
--- 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 ()
 
--- 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
--- 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()
--- 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

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