Fossil SCM
Strip trailing dots on hostnames, which are valid hostnames but not accepted as TLS or certificate hostnames. from libfossil.
Commit
6362cc0666eaa536b0233be3c23990268eac9fe092e5502bc28f0dafa3dbd2ec
Parent
629d4ece0ef7f6c…
1 file changed
+20
-6
+20
-6
| --- src/http_ssl.c | ||
| +++ src/http_ssl.c | ||
| @@ -495,10 +495,12 @@ | ||
| 495 | 495 | ** Return the number of errors. |
| 496 | 496 | */ |
| 497 | 497 | int ssl_open_client(UrlData *pUrlData){ |
| 498 | 498 | X509 *cert; |
| 499 | 499 | const char *zRemoteHost; |
| 500 | + const char *zTlsName; /* zRemoteHost needed by the TLS layer */ | |
| 501 | + char zDotless[256]; /* zRemoteHost without a trailing dot */ | |
| 500 | 502 | int isIpAddr; /* True if zRemoteHost is an IP address */ |
| 501 | 503 | BIO *sBio; |
| 502 | 504 | |
| 503 | 505 | ssl_global_init_client(); |
| 504 | 506 | if( socket_open(pUrlData) ){ |
| @@ -521,15 +523,27 @@ | ||
| 521 | 523 | BIO_set_ssl(sBio, ssl, BIO_NOCLOSE); |
| 522 | 524 | BIO_set_ssl_mode(iBio, 1); |
| 523 | 525 | BIO_get_ssl(iBio, &ssl); |
| 524 | 526 | |
| 525 | 527 | zRemoteHost = ssl_server_name(pUrlData); |
| 526 | - isIpAddr = ssl_host_is_ip_address(zRemoteHost); | |
| 528 | + /* A fully qualified name may end with a dot, as in "example.com.". | |
| 529 | + ** The RFC 6066 TLS server name and all certificate names are | |
| 530 | + ** dotless */ | |
| 531 | + zTlsName = zRemoteHost; | |
| 532 | + { | |
| 533 | + size_t n = strlen(zRemoteHost); | |
| 534 | + if( n>1 && zRemoteHost[n-1]=='.' && n<sizeof(zDotless) ){ | |
| 535 | + memcpy(zDotless, zRemoteHost, n-1); | |
| 536 | + zDotless[n-1] = 0; | |
| 537 | + zTlsName = zDotless; | |
| 538 | + } | |
| 539 | + } | |
| 540 | + isIpAddr = ssl_host_is_ip_address(zTlsName); | |
| 527 | 541 | |
| 528 | 542 | #if (SSLEAY_VERSION_NUMBER >= 0x00908070) && !defined(OPENSSL_NO_TLSEXT) |
| 529 | - if( !isIpAddr && !ssl_host_is_non_ascii(zRemoteHost) | |
| 530 | - && !SSL_set_tlsext_host_name(ssl, zRemoteHost) | |
| 543 | + if( !isIpAddr && !ssl_host_is_non_ascii(zTlsName) | |
| 544 | + && !SSL_set_tlsext_host_name(ssl, zTlsName) | |
| 531 | 545 | ){ |
| 532 | 546 | fossil_warning("WARNING: failed to set server name indication (SNI), " |
| 533 | 547 | "continuing without it.\n"); |
| 534 | 548 | } |
| 535 | 549 | #endif |
| @@ -538,15 +552,15 @@ | ||
| 538 | 552 | #if OPENSSL_VERSION_NUMBER >= 0x010002000 |
| 539 | 553 | if( !sslNoCertVerify ){ |
| 540 | 554 | X509_VERIFY_PARAM *param = 0; |
| 541 | 555 | param = SSL_get0_param(ssl); |
| 542 | 556 | if( isIpAddr ){ |
| 543 | - if( !X509_VERIFY_PARAM_set1_ip_asc(param, zRemoteHost) ){ | |
| 557 | + if( !X509_VERIFY_PARAM_set1_ip_asc(param, zTlsName) ){ | |
| 544 | 558 | fossil_fatal("failed to set IP address."); |
| 545 | 559 | } |
| 546 | - }else if( !X509_VERIFY_PARAM_set1_host(param, zRemoteHost, | |
| 547 | - strlen(zRemoteHost)) ){ | |
| 560 | + }else if( !X509_VERIFY_PARAM_set1_host(param, zTlsName, | |
| 561 | + strlen(zTlsName)) ){ | |
| 548 | 562 | fossil_fatal("failed to set hostname."); |
| 549 | 563 | } |
| 550 | 564 | /* SSL_set_verify(ssl, SSL_VERIFY_PEER, 0); */ |
| 551 | 565 | } |
| 552 | 566 | #endif |
| 553 | 567 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -495,10 +495,12 @@ | |
| 495 | ** Return the number of errors. |
| 496 | */ |
| 497 | int ssl_open_client(UrlData *pUrlData){ |
| 498 | X509 *cert; |
| 499 | const char *zRemoteHost; |
| 500 | int isIpAddr; /* True if zRemoteHost is an IP address */ |
| 501 | BIO *sBio; |
| 502 | |
| 503 | ssl_global_init_client(); |
| 504 | if( socket_open(pUrlData) ){ |
| @@ -521,15 +523,27 @@ | |
| 521 | BIO_set_ssl(sBio, ssl, BIO_NOCLOSE); |
| 522 | BIO_set_ssl_mode(iBio, 1); |
| 523 | BIO_get_ssl(iBio, &ssl); |
| 524 | |
| 525 | zRemoteHost = ssl_server_name(pUrlData); |
| 526 | isIpAddr = ssl_host_is_ip_address(zRemoteHost); |
| 527 | |
| 528 | #if (SSLEAY_VERSION_NUMBER >= 0x00908070) && !defined(OPENSSL_NO_TLSEXT) |
| 529 | if( !isIpAddr && !ssl_host_is_non_ascii(zRemoteHost) |
| 530 | && !SSL_set_tlsext_host_name(ssl, zRemoteHost) |
| 531 | ){ |
| 532 | fossil_warning("WARNING: failed to set server name indication (SNI), " |
| 533 | "continuing without it.\n"); |
| 534 | } |
| 535 | #endif |
| @@ -538,15 +552,15 @@ | |
| 538 | #if OPENSSL_VERSION_NUMBER >= 0x010002000 |
| 539 | if( !sslNoCertVerify ){ |
| 540 | X509_VERIFY_PARAM *param = 0; |
| 541 | param = SSL_get0_param(ssl); |
| 542 | if( isIpAddr ){ |
| 543 | if( !X509_VERIFY_PARAM_set1_ip_asc(param, zRemoteHost) ){ |
| 544 | fossil_fatal("failed to set IP address."); |
| 545 | } |
| 546 | }else if( !X509_VERIFY_PARAM_set1_host(param, zRemoteHost, |
| 547 | strlen(zRemoteHost)) ){ |
| 548 | fossil_fatal("failed to set hostname."); |
| 549 | } |
| 550 | /* SSL_set_verify(ssl, SSL_VERIFY_PEER, 0); */ |
| 551 | } |
| 552 | #endif |
| 553 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -495,10 +495,12 @@ | |
| 495 | ** Return the number of errors. |
| 496 | */ |
| 497 | int ssl_open_client(UrlData *pUrlData){ |
| 498 | X509 *cert; |
| 499 | const char *zRemoteHost; |
| 500 | const char *zTlsName; /* zRemoteHost needed by the TLS layer */ |
| 501 | char zDotless[256]; /* zRemoteHost without a trailing dot */ |
| 502 | int isIpAddr; /* True if zRemoteHost is an IP address */ |
| 503 | BIO *sBio; |
| 504 | |
| 505 | ssl_global_init_client(); |
| 506 | if( socket_open(pUrlData) ){ |
| @@ -521,15 +523,27 @@ | |
| 523 | BIO_set_ssl(sBio, ssl, BIO_NOCLOSE); |
| 524 | BIO_set_ssl_mode(iBio, 1); |
| 525 | BIO_get_ssl(iBio, &ssl); |
| 526 | |
| 527 | zRemoteHost = ssl_server_name(pUrlData); |
| 528 | /* A fully qualified name may end with a dot, as in "example.com.". |
| 529 | ** The RFC 6066 TLS server name and all certificate names are |
| 530 | ** dotless */ |
| 531 | zTlsName = zRemoteHost; |
| 532 | { |
| 533 | size_t n = strlen(zRemoteHost); |
| 534 | if( n>1 && zRemoteHost[n-1]=='.' && n<sizeof(zDotless) ){ |
| 535 | memcpy(zDotless, zRemoteHost, n-1); |
| 536 | zDotless[n-1] = 0; |
| 537 | zTlsName = zDotless; |
| 538 | } |
| 539 | } |
| 540 | isIpAddr = ssl_host_is_ip_address(zTlsName); |
| 541 | |
| 542 | #if (SSLEAY_VERSION_NUMBER >= 0x00908070) && !defined(OPENSSL_NO_TLSEXT) |
| 543 | if( !isIpAddr && !ssl_host_is_non_ascii(zTlsName) |
| 544 | && !SSL_set_tlsext_host_name(ssl, zTlsName) |
| 545 | ){ |
| 546 | fossil_warning("WARNING: failed to set server name indication (SNI), " |
| 547 | "continuing without it.\n"); |
| 548 | } |
| 549 | #endif |
| @@ -538,15 +552,15 @@ | |
| 552 | #if OPENSSL_VERSION_NUMBER >= 0x010002000 |
| 553 | if( !sslNoCertVerify ){ |
| 554 | X509_VERIFY_PARAM *param = 0; |
| 555 | param = SSL_get0_param(ssl); |
| 556 | if( isIpAddr ){ |
| 557 | if( !X509_VERIFY_PARAM_set1_ip_asc(param, zTlsName) ){ |
| 558 | fossil_fatal("failed to set IP address."); |
| 559 | } |
| 560 | }else if( !X509_VERIFY_PARAM_set1_host(param, zTlsName, |
| 561 | strlen(zTlsName)) ){ |
| 562 | fossil_fatal("failed to set hostname."); |
| 563 | } |
| 564 | /* SSL_set_verify(ssl, SSL_VERIFY_PEER, 0); */ |
| 565 | } |
| 566 | #endif |
| 567 |