Mercurial > trustbridge
view common/binverify.c @ 592:778f74d0706f
Verify the binary directly without relying on settings (which might differ)
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Wed, 28 May 2014 08:36:05 +0000 |
parents | 26a18e3c3db4 |
children | facb13c578f1 |
line wrap: on
line source
/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik * Software engineering by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=2) * and comes with ABSOLUTELY NO WARRANTY! * See LICENSE.txt for details. */ #include "binverify.h" #include "strhelp.h" #include "logging.h" bin_verify_result verify_binary(const char *filename, size_t name_len) { #ifdef WIN32 return verify_binary_win(filename, name_len); #else /* TODO */ if (filename && name_len) return VerifyValid; return VerifyUnknownError; #endif } #ifdef WIN32 #include <windows.h> #include <wincrypt.h> #include <wintrust.h> #include <stdio.h> bin_verify_result verify_binary_win(const char *filename, size_t name_len) { bin_verify_result retval = VerifyUnknownError; WCHAR *filenameW = NULL; BOOL result = FALSE; DWORD dwEncoding = 0, dwContentType = 0, dwFormatType = 0, dwSignerInfoSize = 0; HCERTSTORE hStore = NULL; HCRYPTMSG hMsg = NULL; PCERT_INFO pSignerCert = NULL; PCCERT_CONTEXT pSignerCertContext = NULL; if (!filename || name_len > MAX_PATH || strlen(filename) != name_len) { ERRORPRINTF ("Invalid parameters\n"); return VerifyUnknownError; } filenameW = utf8_to_wchar(filename, name_len); result = CryptQueryObject (CERT_QUERY_OBJECT_FILE, filenameW, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, &dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, NULL); if (!result || !hMsg) { PRINTLASTERROR ("Failed to query crypto object"); retval = VerifyReadFailed; goto done; } /* Get the cert info so that we can look up the signer in the store later */ if (CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_INFO_PARAM, 0, NULL, &dwSignerInfoSize) && dwSignerInfoSize > 0) { pSignerCert = xmalloc (dwSignerInfoSize); } else { ERRORPRINTF ("Failed to get signer cert size."); retval = VerifyUnknownError; goto done; } if (!(CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_INFO_PARAM, 0, pSignerCert, &dwSignerInfoSize))) { ERRORPRINTF ("Failed to get signer cert."); retval = VerifyUnknownError; goto done; } pSignerCertContext = CertGetSubjectCertificateFromStore( hStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, pSignerCert); if (!pSignerCertContext) { ERRORPRINTF ("Failed to find signer cert in store."); retval = VerifyUnknownError; goto done; } /* Verify that the signature is actually valid */ if(CryptMsgControl(hMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE, pSignerCertContext->pCertInfo)) { DEBUGPRINTF ("Verify signature succeeded. \n"); /* TODO pinning*/ retval = VerifyValid; } else { ERRORPRINTF ("The signature was not verified. \n"); retval = VerifyInvalidSignature; goto done; } done: xfree(filenameW); xfree(pSignerCert); if(pSignerCertContext) { CertFreeCertificateContext(pSignerCertContext); } if (hStore) { CertCloseStore(hStore, 0); } if (hMsg) { CryptMsgClose(hMsg); } return retval; } #endif /* WIN32 */