@@ -495,10 +495,12 @@ nc_client_tls_ch_del_bind(const char *address, uint16_t port)
495495}
496496
497497static int
498- nc_client_tls_update_opts (struct nc_client_tls_opts * opts )
498+ nc_client_tls_update_opts (struct nc_client_tls_opts * opts , const char * host )
499499{
500+ int rc = 0 ;
500501 char * key ;
501502 X509_LOOKUP * lookup ;
503+ X509_VERIFY_PARAM * vpm = NULL ;
502504
503505 if (!opts -> tls_ctx || opts -> tls_ctx_change ) {
504506 SSL_CTX_free (opts -> tls_ctx );
@@ -512,15 +514,17 @@ nc_client_tls_update_opts(struct nc_client_tls_opts *opts)
512514#endif
513515 {
514516 ERR (NULL , "Unable to create OpenSSL context (%s)." , ERR_reason_error_string (ERR_get_error ()));
515- return -1 ;
517+ rc = -1 ;
518+ goto cleanup ;
516519 }
517520 SSL_CTX_set_verify (opts -> tls_ctx , SSL_VERIFY_PEER , tlsauth_verify_callback );
518521
519522 /* get peer certificate */
520523 if (SSL_CTX_use_certificate_file (opts -> tls_ctx , opts -> cert_path , SSL_FILETYPE_PEM ) != 1 ) {
521524 ERR (NULL , "Loading the client certificate from \'%s\' failed (%s)." , opts -> cert_path ,
522525 ERR_reason_error_string (ERR_get_error ()));
523- return -1 ;
526+ rc = -1 ;
527+ goto cleanup ;
524528 }
525529
526530 /* if the file with private key not specified, expect that the private key is stored with the certificate */
@@ -530,16 +534,33 @@ nc_client_tls_update_opts(struct nc_client_tls_opts *opts)
530534 key = opts -> key_path ;
531535 }
532536 if (SSL_CTX_use_PrivateKey_file (opts -> tls_ctx , key , SSL_FILETYPE_PEM ) != 1 ) {
533- ERR (NULL , "Loading the client priavte key from \'%s\' failed (%s)." , key ,
537+ ERR (NULL , "Loading the client private key from \'%s\' failed (%s)." , key ,
534538 ERR_reason_error_string (ERR_get_error ()));
535- return -1 ;
539+ rc = -1 ;
540+ goto cleanup ;
536541 }
537542
538543 if (!SSL_CTX_load_verify_locations (opts -> tls_ctx , opts -> ca_file , opts -> ca_dir )) {
539544 ERR (NULL , "Failed to load the locations of trusted CA certificates (%s)." ,
540545 ERR_reason_error_string (ERR_get_error ()));
541- return -1 ;
546+ rc = -1 ;
547+ goto cleanup ;
542548 }
549+
550+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L // >= 1.1.0
551+ /* server identity (hostname) verification */
552+ vpm = X509_VERIFY_PARAM_new ();
553+ if (!X509_VERIFY_PARAM_set1_host (vpm , host , 0 )) {
554+ ERR (NULL , "Failed to set expected server hostname (%s)." , ERR_reason_error_string (ERR_get_error ()));
555+ rc = -1 ;
556+ goto cleanup ;
557+ }
558+ if (!SSL_CTX_set1_param (opts -> tls_ctx , vpm )) {
559+ ERR (NULL , "Failed to set verify params (%s)." , ERR_reason_error_string (ERR_get_error ()));
560+ rc = -1 ;
561+ goto cleanup ;
562+ }
563+ #endif
543564 }
544565
545566 if (opts -> crl_store_change || (!opts -> crl_store && (opts -> crl_file || opts -> crl_dir ))) {
@@ -549,7 +570,8 @@ nc_client_tls_update_opts(struct nc_client_tls_opts *opts)
549570 opts -> crl_store = X509_STORE_new ();
550571 if (!opts -> crl_store ) {
551572 ERR (NULL , "Unable to create a certificate store (%s)." , ERR_reason_error_string (ERR_get_error ()));
552- return -1 ;
573+ rc = -1 ;
574+ goto cleanup ;
553575 }
554576
555577#if OPENSSL_VERSION_NUMBER < 0x10100000L // < 1.1.0
@@ -560,37 +582,81 @@ nc_client_tls_update_opts(struct nc_client_tls_opts *opts)
560582 if (opts -> crl_file ) {
561583 if (!(lookup = X509_STORE_add_lookup (opts -> crl_store , X509_LOOKUP_file ()))) {
562584 ERR (NULL , "Failed to add lookup method to CRL checking." );
563- return -1 ;
585+ rc = -1 ;
586+ goto cleanup ;
564587 }
565588 if (X509_LOOKUP_add_dir (lookup , opts -> crl_file , X509_FILETYPE_PEM ) != 1 ) {
566589 ERR (NULL , "Failed to add the revocation lookup file \"%s\"." , opts -> crl_file );
567- return -1 ;
590+ rc = -1 ;
591+ goto cleanup ;
568592 }
569593 }
570594
571595 if (opts -> crl_dir ) {
572596 if (!(lookup = X509_STORE_add_lookup (opts -> crl_store , X509_LOOKUP_hash_dir ()))) {
573597 ERR (NULL , "Failed to add lookup method to CRL checking." );
574- return -1 ;
598+ rc = -1 ;
599+ goto cleanup ;
575600 }
576601 if (X509_LOOKUP_add_dir (lookup , opts -> crl_dir , X509_FILETYPE_PEM ) != 1 ) {
577602 ERR (NULL , "Failed to add the revocation lookup directory \"%s\"." , opts -> crl_dir );
578- return -1 ;
603+ rc = -1 ;
604+ goto cleanup ;
579605 }
580606 }
581607 }
582608
583- return 0 ;
609+ cleanup :
610+ X509_VERIFY_PARAM_free (vpm );
611+ return rc ;
612+ }
613+
614+ static int
615+ nc_client_tls_connect_check (int connect_ret , SSL * tls )
616+ {
617+ int verify ;
618+
619+ /* check certificate verification result */
620+ verify = SSL_get_verify_result (tls );
621+ switch (verify ) {
622+ case X509_V_OK :
623+ if (connect_ret == 1 ) {
624+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L // >= 1.1.0
625+ const char * peername = SSL_get0_peername (tls );
626+ VRB (NULL , "Server certificate verified (domain \"%s\")." , peername ? peername : "<unknown>" );
627+ #else
628+ VRB (NULL , "Server certificate verified." );
629+ #endif
630+ }
631+ break ;
632+ default :
633+ ERR (NULL , "Server certificate error (%s)." , X509_verify_cert_error_string (verify ));
634+ }
635+
636+ /* check TLS connection result */
637+ if (connect_ret != 1 ) {
638+ switch (SSL_get_error (tls , connect_ret )) {
639+ case SSL_ERROR_SYSCALL :
640+ ERR (NULL , "SSL_connect failed (%s)." , errno ? strerror (errno ) : "unexpected EOF" );
641+ break ;
642+ case SSL_ERROR_SSL :
643+ ERR (NULL , "SSL_connect failed (%s)." , ERR_reason_error_string (ERR_get_error ()));
644+ break ;
645+ default :
646+ ERR (NULL , "SSL_connect failed." );
647+ break ;
648+ }
649+ }
650+
651+ return connect_ret ;
584652}
585653
586654API struct nc_session *
587655nc_connect_tls (const char * host , unsigned short port , struct ly_ctx * ctx )
588656{
589657 struct nc_session * session = NULL ;
590- int sock , verify , ret ;
591- unsigned long tls_err ;
658+ int sock , ret ;
592659 struct timespec ts_timeout ;
593- const char * peername ;
594660 char * ip_host = NULL ;
595661
596662 if (!tls_opts .cert_path || (!tls_opts .ca_file && !tls_opts .ca_dir )) {
@@ -608,7 +674,7 @@ nc_connect_tls(const char *host, unsigned short port, struct ly_ctx *ctx)
608674 }
609675
610676 /* create/update TLS structures */
611- if (nc_client_tls_update_opts (& tls_opts )) {
677+ if (nc_client_tls_update_opts (& tls_opts , host )) {
612678 return NULL ;
613679 }
614680
@@ -638,14 +704,6 @@ nc_connect_tls(const char *host, unsigned short port, struct ly_ctx *ctx)
638704 /* set the SSL_MODE_AUTO_RETRY flag to allow OpenSSL perform re-handshake automatically */
639705 SSL_set_mode (session -> ti .tls , SSL_MODE_AUTO_RETRY );
640706
641- #if OPENSSL_VERSION_NUMBER >= 0x10100000L // >= 1.1.0
642- /* server identity (hostname) verification */
643- if (!SSL_set1_host (session -> ti .tls , host )) {
644- ERR (NULL , "Failed to set expected server hostname." );
645- goto fail ;
646- }
647- #endif
648-
649707 /* connect and perform the handshake */
650708 nc_gettimespec_mono_add (& ts_timeout , NC_TRANSPORT_TIMEOUT );
651709 tlsauth_ch = 0 ;
@@ -656,38 +714,10 @@ nc_connect_tls(const char *host, unsigned short port, struct ly_ctx *ctx)
656714 goto fail ;
657715 }
658716 }
659- if (ret != 1 ) {
660- switch (SSL_get_error (session -> ti .tls , ret )) {
661- case SSL_ERROR_SYSCALL :
662- ERR (NULL , "SSL_connect failed (%s)." , errno ? strerror (errno ) : "unexpected EOF" );
663- break ;
664- case SSL_ERROR_SSL :
665- tls_err = ERR_get_error ();
666- ERR (NULL , "SSL_connect failed (%s)." , ERR_reason_error_string (tls_err ));
667- break ;
668- default :
669- ERR (NULL , "SSL_connect failed." );
670- break ;
671- }
717+ if (nc_client_tls_connect_check (ret , session -> ti .tls ) != 1 ) {
672718 goto fail ;
673719 }
674720
675- /* check certificate verification result */
676- verify = SSL_get_verify_result (session -> ti .tls );
677- switch (verify ) {
678- case X509_V_OK :
679- #if OPENSSL_VERSION_NUMBER >= 0x10100000L // >= 1.1.0
680- peername = SSL_get0_peername (session -> ti .tls );
681- VRB (NULL , "Server certificate successfully verified (domain \"%s\")." , peername ? peername : "<unknown>" );
682- #else
683- (void )peername ;
684- VRB (NULL , "Server certificate successfully verified." );
685- #endif
686- break ;
687- default :
688- WRN (NULL , "Server certificate verification problem (%s)." , X509_verify_cert_error_string (verify ));
689- }
690-
691721 if (nc_session_new_ctx (session , ctx ) != EXIT_SUCCESS ) {
692722 goto fail ;
693723 }
@@ -771,7 +801,7 @@ nc_accept_callhome_tls_sock(int sock, const char *host, uint16_t port, struct ly
771801 struct nc_session * session = NULL ;
772802 struct timespec ts_timeout ;
773803
774- if (nc_client_tls_update_opts (& tls_ch_opts )) {
804+ if (nc_client_tls_update_opts (& tls_ch_opts , host )) {
775805 goto cleanup ;
776806 }
777807
0 commit comments