Mercurial > trustbridge
comparison common/binverify.c @ 579:f4ce4eef3b38
Implement PKCS#7 embedded signature verfification for windows
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Tue, 27 May 2014 10:28:36 +0000 |
parents | |
children | ecfd77751daf |
comparison
equal
deleted
inserted
replaced
578:bf54c9fc0d63 | 579:f4ce4eef3b38 |
---|---|
1 /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik | |
2 * Software engineering by Intevation GmbH | |
3 * | |
4 * This file is Free Software under the GNU GPL (v>=2) | |
5 * and comes with ABSOLUTELY NO WARRANTY! | |
6 * See LICENSE.txt for details. | |
7 */ | |
8 | |
9 #include "binverify.h" | |
10 | |
11 #include "strhelp.h" | |
12 #include "logging.h" | |
13 | |
14 #ifdef WIN32 | |
15 | |
16 #include <windows.h> | |
17 #include <wincrypt.h> | |
18 #include <wintrust.h> | |
19 #include <stdio.h> | |
20 | |
21 bin_verify_result | |
22 verify_binary_win(const char *filename, size_t name_len) { | |
23 bin_verify_result retval = UnknownError; | |
24 WCHAR *filenameW = NULL; | |
25 BOOL result = FALSE; | |
26 DWORD dwEncoding = 0, | |
27 dwContentType = 0, | |
28 dwFormatType = 0, | |
29 dwSignerInfoSize = 0; | |
30 HCERTSTORE hStore = NULL; | |
31 HCRYPTMSG hMsg = NULL; | |
32 PCERT_INFO pSignerCert = NULL; | |
33 PCCERT_CONTEXT pSignerCertContext = NULL; | |
34 | |
35 if (!filename || name_len > MAX_PATH || strlen(filename) != name_len) | |
36 { | |
37 ERRORPRINTF ("Invalid parameters\n"); | |
38 return UnknownError; | |
39 } | |
40 | |
41 filenameW = utf8_to_wchar(filename, strnlen(filename, MAX_PATH)); | |
42 | |
43 result = CryptQueryObject (CERT_QUERY_OBJECT_FILE, | |
44 filenameW, | |
45 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, | |
46 CERT_QUERY_FORMAT_FLAG_BINARY, | |
47 0, | |
48 &dwEncoding, | |
49 &dwContentType, | |
50 &dwFormatType, | |
51 &hStore, | |
52 &hMsg, | |
53 NULL); | |
54 | |
55 if (!result || !hMsg) | |
56 { | |
57 PRINTLASTERROR ("Failed to query crypto object"); | |
58 retval = ReadFailed; | |
59 goto done; | |
60 } | |
61 | |
62 /* Get the cert info so that we can look up the signer in the store later */ | |
63 if (CryptMsgGetParam(hMsg, | |
64 CMSG_SIGNER_CERT_INFO_PARAM, | |
65 0, | |
66 NULL, | |
67 &dwSignerInfoSize) && dwSignerInfoSize > 0) | |
68 { | |
69 pSignerCert = xmalloc (dwSignerInfoSize); | |
70 } | |
71 else | |
72 { | |
73 ERRORPRINTF ("Failed to get signer cert size."); | |
74 retval = UnknownError; | |
75 goto done; | |
76 } | |
77 | |
78 if (!(CryptMsgGetParam(hMsg, | |
79 CMSG_SIGNER_CERT_INFO_PARAM, | |
80 0, | |
81 pSignerCert, | |
82 &dwSignerInfoSize))) | |
83 { | |
84 ERRORPRINTF ("Failed to get signer cert."); | |
85 retval = UnknownError; | |
86 goto done; | |
87 } | |
88 | |
89 pSignerCertContext = CertGetSubjectCertificateFromStore( | |
90 hStore, | |
91 PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, | |
92 pSignerCert); | |
93 | |
94 if (!pSignerCertContext) | |
95 { | |
96 ERRORPRINTF ("Failed to find signer cert in store."); | |
97 retval = UnknownError; | |
98 goto done; | |
99 } | |
100 | |
101 /* Verify that the signature is actually valid */ | |
102 if(CryptMsgControl(hMsg, | |
103 0, | |
104 CMSG_CTRL_VERIFY_SIGNATURE, | |
105 pSignerCertContext->pCertInfo)) | |
106 { | |
107 DEBUGPRINTF ("Verify signature succeeded. \n"); | |
108 /* TODO pinning*/ | |
109 retval = Valid; | |
110 } else { | |
111 ERRORPRINTF ("The signature was not verified. \n"); | |
112 retval = InvalidSignature; | |
113 goto done; | |
114 } | |
115 | |
116 done: | |
117 xfree(filenameW); | |
118 xfree(pSignerCert); | |
119 | |
120 if(pSignerCertContext) | |
121 { | |
122 CertFreeCertificateContext(pSignerCertContext); | |
123 } | |
124 if (hStore) | |
125 { | |
126 CertCloseStore(hStore, 0); | |
127 } | |
128 if (hMsg) | |
129 { | |
130 CryptMsgClose(hMsg); | |
131 } | |
132 return retval; | |
133 } | |
134 #endif /* WIN32 */ |