Mercurial > trustbridge
diff common/binverify.c @ 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 | 3cd8dd706aaa |
children | 948f03bb5254 |
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