Commit 588c35e6cce553b1b7d613d82155dc4ee30e6db9

Authored by Perry Werneck
1 parent 4df3e30a

Reorganizing CRL download method.

src/ssl/crl.c
... ... @@ -34,6 +34,7 @@
34 34 #include <lib3270/trace.h>
35 35 #include <lib3270/toggle.h>
36 36 #include <trace_dsc.h>
  37 +#include <array.h>
37 38  
38 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 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 267 #endif // SSL_ENABLE_CRL_CHECK && HAVE_LIBSSL
... ...
src/ssl/crl.h
... ... @@ -49,10 +49,32 @@
49 49 /// @brief Load CRL from URL.
50 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 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 79 #endif // SSL_ENABLE_CRL_CHECK && HAVE_LIBSSL
58 80  
... ...
src/ssl/negotiate.c
... ... @@ -42,7 +42,6 @@
42 42 #include <openssl/err.h>
43 43 #include <openssl/x509_vfy.h>
44 44 #include <openssl/x509v3.h>
45   - #include <array.h>
46 45  
47 46 #ifndef SSL_ST_OK
48 47 #define SSL_ST_OK 3
... ... @@ -77,24 +76,6 @@
77 76 */
78 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 80 * @brief Initialize openssl session.
100 81 *
... ... @@ -135,7 +116,7 @@ static int background_ssl_init(H3270 *hSession, void *message)
135 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 120 int x509_store_ctx_error_callback(int ok, X509_STORE_CTX GNUC_UNUSED(*ctx))
140 121 {
141 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 135 */
155 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 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 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 172 trace_ssl(hSession, "%s","Running SSL_connect\n");
203 173 rv = SSL_connect(hSession->ssl.con);
204 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 224  
255 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 244 //
273 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 248 lib3270_autoptr(CRL_DIST_POINTS) dist_points = (CRL_DIST_POINTS *) X509_get_ext_d2i(peer, NID_crl_distribution_points, NULL, NULL);
281 249 if(!dist_points)
... ... @@ -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 291 // Verify CRL
323 292 //
324 293 // References:
... ... @@ -334,30 +303,17 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
334 303 X509_STORE_CTX_set_verify_cb(csc, x509_store_ctx_error_callback);
335 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 306 if(X509_verify_cert(csc) != 1)
347 307 rv = X509_STORE_CTX_get_error(csc);
348 308 else
349 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 313 SSL_set_verify_result(hSession->ssl.con, rv);
354 314  
355 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 319 // Check validation state.
... ... @@ -393,14 +349,14 @@ static int background_ssl_negotiation(H3270 *hSession, void *message)
393 349  
394 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 353 ((SSL_ERROR_MESSAGE *) message)->title = _( "Security error" );
398 354 ((SSL_ERROR_MESSAGE *) message)->text = _( "The SSL certificate for this host is not trusted." );
399 355 ((SSL_ERROR_MESSAGE *) message)->description = _( "The security certificate presented by this host was not issued by a trusted certificate authority." );
400 356 return EACCES;
401   - #else
  357 +#else
402 358 break;
403   - #endif // SSL_ENABLE_SELF_SIGNED_CERT_CHECK
  359 +#endif // SSL_ENABLE_SELF_SIGNED_CERT_CHECK
404 360  
405 361 default:
406 362 trace_ssl(hSession,"TLS/SSL verify result was %d (%s)\n", rv, msg->description);
... ...