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

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