Home | History | Annotate | Line # | Download | only in quic
      1 /*
      2  * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #include <openssl/ssl.h>
     11 #include "internal/ssl_unwrap.h"
     12 #include "internal/quic_tls.h"
     13 #include "../ssl_local.h"
     14 
     15 static int crypto_send_cb(const unsigned char *buf, size_t buf_len,
     16     size_t *consumed, void *arg)
     17 {
     18     SSL *s = (SSL *)arg;
     19     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
     20 
     21     if (sc == NULL)
     22         return 0;
     23     return sc->qtcb.crypto_send_cb(s, buf, buf_len, consumed, sc->qtarg);
     24 }
     25 
     26 static int crypto_recv_rcd_cb(const unsigned char **buf, size_t *bytes_read,
     27     void *arg)
     28 {
     29     SSL *s = (SSL *)arg;
     30     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
     31 
     32     if (sc == NULL)
     33         return 0;
     34     return sc->qtcb.crypto_recv_rcd_cb(s, buf, bytes_read, sc->qtarg);
     35 }
     36 
     37 static int crypto_release_rcd_cb(size_t bytes_read, void *arg)
     38 {
     39     SSL *s = (SSL *)arg;
     40     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
     41 
     42     if (sc == NULL)
     43         return 0;
     44     return sc->qtcb.crypto_release_rcd_cb(s, bytes_read, sc->qtarg);
     45 }
     46 static int yield_secret_cb(uint32_t prot_level, int direction,
     47     uint32_t suite_id, EVP_MD *md,
     48     const unsigned char *secret, size_t secret_len,
     49     void *arg)
     50 {
     51     SSL *s = (SSL *)arg;
     52     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
     53 
     54     if (sc == NULL)
     55         return 0;
     56     return sc->qtcb.yield_secret_cb(s, prot_level, direction,
     57         secret, secret_len, sc->qtarg);
     58 }
     59 
     60 static int got_transport_params_cb(const unsigned char *params,
     61     size_t params_len,
     62     void *arg)
     63 {
     64     SSL *s = (SSL *)arg;
     65     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
     66 
     67     if (sc == NULL)
     68         return 0;
     69     return sc->qtcb.got_transport_params_cb(s, params, params_len, sc->qtarg);
     70 }
     71 
     72 static int alert_cb(void *arg, unsigned char alert_code)
     73 {
     74     SSL *s = (SSL *)arg;
     75     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
     76 
     77     if (sc == NULL)
     78         return 0;
     79     return sc->qtcb.alert_cb(s, alert_code, sc->qtarg);
     80 }
     81 
     82 static int tls_callbacks_from_dispatch(OSSL_QUIC_TLS_CALLBACKS *qtcb,
     83     const OSSL_DISPATCH *qtdis)
     84 {
     85     for (; qtdis->function_id != 0; qtdis++) {
     86         switch (qtdis->function_id) {
     87         case OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_SEND:
     88             if (qtcb->crypto_send_cb == NULL)
     89                 qtcb->crypto_send_cb = OSSL_FUNC_SSL_QUIC_TLS_crypto_send(qtdis);
     90             break;
     91         case OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_RECV_RCD:
     92             if (qtcb->crypto_recv_rcd_cb == NULL)
     93                 qtcb->crypto_recv_rcd_cb = OSSL_FUNC_SSL_QUIC_TLS_crypto_recv_rcd(qtdis);
     94             break;
     95         case OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_RELEASE_RCD:
     96             if (qtcb->crypto_release_rcd_cb == NULL)
     97                 qtcb->crypto_release_rcd_cb = OSSL_FUNC_SSL_QUIC_TLS_crypto_release_rcd(qtdis);
     98             break;
     99         case OSSL_FUNC_SSL_QUIC_TLS_YIELD_SECRET:
    100             if (qtcb->yield_secret_cb == NULL)
    101                 qtcb->yield_secret_cb = OSSL_FUNC_SSL_QUIC_TLS_yield_secret(qtdis);
    102             break;
    103         case OSSL_FUNC_SSL_QUIC_TLS_GOT_TRANSPORT_PARAMS:
    104             if (qtcb->got_transport_params_cb == NULL)
    105                 qtcb->got_transport_params_cb = OSSL_FUNC_SSL_QUIC_TLS_got_transport_params(qtdis);
    106             break;
    107         case OSSL_FUNC_SSL_QUIC_TLS_ALERT:
    108             if (qtcb->alert_cb == NULL)
    109                 qtcb->alert_cb = OSSL_FUNC_SSL_QUIC_TLS_alert(qtdis);
    110             break;
    111         }
    112     }
    113 
    114     if (qtcb->crypto_send_cb == NULL
    115         || qtcb->crypto_recv_rcd_cb == NULL
    116         || qtcb->crypto_release_rcd_cb == NULL
    117         || qtcb->yield_secret_cb == NULL
    118         || qtcb->got_transport_params_cb == NULL
    119         || qtcb->alert_cb == NULL) {
    120         ERR_raise(ERR_LIB_SSL, SSL_R_MISSING_QUIC_TLS_FUNCTIONS);
    121         return 0;
    122     }
    123 
    124     return 1;
    125 }
    126 
    127 int SSL_set_quic_tls_cbs(SSL *s, const OSSL_DISPATCH *qtdis, void *arg)
    128 {
    129     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
    130     QUIC_TLS_ARGS qtlsargs;
    131 
    132     if (!SSL_is_tls(s)) {
    133         ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    134         return 0;
    135     }
    136 
    137     if (!tls_callbacks_from_dispatch(&sc->qtcb, qtdis))
    138         /* ERR_raise already called */
    139         return 0;
    140 
    141     sc->qtarg = arg;
    142 
    143     ossl_quic_tls_free(sc->qtls);
    144     qtlsargs.s = s;
    145     qtlsargs.crypto_send_cb = crypto_send_cb;
    146     qtlsargs.crypto_send_cb_arg = s;
    147     qtlsargs.crypto_recv_rcd_cb = crypto_recv_rcd_cb;
    148     qtlsargs.crypto_recv_rcd_cb_arg = s;
    149     qtlsargs.crypto_release_rcd_cb = crypto_release_rcd_cb;
    150     qtlsargs.crypto_release_rcd_cb_arg = s;
    151     qtlsargs.yield_secret_cb = yield_secret_cb;
    152     qtlsargs.yield_secret_cb_arg = s;
    153     qtlsargs.got_transport_params_cb = got_transport_params_cb;
    154     qtlsargs.got_transport_params_cb_arg = s;
    155     qtlsargs.handshake_complete_cb = NULL;
    156     qtlsargs.handshake_complete_cb_arg = NULL;
    157     qtlsargs.alert_cb = alert_cb;
    158     qtlsargs.alert_cb_arg = s;
    159     qtlsargs.is_server = sc->server;
    160     qtlsargs.ossl_quic = 0;
    161     sc->qtls = ossl_quic_tls_new(&qtlsargs);
    162     if (sc->qtls == NULL)
    163         return 0;
    164 
    165     if (!ossl_quic_tls_configure(sc->qtls))
    166         return 0;
    167 
    168     return 1;
    169 }
    170 
    171 int SSL_set_quic_tls_transport_params(SSL *s,
    172     const unsigned char *params,
    173     size_t params_len)
    174 {
    175     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
    176 
    177     if (sc == NULL)
    178         return 0;
    179 
    180     if (sc->qtls == NULL) {
    181         ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    182         return 0;
    183     }
    184 
    185     return ossl_quic_tls_set_transport_params(sc->qtls, params, params_len);
    186 }
    187 
    188 int SSL_set_quic_tls_early_data_enabled(SSL *s, int enabled)
    189 {
    190     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
    191 
    192     if (!SSL_is_tls(s)) {
    193         ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    194         return 0;
    195     }
    196 
    197     if (sc->qtls == NULL) {
    198         ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    199         return 0;
    200     }
    201 
    202     return ossl_quic_tls_set_early_data_enabled(sc->qtls, enabled);
    203 }
    204