From 3bf563319f02a96e3784a8f208b50cda9e5d931c Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Wed, 27 Feb 2019 13:34:25 -0300 Subject: [PATCH] Fixing CRL expiration problem. --- src/lib3270/connect.c | 30 +++++++++++++++++++++++++++++- src/lib3270/private.h | 4 +++- src/lib3270/ssl/ctx_init.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- src/lib3270/ssl/negotiate.c | 1 + 4 files changed, 162 insertions(+), 33 deletions(-) diff --git a/src/lib3270/connect.c b/src/lib3270/connect.c index 99e9bfb..43b9533 100644 --- a/src/lib3270/connect.c +++ b/src/lib3270/connect.c @@ -33,6 +33,10 @@ #include #include +#if defined(HAVE_LIBSSL) + #include +#endif + /*---[ Implement ]-------------------------------------------------------------------------------*/ LIB3270_EXPORT int lib3270_connect_url(H3270 *hSession, const char *url, int wait) @@ -48,6 +52,13 @@ } +#ifdef SSL_ENABLE_CRL_CHECK +static int background_ssl_crl_check(H3270 *hSession, void *ssl_error) +{ + return lib3270_check_X509_crl(hSession, (SSL_ERROR_MESSAGE *) ssl_error); +} +#endif // SSL_ENABLE_CRL_CHECK + int lib3270_reconnect(H3270 *hSession, int seconds) { debug("%s",__FUNCTION__); @@ -80,8 +91,25 @@ } } +#ifdef SSL_ENABLE_CRL_CHECK + SSL_ERROR_MESSAGE ssl_error; + memset(&ssl_error,0,sizeof(ssl_error)); + + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); + int rc = lib3270_run_task(hSession, background_ssl_crl_check, &ssl_error); + if(rc) + { + if(ssl_error.description) + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", ssl_error.description); + else + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", ERR_reason_error_string(ssl_error.error)); + + return errno = rc; + } +#endif // SSL_ENABLE_CRL_CHECK + #if defined(HAVE_LIBSSL) - set_ssl_state(hSession,LIB3270_SSL_UNSECURE); + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); #endif // HAVE_LIBSSL snprintf(hSession->full_model_name,LIB3270_FULL_MODEL_NAME_LENGTH,"IBM-327%c-%d",hSession->m3279 ? '9' : '8', hSession->model_num); diff --git a/src/lib3270/private.h b/src/lib3270/private.h index ee05ca1..57ebbbf 100644 --- a/src/lib3270/private.h +++ b/src/lib3270/private.h @@ -712,7 +712,9 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); LIB3270_INTERNAL int ssl_3270_ex_index; #ifdef SSL_ENABLE_CRL_CHECK - int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message); + LIB3270_INTERNAL int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message); + LIB3270_INTERNAL int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message); + #endif // SSL_ENABLE_CRL_CHECK #endif diff --git a/src/lib3270/ssl/ctx_init.c b/src/lib3270/ssl/ctx_init.c index 02e540e..4edf9cd 100644 --- a/src/lib3270/ssl/ctx_init.c +++ b/src/lib3270/ssl/ctx_init.c @@ -63,6 +63,132 @@ /*--[ Implement ]------------------------------------------------------------------------------------*/ +#ifdef SSL_ENABLE_CRL_CHECK + +/* +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsequence-point" + +// https://stackoverflow.com/questions/10975542/asn1-time-to-time-t-conversion +static time_t ASN1_GetTimeT(const ASN1_TIME* time) +{ + struct tm t; + const char* str = (const char*) time->data; + size_t i = 0; + + memset(&t, 0, sizeof(t)); + + if (time->type == V_ASN1_UTCTIME) // two digit year + { + t.tm_year = (str[i++] - '0') * 10 + (str[++i] - '0'); + if (t.tm_year < 70) + t.tm_year += 100; + } + else if (time->type == V_ASN1_GENERALIZEDTIME) // four digit year + { + t.tm_year = (str[i++] - '0') * 1000 + (str[++i] - '0') * 100 + (str[++i] - '0') * 10 + (str[++i] - '0'); + t.tm_year -= 1900; + } + t.tm_mon = ((str[i++] - '0') * 10 + (str[++i] - '0')) - 1; // -1 since January is 0 not 1. + t.tm_mday = (str[i++] - '0') * 10 + (str[++i] - '0'); + t.tm_hour = (str[i++] - '0') * 10 + (str[++i] - '0'); + t.tm_min = (str[i++] - '0') * 10 + (str[++i] - '0'); + t.tm_sec = (str[i++] - '0') * 10 + (str[++i] - '0'); + + // Note: we did not adjust the time based on time zone information + return mktime(&t); +} +#pragma GCC diagnostic pop +*/ + +int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message) +{ + // Returns if don't have an SSL context. + if(!ssl_ctx) + return 0; + + // Do I have X509 CRL? Is it valid? + if(hSession->ssl.crl.cert) + { + + // https://stackoverflow.com/questions/23407376/testing-x509-certificate-expiry-date-with-c + time_t now = time(NULL); + if(X509_cmp_time(X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert), &now)) + { + int day, sec; + if(ASN1_TIME_diff(&day, &sec, NULL, X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert))) + { + trace_ssl(hSession,"CRL Certificate is valid for %d day(s) and %d second(s)\n",day,sec); + return 0; + } + else + { + trace_ssl(hSession,"Can't get CRL next update\n"); + } + + } + + // Certificate is no longer valid, release it. + trace_ssl(hSession,"CRL Certificate is no longer valid\n"); + + X509_CRL_free(hSession->ssl.crl.cert); + hSession->ssl.crl.cert = NULL; + + } + + // + // Set up CRL validation + // + // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session + // + if(lib3270_get_X509_CRL(hSession,message)) + return -1; + + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) + { + lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession); + + if(text) + trace_ssl(hSession,"\n%s\n",text); + + } + + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); + + if(hSession->ssl.crl.cert) + { + X509_STORE_add_crl(store, hSession->ssl.crl.cert); + trace_ssl(hSession,"CRL was added to cert store\n"); + + //time_t next_update = ASN1_GetTimeT(X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert)); + +#ifdef DEBUG + { + int day, sec; + + if(ASN1_TIME_diff(&day, &sec, NULL, X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert))) + { + debug("CRL Expiration: %d day(x) %d second(s)",day,sec); + } + + time_t now = time(NULL); + debug("********************* CMP_TIME=%d",X509_cmp_time(X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert), &now)); + + } +#endif // DEBUG + + } + + X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); + X509_STORE_set1_param(store, param); + X509_VERIFY_PARAM_free(param); + + return 0; +} +#endif // SSL_ENABLE_CRL_CHECK + + /** * @brief Initialize openssl library. * @@ -125,39 +251,11 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message) ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL); #ifdef SSL_ENABLE_CRL_CHECK - // - // Set up CRL validation - // - // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session - // - if(lib3270_get_X509_CRL(hSession,message)) - return -1; - - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) - { - lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession); - - if(text) - trace_ssl(hSession,"\n%s\n",text); - - } - - X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); - - if(hSession->ssl.crl.cert) - { - X509_STORE_add_crl(store, hSession->ssl.crl.cert); - trace_ssl(hSession,"CRL was added to cert store\n"); - } - - X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); - X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); - X509_STORE_set1_param(store, param); - X509_VERIFY_PARAM_free(param); - + return lib3270_check_X509_crl(hSession,message); +#else + return 0; #endif // SSL_ENABLE_CRL_CHECK - return 0; } #endif // HAVE_LIBSSL diff --git a/src/lib3270/ssl/negotiate.c b/src/lib3270/ssl/negotiate.c index 3b992ed..c8e6c0b 100644 --- a/src/lib3270/ssl/negotiate.c +++ b/src/lib3270/ssl/negotiate.c @@ -34,6 +34,7 @@ #include + #if defined(HAVE_LIBSSL) #include #include -- libgit2 0.21.2