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
crypto_send_cb(const unsigned char * buf,size_t buf_len,size_t * consumed,void * arg)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
crypto_recv_rcd_cb(const unsigned char ** buf,size_t * bytes_read,void * arg)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
crypto_release_rcd_cb(size_t bytes_read,void * arg)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 }
yield_secret_cb(uint32_t prot_level,int direction,uint32_t suite_id,EVP_MD * md,const unsigned char * secret,size_t secret_len,void * arg)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
got_transport_params_cb(const unsigned char * params,size_t params_len,void * arg)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
alert_cb(void * arg,unsigned char alert_code)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
tls_callbacks_from_dispatch(OSSL_QUIC_TLS_CALLBACKS * qtcb,const OSSL_DISPATCH * qtdis)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
SSL_set_quic_tls_cbs(SSL * s,const OSSL_DISPATCH * qtdis,void * arg)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
SSL_set_quic_tls_transport_params(SSL * s,const unsigned char * params,size_t params_len)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
SSL_set_quic_tls_early_data_enabled(SSL * s,int enabled)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