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