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 */

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