@@ -986,6 +986,21 @@ nc_server_tls_set_server_cert_clb(int (*cert_clb)(const char *name, void *user_d
986986 server_opts .server_cert_data_free = free_user_data ;
987987}
988988
989+ API void
990+ nc_server_tls_set_server_cert_chain_clb (int (* cert_chain_clb )(const char * name , void * user_data , char * * * cert_paths ,
991+ int * cert_path_count , char * * * cert_data , int * cert_data_count ),
992+ void * user_data , void (* free_user_data )(void * user_data ))
993+ {
994+ if (!cert_chain_clb ) {
995+ ERRARG ("cert_chain_clb" );
996+ return ;
997+ }
998+
999+ server_opts .server_cert_chain_clb = cert_chain_clb ;
1000+ server_opts .server_cert_chain_data = user_data ;
1001+ server_opts .server_cert_chain_data_free = free_user_data ;
1002+ }
1003+
9891004static int
9901005nc_server_tls_add_trusted_cert_list (const char * name , struct nc_server_tls_opts * opts )
9911006{
@@ -1705,6 +1720,78 @@ nc_tls_make_verify_key(void)
17051720 pthread_key_create (& verify_key , NULL );
17061721}
17071722
1723+ static X509 *
1724+ tls_load_cert (const char * cert_path , const char * cert_data )
1725+ {
1726+ X509 * cert ;
1727+
1728+ if (cert_path ) {
1729+ cert = pem_to_cert (cert_path );
1730+ } else {
1731+ cert = base64der_to_cert (cert_data );
1732+ }
1733+
1734+ if (!cert ) {
1735+ if (cert_path ) {
1736+ ERR ("Loading a trusted certificate (path \"%s\") failed (%s)." , cert_path ,
1737+ ERR_reason_error_string (ERR_get_error ()));
1738+ } else {
1739+ ERR ("Loading a trusted certificate (data \"%s\") failed (%s)." , cert_data ,
1740+ ERR_reason_error_string (ERR_get_error ()));
1741+ }
1742+ }
1743+ return cert ;
1744+ }
1745+
1746+ static int
1747+ nc_tls_ctx_set_server_cert_chain (SSL_CTX * tls_ctx , const char * cert_name )
1748+ {
1749+ char * * cert_paths = NULL , * * cert_data = NULL ;
1750+ int cert_path_count = 0 , cert_data_count = 0 , ret = 0 , i = 0 ;
1751+ X509 * cert = NULL ;
1752+
1753+ if (!server_opts .server_cert_chain_clb ) {
1754+ /* This is optional, so return OK */
1755+ return 0 ;
1756+ }
1757+
1758+ if (server_opts .server_cert_chain_clb (cert_name , server_opts .server_cert_chain_data , & cert_paths ,
1759+ & cert_path_count , & cert_data , & cert_data_count )) {
1760+ ERR ("Server certificate chain callback failed." );
1761+ return -1 ;
1762+ }
1763+
1764+ for (i = 0 ; i < cert_path_count ; ++ i ) {
1765+ cert = tls_load_cert (cert_paths [i ], NULL );
1766+ if (!cert || SSL_CTX_add_extra_chain_cert (tls_ctx , cert ) != 1 ) {
1767+ ERR ("Loading the server certificate chain failed (%s)." , ERR_reason_error_string (ERR_get_error ()));
1768+ ret = -1 ;
1769+ goto cleanup ;
1770+ }
1771+ }
1772+
1773+ for (i = 0 ; i < cert_data_count ; ++ i ) {
1774+ cert = tls_load_cert (NULL , cert_data [i ]);
1775+ if (!cert || SSL_CTX_add_extra_chain_cert (tls_ctx , cert ) != 1 ) {
1776+ ERR ("Loading the server certificate chain failed (%s)." , ERR_reason_error_string (ERR_get_error ()));
1777+ ret = -1 ;
1778+ goto cleanup ;
1779+ }
1780+ }
1781+ cleanup :
1782+ for (i = 0 ; i < cert_path_count ; ++ i ) {
1783+ free (cert_paths [i ]);
1784+ }
1785+ free (cert_paths );
1786+ for (i = 0 ; i < cert_data_count ; ++ i ) {
1787+ free (cert_data [i ]);
1788+ }
1789+ free (cert_data );
1790+ /* cert is owned by the SSL_CTX */
1791+
1792+ return ret ;
1793+ }
1794+
17081795static int
17091796nc_tls_ctx_set_server_cert_key (SSL_CTX * tls_ctx , const char * cert_name )
17101797{
@@ -1759,6 +1846,8 @@ nc_tls_ctx_set_server_cert_key(SSL_CTX *tls_ctx, const char *cert_name)
17591846 }
17601847 }
17611848
1849+ ret = nc_tls_ctx_set_server_cert_chain (tls_ctx , cert_name );
1850+
17621851cleanup :
17631852 X509_free (cert );
17641853 EVP_PKEY_free (pkey );
@@ -1772,22 +1861,8 @@ nc_tls_ctx_set_server_cert_key(SSL_CTX *tls_ctx, const char *cert_name)
17721861static void
17731862tls_store_add_trusted_cert (X509_STORE * cert_store , const char * cert_path , const char * cert_data )
17741863{
1775- X509 * cert ;
1776-
1777- if (cert_path ) {
1778- cert = pem_to_cert (cert_path );
1779- } else {
1780- cert = base64der_to_cert (cert_data );
1781- }
1782-
1864+ X509 * cert = tls_load_cert (cert_path , cert_data );
17831865 if (!cert ) {
1784- if (cert_path ) {
1785- ERR ("Loading a trusted certificate (path \"%s\") failed (%s)." , cert_path ,
1786- ERR_reason_error_string (ERR_get_error ()));
1787- } else {
1788- ERR ("Loading a trusted certificate (data \"%s\") failed (%s)." , cert_data ,
1789- ERR_reason_error_string (ERR_get_error ()));
1790- }
17911866 return ;
17921867 }
17931868
0 commit comments