Commit 3bf563319f02a96e3784a8f208b50cda9e5d931c

Authored by Perry Werneck
1 parent b11750ad

Fixing CRL expiration problem.

src/lib3270/connect.c
... ... @@ -33,6 +33,10 @@
33 33 #include <errno.h>
34 34 #include <lib3270/trace.h>
35 35  
  36 +#if defined(HAVE_LIBSSL)
  37 + #include <openssl/err.h>
  38 +#endif
  39 +
36 40 /*---[ Implement ]-------------------------------------------------------------------------------*/
37 41  
38 42 LIB3270_EXPORT int lib3270_connect_url(H3270 *hSession, const char *url, int wait)
... ... @@ -48,6 +52,13 @@
48 52  
49 53 }
50 54  
  55 +#ifdef SSL_ENABLE_CRL_CHECK
  56 +static int background_ssl_crl_check(H3270 *hSession, void *ssl_error)
  57 +{
  58 + return lib3270_check_X509_crl(hSession, (SSL_ERROR_MESSAGE *) ssl_error);
  59 +}
  60 +#endif // SSL_ENABLE_CRL_CHECK
  61 +
51 62 int lib3270_reconnect(H3270 *hSession, int seconds)
52 63 {
53 64 debug("%s",__FUNCTION__);
... ... @@ -80,8 +91,25 @@
80 91 }
81 92 }
82 93  
  94 +#ifdef SSL_ENABLE_CRL_CHECK
  95 + SSL_ERROR_MESSAGE ssl_error;
  96 + memset(&ssl_error,0,sizeof(ssl_error));
  97 +
  98 + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
  99 + int rc = lib3270_run_task(hSession, background_ssl_crl_check, &ssl_error);
  100 + if(rc)
  101 + {
  102 + if(ssl_error.description)
  103 + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", ssl_error.description);
  104 + else
  105 + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", ERR_reason_error_string(ssl_error.error));
  106 +
  107 + return errno = rc;
  108 + }
  109 +#endif // SSL_ENABLE_CRL_CHECK
  110 +
83 111 #if defined(HAVE_LIBSSL)
84   - set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
  112 + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
85 113 #endif // HAVE_LIBSSL
86 114  
87 115 snprintf(hSession->full_model_name,LIB3270_FULL_MODEL_NAME_LENGTH,"IBM-327%c-%d",hSession->m3279 ? '9' : '8', hSession->model_num);
... ...
src/lib3270/private.h
... ... @@ -712,7 +712,9 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
712 712 LIB3270_INTERNAL int ssl_3270_ex_index;
713 713  
714 714 #ifdef SSL_ENABLE_CRL_CHECK
715   - int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message);
  715 + LIB3270_INTERNAL int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message);
  716 + LIB3270_INTERNAL int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message);
  717 +
716 718 #endif // SSL_ENABLE_CRL_CHECK
717 719  
718 720 #endif
... ...
src/lib3270/ssl/ctx_init.c
... ... @@ -63,6 +63,132 @@
63 63  
64 64 /*--[ Implement ]------------------------------------------------------------------------------------*/
65 65  
  66 +#ifdef SSL_ENABLE_CRL_CHECK
  67 +
  68 +/*
  69 +#pragma GCC diagnostic push
  70 +#pragma GCC diagnostic ignored "-Wsequence-point"
  71 +
  72 +// https://stackoverflow.com/questions/10975542/asn1-time-to-time-t-conversion
  73 +static time_t ASN1_GetTimeT(const ASN1_TIME* time)
  74 +{
  75 + struct tm t;
  76 + const char* str = (const char*) time->data;
  77 + size_t i = 0;
  78 +
  79 + memset(&t, 0, sizeof(t));
  80 +
  81 + if (time->type == V_ASN1_UTCTIME) // two digit year
  82 + {
  83 + t.tm_year = (str[i++] - '0') * 10 + (str[++i] - '0');
  84 + if (t.tm_year < 70)
  85 + t.tm_year += 100;
  86 + }
  87 + else if (time->type == V_ASN1_GENERALIZEDTIME) // four digit year
  88 + {
  89 + t.tm_year = (str[i++] - '0') * 1000 + (str[++i] - '0') * 100 + (str[++i] - '0') * 10 + (str[++i] - '0');
  90 + t.tm_year -= 1900;
  91 + }
  92 + t.tm_mon = ((str[i++] - '0') * 10 + (str[++i] - '0')) - 1; // -1 since January is 0 not 1.
  93 + t.tm_mday = (str[i++] - '0') * 10 + (str[++i] - '0');
  94 + t.tm_hour = (str[i++] - '0') * 10 + (str[++i] - '0');
  95 + t.tm_min = (str[i++] - '0') * 10 + (str[++i] - '0');
  96 + t.tm_sec = (str[i++] - '0') * 10 + (str[++i] - '0');
  97 +
  98 + // Note: we did not adjust the time based on time zone information
  99 + return mktime(&t);
  100 +}
  101 +#pragma GCC diagnostic pop
  102 +*/
  103 +
  104 +int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message)
  105 +{
  106 + // Returns if don't have an SSL context.
  107 + if(!ssl_ctx)
  108 + return 0;
  109 +
  110 + // Do I have X509 CRL? Is it valid?
  111 + if(hSession->ssl.crl.cert)
  112 + {
  113 +
  114 + // https://stackoverflow.com/questions/23407376/testing-x509-certificate-expiry-date-with-c
  115 + time_t now = time(NULL);
  116 + if(X509_cmp_time(X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert), &now))
  117 + {
  118 + int day, sec;
  119 + if(ASN1_TIME_diff(&day, &sec, NULL, X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert)))
  120 + {
  121 + trace_ssl(hSession,"CRL Certificate is valid for %d day(s) and %d second(s)\n",day,sec);
  122 + return 0;
  123 + }
  124 + else
  125 + {
  126 + trace_ssl(hSession,"Can't get CRL next update\n");
  127 + }
  128 +
  129 + }
  130 +
  131 + // Certificate is no longer valid, release it.
  132 + trace_ssl(hSession,"CRL Certificate is no longer valid\n");
  133 +
  134 + X509_CRL_free(hSession->ssl.crl.cert);
  135 + hSession->ssl.crl.cert = NULL;
  136 +
  137 + }
  138 +
  139 + //
  140 + // Set up CRL validation
  141 + //
  142 + // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session
  143 + //
  144 + if(lib3270_get_X509_CRL(hSession,message))
  145 + return -1;
  146 +
  147 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  148 + {
  149 + lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession);
  150 +
  151 + if(text)
  152 + trace_ssl(hSession,"\n%s\n",text);
  153 +
  154 + }
  155 +
  156 + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
  157 +
  158 + if(hSession->ssl.crl.cert)
  159 + {
  160 + X509_STORE_add_crl(store, hSession->ssl.crl.cert);
  161 + trace_ssl(hSession,"CRL was added to cert store\n");
  162 +
  163 + //time_t next_update = ASN1_GetTimeT(X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert));
  164 +
  165 +#ifdef DEBUG
  166 + {
  167 + int day, sec;
  168 +
  169 + if(ASN1_TIME_diff(&day, &sec, NULL, X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert)))
  170 + {
  171 + debug("CRL Expiration: %d day(x) %d second(s)",day,sec);
  172 + }
  173 +
  174 + time_t now = time(NULL);
  175 + debug("********************* CMP_TIME=%d",X509_cmp_time(X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert), &now));
  176 +
  177 + }
  178 +#endif // DEBUG
  179 +
  180 + }
  181 +
  182 + X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
  183 + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
  184 + X509_STORE_set1_param(store, param);
  185 + X509_VERIFY_PARAM_free(param);
  186 +
  187 + return 0;
  188 +}
  189 +#endif // SSL_ENABLE_CRL_CHECK
  190 +
  191 +
66 192 /**
67 193 * @brief Initialize openssl library.
68 194 *
... ... @@ -125,39 +251,11 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message)
125 251 ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL);
126 252  
127 253 #ifdef SSL_ENABLE_CRL_CHECK
128   - //
129   - // Set up CRL validation
130   - //
131   - // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session
132   - //
133   - if(lib3270_get_X509_CRL(hSession,message))
134   - return -1;
135   -
136   - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
137   - {
138   - lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession);
139   -
140   - if(text)
141   - trace_ssl(hSession,"\n%s\n",text);
142   -
143   - }
144   -
145   - X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
146   -
147   - if(hSession->ssl.crl.cert)
148   - {
149   - X509_STORE_add_crl(store, hSession->ssl.crl.cert);
150   - trace_ssl(hSession,"CRL was added to cert store\n");
151   - }
152   -
153   - X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
154   - X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
155   - X509_STORE_set1_param(store, param);
156   - X509_VERIFY_PARAM_free(param);
157   -
  254 + return lib3270_check_X509_crl(hSession,message);
  255 +#else
  256 + return 0;
158 257 #endif // SSL_ENABLE_CRL_CHECK
159 258  
160   - return 0;
161 259 }
162 260  
163 261 #endif // HAVE_LIBSSL
... ...
src/lib3270/ssl/negotiate.c
... ... @@ -34,6 +34,7 @@
34 34  
35 35  
36 36 #include <config.h>
  37 +
37 38 #if defined(HAVE_LIBSSL)
38 39 #include <openssl/ssl.h>
39 40 #include <openssl/err.h>
... ...