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 = 94 OSSL_FUNC_SSL_QUIC_TLS_crypto_recv_rcd(qtdis); 95 break; 96 case OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_RELEASE_RCD: 97 if (qtcb->crypto_release_rcd_cb == NULL) 98 qtcb->crypto_release_rcd_cb = 99 OSSL_FUNC_SSL_QUIC_TLS_crypto_release_rcd(qtdis); 100 break; 101 case OSSL_FUNC_SSL_QUIC_TLS_YIELD_SECRET: 102 if (qtcb->yield_secret_cb == NULL) 103 qtcb->yield_secret_cb = 104 OSSL_FUNC_SSL_QUIC_TLS_yield_secret(qtdis); 105 break; 106 case OSSL_FUNC_SSL_QUIC_TLS_GOT_TRANSPORT_PARAMS: 107 if (qtcb->got_transport_params_cb == NULL) 108 qtcb->got_transport_params_cb = 109 OSSL_FUNC_SSL_QUIC_TLS_got_transport_params(qtdis); 110 break; 111 case OSSL_FUNC_SSL_QUIC_TLS_ALERT: 112 if (qtcb->alert_cb == NULL) 113 qtcb->alert_cb = 114 OSSL_FUNC_SSL_QUIC_TLS_alert(qtdis); 115 break; 116 } 117 } 118 119 if (qtcb->crypto_send_cb == NULL 120 || qtcb->crypto_recv_rcd_cb == NULL 121 || qtcb->crypto_release_rcd_cb == NULL 122 || qtcb->yield_secret_cb == NULL 123 || qtcb->got_transport_params_cb == NULL 124 || qtcb->alert_cb == NULL) { 125 ERR_raise(ERR_LIB_SSL, SSL_R_MISSING_QUIC_TLS_FUNCTIONS); 126 return 0; 127 } 128 129 return 1; 130 } 131 132 int SSL_set_quic_tls_cbs(SSL *s, const OSSL_DISPATCH *qtdis, void *arg) 133 { 134 SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 135 QUIC_TLS_ARGS qtlsargs; 136 137 if (!SSL_is_tls(s)) { 138 ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 139 return 0; 140 } 141 142 if (!tls_callbacks_from_dispatch(&sc->qtcb, qtdis)) 143 /* ERR_raise already called */ 144 return 0; 145 146 sc->qtarg = arg; 147 148 ossl_quic_tls_free(sc->qtls); 149 qtlsargs.s = s; 150 qtlsargs.crypto_send_cb = crypto_send_cb; 151 qtlsargs.crypto_send_cb_arg = s; 152 qtlsargs.crypto_recv_rcd_cb = crypto_recv_rcd_cb; 153 qtlsargs.crypto_recv_rcd_cb_arg = s; 154 qtlsargs.crypto_release_rcd_cb = crypto_release_rcd_cb; 155 qtlsargs.crypto_release_rcd_cb_arg = s; 156 qtlsargs.yield_secret_cb = yield_secret_cb; 157 qtlsargs.yield_secret_cb_arg = s; 158 qtlsargs.got_transport_params_cb = got_transport_params_cb; 159 qtlsargs.got_transport_params_cb_arg = s; 160 qtlsargs.handshake_complete_cb = NULL; 161 qtlsargs.handshake_complete_cb_arg = NULL; 162 qtlsargs.alert_cb = alert_cb; 163 qtlsargs.alert_cb_arg = s; 164 qtlsargs.is_server = sc->server; 165 qtlsargs.ossl_quic = 0; 166 sc->qtls = ossl_quic_tls_new(&qtlsargs); 167 if (sc->qtls == NULL) 168 return 0; 169 170 if (!ossl_quic_tls_configure(sc->qtls)) 171 return 0; 172 173 return 1; 174 } 175 176 int SSL_set_quic_tls_transport_params(SSL *s, 177 const unsigned char *params, 178 size_t params_len) 179 { 180 SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 181 182 if (sc == NULL) 183 return 0; 184 185 if (sc->qtls == NULL) { 186 ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 187 return 0; 188 } 189 190 return ossl_quic_tls_set_transport_params(sc->qtls, params, params_len); 191 } 192 193 int SSL_set_quic_tls_early_data_enabled(SSL *s, int enabled) 194 { 195 SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); 196 197 if (!SSL_is_tls(s)) { 198 ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 199 return 0; 200 } 201 202 if (sc->qtls == NULL) { 203 ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 204 return 0; 205 } 206 207 return ossl_quic_tls_set_early_data_enabled(sc->qtls, enabled); 208 } 209