OPENSSL_free(sc->psksession_id);
sc->psksession_id = NULL;
sc->psksession_id_len = 0;
- sc->hello_retry_request = 0;
+ sc->hello_retry_request = SSL_HRR_NONE;
sc->sent_tickets = 0;
sc->error = 0;
ossl_statem_clear(sc);
- /* TODO(QUIC): Version handling not yet clear */
sc->version = s->method->version;
sc->client_version = sc->version;
sc->rwstate = SSL_NOTHING;
{
STACK_OF(SSL_CIPHER) *sk;
+ if (IS_QUIC_CTX(ctx)) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
+ return 0;
+ }
+
ctx->method = meth;
if (!SSL_CTX_set_ciphersuites(ctx, OSSL_default_ciphersuites())) {
s->min_proto_version = ctx->min_proto_version;
s->max_proto_version = ctx->max_proto_version;
}
+
s->mode = ctx->mode;
s->max_cert_list = ctx->max_cert_list;
s->max_early_data = ctx->max_early_data;
s->recv_max_early_data = ctx->recv_max_early_data;
+
s->num_tickets = ctx->num_tickets;
s->pha_enabled = ctx->pha_enabled;
if (s->param == NULL)
goto asn1err;
X509_VERIFY_PARAM_inherit(s->param, ctx->param);
- s->quiet_shutdown = ctx->quiet_shutdown;
+ s->quiet_shutdown = IS_QUIC_CTX(ctx) ? 0 : ctx->quiet_shutdown;
+
+ if (!IS_QUIC_CTX(ctx))
+ s->ext.max_fragment_len_mode = ctx->ext.max_fragment_len_mode;
- s->ext.max_fragment_len_mode = ctx->ext.max_fragment_len_mode;
s->max_send_fragment = ctx->max_send_fragment;
s->split_send_fragment = ctx->split_send_fragment;
s->max_pipelines = ctx->max_pipelines;
s->key_update = SSL_KEY_UPDATE_NONE;
- s->allow_early_data_cb = ctx->allow_early_data_cb;
- s->allow_early_data_cb_data = ctx->allow_early_data_cb_data;
+ if (!IS_QUIC_CTX(ctx)) {
+ s->allow_early_data_cb = ctx->allow_early_data_cb;
+ s->allow_early_data_cb_data = ctx->allow_early_data_cb_data;
+ }
if (!method->ssl_init(ssl))
goto sslerr;
}
#ifndef OPENSSL_NO_SOCK
+static const BIO_METHOD *fd_method(SSL *s)
+{
+#ifndef OPENSSL_NO_DGRAM
+ if (IS_QUIC(s))
+ return BIO_s_datagram();
+#endif
+
+ return BIO_s_socket();
+}
+
int SSL_set_fd(SSL *s, int fd)
{
int ret = 0;
BIO *bio = NULL;
- bio = BIO_new(BIO_s_socket());
+ if (s->type == SSL_TYPE_QUIC_XSO) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY);
+ goto err;
+ }
+
+ bio = BIO_new(fd_method(s));
if (bio == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
int SSL_set_wfd(SSL *s, int fd)
{
BIO *rbio = SSL_get_rbio(s);
+ int desired_type = IS_QUIC(s) ? BIO_TYPE_DGRAM : BIO_TYPE_SOCKET;
+
+ if (s->type == SSL_TYPE_QUIC_XSO) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY);
+ return 0;
+ }
- if (rbio == NULL || BIO_method_type(rbio) != BIO_TYPE_SOCKET
+ if (rbio == NULL || BIO_method_type(rbio) != desired_type
|| (int)BIO_get_fd(rbio, NULL) != fd) {
- BIO *bio = BIO_new(BIO_s_socket());
+ BIO *bio = BIO_new(fd_method(s));
if (bio == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
int SSL_set_rfd(SSL *s, int fd)
{
BIO *wbio = SSL_get_wbio(s);
+ int desired_type = IS_QUIC(s) ? BIO_TYPE_DGRAM : BIO_TYPE_SOCKET;
+
+ if (s->type == SSL_TYPE_QUIC_XSO) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY);
+ return 0;
+ }
- if (wbio == NULL || BIO_method_type(wbio) != BIO_TYPE_SOCKET
+ if (wbio == NULL || BIO_method_type(wbio) != desired_type
|| ((int)BIO_get_fd(wbio, NULL) != fd)) {
- BIO *bio = BIO_new(BIO_s_socket());
+ BIO *bio = BIO_new(fd_method(s));
if (bio == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
void SSL_set_read_ahead(SSL *s, int yes)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
OSSL_PARAM options[2], *opts = options;
if (sc == NULL)
int SSL_get_read_ahead(const SSL *s)
{
- const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+ const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);
if (sc == NULL)
return 0;
int SSL_has_pending(const SSL *s)
{
-#ifndef OPENSSL_NO_QUIC
- const QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
-#endif
-
/*
* Similar to SSL_pending() but returns a 1 to indicate that we have
* processed or unprocessed data available or 0 otherwise (as opposed to the
sc = SSL_CONNECTION_FROM_CONST_SSL(s);
-#ifndef OPENSSL_NO_QUIC
- if (qc != NULL)
- return ossl_quic_has_pending(qc);
-#endif
-
/* Check buffered app data if any first */
if (SSL_CONNECTION_IS_DTLS(sc)) {
TLS_RECORD *rdata;
int SSL_copy_session_id(SSL *t, const SSL *f)
{
int i;
- /* TODO(QUIC): Do we want to support this for QUIC connections? */
+ /* TODO(QUIC FUTURE): Not allowed for QUIC currently. */
SSL_CONNECTION *tsc = SSL_CONNECTION_FROM_SSL_ONLY(t);
const SSL_CONNECTION *fsc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(f);
int ret;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- /* TODO(QUIC): This will need special handling for QUIC */
- if (sc == NULL)
- return 0;
-
- if (!sc->server) {
+ /* TODO(QUIC 0RTT): 0-RTT support */
+ if (sc == NULL || !sc->server) {
ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return SSL_READ_EARLY_DATA_ERROR;
}
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);
- /* TODO(QUIC): This will need special handling for QUIC */
+ /* TODO(QUIC 0RTT): 0-RTT support */
if (sc == NULL)
return 0;
uint32_t partialwrite;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- /* TODO(QUIC): This will need special handling for QUIC */
+ /* TODO(QUIC 0RTT): This will need special handling for QUIC */
if (sc == NULL)
return 0;
}
long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
+{
+ return ossl_ctrl_internal(s, cmd, larg, parg, /*no_quic=*/0);
+}
+
+long ossl_ctrl_internal(SSL *s, int cmd, long larg, void *parg, int no_quic)
{
long l;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
- /* TODO(QUIC): Special handling for some ctrls will be needed */
- if (sc == NULL)
- return 0;
+ /*
+ * Routing of ctrl calls for QUIC is a little counterintuitive:
+ *
+ * - Firstly (no_quic=0), we pass the ctrl directly to our QUIC
+ * implementation in case it wants to handle the ctrl specially.
+ *
+ * - If our QUIC implementation does not care about the ctrl, it
+ * will reenter this function with no_quic=1 and we will try to handle
+ * it directly using the QCSO SSL object stub (not the handshake layer
+ * SSL object). This is important for e.g. the version configuration
+ * ctrls below, which must use s->defltmeth (and not sc->defltmeth).
+ *
+ * - If we don't handle a ctrl here specially, then processing is
+ * redirected to the handshake layer SSL object.
+ */
+ if (!no_quic && IS_QUIC(s))
+ return s->method->ssl_ctrl(s, cmd, larg, parg);
switch (cmd) {
case SSL_CTRL_GET_READ_AHEAD:
case SSL_CTRL_GET_MAX_PROTO_VERSION:
return sc->max_proto_version;
default:
- return s->method->ssl_ctrl(s, cmd, larg, parg);
+ if (IS_QUIC(s))
+ return SSL_ctrl((SSL *)sc, cmd, larg, parg);
+ else
+ return s->method->ssl_ctrl(s, cmd, larg, parg);
}
}
if (sk_SSL_CIPHER_find(srvrsk, c) < 0)
continue;
- n = strlen(c->name);
- if (n + 1 > size) {
+ n = OPENSSL_strnlen(c->name, size);
+ if (n >= size) {
if (p != buf)
--p;
*p = '\0';
return buf;
}
- strcpy(p, c->name);
+ memcpy(p, c->name, n);
p += n;
*(p++) = ':';
size -= n + 1;
int ret = 1;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
- /* TODO(QUIC): Do we want this for QUIC? */
+ /* Not allowed for QUIC */
if (sc == NULL
- || (s->type != SSL_TYPE_SSL_CONNECTION && s->method != meth))
+ || (s->type != SSL_TYPE_SSL_CONNECTION && s->method != meth)
+ || (s->type == SSL_TYPE_SSL_CONNECTION && IS_QUIC_METHOD(meth)))
return 0;
if (s->method != meth) {
}
int SSL_get_error(const SSL *s, int i)
+{
+ return ossl_ssl_get_error(s, i, /*check_err=*/1);
+}
+
+int ossl_ssl_get_error(const SSL *s, int i, int check_err)
{
int reason;
unsigned long l;
* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
* where we do encode the error
*/
- if ((l = ERR_peek_error()) != 0) {
+ if (check_err && (l = ERR_peek_error()) != 0) {
if (ERR_GET_LIB(l) == ERR_LIB_SYS)
return SSL_ERROR_SYSCALL;
else
{
SSL *ret;
int i;
- /* TODO(QUIC): Add a SSL_METHOD function for duplication */
+ /* TODO(QUIC FUTURE): Add a SSL_METHOD function for duplication */
SSL_CONNECTION *retsc;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- /* TODO(QUIC): Do we want this for QUIC? */
+ /* TODO(QUIC): Currently not supported for QUIC. */
if (sc == NULL)
return;
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);
- /* TODO(QUIC): Do we want this for QUIC? */
+ /* TODO(QUIC): Currently not supported for QUIC. */
if (sc == NULL)
return 0;
if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
return OSSL_QUIC1_VERSION;
#endif
- /* TODO(QUIC): Do we want to report QUIC version this way instead? */
if (sc == NULL)
return 0;
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
- /* TODO(QUIC): Do we want to report QUIC version this way instead? */
+#ifndef OPENSSL_NO_QUIC
+ /* We only support QUICv1 - so if its QUIC its QUICv1 */
+ if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
+ return OSSL_QUIC1_VERSION;
+#endif
if (sc == NULL)
return 0;
CERT *new_cert;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
- /* TODO(QUIC): Do we need this for QUIC support? */
+ /* TODO(QUIC FUTURE): Add support for QUIC */
if (sc == NULL)
return NULL;
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_want(s);
+#endif
+
if (sc == NULL)
return SSL_NOTHING;
int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size)
{
+ if (IS_QUIC_CTX(ctx) && block_size > 1)
+ return 0;
+
/* block size of 0 or 1 is basically no padding */
if (block_size == 1)
ctx->block_padding = 0;
size_t len, void *arg))
{
BIO *b;
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
if (sc == NULL)
return 0;
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
- if (sc == NULL)
+ if (sc == NULL || (IS_QUIC(ssl) && block_size > 1))
return 0;
/* block size of 0 or 1 is basically no padding */
return NULL;
}
-static int ct_permissive(const CT_POLICY_EVAL_CTX * ctx,
+static int ct_permissive(const CT_POLICY_EVAL_CTX *ctx,
const STACK_OF(SCT) *scts, void *unused_arg)
{
return 1;
}
-static int ct_strict(const CT_POLICY_EVAL_CTX * ctx,
+static int ct_strict(const CT_POLICY_EVAL_CTX *ctx,
const STACK_OF(SCT) *scts, void *unused_arg)
{
int count = scts != NULL ? sk_SCT_num(scts) : 0;
return CTLOG_STORE_load_file(ctx->ctlog_store, path);
}
-void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE * logs)
+void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE *logs)
{
CTLOG_STORE_free(ctx->ctlog_store);
ctx->ctlog_store = logs;
int SSL_free_buffers(SSL *ssl)
{
RECORD_LAYER *rl;
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
if (sc == NULL)
return 0;
if (sc == NULL)
return 0;
+ /* QUIC always has buffers allocated. */
+ if (IS_QUIC(ssl))
+ return 1;
+
rl = &sc->rlayer;
return rl->rrlmethod->alloc_buffers(rl->rrl)
int SSL_set_max_early_data(SSL *s, uint32_t max_early_data)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
if (sc == NULL)
return 0;
int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
if (sc == NULL)
return 0;
int SSL_stateless(SSL *s)
{
int ret;
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- /* TODO(QUIC): This will need further work. */
if (sc == NULL)
return 0;
void SSL_set_post_handshake_auth(SSL *ssl, int val)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
-#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(ssl);
-
- if (qc != NULL)
- return;
-#endif
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
if (sc == NULL)
return;
int SSL_verify_client_post_handshake(SSL *ssl)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
-#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(ssl);
- if (qc != NULL) {
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(ssl)) {
ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
return 0;
}
SSL_allow_early_data_cb_fn cb,
void *arg)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
if (sc == NULL)
return;
#endif
}
-int SSL_set_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr)
+int SSL_set1_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr)
{
#ifndef OPENSSL_NO_QUIC
if (!IS_QUIC(s))
#endif
}
+int SSL_is_stream_local(SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
+ return -1;
+
+ return ossl_quic_is_stream_local(s);
+#else
+ return -1;
+#endif
+}
+
int SSL_set_default_stream_mode(SSL *s, uint32_t mode)
{
#ifndef OPENSSL_NO_QUIC