[PATCH 1 of 3] Add certificate pinning to verify_binary_win
Wald Commits
scm-commit at wald.intevation.org
Mon Jun 23 13:05:11 CEST 2014
# HG changeset patch
# User Andre Heinecke <andre.heinecke at intevation.de>
# Date 1403521474 -7200
# Node ID facb13c578f10fbaf083483d437fd10a2e31e1e1
# Parent f595fcbe3e762404e8ff287c4d5203c47e6b8328
Add certificate pinning to verify_binary_win
diff -r f595fcbe3e76 -r facb13c578f1 common/binverify.c
--- a/common/binverify.c Fri Jun 20 14:29:05 2014 +0200
+++ b/common/binverify.c Mon Jun 23 13:04:34 2014 +0200
@@ -11,6 +11,12 @@
#include "strhelp.h"
#include "logging.h"
+#ifdef RELEASE_BUILD
+#include "pubkey-release.h"
+#else
+#include "pubkey-test.h"
+#endif
+
bin_verify_result
verify_binary(const char *filename, size_t name_len) {
#ifdef WIN32
@@ -25,11 +31,74 @@
#ifdef WIN32
+#include <polarssl/x509_crt.h>
+
#include <windows.h>
#include <wincrypt.h>
#include <wintrust.h>
#include <stdio.h>
+
+/** @brief Check if the certificate @a pCCertContext is pinned
+ *
+ * Compares the certificate's binary data (public key and attributes)
+ * with each other to validate that the certificate pCCertContext has
+ * exactly the same data as the builtin public certificate.
+ *
+ * @param[in] pCCertContext pointer to the certificate to check
+ *
+ * @returns true if the certificate matches, false otherwise.
+ */
+static bool
+check_certificate (PCCERT_CONTEXT pCCertContext)
+{
+ x509_crt codesign_cert;
+ int ret = 0;
+ DWORD dwI = 0;
+ bool retval = false;
+
+ if (pCCertContext == NULL)
+ {
+ ERRORPRINTF ("Invalid call to check_certificate");
+ return false;
+ }
+
+ x509_crt_init(&codesign_cert);
+
+ /* Parse the pinned certificate */
+ ret = x509_crt_parse(&codesign_cert,
+ public_key_codesign_pem,
+ public_key_codesign_pem_size);
+ if (ret != 0)
+ {
+ ERRORPRINTF ("x509_crt_parse failed with -0x%04x\n\n", -ret);
+ goto done;
+ }
+
+ if (codesign_cert.raw.len != pCCertContext->cbCertEncoded ||
+ codesign_cert.raw.len <= 0)
+ {
+ ERRORPRINTF ("Certificate size mismatch");
+ goto done;
+ }
+
+ /* Check that the certificate is exactly the same as the pinned one */
+ for (dwI = 0; dwI < pCCertContext->cbCertEncoded; dwI++)
+ {
+ if (pCCertContext->pbCertEncoded[dwI] != codesign_cert.raw.p[dwI])
+ {
+ ERRORPRINTF ("Certificate content mismatch");
+ goto done;
+ }
+ }
+
+ retval = true;
+
+done:
+ x509_crt_free(&codesign_cert);
+ return retval;
+}
+
bin_verify_result
verify_binary_win(const char *filename, size_t name_len) {
bin_verify_result retval = VerifyUnknownError;
@@ -111,17 +180,29 @@
}
/* Verify that the signature is actually valid */
- if(CryptMsgControl(hMsg,
- 0,
- CMSG_CTRL_VERIFY_SIGNATURE,
- pSignerCertContext->pCertInfo))
+ if(!CryptMsgControl(hMsg,
+ 0,
+ CMSG_CTRL_VERIFY_SIGNATURE,
+ pSignerCertContext->pCertInfo))
{
- DEBUGPRINTF ("Verify signature succeeded. \n");
- /* TODO pinning*/
+ ERRORPRINTF ("The signature is invalid. \n");
+ retval = VerifyInvalidSignature;
+ syslog_error_printf ("Software update embedded signature is invalid.");
+ goto done;
+ }
+
+ if(check_certificate(pSignerCertContext))
+ {
+ DEBUGPRINTF ("Valid signature with pinned certificate.");
retval = VerifyValid;
- } else {
- ERRORPRINTF ("The signature was not verified. \n");
+ goto done;
+ }
+ else
+ {
+ ERRORPRINTF ("Certificate mismatch. \n");
retval = VerifyInvalidSignature;
+ syslog_error_printf ("Software update embedded signature "
+ "created with wrong certificate.");
goto done;
}
diff -r f595fcbe3e76 -r facb13c578f1 common/binverify.h
--- a/common/binverify.h Fri Jun 20 14:29:05 2014 +0200
+++ b/common/binverify.h Mon Jun 23 13:04:34 2014 +0200
@@ -26,6 +26,7 @@
VerifyValid = 100, /*! Could be read and signature matched */
VerifyUnknownError = 1, /*! The expected unexpected */
VerifyInvalidSignature = 4, /*! Signature was invalid */
+ VerifyInvalidCertificate = 5, /*! Certificate mismatch */
VerifyReadFailed = 6, /*! File exists but could not read the file */
} bin_verify_result;
diff -r f595fcbe3e76 -r facb13c578f1 common/pubkey-test.h
--- a/common/pubkey-test.h Fri Jun 20 14:29:05 2014 +0200
+++ b/common/pubkey-test.h Mon Jun 23 13:04:34 2014 +0200
@@ -23,4 +23,43 @@
"-----END PUBLIC KEY-----\n";
static const size_t public_key_pem_size = 625;
+
+/* Key used for codesigning */
+static const unsigned char public_key_codesign_pem[] =
+"-----BEGIN CERTIFICATE-----\n"
+"MIIFqTCCA5GgAwIBAgIBATANBgkqhkiG9w0BAQUFADBZMSAwHgYDVQQDExdQdWJs\n"
+"aWMgVHJ1c3RCcmlkZ2UgVGVzdDEoMCYGA1UEChMfUHVibGljIHNlY3JldCBkbyBu\n"
+"b3QgdHJ1c3QgdGhpczELMAkGA1UEBhMCREUwHhcNMTMwMTAxMDAwMDAwWhcNMTUx\n"
+"MjMxMjM1OTU5WjBlMSwwKgYDVQQDEyNQdWJsaWMgVHJ1c3RCcmlkZ2UgY29kZXNp\n"
+"Z25pbmcgdGVzdDEoMCYGA1UEChMfUHVibGljIHNlY3JldCBkbyBub3QgdHJ1c3Qg\n"
+"dGhpczELMAkGA1UEBhMCREUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\n"
+"AQDIz9IetAtdqJJ7aSfJcLmA9Mb4nxrqEJ5E6PMejDJZmmHNjyhCVp1qsLYmyC60\n"
+"m7qJ4OBENx0v2n5LiCUHJpJ4mzAklkWn1GffUkzWgQ2VHw5Nr44NWEwkUUa5/jT7\n"
+"Sxts2DWuaLz2r7oi6BUQpoRmQRPwwzFPONcCSw9iAvTU6oVI2jW1opEW3t10UwY3\n"
+"5/muryPsUz6y5VkBIc73VC0wByXoAruEPBBpMgOVw1+npOaJ1PL1XXQ/P6xziZo0\n"
+"Ab/tKvN6IpEHrNEGv1gScJt//pKKklvIyXm9UdIY9XpB6aauzthKpTFJXGYySlXx\n"
+"bD1a5sq0i2sAK/p8RvErVWg3EfBlUrQryJxONPVqribczZIWcgKVEFfXjX1tQqiC\n"
+"qRCgO4M6zhNIKLkAicp0DvYs8M4hIoPng98nqK6kSpfXR6Y4b9DU3yEktH7wGrwL\n"
+"jKATVM2l2yTF17Pjxkr2tH0XWrChfS+oV6Qzm9JQ/vmLKz5piLKpt5SXuZny+j0Y\n"
+"68ch709sVTuuPm4RAm5c5t0SCwEippClFpkZynYRsJVrjG9ZTrdvULxZao8GBzJx\n"
+"Lb+tCaKP60BRoUuRfwGMKZbU6j6ujOCy5bZIoJaKgHgyAHXRuS4PIjY9K2BGM5vI\n"
+"seA2GEdAJNmZPAQJE5rxkrsAH9n8QtmHucEqzCZVFcLuCwIDAQABo3AwbjAJBgNV\n"
+"HRMEAjAAMB0GA1UdDgQWBBSMgUaKY3L65wH5M4il/gbHCeVm4TAfBgNVHSMEGDAW\n"
+"gBTl/kZGRoa0cm82zW7CPn3yqk4MeTAOBgNVHQ8BAQEEBAMCAYAwEQYJYIZIAYb4\n"
+"QgEBBAQDAgAQMA0GCSqGSIb3DQEBBQUAA4ICAQAdmpf8k+ZKuhDvNwMCrf1JIZh3\n"
+"uJxlCHFke/ypsMT2E6p/GZpD/lLyRHbk7V5aEYdmBaK6Dem0KYhRuDclWscpQdXl\n"
+"96wx1IDNueMkj5ZDmpBLFl/nqxlM9HfHo8YTE9dRgzJAR8+dFR8HyRSayKo+pz4L\n"
+"FkNFT5Jtm9kKLIN+mSGKMBmpY4owfpeh7K6YyASoOHL9Zk8A0I7iZX8FB5KujrlG\n"
+"WJahjSAyvLvy98XDCf9/SyX73F1ol5ycAb/du+G5VZFDEI8sv/7fIdTx/AUR30Ac\n"
+"f3tqXZ4HwxWc0gofT0J2z/I4FZ/sT/1SNHReGNrG9GNn5bxjwpSXfc5A1bjhRfxd\n"
+"x73xKEInjpgo6AXY7wfNk1V+2z7keVOpaDEZUOsd/x/C+L8FsUh2JJHZp/hKX6Co\n"
+"AD///pxqNfvH5pPLUINC7VRUOTynUas7p9UvkPeJjqnWY6pmjeb4Fs6Z6vn0+Opy\n"
+"HP1MjLL41a+U9VxuNb6SfRDoeT19pqK6ovT2gbc61OvTI0lE97ChC622rjnV0c/N\n"
+"QYqkeTQG/IjPk0QFrYQxMqq6QKgds2nheYd4LyLGhk72pKWr28Hfj1ElcoTFFbWP\n"
+"ndI+uZePkkCsVYNMXbIAIpqLb++1ftl+L+itqxTyq+0tPObIL3WG9rzBGz8X6WT0\n"
+"KIzi4KAn66e5/iWZng==\n"
+"-----END CERTIFICATE-----\n";
+
+static const size_t public_key_codesign_pem_size = 2025;
+
#endif
More information about the Trustbridge-commits
mailing list