xref: /freebsd/crypto/openssl/ssl/quic/quic_tls_api.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
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 = 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 
SSL_set_quic_tls_cbs(SSL * s,const OSSL_DISPATCH * qtdis,void * arg)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 
SSL_set_quic_tls_transport_params(SSL * s,const unsigned char * params,size_t params_len)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 
SSL_set_quic_tls_early_data_enabled(SSL * s,int enabled)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