comparison common/binverify.c @ 629:facb13c578f1

Add certificate pinning to verify_binary_win
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 23 Jun 2014 13:04:34 +0200
parents 26a18e3c3db4
children be30d50bc4f0
comparison
equal deleted inserted replaced
626:f595fcbe3e76 629:facb13c578f1
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
15 #include "pubkey-release.h"
16 #else
17 #include "pubkey-test.h"
18 #endif
13 19
14 bin_verify_result 20 bin_verify_result
15 verify_binary(const char *filename, size_t name_len) { 21 verify_binary(const char *filename, size_t name_len) {
16 #ifdef WIN32 22 #ifdef WIN32
17 return verify_binary_win(filename, name_len); 23 return verify_binary_win(filename, name_len);
23 #endif 29 #endif
24 } 30 }
25 31
26 #ifdef WIN32 32 #ifdef WIN32
27 33
34 #include <polarssl/x509_crt.h>
35
28 #include <windows.h> 36 #include <windows.h>
29 #include <wincrypt.h> 37 #include <wincrypt.h>
30 #include <wintrust.h> 38 #include <wintrust.h>
31 #include <stdio.h> 39 #include <stdio.h>
40
41
42 /** @brief Check if the certificate @a pCCertContext is pinned
43 *
44 * Compares the certificate's binary data (public key and attributes)
45 * with each other to validate that the certificate pCCertContext has
46 * exactly the same data as the builtin public certificate.
47 *
48 * @param[in] pCCertContext pointer to the certificate to check
49 *
50 * @returns true if the certificate matches, false otherwise.
51 */
52 static bool
53 check_certificate (PCCERT_CONTEXT pCCertContext)
54 {
55 x509_crt codesign_cert;
56 int ret = 0;
57 DWORD dwI = 0;
58 bool retval = false;
59
60 if (pCCertContext == NULL)
61 {
62 ERRORPRINTF ("Invalid call to check_certificate");
63 return false;
64 }
65
66 x509_crt_init(&codesign_cert);
67
68 /* Parse the pinned certificate */
69 ret = x509_crt_parse(&codesign_cert,
70 public_key_codesign_pem,
71 public_key_codesign_pem_size);
72 if (ret != 0)
73 {
74 ERRORPRINTF ("x509_crt_parse failed with -0x%04x\n\n", -ret);
75 goto done;
76 }
77
78 if (codesign_cert.raw.len != pCCertContext->cbCertEncoded ||
79 codesign_cert.raw.len <= 0)
80 {
81 ERRORPRINTF ("Certificate size mismatch");
82 goto done;
83 }
84
85 /* Check that the certificate is exactly the same as the pinned one */
86 for (dwI = 0; dwI < pCCertContext->cbCertEncoded; dwI++)
87 {
88 if (pCCertContext->pbCertEncoded[dwI] != codesign_cert.raw.p[dwI])
89 {
90 ERRORPRINTF ("Certificate content mismatch");
91 goto done;
92 }
93 }
94
95 retval = true;
96
97 done:
98 x509_crt_free(&codesign_cert);
99 return retval;
100 }
32 101
33 bin_verify_result 102 bin_verify_result
34 verify_binary_win(const char *filename, size_t name_len) { 103 verify_binary_win(const char *filename, size_t name_len) {
35 bin_verify_result retval = VerifyUnknownError; 104 bin_verify_result retval = VerifyUnknownError;
36 WCHAR *filenameW = NULL; 105 WCHAR *filenameW = NULL;
109 retval = VerifyUnknownError; 178 retval = VerifyUnknownError;
110 goto done; 179 goto done;
111 } 180 }
112 181
113 /* Verify that the signature is actually valid */ 182 /* Verify that the signature is actually valid */
114 if(CryptMsgControl(hMsg, 183 if(!CryptMsgControl(hMsg,
115 0, 184 0,
116 CMSG_CTRL_VERIFY_SIGNATURE, 185 CMSG_CTRL_VERIFY_SIGNATURE,
117 pSignerCertContext->pCertInfo)) 186 pSignerCertContext->pCertInfo))
118 { 187 {
119 DEBUGPRINTF ("Verify signature succeeded. \n"); 188 ERRORPRINTF ("The signature is invalid. \n");
120 /* TODO pinning*/ 189 retval = VerifyInvalidSignature;
190 syslog_error_printf ("Software update embedded signature is invalid.");
191 goto done;
192 }
193
194 if(check_certificate(pSignerCertContext))
195 {
196 DEBUGPRINTF ("Valid signature with pinned certificate.");
121 retval = VerifyValid; 197 retval = VerifyValid;
122 } else { 198 goto done;
123 ERRORPRINTF ("The signature was not verified. \n"); 199 }
200 else
201 {
202 ERRORPRINTF ("Certificate mismatch. \n");
124 retval = VerifyInvalidSignature; 203 retval = VerifyInvalidSignature;
204 syslog_error_printf ("Software update embedded signature "
205 "created with wrong certificate.");
125 goto done; 206 goto done;
126 } 207 }
127 208
128 done: 209 done:
129 xfree(filenameW); 210 xfree(filenameW);

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