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