I've made a PATCH to address this issue but may or may not be the correct way to go about it.
If you sign a digest with a certificate and want to verify this later on, the current library does not support being able to set the time for verification in the X509 cert store when verifying the certificate. I've changed the TS_RESP_verify to extract the time from the TST and specify the time. Patch details: diff -ur openssl-orig/crypto/asn1/a_gentm.c openssl-work/crypto/asn1/a_gentm.c --- openssl-orig/crypto/asn1/a_gentm.c Wed Oct 8 10:00:10 2008 +++ openssl-work/crypto/asn1/a_gentm.c Tue Dec 2 14:38:03 2008 @@ -208,6 +208,24 @@ return(0); } +time_t ASN1_GENERALIZEDTIME_get(const ASN1_GENERALIZEDTIME *tm) +{ + char strtime[30]; + time_t returnTime = (time_t) 0; + int i ; + if (tm->length != 15) + return (time_t)-1; + + for (i = ( sizeof(time_t)*8-2) ; i>=0; i--) + { + returnTime += (time_t)(1 << i) ; + strftime(strtime, 16, "%Y%m%d%H%M%SZ",gmtime(&returnTime)); + if (strncmp((char*)tm->data,strtime,15) < 0) + returnTime -= (time_t)(1 << i) ; + } + return returnTime; +} + ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, time_t t) { diff -ur openssl-orig/crypto/asn1/asn1.h openssl-work/crypto/asn1/asn1.h --- openssl-orig/crypto/asn1/asn1.h Wed Nov 12 15:00:10 2008 +++ openssl-work/crypto/asn1/asn1.h Tue Dec 2 14:21:14 2008 @@ -850,6 +850,7 @@ ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, long offset_sec); int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); +time_t ASN1_GENERALIZEDTIME_get(const ASN1_GENERALIZEDTIME *tm); DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); diff -ur openssl-orig/crypto/ts/ts.h openssl-work/crypto/ts/ts.h --- openssl-orig/crypto/ts/ts.h Wed Nov 12 15:00:22 2008 +++ openssl-work/crypto/ts/ts.h Tue Dec 2 14:44:19 2008 @@ -612,7 +612,7 @@ */ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, - X509_STORE *store, X509 **signer_out); + X509_STORE *store, X509 **signer_out, TS_TST_INFO *tst_info); /* Context structure for the generic verify method. */ diff -ur openssl-orig/crypto/ts/ts_rsp_verify.c openssl-work/crypto/ts/ts_rsp_verify.c --- openssl-orig/crypto/ts/ts_rsp_verify.c Tue Apr 24 12:01:28 2007 +++ openssl-work/crypto/ts/ts_rsp_verify.c Tue Dec 2 14:46:52 2008 @@ -65,7 +65,7 @@ /* Private function declarations. */ static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, - X509 *signer, STACK_OF(X509) **chain); + X509 *signer, STACK_OF(X509) **chain, time_t certTime); static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); @@ -138,7 +138,7 @@ * - Returns the signer certificate in 'signer', if 'signer' is not NULL. */ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, - X509_STORE *store, X509 **signer_out) + X509_STORE *store, X509 **signer_out, TS_TST_INFO *tst_info) { STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; PKCS7_SIGNER_INFO *si; @@ -186,8 +186,16 @@ if (!signers || sk_X509_num(signers) != 1) goto err; signer = sk_X509_value(signers, 0); + /* Get the time that the token was signed at */ + const ASN1_GENERALIZEDTIME *theTime = TS_TST_INFO_get_time(tst_info); + time_t certTime = time(NULL); + if (theTime) + { + certTime = ASN1_GENERALIZEDTIME_get(theTime); + } + /* Now verify the certificate. */ - if (!TS_verify_cert(store, certs, signer, &chain)) goto err; + if (!TS_verify_cert(store, certs, signer, &chain, certTime)) goto err; /* Check if the signer certificate is consistent with the ESS extension. */ @@ -229,7 +237,7 @@ * freeing the vector. */ static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, - X509 *signer, STACK_OF(X509) **chain) + X509 *signer, STACK_OF(X509) **chain, time_t certTime) { X509_STORE_CTX cert_ctx; int i; @@ -239,6 +247,10 @@ *chain = NULL; X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted); X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN); + + /* set the time in the certificate store for verification */ + X509_STORE_CTX_set_time(&cert_ctx, 0, certTime); + i = X509_verify_cert(&cert_ctx); if (i <= 0) { @@ -418,7 +430,7 @@ /* Verify the signature. */ if ((ctx->flags & TS_VFY_SIGNATURE) && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, - &signer)) + &signer, tst_info)) goto err; /* Check version number of response. */
I’ve made a PATCH to address this issue but may or may
not be the correct way to go about it. If you sign a digest with a certificate and want to verify
this later on, the current library does not support being able to set the time
for verification in the X509 cert store when verifying the certificate. I’ve changed the TS_RESP_verify to extract the time
from the TST and specify the time. Patch details: diff - ---
openssl-orig/crypto/asn1/a_gentm.c Wed Oct 8 10:00:10 2008 +++
openssl-work/crypto/asn1/a_gentm.c Tue Dec 2 14:38:03 2008 @@ -208,6 +208,24 @@ return(0); } +time_t
ASN1_GENERALIZEDTIME_get(const ASN1_GENERALIZEDTIME *tm) +{ + char strtime[30]; + time_t returnTime =
(time_t) 0; + int i ; + if (tm->length != 15) + return (time_t)-1; + + for (i = (
sizeof(time_t)*8-2) ; i>=0; i--) + { + returnTime +=
(time_t)(1 << i) ; + strftime(strtime, 16,
"%Y%m%d%H%M%SZ",gmtime(&returnTime)); + if
(strncmp((char*)tm->data,strtime,15) < 0) + returnTime -=
(time_t)(1 << i) ; + } + return returnTime; +} + ASN1_GENERALIZEDTIME
*ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, time_t t) { diff - ---
openssl-orig/crypto/asn1/asn1.h Wed Nov 12 15:00:10 2008 +++
openssl-work/crypto/asn1/asn1.h Tue Dec 2 14:21:14 2008 @@ -850,6 +850,7 @@ ASN1_GENERALIZEDTIME
*ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int
offset_day, long offset_sec); int
ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); +time_t
ASN1_GENERALIZEDTIME_get(const ASN1_GENERALIZEDTIME *tm); DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(const
ASN1_OCTET_STRING *a); diff - --- openssl-orig/crypto/ts/ts.h Wed
Nov 12 15:00:22 2008 +++
openssl-work/crypto/ts/ts.h Tue Dec 2 14:44:19 2008 @@ -612,7 +612,7 @@ */ int
TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, -
X509_STORE *store, X509 **signer_out); + X509_STORE
*store, X509 **signer_out, TS_TST_INFO *tst_info); /* Context structure for
the generic verify method. */ diff - ---
openssl-orig/crypto/ts/ts_rsp_verify.c Tue Apr 24 12:01:28 2007 +++
openssl-work/crypto/ts/ts_rsp_verify.c Tue Dec 2 14:46:52 2008 @@ -65,7 +65,7 @@ /* Private function
declarations. */ static int
TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, - X509
*signer, STACK_OF(X509) **chain); + X509
*signer, STACK_OF(X509) **chain, time_t certTime); static int
TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); static ESS_SIGNING_CERT
*ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); static int
TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); @@ -138,7 +138,7 @@ * - Returns the signer
certificate in 'signer', if 'signer' is not NULL. */ int
TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, -
X509_STORE *store, X509 **signer_out) +
X509_STORE *store, X509 **signer_out, TS_TST_INFO *tst_info) { STACK_OF(PKCS7_SIGNER_INFO)
*sinfos = NULL; PKCS7_SIGNER_INFO *si; @@ -186,8 +186,16 @@ if (!signers ||
sk_X509_num(signers) != 1) goto err; signer =
sk_X509_value(signers, 0); + /* Get the time that
the token was signed at */ + const
ASN1_GENERALIZEDTIME *theTime = TS_TST_INFO_get_time(tst_info); + time_t certTime =
time(NULL); + if (theTime) + { + certTime =
ASN1_GENERALIZEDTIME_get(theTime); + } + /* Now verify the
certificate. */ - if
(!TS_verify_cert(store, certs, signer, &chain)) goto err; + if
(!TS_verify_cert(store, certs, signer, &chain, certTime)) goto err; /* Check if the signer
certificate is consistent with the ESS extension. */ @@ -229,7 +237,7 @@ * freeing the vector. */ static int
TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, - X509
*signer, STACK_OF(X509) **chain) + X509
*signer, STACK_OF(X509) **chain, time_t certTime) { X509_STORE_CTX cert_ctx; int i; @@ -239,6 +247,10 @@ *chain = NULL; X509_STORE_CTX_init(&cert_ctx,
store, signer, untrusted); X509_STORE_CTX_set_purpose(&cert_ctx,
X509_PURPOSE_TIMESTAMP_SIGN); + + /* set the time in the
certificate store for verification */ + X509_STORE_CTX_set_time(&cert_ctx,
0, certTime); + i =
X509_verify_cert(&cert_ctx); if (i <= 0) { @@ -418,7 +430,7 @@ /* Verify the
signature. */ if ((ctx->flags
& TS_VFY_SIGNATURE) &&
!TS_RESP_verify_signature(token, ctx->certs, ctx->store, -
&signer)) +
&signer, tst_info)) goto err; /* Check version
number of response. */ |