Commit 4df3e30abfe601bbfd366bcd79b835c4f9bc2ea8

Authored by Perry Werneck
1 parent ed91a6f4

Organizing CRL check engine to avoid duplications.

@@ -388,10 +388,10 @@ if test "$app_cv_enable_crl_check" == "yes"; then @@ -388,10 +388,10 @@ if test "$app_cv_enable_crl_check" == "yes"; then
388 AC_DEFINE(SSL_ENABLE_CRL_CHECK) 388 AC_DEFINE(SSL_ENABLE_CRL_CHECK)
389 fi 389 fi
390 390
391 -AC_ARG_WITH([default-crl-url],  
392 - [AS_HELP_STRING([--with-default-crl-url], [Set lib3270 default crl url])], 391 +AC_ARG_WITH([crl-url],
  392 + [AS_HELP_STRING([--with-crl-url], [Set a hardcoded URL for CRL download])],
393 [ 393 [
394 - AC_DEFINE_UNQUOTED(SSL_DEFAULT_CRL_URL,"$withval") 394 + AC_DEFINE_UNQUOTED(SSL_CRL_URL,"$withval")
395 ],[ 395 ],[
396 AC_MSG_NOTICE(No default crl url) 396 AC_MSG_NOTICE(No default crl url)
397 ]) 397 ])
@@ -232,6 +232,7 @@ @@ -232,6 +232,7 @@
232 <Unit filename="src/include/cg.h" /> 232 <Unit filename="src/include/cg.h" />
233 <Unit filename="src/include/config.h" /> 233 <Unit filename="src/include/config.h" />
234 <Unit filename="src/include/config.h.in" /> 234 <Unit filename="src/include/config.h.in" />
  235 + <Unit filename="src/include/crl.h" />
235 <Unit filename="src/include/ctlrc.h" /> 236 <Unit filename="src/include/ctlrc.h" />
236 <Unit filename="src/include/ft_cut_ds.h" /> 237 <Unit filename="src/include/ft_cut_ds.h" />
237 <Unit filename="src/include/ft_cutc.h" /> 238 <Unit filename="src/include/ft_cutc.h" />
@@ -304,6 +305,7 @@ @@ -304,6 +305,7 @@
304 <Unit filename="src/ssl/crl.c"> 305 <Unit filename="src/ssl/crl.c">
305 <Option compilerVar="CC" /> 306 <Option compilerVar="CC" />
306 </Unit> 307 </Unit>
  308 + <Unit filename="src/ssl/crl.h" />
307 <Unit filename="src/ssl/linux/curl.c"> 309 <Unit filename="src/ssl/linux/curl.c">
308 <Option compilerVar="CC" /> 310 <Option compilerVar="CC" />
309 </Unit> 311 </Unit>
@@ -320,6 +322,10 @@ @@ -320,6 +322,10 @@
320 <Unit filename="src/ssl/negotiate.c"> 322 <Unit filename="src/ssl/negotiate.c">
321 <Option compilerVar="CC" /> 323 <Option compilerVar="CC" />
322 </Unit> 324 </Unit>
  325 + <Unit filename="src/ssl/notify.c">
  326 + <Option compilerVar="CC" />
  327 + </Unit>
  328 + <Unit filename="src/ssl/private.h" />
323 <Unit filename="src/ssl/properties.c"> 329 <Unit filename="src/ssl/properties.c">
324 <Option compilerVar="CC" /> 330 <Option compilerVar="CC" />
325 </Unit> 331 </Unit>
src/core/connect.c
@@ -36,9 +36,7 @@ @@ -36,9 +36,7 @@
36 #include <lib3270/toggle.h> 36 #include <lib3270/toggle.h>
37 #include <trace_dsc.h> 37 #include <trace_dsc.h>
38 38
39 -#if defined(HAVE_LIBSSL)  
40 - #include <openssl/err.h>  
41 -#endif 39 +#include "../ssl/crl.h"
42 40
43 /*---[ Implement ]-------------------------------------------------------------------------------*/ 41 /*---[ Implement ]-------------------------------------------------------------------------------*/
44 42
@@ -55,104 +53,22 @@ @@ -55,104 +53,22 @@
55 53
56 } 54 }
57 55
58 -static int background_ssl_crl_get(H3270 *hSession, void *ssl_error)  
59 -{  
60 - if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) ssl_error)) {  
61 - return -1;  
62 - }  
63 -  
64 - // Do I have X509 CRL?  
65 - if(hSession->ssl.crl.cert)  
66 - {  
67 - // Ok, have it. Is it valid?  
68 -  
69 - // https://stackoverflow.com/questions/23407376/testing-x509-certificate-expiry-date-with-c  
70 - // X509_CRL_get_nextUpdate is deprecated in openssl 1.1.0  
71 - #if OPENSSL_VERSION_NUMBER < 0x10100000L  
72 - const ASN1_TIME * next_update = X509_CRL_get_nextUpdate(hSession->ssl.crl.cert);  
73 - #else  
74 - const ASN1_TIME * next_update = X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert);  
75 - #endif  
76 -  
77 - if(X509_cmp_current_time(next_update) == 1)  
78 - {  
79 - int day, sec;  
80 - if(ASN1_TIME_diff(&day, &sec, NULL, next_update))  
81 - {  
82 - trace_ssl(hSession,"CRL Certificate is valid for %d day(s) and %d second(s)\n",day,sec);  
83 - return 0;  
84 - }  
85 - else  
86 - {  
87 - trace_ssl(hSession,"Can't get CRL next update, releasing it\n");  
88 - }  
89 -  
90 - }  
91 - else  
92 - {  
93 - trace_ssl(hSession,"CRL Certificate is no longer valid\n");  
94 - }  
95 -  
96 - // Certificate is no longer valid, release it.  
97 - X509_CRL_free(hSession->ssl.crl.cert);  
98 - hSession->ssl.crl.cert = NULL;  
99 -  
100 - }  
101 -  
102 - //  
103 - // Get CRL  
104 - //  
105 - // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session  
106 - //  
107 - return lib3270_get_crl_from_url(hSession, ssl_error, lib3270_get_crl_url(hSession));  
108 -  
109 -}  
110 -  
111 -#ifdef SSL_ENABLE_CRL_CHECK  
112 -static int notify_crl_error(H3270 *hSession, int rc, const SSL_ERROR_MESSAGE *message)  
113 -{  
114 - lib3270_write_log(  
115 - hSession,  
116 - "SSL-CRL-GET",  
117 - "CRL GET error: %s (rc=%d ssl_error=%d)",  
118 - message->title,  
119 - rc,  
120 - message->error  
121 - );  
122 -  
123 - if(message->description)  
124 - {  
125 - if(popup_ssl_error(hSession,rc,message->title,message->text,message->description))  
126 - return rc;  
127 - }  
128 -#ifdef _WIN32  
129 - else if(message->lasterror)  
130 - {  
131 - lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(message->lasterror);  
132 - lib3270_autoptr(char) formatted_error = lib3270_strdup_printf(_( "Windows error was \"%s\" (%u)" ), windows_error,(unsigned int) message->lasterror);  
133 56
134 - if(popup_ssl_error(hSession,rc,message->title,message->text,formatted_error))  
135 - return rc; 57 +#if defined(HAVE_LIBSSL)
136 58
137 - }  
138 -#endif // WIN32  
139 - else if(message->error)  
140 - {  
141 - lib3270_autoptr(char) formatted_error = lib3270_strdup_printf(_( "%s (SSL error %d)" ),ERR_reason_error_string(message->error),message->error);  
142 - lib3270_write_log(hSession,"SSL-CRL-GET","%s",formatted_error); 59 + static int background_ssl_init(H3270 *hSession, void *ssl_error)
  60 + {
  61 + if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) ssl_error))
  62 + return -1;
143 63
144 - if(popup_ssl_error(hSession,rc,message->title,message->text,formatted_error))  
145 - return rc;  
146 - }  
147 - else  
148 - {  
149 - if(popup_ssl_error(hSession,rc,message->title,message->text,""))  
150 - return rc;  
151 - } 64 +#if defined(SSL_ENABLE_CRL_CHECK)
  65 + lib3270_crl_free_if_expired(hSession);
  66 +#endif // defined(SSL_ENABLE_CRL_CHECK)
152 67
153 return 0; 68 return 0;
154 -}  
155 -#endif // SSL_ENABLE_CRL_CHECK 69 + }
  70 +
  71 +#endif // HAVE_LIBSSL
156 72
157 int lib3270_reconnect(H3270 *hSession, int seconds) 73 int lib3270_reconnect(H3270 *hSession, int seconds)
158 { 74 {
@@ -186,24 +102,20 @@ static int notify_crl_error(H3270 *hSession, int rc, const SSL_ERROR_MESSAGE *me @@ -186,24 +102,20 @@ static int notify_crl_error(H3270 *hSession, int rc, const SSL_ERROR_MESSAGE *me
186 } 102 }
187 } 103 }
188 104
189 -#ifdef SSL_ENABLE_CRL_CHECK  
190 -  
191 - SSL_ERROR_MESSAGE ssl_error;  
192 - memset(&ssl_error,0,sizeof(ssl_error));  
193 -  
194 - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);  
195 - int rc = lib3270_run_task(hSession, background_ssl_crl_get, &ssl_error);  
196 -  
197 - debug("CRL check returns %d",rc); 105 +#if defined(HAVE_LIBSSL)
  106 + {
  107 + SSL_ERROR_MESSAGE ssl_error;
  108 + memset(&ssl_error,0,sizeof(ssl_error));
198 109
199 - if(rc && notify_crl_error(hSession, rc,&ssl_error))  
200 - return errno = rc; 110 + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
  111 + int rc = lib3270_run_task(hSession, background_ssl_init, &ssl_error);
201 112
202 -#endif // SSL_ENABLE_CRL_CHECK 113 + if(rc && notify_ssl_error(hSession, rc, &ssl_error))
  114 + return errno = rc;
203 115
204 -#if defined(HAVE_LIBSSL)  
205 - set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);  
206 - hSession->ssl.host = 0; 116 + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
  117 + hSession->ssl.host = 0;
  118 + }
207 #endif // HAVE_LIBSSL 119 #endif // HAVE_LIBSSL
208 120
209 snprintf(hSession->full_model_name,LIB3270_FULL_MODEL_NAME_LENGTH,"IBM-327%c-%d",hSession->m3279 ? '9' : '8', hSession->model_num); 121 snprintf(hSession->full_model_name,LIB3270_FULL_MODEL_NAME_LENGTH,"IBM-327%c-%d",hSession->m3279 ? '9' : '8', hSession->model_num);
src/core/session.c
@@ -44,6 +44,7 @@ @@ -44,6 +44,7 @@
44 #include "kybdc.h" 44 #include "kybdc.h"
45 #include "3270ds.h" 45 #include "3270ds.h"
46 #include "popupsc.h" 46 #include "popupsc.h"
  47 +#include "../ssl/crl.h"
47 #include <lib3270/trace.h> 48 #include <lib3270/trace.h>
48 #include <lib3270/log.h> 49 #include <lib3270/log.h>
49 50
@@ -88,11 +89,7 @@ void lib3270_session_free(H3270 *h) @@ -88,11 +89,7 @@ void lib3270_session_free(H3270 *h)
88 h->ssl.crl.prefer = NULL; 89 h->ssl.crl.prefer = NULL;
89 } 90 }
90 91
91 - if(h->ssl.crl.cert)  
92 - {  
93 - X509_CRL_free(h->ssl.crl.cert);  
94 - h->ssl.crl.cert = NULL;  
95 - } 92 + lib3270_crl_free(h);
96 #endif // SSL_ENABLE_CRL_CHECK 93 #endif // SSL_ENABLE_CRL_CHECK
97 94
98 // Release state change callbacks 95 // Release state change callbacks
src/include/config.h.in
@@ -72,7 +72,7 @@ @@ -72,7 +72,7 @@
72 #undef SSL_ENABLE_NOTIFICATION_WHEN_FAILED 72 #undef SSL_ENABLE_NOTIFICATION_WHEN_FAILED
73 73
74 /* If defined uses a hardcoded CRL path */ 74 /* If defined uses a hardcoded CRL path */
75 - #undef SSL_DEFAULT_CRL_URL 75 + #undef SSL_CRL_URL
76 76
77 /* Optional parts. */ 77 /* Optional parts. */
78 #undef X3270_DBCS 78 #undef X3270_DBCS
src/include/lib3270-internals.h
@@ -849,11 +849,11 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); @@ -849,11 +849,11 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
849 */ 849 */
850 LIB3270_INTERNAL int popup_ssl_error(H3270 *session, int rc, const char *title, const char *summary, const char *body); 850 LIB3270_INTERNAL int popup_ssl_error(H3270 *session, int rc, const char *title, const char *summary, const char *body);
851 851
852 - #ifdef SSL_ENABLE_CRL_CHECK  
853 - LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *url);  
854 - LIB3270_INTERNAL int lib3270_get_crl_from_url(H3270 *hSession, void *ssl_error, const char *url);  
855 - LIB3270_INTERNAL int lib3270_get_crl_from_dist_points(H3270 *hSession, CRL_DIST_POINTS * dist_points, void *ssl_error);  
856 - #endif // SSL_ENABLE_CRL_CHECK 852 + /**
  853 + * @brief Emite popup on SSL error.
  854 + *
  855 + */
  856 + LIB3270_INTERNAL int notify_ssl_error(H3270 *hSession, int rc, const SSL_ERROR_MESSAGE *message);
857 857
858 #endif 858 #endif
859 859
@@ -28,46 +28,92 @@ @@ -28,46 +28,92 @@
28 */ 28 */
29 29
30 #include <config.h> 30 #include <config.h>
  31 +
31 #include <lib3270-internals.h> 32 #include <lib3270-internals.h>
32 -#include <lib3270.h>  
33 #include <lib3270/log.h> 33 #include <lib3270/log.h>
  34 +#include <lib3270/trace.h>
  35 +#include <lib3270/toggle.h>
34 #include <trace_dsc.h> 36 #include <trace_dsc.h>
35 -#include <array.h>  
36 37
37 -#ifdef HAVE_LIBSSL  
38 - #include <openssl/ssl.h>  
39 - #include <openssl/err.h>  
40 -#endif // HAVE_LIBSSL 38 +#include "crl.h"
41 39
42 /*--[ Implement ]------------------------------------------------------------------------------------*/ 40 /*--[ Implement ]------------------------------------------------------------------------------------*/
43 41
44 -#ifdef SSL_ENABLE_CRL_CHECK  
45 -int lib3270_get_crl_from_url(H3270 *hSession, void *ssl_error, const char *url)  
46 -{  
47 -  
48 - if(!(url && *url))  
49 - return -1; 42 +#if defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBSSL)
50 43
51 - // Invalidate current certificate. 44 +void lib3270_crl_free(H3270 *hSession)
  45 +{
52 if(hSession->ssl.crl.cert) 46 if(hSession->ssl.crl.cert)
53 { 47 {
54 - trace_ssl(hSession,"%s\n","Discarding current CRL");  
55 X509_CRL_free(hSession->ssl.crl.cert); 48 X509_CRL_free(hSession->ssl.crl.cert);
56 hSession->ssl.crl.cert = NULL; 49 hSession->ssl.crl.cert = NULL;
57 } 50 }
58 51
  52 +}
  53 +
  54 +void lib3270_crl_free_if_expired(H3270 *hSession)
  55 +{
  56 + if(!hSession->ssl.crl.cert)
  57 + return;
  58 +
  59 + // https://stackoverflow.com/questions/23407376/testing-x509-certificate-expiry-date-with-c
  60 + // X509_CRL_get_nextUpdate is deprecated in openssl 1.1.0
  61 + #if OPENSSL_VERSION_NUMBER < 0x10100000L
  62 + const ASN1_TIME * next_update = X509_CRL_get_nextUpdate(hSession->ssl.crl.cert);
  63 + #else
  64 + const ASN1_TIME * next_update = X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert);
  65 + #endif
  66 +
  67 + if(X509_cmp_current_time(next_update) == 1)
  68 + {
  69 + int day, sec;
  70 + if(ASN1_TIME_diff(&day, &sec, NULL, next_update))
  71 + {
  72 + trace_ssl(hSession,"CRL is valid for %d day(s) and %d second(s)\n",day,sec);
  73 + return;
  74 + }
  75 +
  76 + trace_ssl(hSession,"Can't get CRL next update, discarding it\n");
  77 +
  78 + }
  79 + else
  80 + {
  81 + trace_ssl(hSession,"CRL is no longer valid\n");
  82 + }
  83 +
  84 + // Certificate is no longer valid, release it.
  85 + X509_CRL_free(hSession->ssl.crl.cert);
  86 + hSession->ssl.crl.cert = NULL;
  87 +
  88 +}
  89 +
  90 +int lib3270_crl_new_from_url(H3270 *hSession, void *ssl_error, const char *url)
  91 +{
  92 + if(!(url && *url))
  93 + return -1;
  94 +
  95 + lib3270_crl_free(hSession); // Just in case!
  96 +
59 // 97 //
60 // Get the new CRL 98 // Get the new CRL
61 // 99 //
62 // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session 100 // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session
63 // 101 //
64 - trace_ssl(hSession,"Getting new CRL from %s\n",url); 102 + trace_ssl(hSession,"Getting CRL from %s\n",url);
65 103
66 - hSession->ssl.crl.cert = lib3270_get_crl(hSession,(SSL_ERROR_MESSAGE *) ssl_error,url); 104 + hSession->ssl.crl.cert = lib3270_download_crl(hSession,(SSL_ERROR_MESSAGE *) ssl_error, url);
67 105
68 if(hSession->ssl.crl.cert) 106 if(hSession->ssl.crl.cert)
69 { 107 {
70 - // Got CRL, add it to ssl store 108 + // Got CRL!
  109 +
  110 + // Update URL
  111 + if(hSession->ssl.crl.url)
  112 + lib3270_free(hSession->ssl.crl.url);
  113 +
  114 + hSession->ssl.crl.url = lib3270_strdup(url);
  115 +
  116 + // Add it to ssl store
71 if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) 117 if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
72 { 118 {
73 lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession); 119 lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession);
@@ -94,95 +140,5 @@ int lib3270_get_crl_from_url(H3270 *hSession, void *ssl_error, const char *url) @@ -94,95 +140,5 @@ int lib3270_get_crl_from_url(H3270 *hSession, void *ssl_error, const char *url)
94 return -1; 140 return -1;
95 141
96 } 142 }
97 -#endif // SSL_ENABLE_CRL_CHECK  
98 -  
99 -#if !defined(SSL_DEFAULT_CRL_URL) && defined(SSL_ENABLE_CRL_CHECK)  
100 -int lib3270_get_crl_from_dist_points(H3270 *hSession, CRL_DIST_POINTS * dist_points, void *ssl_error)  
101 -{  
102 - size_t ix;  
103 - int i, gtype;  
104 - lib3270_autoptr(LIB3270_STRING_ARRAY) uris = lib3270_string_array_new();  
105 -  
106 - // https://nougat.cablelabs.com/DLNA-RUI/openssl/commit/57912ed329f870b237f2fd9f2de8dec3477d1729  
107 -  
108 - for(ix = 0; ix < (size_t) sk_DIST_POINT_num(dist_points); ix++) {  
109 143
110 - DIST_POINT *dp = sk_DIST_POINT_value(dist_points, ix);  
111 -  
112 - if(!dp->distpoint || dp->distpoint->type != 0)  
113 - continue;  
114 -  
115 - GENERAL_NAMES *gens = dp->distpoint->name.fullname;  
116 -  
117 - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)  
118 - {  
119 - GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);  
120 - ASN1_STRING *uri = GENERAL_NAME_get0_value(gen, &gtype);  
121 - if(uri)  
122 - {  
123 -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) // OpenSSL 1.1.0+  
124 - const unsigned char * data = ASN1_STRING_get0_data(uri);  
125 -#else  
126 - const unsigned char * data = ASN1_STRING_data(uri); // ASN1_STRING_get0_data(uri);  
127 -#endif // OpenSSL 1.1.0+  
128 - if(data)  
129 - {  
130 - lib3270_string_array_append(uris,(char *) data);  
131 - }  
132 - }  
133 -  
134 - }  
135 -  
136 - }  
137 -  
138 -#ifdef DEBUG  
139 - {  
140 - for(ix = 0; ix < uris->length; ix++)  
141 - {  
142 - debug("%u: %s", (unsigned int) ix, uris->str[ix]);  
143 - }  
144 - }  
145 -#endif // DEBUG  
146 -  
147 - if(hSession->ssl.crl.url)  
148 - {  
149 - // Check if we already have the URL.  
150 - if(!strcmp(hSession->ssl.crl.url,uris->str[ix]))  
151 - {  
152 - trace_ssl(hSession,"Keeping CRL from %s\n",hSession->ssl.crl.url);  
153 - return 0;  
154 - }  
155 -  
156 - // The URL is invalid or not to this cert, remove it!  
157 - lib3270_free(hSession->ssl.crl.url);  
158 - hSession->ssl.crl.url = NULL;  
159 - }  
160 -  
161 - if(hSession->ssl.crl.prefer && *hSession->ssl.crl.prefer)  
162 - {  
163 - size_t length = strlen(hSession->ssl.crl.prefer);  
164 -  
165 - for(ix = 0; ix < uris->length; ix++)  
166 - {  
167 - if(!strncmp(uris->str[ix],hSession->ssl.crl.prefer,length))  
168 - {  
169 - trace_ssl(hSession,"Trying preferred URL %s\n",uris->str[ix]);  
170 - if(lib3270_get_crl_from_url(hSession, ssl_error, uris->str[ix]) == 0)  
171 - return 0;  
172 - }  
173 -  
174 - }  
175 -  
176 - }  
177 -  
178 - // Can't load, try all of them.  
179 - for(ix = 0; ix < uris->length; ix++)  
180 - {  
181 - trace_ssl(hSession,"Trying CRL from %s\n",uris->str[ix]);  
182 - if(lib3270_get_crl_from_url(hSession, ssl_error, uris->str[ix]) == 0)  
183 - return 0;  
184 - }  
185 -  
186 - return -1;  
187 -}  
188 -#endif // !SSL_DEFAULT_CRL_URL && SSL_ENABLE_CRL_CHECK 144 +#endif // SSL_ENABLE_CRL_CHECK && HAVE_LIBSSL
src/ssl/crl.h 0 → 100644
@@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
  1 +/*
  2 + * "Software G3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral ', conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como private.h e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça)
  27 + *
  28 + */
  29 +
  30 +#ifdef WIN32
  31 + #include <winsock2.h>
  32 + #include <windows.h>
  33 +#endif // WIN32
  34 +
  35 +#include <config.h> /* autoconf settings */
  36 +#include <lib3270.h> /* lib3270 API calls and defs */
  37 +
  38 +#if defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBSSL)
  39 +
  40 + #include <openssl/ssl.h>
  41 + #include <openssl/err.h>
  42 +
  43 + /// @brief Unconditional release of the session CRL.
  44 + LIB3270_INTERNAL void lib3270_crl_free(H3270 *hSession);
  45 +
  46 + /// @brief Release CRL if expired.
  47 + LIB3270_INTERNAL void lib3270_crl_free_if_expired(H3270 *hSession);
  48 +
  49 + /// @brief Load CRL from URL.
  50 + LIB3270_INTERNAL int lib3270_crl_new_from_url(H3270 *hSession, void *ssl_error, const char *url);
  51 +
  52 +
  53 + LIB3270_INTERNAL X509_CRL * lib3270_download_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *url);
  54 +// LIB3270_INTERNAL int lib3270_get_crl_from_url(H3270 *hSession, void *ssl_error, const char *url);
  55 +// LIB3270_INTERNAL int lib3270_get_crl_from_dist_points(H3270 *hSession, CRL_DIST_POINTS * dist_points, void *ssl_error);
  56 +
  57 +#endif // SSL_ENABLE_CRL_CHECK && HAVE_LIBSSL
  58 +
  59 +
  60 +
src/ssl/linux/getcrl.c
@@ -45,7 +45,7 @@ static inline void lib3270_autoptr_cleanup_FILE(FILE **file) @@ -45,7 +45,7 @@ static inline void lib3270_autoptr_cleanup_FILE(FILE **file)
45 fclose(*file); 45 fclose(*file);
46 } 46 }
47 47
48 -LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl) 48 +LIB3270_INTERNAL X509_CRL * lib3270_download_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
49 { 49 {
50 X509_CRL * x509_crl = NULL; 50 X509_CRL * x509_crl = NULL;
51 51
src/ssl/linux/init.c
@@ -106,6 +106,7 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message) @@ -106,6 +106,7 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message)
106 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); 106 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
107 X509_STORE_set1_param(store, param); 107 X509_STORE_set1_param(store, param);
108 X509_VERIFY_PARAM_free(param); 108 X509_VERIFY_PARAM_free(param);
  109 +
109 trace_ssl(hSession,"CRL CHECK was enabled\n"); 110 trace_ssl(hSession,"CRL CHECK was enabled\n");
110 111
111 #endif // SSL_ENABLE_CRL_CHECK 112 #endif // SSL_ENABLE_CRL_CHECK
src/ssl/negotiate.c
@@ -48,6 +48,8 @@ @@ -48,6 +48,8 @@
48 #define SSL_ST_OK 3 48 #define SSL_ST_OK 3
49 #endif // !SSL_ST_OK 49 #endif // !SSL_ST_OK
50 50
  51 + #include "crl.h"
  52 +
51 #endif 53 #endif
52 54
53 #include <errno.h> 55 #include <errno.h>
@@ -133,7 +135,7 @@ static int background_ssl_init(H3270 *hSession, void *message) @@ -133,7 +135,7 @@ static int background_ssl_init(H3270 *hSession, void *message)
133 return 0; 135 return 0;
134 } 136 }
135 137
136 -#if !defined(SSL_DEFAULT_CRL_URL) && defined(SSL_ENABLE_CRL_CHECK) 138 +#if !defined(SSL_CRL_URL) && defined(SSL_ENABLE_CRL_CHECK)
137 int x509_store_ctx_error_callback(int ok, X509_STORE_CTX GNUC_UNUSED(*ctx)) 139 int x509_store_ctx_error_callback(int ok, X509_STORE_CTX GNUC_UNUSED(*ctx))
138 { 140 {
139 debug("%s(%d)",__FUNCTION__,ok); 141 debug("%s(%d)",__FUNCTION__,ok);
@@ -152,8 +154,26 @@ int x509_store_ctx_error_callback(int ok, X509_STORE_CTX GNUC_UNUSED(*ctx)) @@ -152,8 +154,26 @@ int x509_store_ctx_error_callback(int ok, X509_STORE_CTX GNUC_UNUSED(*ctx))
152 */ 154 */
153 return ok; 155 return ok;
154 } 156 }
155 -#endif // !SSL_DEFAULT_CRL_URL && SSL_ENABLE_CRL_CHECK 157 +#endif // !SSL_CRL_URL && SSL_ENABLE_CRL_CHECK
156 158
  159 +static int x509_store_ctx_error_callback(int ok, X509_STORE_CTX GNUC_UNUSED(*ctx))
  160 +{
  161 + debug("%s(%d)",__FUNCTION__,ok);
  162 +
  163 +/*
  164 + 55 {
  165 + 56 if (!ok) {
  166 + 57 Category::getInstance("OpenSSL").error(
  167 + 58 "path validation failure at depth(%d): %s",
  168 + 59 X509_STORE_CTX_get_error_depth(ctx),
  169 + 60 X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx))
  170 + 61 );
  171 + 62 }
  172 + 63 return ok;
  173 + 64 }
  174 +*/
  175 + return ok;
  176 +}
157 177
158 static int background_ssl_negotiation(H3270 *hSession, void *message) 178 static int background_ssl_negotiation(H3270 *hSession, void *message)
159 { 179 {
@@ -234,7 +254,21 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) @@ -234,7 +254,21 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
234 254
235 hSession->cbk.set_peer_certificate(peer); 255 hSession->cbk.set_peer_certificate(peer);
236 256
237 -#if !defined(SSL_DEFAULT_CRL_URL) && defined(SSL_ENABLE_CRL_CHECK) 257 +#ifdef SSL_CRL_URL
  258 +
  259 + // Load CRL from pre-defined URL
  260 + if(lib3270_crl_new_from_url(hSession, message, SSL_CRL_URL))
  261 + return EACCES;
  262 +
  263 +#endif // SSL_CRL_URL
  264 +
  265 + }
  266 +
  267 + /*
  268 + if(peer)
  269 + {
  270 +
  271 +#if !defined(SSL_CRL_URL) && defined(SSL_ENABLE_CRL_CHECK)
238 // 272 //
239 // No default CRL, try to download from the peer 273 // No default CRL, try to download from the peer
240 // 274 //
@@ -274,17 +308,60 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) @@ -274,17 +308,60 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
274 // No CRL download, use the standard verification. 308 // No CRL download, use the standard verification.
275 rv = SSL_get_verify_result(hSession->ssl.con); 309 rv = SSL_get_verify_result(hSession->ssl.con);
276 310
277 -#endif // !SSL_DEFAULT_CRL_URL && SSL_ENABLE_CRL_CHECK 311 +#endif // !SSL_CRL_URL && SSL_ENABLE_CRL_CHECK
278 312
279 } 313 }
280 else 314 else
281 { 315 {
282 rv = SSL_get_verify_result(hSession->ssl.con); 316 rv = SSL_get_verify_result(hSession->ssl.con);
283 } 317 }
  318 + */
  319 +
  320 + if(SSL_get_verify_result(hSession->ssl.con) == X509_V_ERR_UNABLE_TO_GET_CRL && hSession->ssl.crl.cert)
  321 + {
  322 + // Verify CRL
  323 + //
  324 + // References:
  325 + //
  326 + // http://www.zedwood.com/article/cpp-check-crl-for-revocation
  327 + //
284 328
  329 + trace_ssl(hSession,"Doing CRL check using %s\n",hSession->ssl.crl.url);
285 330
286 - // Validate certificate. 331 + // Got CRL, verify it!
  332 + // Reference: https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session
  333 + X509_STORE_CTX *csc = X509_STORE_CTX_new();
  334 + X509_STORE_CTX_set_verify_cb(csc, x509_store_ctx_error_callback);
  335 + X509_STORE_CTX_init(csc, SSL_CTX_get_cert_store(ssl_ctx), peer, NULL);
  336 +
  337 +/*
  338 +#ifdef SSL_ENABLE_CRL_CHECK
  339 + // Enable CRL check
  340 + X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
  341 + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
  342 + X509_STORE_CTX_set0_param(csc, param);
  343 +#endif // SSL_ENABLE_CRL_CHECK
  344 +*/
  345 +
  346 + if(X509_verify_cert(csc) != 1)
  347 + rv = X509_STORE_CTX_get_error(csc);
  348 + else
  349 + rv = X509_V_OK;
  350 +
  351 + debug("CRL Check response was %d", rv);
  352 +
  353 + SSL_set_verify_result(hSession->ssl.con, rv);
  354 +
  355 + X509_STORE_CTX_free(csc);
287 356
  357 +#ifdef SSL_ENABLE_CRL_CHECK
  358 +// X509_VERIFY_PARAM_free(param);
  359 +#endif // SSL_ENABLE_CRL_CHECK
  360 +
  361 + }
  362 +
  363 + // Check validation state.
  364 + rv = SSL_get_verify_result(hSession->ssl.con);
288 debug("SSL Verify result was %d", rv); 365 debug("SSL Verify result was %d", rv);
289 const struct ssl_status_msg * msg = ssl_get_status_from_error_code((long) rv); 366 const struct ssl_status_msg * msg = ssl_get_status_from_error_code((long) rv);
290 367
@@ -526,45 +603,3 @@ void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) @@ -526,45 +603,3 @@ void ssl_info_callback(INFO_CONST SSL *s, int where, int ret)
526 603
527 #endif /*]*/ 604 #endif /*]*/
528 605
529 -int popup_ssl_error(H3270 GNUC_UNUSED(*hSession), int rc, const char GNUC_UNUSED(*title), const char *summary, const char *body)  
530 -{  
531 -#ifdef _WIN32  
532 -  
533 - lib3270_autoptr(char) rcMessage = lib3270_strdup_printf("The error code was %d",rc);  
534 -  
535 - const char *outMsg[] = {  
536 - title,  
537 - summary,  
538 - (body ? body : ""),  
539 - rcMessage  
540 - };  
541 -  
542 - ReportEvent(  
543 - hEventLog,  
544 - EVENTLOG_ERROR_TYPE,  
545 - 1,  
546 - 0,  
547 - NULL,  
548 - (sizeof(outMsg)/sizeof(outMsg[0])),  
549 - 0,  
550 - outMsg,  
551 - NULL  
552 - );  
553 -  
554 -#else  
555 -  
556 - lib3270_write_log(hSession, "SSL", "%s %s (rc=%d)", summary, (body ? body : ""), rc);  
557 -  
558 -#endif // _WIN32  
559 -  
560 -#ifdef SSL_ENABLE_NOTIFICATION_WHEN_FAILED  
561 -  
562 - return hSession->cbk.popup_ssl_error(hSession,rc,title,summary,body);  
563 -  
564 -#else  
565 -  
566 - return 0;  
567 -  
568 -#endif // SSL_ENABLE_NOTIFICATION_WHEN_FAILED  
569 -  
570 -}  
src/ssl/notify.c 0 → 100644
@@ -0,0 +1,132 @@ @@ -0,0 +1,132 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + *
  29 + * References:
  30 + *
  31 + * http://www.openssl.org/docs/ssl/
  32 + *
  33 + */
  34 +
  35 +
  36 +#include <config.h>
  37 +#include <lib3270-internals.h>
  38 +#include <lib3270/log.h>
  39 +
  40 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  41 +
  42 +#if defined(HAVE_LIBSSL)
  43 +
  44 +#include <openssl/err.h>
  45 +
  46 +int popup_ssl_error(H3270 GNUC_UNUSED(*hSession), int rc, const char GNUC_UNUSED(*title), const char *summary, const char *body)
  47 +{
  48 +#ifdef _WIN32
  49 +
  50 + lib3270_autoptr(char) rcMessage = lib3270_strdup_printf("The error code was %d",rc);
  51 +
  52 + const char *outMsg[] = {
  53 + title,
  54 + summary,
  55 + (body ? body : ""),
  56 + rcMessage
  57 + };
  58 +
  59 + ReportEvent(
  60 + hEventLog,
  61 + EVENTLOG_ERROR_TYPE,
  62 + 1,
  63 + 0,
  64 + NULL,
  65 + (sizeof(outMsg)/sizeof(outMsg[0])),
  66 + 0,
  67 + outMsg,
  68 + NULL
  69 + );
  70 +
  71 +#else
  72 +
  73 + lib3270_write_log(hSession, "SSL", "%s %s (rc=%d)", summary, (body ? body : ""), rc);
  74 +
  75 +#endif // _WIN32
  76 +
  77 +#ifdef SSL_ENABLE_NOTIFICATION_WHEN_FAILED
  78 +
  79 + return hSession->cbk.popup_ssl_error(hSession,rc,title,summary,body);
  80 +
  81 +#else
  82 +
  83 + return 0;
  84 +
  85 +#endif // SSL_ENABLE_NOTIFICATION_WHEN_FAILED
  86 +}
  87 +
  88 +int notify_ssl_error(H3270 *hSession, int rc, const SSL_ERROR_MESSAGE *message)
  89 +{
  90 + lib3270_write_log(
  91 + hSession,
  92 + "SSL-CRL-GET",
  93 + "CRL GET error: %s (rc=%d ssl_error=%d)",
  94 + message->title,
  95 + rc,
  96 + message->error
  97 + );
  98 +
  99 + if(message->description)
  100 + {
  101 + if(popup_ssl_error(hSession,rc,message->title,message->text,message->description))
  102 + return rc;
  103 + }
  104 +#ifdef _WIN32
  105 + else if(message->lasterror)
  106 + {
  107 + lib3270_autoptr(char) windows_error = lib3270_win32_translate_error_code(message->lasterror);
  108 + lib3270_autoptr(char) formatted_error = lib3270_strdup_printf(_( "Windows error was \"%s\" (%u)" ), windows_error,(unsigned int) message->lasterror);
  109 +
  110 + if(popup_ssl_error(hSession,rc,message->title,message->text,formatted_error))
  111 + return rc;
  112 +
  113 + }
  114 +#endif // WIN32
  115 + else if(message->error)
  116 + {
  117 + lib3270_autoptr(char) formatted_error = lib3270_strdup_printf(_( "%s (SSL error %d)" ),ERR_reason_error_string(message->error),message->error);
  118 + lib3270_write_log(hSession,"SSL-CRL-GET","%s",formatted_error);
  119 +
  120 + if(popup_ssl_error(hSession,rc,message->title,message->text,formatted_error))
  121 + return rc;
  122 + }
  123 + else
  124 + {
  125 + if(popup_ssl_error(hSession,rc,message->title,message->text,""))
  126 + return rc;
  127 + }
  128 +
  129 + return 0;
  130 +}
  131 +
  132 +#endif // defined(HAVE_LIBSSL)
src/ssl/properties.c
@@ -124,11 +124,11 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio @@ -124,11 +124,11 @@ LIB3270_EXPORT char * lib3270_get_ssl_peer_certificate_text(const H3270 *hSessio
124 if(hSession->ssl.crl.url) 124 if(hSession->ssl.crl.url)
125 return hSession->ssl.crl.url; 125 return hSession->ssl.crl.url;
126 126
127 -#ifdef SSL_DEFAULT_CRL_URL  
128 - return SSL_DEFAULT_CRL_URL; 127 +#ifdef SSL_CRL_URL
  128 + return SSL_CRL_URL;
129 #else 129 #else
130 return getenv("LIB3270_DEFAULT_CRL"); 130 return getenv("LIB3270_DEFAULT_CRL");
131 -#endif // SSL_DEFAULT_CRL_URL 131 +#endif // SSL_CRL_URL
132 132
133 #else 133 #else
134 errno = ENOTSUP; 134 errno = ENOTSUP;