Mercurial > trustbridge
changeset 1364:28885e8c891f
(issue177) Read signature time from PKCS#7 object in selftest and binverify
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Fri, 21 Nov 2014 18:33:31 +0100 |
parents | 3d6faded03dd |
children | 3d7ddf698480 |
files | common/binverify.c common/binverify.h common/selftest.c common/selftest.h |
diffstat | 4 files changed, 108 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/common/binverify.c Fri Nov 21 18:32:35 2014 +0100 +++ b/common/binverify.c Fri Nov 21 18:33:31 2014 +0100 @@ -24,6 +24,7 @@ bin_verify_result retval; retval.fptr = NULL; retval.result = VerifyUnknownError; + retval.sig_time = 0; return retval; } @@ -104,6 +105,97 @@ return retval; } +time_t +systemtime_to_time_t (SYSTEMTIME *systemTime) + +{ + LARGE_INTEGER jan1970FT = {{0}}; + jan1970FT.QuadPart = 116444736000000000LL; // january 1st 1970 well known value + LARGE_INTEGER utcFT = {{0}}; + + SystemTimeToFileTime(systemTime, (FILETIME*)&utcFT); + + __int64 utcDosTime = (utcFT.QuadPart - jan1970FT.QuadPart)/10000000; + + return (time_t)utcDosTime; +} + + +time_t +get_signature_time (HCRYPTMSG hMsg) +{ + FILETIME lft, ft; + SYSTEMTIME st; + DWORD dwData = 0, + n = 0, + dwSignerInfo = 0; + PCMSG_SIGNER_INFO pSignerInfo = NULL; + + time_t ret = -1; + + if (!hMsg) + { + return -1; + } + + // Get signer information size. + if (!CryptMsgGetParam(hMsg, + CMSG_SIGNER_INFO_PARAM, + 0, + NULL, + &dwSignerInfo)) + { + ERRORPRINTF ("Failed to get signer info size."); + return -1; + } + pSignerInfo = xmalloc (dwSignerInfo); + + if (!CryptMsgGetParam(hMsg, + CMSG_SIGNER_INFO_PARAM, + 0, + (PVOID)pSignerInfo, + &dwSignerInfo)) + { + ERRORPRINTF ("Failed to get signer info."); + goto done; + } + + + // Loop through authenticated attributes and find + // szOID_RSA_signingTime OID. + for (n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++) + { + if (lstrcmpA(szOID_RSA_signingTime, + pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0) + { + dwData = sizeof(ft); + if (!CryptDecodeObject((X509_ASN_ENCODING | PKCS_7_ASN_ENCODING), + szOID_RSA_signingTime, + pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData, + pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData, + 0, + (PVOID)&ft, + &dwData)) + { + PRINTLASTERROR ("Failed to decode time: "); + break; + } + + // Convert to local time. + FileTimeToLocalFileTime(&ft, &lft); + FileTimeToSystemTime(&lft, &st); + + ret = systemtime_to_time_t(&st); + break; + } + } + +done: + xfree(pSignerInfo); + + return ret; +} + bin_verify_result verify_binary_win(const char *filename, size_t name_len) { @@ -219,6 +311,7 @@ DEBUGPRINTF ("Valid signature with pinned certificate."); retval.result = VerifyValid; retval.fptr = fptr; + retval.sig_time = get_signature_time (hMsg); goto done; } else
--- a/common/binverify.h Fri Nov 21 18:32:35 2014 +0100 +++ b/common/binverify.h Fri Nov 21 18:33:31 2014 +0100 @@ -14,6 +14,7 @@ #include <stdbool.h> #include <stddef.h> #include <stdio.h> +#include <time.h> #ifdef __cplusplus extern "C" { @@ -47,6 +48,7 @@ FILE *fptr; /**< Pointer to the open file struct of the verified file The ptr is only valid if verify_result is VerifyValid and needs to be closed by the caller in that case.*/ + time_t sig_time; /** < Time of the signature. */ /*@}*/ } bin_verify_result;
--- a/common/selftest.c Fri Nov 21 18:32:35 2014 +0100 +++ b/common/selftest.c Fri Nov 21 18:33:31 2014 +0100 @@ -12,7 +12,7 @@ #include "logging.h" bool -selftest() +selftest(time_t *sig_time) { bin_verify_result res; #ifdef WIN32 @@ -45,6 +45,10 @@ return false; } + if (sig_time) + { + *sig_time = res.sig_time; + } fclose(res.fptr); xfree(utf8path); return true; @@ -55,6 +59,10 @@ syslog_error_printf ("Integrity check failed."); return false; } + if (sig_time) + { + *sig_time = res.sig_time; + } fclose(res.fptr); return true; #endif
--- a/common/selftest.h Fri Nov 21 18:32:35 2014 +0100 +++ b/common/selftest.h Fri Nov 21 18:33:31 2014 +0100 @@ -19,6 +19,7 @@ */ #include <stdbool.h> +#include <time.h> #ifdef __cplusplus extern "C" { @@ -28,9 +29,11 @@ * Checks that the certificate is signed with a valid signature and the * builtin public certificate. * + * @param[out] sig_time point this to a time_t to get the signature timestamp + * * @returns true if the selftest is successful. false on error. */ -bool selftest(); +bool selftest(time_t *sig_time); #ifdef __cplusplus }