Commit 588c35e6cce553b1b7d613d82155dc4ee30e6db9

Authored by Perry Werneck
1 parent 4df3e30a

Reorganizing CRL download method.

@@ -34,6 +34,7 @@ @@ -34,6 +34,7 @@
34 #include <lib3270/trace.h> 34 #include <lib3270/trace.h>
35 #include <lib3270/toggle.h> 35 #include <lib3270/toggle.h>
36 #include <trace_dsc.h> 36 #include <trace_dsc.h>
  37 +#include <array.h>
37 38
38 #include "crl.h" 39 #include "crl.h"
39 40
@@ -141,4 +142,126 @@ int lib3270_crl_new_from_url(H3270 *hSession, void *ssl_error, const char *url) @@ -141,4 +142,126 @@ int lib3270_crl_new_from_url(H3270 *hSession, void *ssl_error, const char *url)
141 142
142 } 143 }
143 144
  145 +/// @brief Load CRL from X509 certificate.
  146 +int lib3270_crl_new_from_x509(H3270 *hSession, void *ssl_error, X509 *cert)
  147 +{
  148 + // References:
  149 + //
  150 + // http://www.zedwood.com/article/cpp-check-crl-for-revocation
  151 + //
  152 + lib3270_autoptr(CRL_DIST_POINTS) dist_points = (CRL_DIST_POINTS *) X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL);
  153 +
  154 + if(!dist_points)
  155 + {
  156 + ((SSL_ERROR_MESSAGE *) ssl_error)->title = _( "Security error" );
  157 + ((SSL_ERROR_MESSAGE *) ssl_error)->text = _( "Can't verify." );
  158 + ((SSL_ERROR_MESSAGE *) ssl_error)->description = _( "The host certificate doesn't have CRL distribution points" );
  159 + return EACCES;
  160 + }
  161 +
  162 + if(lib3270_crl_new_from_dist_points(hSession, ssl_error, dist_points))
  163 + return EACCES;
  164 +
  165 + return 0;
  166 +}
  167 +
  168 +int lib3270_crl_new_from_dist_points(H3270 *hSession, void *ssl_error, CRL_DIST_POINTS * dist_points)
  169 +{
  170 + //
  171 + // Reference:
  172 + //
  173 + // https://nougat.cablelabs.com/DLNA-RUI/openssl/commit/57912ed329f870b237f2fd9f2de8dec3477d1729
  174 + //
  175 + size_t ix;
  176 + int i, gtype;
  177 +
  178 + lib3270_autoptr(LIB3270_STRING_ARRAY) uris = lib3270_string_array_new();
  179 +
  180 + for(ix = 0; ix < (size_t) sk_DIST_POINT_num(dist_points); ix++) {
  181 +
  182 + DIST_POINT *dp = sk_DIST_POINT_value(dist_points, ix);
  183 +
  184 + if(!dp->distpoint || dp->distpoint->type != 0)
  185 + continue;
  186 +
  187 + GENERAL_NAMES *gens = dp->distpoint->name.fullname;
  188 +
  189 + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
  190 + {
  191 + GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);
  192 + ASN1_STRING *uri = GENERAL_NAME_get0_value(gen, &gtype);
  193 + if(uri)
  194 + {
  195 +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) // OpenSSL 1.1.0+
  196 + const unsigned char * data = ASN1_STRING_get0_data(uri);
  197 +#else
  198 + const unsigned char * data = ASN1_STRING_data(uri); // ASN1_STRING_get0_data(uri);
  199 +#endif // OpenSSL 1.1.0+
  200 + if(data)
  201 + {
  202 + lib3270_string_array_append(uris,(char *) data);
  203 + }
  204 + }
  205 +
  206 + }
  207 +
  208 + }
  209 +
  210 +#ifdef DEBUG
  211 + {
  212 + for(ix = 0; ix < uris->length; ix++)
  213 + {
  214 + debug("%u: %s", (unsigned int) ix, uris->str[ix]);
  215 + }
  216 + }
  217 +#endif // DEBUG
  218 +
  219 + if(hSession->ssl.crl.url)
  220 + {
  221 + // Check if the current URL is still valid.
  222 + for(ix = 0; ix < uris->length; ix++)
  223 + {
  224 + if(!strcmp(hSession->ssl.crl.url,uris->str[ix]))
  225 + {
  226 + trace_ssl(hSession,"Keeping CRL from %s\n",hSession->ssl.crl.url);
  227 + return 0;
  228 + }
  229 + }
  230 +
  231 + trace_ssl(hSession,"Discarding invalid CRL from %s\n",hSession->ssl.crl.url);
  232 +
  233 + // The URL is invalid or not to this cert, remove it!
  234 + lib3270_free(hSession->ssl.crl.url);
  235 + hSession->ssl.crl.url = NULL;
  236 + }
  237 +
  238 + if(hSession->ssl.crl.prefer && *hSession->ssl.crl.prefer)
  239 + {
  240 + size_t length = strlen(hSession->ssl.crl.prefer);
  241 +
  242 + for(ix = 0; ix < uris->length; ix++)
  243 + {
  244 + if(!strncmp(uris->str[ix],hSession->ssl.crl.prefer,length))
  245 + {
  246 + trace_ssl(hSession,"Trying preferred URL %s\n",uris->str[ix]);
  247 + if(lib3270_crl_new_from_url(hSession, ssl_error, uris->str[ix]) == 0)
  248 + return 0;
  249 + }
  250 +
  251 + }
  252 +
  253 + }
  254 +
  255 + // Can't load, try all of them.
  256 + for(ix = 0; ix < uris->length; ix++)
  257 + {
  258 + trace_ssl(hSession,"Trying CRL from %s\n",uris->str[ix]);
  259 + if(lib3270_crl_new_from_url(hSession, ssl_error, uris->str[ix]) == 0)
  260 + return 0;
  261 + }
  262 +
  263 + return -1;
  264 +
  265 +}
  266 +
144 #endif // SSL_ENABLE_CRL_CHECK && HAVE_LIBSSL 267 #endif // SSL_ENABLE_CRL_CHECK && HAVE_LIBSSL
@@ -49,10 +49,32 @@ @@ -49,10 +49,32 @@
49 /// @brief Load CRL from URL. 49 /// @brief Load CRL from URL.
50 LIB3270_INTERNAL int lib3270_crl_new_from_url(H3270 *hSession, void *ssl_error, const char *url); 50 LIB3270_INTERNAL int lib3270_crl_new_from_url(H3270 *hSession, void *ssl_error, const char *url);
51 51
  52 + /// @brief Load CRL from X509 certificate.
  53 + LIB3270_INTERNAL int lib3270_crl_new_from_x509(H3270 *hSession, void *ssl_error, X509 *cert);
  54 +
  55 + /// @brief Load CRL from distribution points.
  56 + LIB3270_INTERNAL int lib3270_crl_new_from_dist_points(H3270 *hSession, void *ssl_error, CRL_DIST_POINTS * dist_points);
52 57
53 LIB3270_INTERNAL X509_CRL * lib3270_download_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *url); 58 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); 59 +
  60 + /**
  61 + * @brief X509 auto-cleanup.
  62 + */
  63 + static inline void lib3270_autoptr_cleanup_X509(X509 **ptr)
  64 + {
  65 + if(*ptr)
  66 + X509_free(*ptr);
  67 + }
  68 +
  69 + /**
  70 + * @brief Dist points auto-cleanup.
  71 + */
  72 + static inline void lib3270_autoptr_cleanup_CRL_DIST_POINTS(CRL_DIST_POINTS **ptr)
  73 + {
  74 + if(*ptr)
  75 + CRL_DIST_POINTS_free(*ptr);
  76 + }
  77 +
56 78
57 #endif // SSL_ENABLE_CRL_CHECK && HAVE_LIBSSL 79 #endif // SSL_ENABLE_CRL_CHECK && HAVE_LIBSSL
58 80
src/ssl/negotiate.c
@@ -42,7 +42,6 @@ @@ -42,7 +42,6 @@
42 #include <openssl/err.h> 42 #include <openssl/err.h>
43 #include <openssl/x509_vfy.h> 43 #include <openssl/x509_vfy.h>
44 #include <openssl/x509v3.h> 44 #include <openssl/x509v3.h>
45 - #include <array.h>  
46 45
47 #ifndef SSL_ST_OK 46 #ifndef SSL_ST_OK
48 #define SSL_ST_OK 3 47 #define SSL_ST_OK 3
@@ -77,24 +76,6 @@ @@ -77,24 +76,6 @@
77 */ 76 */
78 SSL_CTX * ssl_ctx = NULL; 77 SSL_CTX * ssl_ctx = NULL;
79 78
80 - /**  
81 - * @brief X509 auto-cleanup.  
82 - */  
83 -static inline void lib3270_autoptr_cleanup_X509(X509 **ptr)  
84 -{  
85 - if(*ptr)  
86 - X509_free(*ptr);  
87 -}  
88 -  
89 - /**  
90 - * @brief Dist points auto-cleanup.  
91 - */  
92 -static inline void lib3270_autoptr_cleanup_CRL_DIST_POINTS(CRL_DIST_POINTS **ptr)  
93 -{  
94 - if(*ptr)  
95 - CRL_DIST_POINTS_free(*ptr);  
96 -}  
97 -  
98 /** 79 /**
99 * @brief Initialize openssl session. 80 * @brief Initialize openssl session.
100 * 81 *
@@ -135,7 +116,7 @@ static int background_ssl_init(H3270 *hSession, void *message) @@ -135,7 +116,7 @@ static int background_ssl_init(H3270 *hSession, void *message)
135 return 0; 116 return 0;
136 } 117 }
137 118
138 -#if !defined(SSL_CRL_URL) && defined(SSL_ENABLE_CRL_CHECK) 119 +#if defined(SSL_ENABLE_CRL_CHECK)
139 int x509_store_ctx_error_callback(int ok, X509_STORE_CTX GNUC_UNUSED(*ctx)) 120 int x509_store_ctx_error_callback(int ok, X509_STORE_CTX GNUC_UNUSED(*ctx))
140 { 121 {
141 debug("%s(%d)",__FUNCTION__,ok); 122 debug("%s(%d)",__FUNCTION__,ok);
@@ -154,26 +135,7 @@ int x509_store_ctx_error_callback(int ok, X509_STORE_CTX GNUC_UNUSED(*ctx)) @@ -154,26 +135,7 @@ int x509_store_ctx_error_callback(int ok, X509_STORE_CTX GNUC_UNUSED(*ctx))
154 */ 135 */
155 return ok; 136 return ok;
156 } 137 }
157 -#endif // !SSL_CRL_URL && SSL_ENABLE_CRL_CHECK  
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 -} 138 +#endif // SSL_ENABLE_CRL_CHECK
177 139
178 static int background_ssl_negotiation(H3270 *hSession, void *message) 140 static int background_ssl_negotiation(H3270 *hSession, void *message)
179 { 141 {
@@ -199,6 +161,14 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) @@ -199,6 +161,14 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
199 return -1; 161 return -1;
200 } 162 }
201 163
  164 +#ifdef SSL_CRL_URL
  165 +
  166 + // Load CRL from pre-defined URL
  167 + if(lib3270_crl_new_from_url(hSession, message, SSL_CRL_URL))
  168 + return EACCES;
  169 +
  170 +#endif // SSL_CRL_URL
  171 +
202 trace_ssl(hSession, "%s","Running SSL_connect\n"); 172 trace_ssl(hSession, "%s","Running SSL_connect\n");
203 rv = SSL_connect(hSession->ssl.con); 173 rv = SSL_connect(hSession->ssl.con);
204 trace_ssl(hSession, "SSL_connect exits with rc=%d\n",rv); 174 trace_ssl(hSession, "SSL_connect exits with rc=%d\n",rv);
@@ -254,13 +224,15 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) @@ -254,13 +224,15 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
254 224
255 hSession->cbk.set_peer_certificate(peer); 225 hSession->cbk.set_peer_certificate(peer);
256 226
257 -#ifdef SSL_CRL_URL 227 +#ifdef SSL_ENABLE_CRL_CHECK
258 228
259 - // Load CRL from pre-defined URL  
260 - if(lib3270_crl_new_from_url(hSession, message, SSL_CRL_URL))  
261 - return EACCES; 229 + if(!hSession->ssl.crl.cert)
  230 + {
  231 + if(lib3270_crl_new_from_x509(hSession, message, peer))
  232 + return EACCES;
  233 + }
262 234
263 -#endif // SSL_CRL_URL 235 +#endif // SSL_ENABLE_CRL_CHECK
264 236
265 } 237 }
266 238
@@ -272,10 +244,6 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) @@ -272,10 +244,6 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
272 // 244 //
273 // No default CRL, try to download from the peer 245 // No default CRL, try to download from the peer
274 // 246 //
275 - // References:  
276 - //  
277 - // http://www.zedwood.com/article/cpp-check-crl-for-revocation  
278 - //  
279 247
280 lib3270_autoptr(CRL_DIST_POINTS) dist_points = (CRL_DIST_POINTS *) X509_get_ext_d2i(peer, NID_crl_distribution_points, NULL, NULL); 248 lib3270_autoptr(CRL_DIST_POINTS) dist_points = (CRL_DIST_POINTS *) X509_get_ext_d2i(peer, NID_crl_distribution_points, NULL, NULL);
281 if(!dist_points) 249 if(!dist_points)
@@ -317,8 +285,9 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) @@ -317,8 +285,9 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
317 } 285 }
318 */ 286 */
319 287
320 - if(SSL_get_verify_result(hSession->ssl.con) == X509_V_ERR_UNABLE_TO_GET_CRL && hSession->ssl.crl.cert) 288 + if(SSL_get_verify_result(hSession->ssl.con) == X509_V_ERR_UNABLE_TO_GET_CRL && hSession->ssl.crl.cert && peer)
321 { 289 {
  290 + //
322 // Verify CRL 291 // Verify CRL
323 // 292 //
324 // References: 293 // References:
@@ -334,30 +303,17 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) @@ -334,30 +303,17 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
334 X509_STORE_CTX_set_verify_cb(csc, x509_store_ctx_error_callback); 303 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); 304 X509_STORE_CTX_init(csc, SSL_CTX_get_cert_store(ssl_ctx), peer, NULL);
336 305
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) 306 if(X509_verify_cert(csc) != 1)
347 rv = X509_STORE_CTX_get_error(csc); 307 rv = X509_STORE_CTX_get_error(csc);
348 else 308 else
349 rv = X509_V_OK; 309 rv = X509_V_OK;
350 310
351 - debug("CRL Check response was %d", rv); 311 + trace_ssl(hSession, "X509_verify_cert error code was %d", rv);
352 312
353 SSL_set_verify_result(hSession->ssl.con, rv); 313 SSL_set_verify_result(hSession->ssl.con, rv);
354 314
355 X509_STORE_CTX_free(csc); 315 X509_STORE_CTX_free(csc);
356 316
357 -#ifdef SSL_ENABLE_CRL_CHECK  
358 -// X509_VERIFY_PARAM_free(param);  
359 -#endif // SSL_ENABLE_CRL_CHECK  
360 -  
361 } 317 }
362 318
363 // Check validation state. 319 // Check validation state.
@@ -393,14 +349,14 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) @@ -393,14 +349,14 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
393 349
394 set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED); 350 set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED);
395 351
396 - #ifdef SSL_ENABLE_SELF_SIGNED_CERT_CHECK 352 +#ifdef SSL_ENABLE_SELF_SIGNED_CERT_CHECK
397 ((SSL_ERROR_MESSAGE *) message)->title = _( "Security error" ); 353 ((SSL_ERROR_MESSAGE *) message)->title = _( "Security error" );
398 ((SSL_ERROR_MESSAGE *) message)->text = _( "The SSL certificate for this host is not trusted." ); 354 ((SSL_ERROR_MESSAGE *) message)->text = _( "The SSL certificate for this host is not trusted." );
399 ((SSL_ERROR_MESSAGE *) message)->description = _( "The security certificate presented by this host was not issued by a trusted certificate authority." ); 355 ((SSL_ERROR_MESSAGE *) message)->description = _( "The security certificate presented by this host was not issued by a trusted certificate authority." );
400 return EACCES; 356 return EACCES;
401 - #else 357 +#else
402 break; 358 break;
403 - #endif // SSL_ENABLE_SELF_SIGNED_CERT_CHECK 359 +#endif // SSL_ENABLE_SELF_SIGNED_CERT_CHECK
404 360
405 default: 361 default:
406 trace_ssl(hSession,"TLS/SSL verify result was %d (%s)\n", rv, msg->description); 362 trace_ssl(hSession,"TLS/SSL verify result was %d (%s)\n", rv, msg->description);