quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

vquic-tls.c (7687B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 
     25 #include "../curl_setup.h"
     26 
     27 #if defined(USE_HTTP3) && \
     28   (defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_WOLFSSL))
     29 
     30 #ifdef USE_OPENSSL
     31 #include <openssl/err.h>
     32 #include "../vtls/openssl.h"
     33 #elif defined(USE_GNUTLS)
     34 #include <gnutls/abstract.h>
     35 #include <gnutls/gnutls.h>
     36 #include <gnutls/x509.h>
     37 #include <gnutls/crypto.h>
     38 #include <nettle/sha2.h>
     39 #include "../vtls/gtls.h"
     40 #elif defined(USE_WOLFSSL)
     41 #include <wolfssl/options.h>
     42 #include <wolfssl/ssl.h>
     43 #include <wolfssl/quic.h>
     44 #include "../vtls/wolfssl.h"
     45 #endif
     46 
     47 #include "../urldata.h"
     48 #include "../curl_trc.h"
     49 #include "../cfilters.h"
     50 #include "../multiif.h"
     51 #include "../vtls/keylog.h"
     52 #include "../vtls/vtls.h"
     53 #include "../vtls/vtls_scache.h"
     54 #include "vquic-tls.h"
     55 
     56 /* The last 3 #include files should be in this order */
     57 #include "../curl_printf.h"
     58 #include "../curl_memory.h"
     59 #include "../memdebug.h"
     60 
     61 CURLcode Curl_vquic_tls_init(struct curl_tls_ctx *ctx,
     62                              struct Curl_cfilter *cf,
     63                              struct Curl_easy *data,
     64                              struct ssl_peer *peer,
     65                              const struct alpn_spec *alpns,
     66                              Curl_vquic_tls_ctx_setup *cb_setup,
     67                              void *cb_user_data, void *ssl_user_data,
     68                              Curl_vquic_session_reuse_cb *session_reuse_cb)
     69 {
     70   char tls_id[80];
     71   CURLcode result;
     72 
     73 #ifdef USE_OPENSSL
     74   Curl_ossl_version(tls_id, sizeof(tls_id));
     75 #elif defined(USE_GNUTLS)
     76   Curl_gtls_version(tls_id, sizeof(tls_id));
     77 #elif defined(USE_WOLFSSL)
     78   Curl_wssl_version(tls_id, sizeof(tls_id));
     79 #else
     80 #error "no TLS lib in used, should not happen"
     81   return CURLE_FAILED_INIT;
     82 #endif
     83   (void)session_reuse_cb;
     84   result = Curl_ssl_peer_init(peer, cf, tls_id, TRNSPRT_QUIC);
     85   if(result)
     86     return result;
     87 
     88 #ifdef USE_OPENSSL
     89   (void)result;
     90   return Curl_ossl_ctx_init(&ctx->ossl, cf, data, peer, alpns,
     91                             cb_setup, cb_user_data, NULL, ssl_user_data,
     92                             session_reuse_cb);
     93 #elif defined(USE_GNUTLS)
     94   return Curl_gtls_ctx_init(&ctx->gtls, cf, data, peer, alpns,
     95                             cb_setup, cb_user_data, ssl_user_data,
     96                             session_reuse_cb);
     97 #elif defined(USE_WOLFSSL)
     98   return Curl_wssl_ctx_init(&ctx->wssl, cf, data, peer, alpns,
     99                             cb_setup, cb_user_data,
    100                             ssl_user_data, session_reuse_cb);
    101 #else
    102 #error "no TLS lib in used, should not happen"
    103   return CURLE_FAILED_INIT;
    104 #endif
    105 }
    106 
    107 void Curl_vquic_tls_cleanup(struct curl_tls_ctx *ctx)
    108 {
    109 #ifdef USE_OPENSSL
    110   if(ctx->ossl.ssl)
    111     SSL_free(ctx->ossl.ssl);
    112   if(ctx->ossl.ssl_ctx)
    113     SSL_CTX_free(ctx->ossl.ssl_ctx);
    114 #elif defined(USE_GNUTLS)
    115   if(ctx->gtls.session)
    116     gnutls_deinit(ctx->gtls.session);
    117   Curl_gtls_shared_creds_free(&ctx->gtls.shared_creds);
    118 #elif defined(USE_WOLFSSL)
    119   if(ctx->wssl.ssl)
    120     wolfSSL_free(ctx->wssl.ssl);
    121   if(ctx->wssl.ssl_ctx)
    122     wolfSSL_CTX_free(ctx->wssl.ssl_ctx);
    123 #endif
    124   memset(ctx, 0, sizeof(*ctx));
    125 }
    126 
    127 CURLcode Curl_vquic_tls_before_recv(struct curl_tls_ctx *ctx,
    128                                     struct Curl_cfilter *cf,
    129                                     struct Curl_easy *data)
    130 {
    131 #ifdef USE_OPENSSL
    132   if(!ctx->ossl.x509_store_setup) {
    133     CURLcode result = Curl_ssl_setup_x509_store(cf, data, ctx->ossl.ssl_ctx);
    134     if(result)
    135       return result;
    136     ctx->ossl.x509_store_setup = TRUE;
    137   }
    138 #elif defined(USE_WOLFSSL)
    139   if(!ctx->wssl.x509_store_setup) {
    140     CURLcode result = Curl_wssl_setup_x509_store(cf, data, &ctx->wssl);
    141     if(result)
    142       return result;
    143   }
    144 #elif defined(USE_GNUTLS)
    145   if(!ctx->gtls.shared_creds->trust_setup) {
    146     CURLcode result = Curl_gtls_client_trust_setup(cf, data, &ctx->gtls);
    147     if(result)
    148       return result;
    149   }
    150 #else
    151   (void)ctx; (void)cf; (void)data;
    152 #endif
    153   return CURLE_OK;
    154 }
    155 
    156 CURLcode Curl_vquic_tls_verify_peer(struct curl_tls_ctx *ctx,
    157                                     struct Curl_cfilter *cf,
    158                                     struct Curl_easy *data,
    159                                     struct ssl_peer *peer)
    160 {
    161   struct ssl_primary_config *conn_config;
    162   CURLcode result = CURLE_OK;
    163 
    164   conn_config = Curl_ssl_cf_get_primary_config(cf);
    165   if(!conn_config)
    166     return CURLE_FAILED_INIT;
    167 
    168 #ifdef USE_OPENSSL
    169   (void)conn_config;
    170   result = Curl_oss_check_peer_cert(cf, data, &ctx->ossl, peer);
    171 #elif defined(USE_GNUTLS)
    172   if(conn_config->verifyhost) {
    173     result = Curl_gtls_verifyserver(data, ctx->gtls.session,
    174                                     conn_config, &data->set.ssl, peer,
    175                                     data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
    176     if(result)
    177       return result;
    178   }
    179 #elif defined(USE_WOLFSSL)
    180   (void)data;
    181   if(conn_config->verifyhost) {
    182     char *snihost = peer->sni ? peer->sni : peer->hostname;
    183     WOLFSSL_X509* cert = wolfSSL_get_peer_certificate(ctx->wssl.ssl);
    184     if(wolfSSL_X509_check_host(cert, snihost, strlen(snihost), 0, NULL)
    185           == WOLFSSL_FAILURE) {
    186       result = CURLE_PEER_FAILED_VERIFICATION;
    187     }
    188     wolfSSL_X509_free(cert);
    189   }
    190   if(!result)
    191     result = Curl_wssl_verify_pinned(cf, data, &ctx->wssl);
    192 #endif
    193   /* on error, remove any session we might have in the pool */
    194   if(result)
    195     Curl_ssl_scache_remove_all(cf, data, peer->scache_key);
    196   return result;
    197 }
    198 
    199 
    200 bool Curl_vquic_tls_get_ssl_info(struct curl_tls_ctx *ctx,
    201                                  bool give_ssl_ctx,
    202                                  struct curl_tlssessioninfo *info)
    203 {
    204 #ifdef USE_OPENSSL
    205   info->backend = CURLSSLBACKEND_OPENSSL;
    206   info->internals = give_ssl_ctx ?
    207                     (void *)ctx->ossl.ssl_ctx : (void *)ctx->ossl.ssl;
    208   return TRUE;
    209 #elif defined(USE_GNUTLS)
    210   (void)give_ssl_ctx; /* gnutls always returns its session */
    211   info->backend = CURLSSLBACKEND_OPENSSL;
    212   info->internals = ctx->gtls.session;
    213   return TRUE;
    214 #elif defined(USE_WOLFSSL)
    215   info->backend = CURLSSLBACKEND_WOLFSSL;
    216   info->internals = give_ssl_ctx ?
    217                     (void *)ctx->wssl.ssl_ctx : (void *)ctx->wssl.ssl;
    218   return TRUE;
    219 #else
    220   return FALSE;
    221 #endif
    222 }
    223 
    224 void Curl_vquic_report_handshake(struct curl_tls_ctx *ctx,
    225                                  struct Curl_cfilter *cf,
    226                                  struct Curl_easy *data)
    227 {
    228   (void)cf;
    229 #ifdef USE_OPENSSL
    230   (void)cf;
    231   Curl_ossl_report_handshake(data, &ctx->ossl);
    232 #elif defined(USE_GNUTLS)
    233   Curl_gtls_report_handshake(data, &ctx->gtls);
    234 #elif defined(USE_WOLFSSL)
    235   Curl_wssl_report_handshake(data, &ctx->wssl);
    236 #else
    237   (void)data;
    238   (void)ctx;
    239 #endif
    240 }
    241 
    242 #endif /* !USE_HTTP3 && (USE_OPENSSL || USE_GNUTLS || USE_WOLFSSL) */