Commit 3bf563319f02a96e3784a8f208b50cda9e5d931c

Authored by Perry Werneck
1 parent b11750ad

Fixing CRL expiration problem.

src/lib3270/connect.c
@@ -33,6 +33,10 @@ @@ -33,6 +33,10 @@
33 #include <errno.h> 33 #include <errno.h>
34 #include <lib3270/trace.h> 34 #include <lib3270/trace.h>
35 35
  36 +#if defined(HAVE_LIBSSL)
  37 + #include <openssl/err.h>
  38 +#endif
  39 +
36 /*---[ Implement ]-------------------------------------------------------------------------------*/ 40 /*---[ Implement ]-------------------------------------------------------------------------------*/
37 41
38 LIB3270_EXPORT int lib3270_connect_url(H3270 *hSession, const char *url, int wait) 42 LIB3270_EXPORT int lib3270_connect_url(H3270 *hSession, const char *url, int wait)
@@ -48,6 +52,13 @@ @@ -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 int lib3270_reconnect(H3270 *hSession, int seconds) 62 int lib3270_reconnect(H3270 *hSession, int seconds)
52 { 63 {
53 debug("%s",__FUNCTION__); 64 debug("%s",__FUNCTION__);
@@ -80,8 +91,25 @@ @@ -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 #if defined(HAVE_LIBSSL) 111 #if defined(HAVE_LIBSSL)
84 - set_ssl_state(hSession,LIB3270_SSL_UNSECURE); 112 + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
85 #endif // HAVE_LIBSSL 113 #endif // HAVE_LIBSSL
86 114
87 snprintf(hSession->full_model_name,LIB3270_FULL_MODEL_NAME_LENGTH,"IBM-327%c-%d",hSession->m3279 ? '9' : '8', hSession->model_num); 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,7 +712,9 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
712 LIB3270_INTERNAL int ssl_3270_ex_index; 712 LIB3270_INTERNAL int ssl_3270_ex_index;
713 713
714 #ifdef SSL_ENABLE_CRL_CHECK 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 #endif // SSL_ENABLE_CRL_CHECK 718 #endif // SSL_ENABLE_CRL_CHECK
717 719
718 #endif 720 #endif
src/lib3270/ssl/ctx_init.c
@@ -63,6 +63,132 @@ @@ -63,6 +63,132 @@
63 63
64 /*--[ Implement ]------------------------------------------------------------------------------------*/ 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 * @brief Initialize openssl library. 193 * @brief Initialize openssl library.
68 * 194 *
@@ -125,39 +251,11 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message) @@ -125,39 +251,11 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message)
125 ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL); 251 ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL);
126 252
127 #ifdef SSL_ENABLE_CRL_CHECK 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 #endif // SSL_ENABLE_CRL_CHECK 257 #endif // SSL_ENABLE_CRL_CHECK
159 258
160 - return 0;  
161 } 259 }
162 260
163 #endif // HAVE_LIBSSL 261 #endif // HAVE_LIBSSL
src/lib3270/ssl/negotiate.c
@@ -34,6 +34,7 @@ @@ -34,6 +34,7 @@
34 34
35 35
36 #include <config.h> 36 #include <config.h>
  37 +
37 #if defined(HAVE_LIBSSL) 38 #if defined(HAVE_LIBSSL)
38 #include <openssl/ssl.h> 39 #include <openssl/ssl.h>
39 #include <openssl/err.h> 40 #include <openssl/err.h>