Mercurial > trustbridge
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); |