Fossil SCM
Fix the client-side SSL connection setup so that it actually verifies the hostname on the certification from the server.
Commit
aaab2a15d1dfc22f5453c2bad8f25ecf518ed3eef9a7fa6f4c5bd69ab4e4b075
Parent
a9917d4fc7da32d…
1 file changed
+14
-3
+14
-3
| --- src/http_ssl.c | ||
| +++ src/http_ssl.c | ||
| @@ -252,10 +252,11 @@ | ||
| 252 | 252 | ** |
| 253 | 253 | ** Return the number of errors. |
| 254 | 254 | */ |
| 255 | 255 | int ssl_open(UrlData *pUrlData){ |
| 256 | 256 | X509 *cert; |
| 257 | + const char *zRemoteHost; | |
| 257 | 258 | |
| 258 | 259 | ssl_global_init(); |
| 259 | 260 | if( pUrlData->useProxy ){ |
| 260 | 261 | int rc; |
| 261 | 262 | char *connStr = mprintf("%s:%d", g.url.name, pUrlData->port); |
| @@ -276,30 +277,40 @@ | ||
| 276 | 277 | |
| 277 | 278 | pUrlData->path = pUrlData->proxyUrlPath; |
| 278 | 279 | |
| 279 | 280 | iBio = BIO_new_ssl(sslCtx, 1); |
| 280 | 281 | BIO_push(iBio, sBio); |
| 282 | + zRemoteHost = pUrlData->hostname; | |
| 281 | 283 | }else{ |
| 282 | 284 | iBio = BIO_new_ssl_connect(sslCtx); |
| 285 | + zRemoteHost = pUrlData->name; | |
| 283 | 286 | } |
| 284 | 287 | if( iBio==NULL ) { |
| 285 | 288 | ssl_set_errmsg("SSL: cannot open SSL (%s)", |
| 286 | 289 | ERR_reason_error_string(ERR_get_error())); |
| 287 | 290 | return 1; |
| 288 | 291 | } |
| 289 | 292 | BIO_get_ssl(iBio, &ssl); |
| 290 | 293 | |
| 291 | 294 | #if (SSLEAY_VERSION_NUMBER >= 0x00908070) && !defined(OPENSSL_NO_TLSEXT) |
| 292 | - if( !SSL_set_tlsext_host_name(ssl, | |
| 293 | - (pUrlData->useProxy?pUrlData->hostname:pUrlData->name)) | |
| 294 | - ){ | |
| 295 | + if( !SSL_set_tlsext_host_name(ssl, zRemoteHost)){ | |
| 295 | 296 | fossil_warning("WARNING: failed to set server name indication (SNI), " |
| 296 | 297 | "continuing without it.\n"); |
| 297 | 298 | } |
| 298 | 299 | #endif |
| 299 | 300 | |
| 300 | 301 | SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); |
| 302 | +#if OPENSSL_VERSION_NUMBER >= 0x010002000 | |
| 303 | + if( !sslNoCertVerify ){ | |
| 304 | + X509_VERIFY_PARAM *param = 0; | |
| 305 | + param = SSL_get0_param(ssl); | |
| 306 | + if( !X509_VERIFY_PARAM_set1_host(param, zRemoteHost, strlen(zRemoteHost)) ){ | |
| 307 | + fossil_fatal("failed to set hostname."); | |
| 308 | + } | |
| 309 | + /* SSL_set_verify(ssl, SSL_VERIFY_PEER, 0); */ | |
| 310 | + } | |
| 311 | +#endif | |
| 301 | 312 | |
| 302 | 313 | if( !pUrlData->useProxy ){ |
| 303 | 314 | char *connStr = mprintf("%s:%d", pUrlData->name, pUrlData->port); |
| 304 | 315 | BIO_set_conn_hostname(iBio, connStr); |
| 305 | 316 | free(connStr); |
| 306 | 317 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -252,10 +252,11 @@ | |
| 252 | ** |
| 253 | ** Return the number of errors. |
| 254 | */ |
| 255 | int ssl_open(UrlData *pUrlData){ |
| 256 | X509 *cert; |
| 257 | |
| 258 | ssl_global_init(); |
| 259 | if( pUrlData->useProxy ){ |
| 260 | int rc; |
| 261 | char *connStr = mprintf("%s:%d", g.url.name, pUrlData->port); |
| @@ -276,30 +277,40 @@ | |
| 276 | |
| 277 | pUrlData->path = pUrlData->proxyUrlPath; |
| 278 | |
| 279 | iBio = BIO_new_ssl(sslCtx, 1); |
| 280 | BIO_push(iBio, sBio); |
| 281 | }else{ |
| 282 | iBio = BIO_new_ssl_connect(sslCtx); |
| 283 | } |
| 284 | if( iBio==NULL ) { |
| 285 | ssl_set_errmsg("SSL: cannot open SSL (%s)", |
| 286 | ERR_reason_error_string(ERR_get_error())); |
| 287 | return 1; |
| 288 | } |
| 289 | BIO_get_ssl(iBio, &ssl); |
| 290 | |
| 291 | #if (SSLEAY_VERSION_NUMBER >= 0x00908070) && !defined(OPENSSL_NO_TLSEXT) |
| 292 | if( !SSL_set_tlsext_host_name(ssl, |
| 293 | (pUrlData->useProxy?pUrlData->hostname:pUrlData->name)) |
| 294 | ){ |
| 295 | fossil_warning("WARNING: failed to set server name indication (SNI), " |
| 296 | "continuing without it.\n"); |
| 297 | } |
| 298 | #endif |
| 299 | |
| 300 | SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); |
| 301 | |
| 302 | if( !pUrlData->useProxy ){ |
| 303 | char *connStr = mprintf("%s:%d", pUrlData->name, pUrlData->port); |
| 304 | BIO_set_conn_hostname(iBio, connStr); |
| 305 | free(connStr); |
| 306 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -252,10 +252,11 @@ | |
| 252 | ** |
| 253 | ** Return the number of errors. |
| 254 | */ |
| 255 | int ssl_open(UrlData *pUrlData){ |
| 256 | X509 *cert; |
| 257 | const char *zRemoteHost; |
| 258 | |
| 259 | ssl_global_init(); |
| 260 | if( pUrlData->useProxy ){ |
| 261 | int rc; |
| 262 | char *connStr = mprintf("%s:%d", g.url.name, pUrlData->port); |
| @@ -276,30 +277,40 @@ | |
| 277 | |
| 278 | pUrlData->path = pUrlData->proxyUrlPath; |
| 279 | |
| 280 | iBio = BIO_new_ssl(sslCtx, 1); |
| 281 | BIO_push(iBio, sBio); |
| 282 | zRemoteHost = pUrlData->hostname; |
| 283 | }else{ |
| 284 | iBio = BIO_new_ssl_connect(sslCtx); |
| 285 | zRemoteHost = pUrlData->name; |
| 286 | } |
| 287 | if( iBio==NULL ) { |
| 288 | ssl_set_errmsg("SSL: cannot open SSL (%s)", |
| 289 | ERR_reason_error_string(ERR_get_error())); |
| 290 | return 1; |
| 291 | } |
| 292 | BIO_get_ssl(iBio, &ssl); |
| 293 | |
| 294 | #if (SSLEAY_VERSION_NUMBER >= 0x00908070) && !defined(OPENSSL_NO_TLSEXT) |
| 295 | if( !SSL_set_tlsext_host_name(ssl, zRemoteHost)){ |
| 296 | fossil_warning("WARNING: failed to set server name indication (SNI), " |
| 297 | "continuing without it.\n"); |
| 298 | } |
| 299 | #endif |
| 300 | |
| 301 | SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); |
| 302 | #if OPENSSL_VERSION_NUMBER >= 0x010002000 |
| 303 | if( !sslNoCertVerify ){ |
| 304 | X509_VERIFY_PARAM *param = 0; |
| 305 | param = SSL_get0_param(ssl); |
| 306 | if( !X509_VERIFY_PARAM_set1_host(param, zRemoteHost, strlen(zRemoteHost)) ){ |
| 307 | fossil_fatal("failed to set hostname."); |
| 308 | } |
| 309 | /* SSL_set_verify(ssl, SSL_VERIFY_PEER, 0); */ |
| 310 | } |
| 311 | #endif |
| 312 | |
| 313 | if( !pUrlData->useProxy ){ |
| 314 | char *connStr = mprintf("%s:%d", pUrlData->name, pUrlData->port); |
| 315 | BIO_set_conn_hostname(iBio, connStr); |
| 316 | free(connStr); |
| 317 |