Raise errors when appropriate.
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21700)
cid->id_len = (unsigned char)len;
if (RAND_bytes_ex(libctx, cid->id, len, len * 8) != 1) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_RAND_LIB);
cid->id_len = 0;
return 0;
}
if (ch->got_remote_transport_params)
goto malformed;
- if (!PACKET_buf_init(&pkt, params, params_len))
+ if (!PACKET_buf_init(&pkt, params, params_len)) {
+ ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0,
+ "internal error (packet buf init)");
return 0;
+ }
while (PACKET_remaining(&pkt) > 0) {
if (!ossl_quic_wire_peek_transport_param(&pkt, &id))
if (got_max_ack_delay) {
/* must not appear more than once */
reason = TP_REASON_DUP("MAX_ACK_DELAY");
- return 0;
+ goto malformed;
}
if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)
if (got_initial_max_streams_bidi) {
/* must not appear more than once */
reason = TP_REASON_DUP("INITIAL_MAX_STREAMS_BIDI");
- return 0;
+ goto malformed;
}
if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)
/* Malformed retry packet, ignore. */
return;
- ch_retry(ch, ch->qrx_pkt->hdr->data,
- ch->qrx_pkt->hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN,
- &ch->qrx_pkt->hdr->src_conn_id);
+ if (!ch_retry(ch, ch->qrx_pkt->hdr->data,
+ ch->qrx_pkt->hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN,
+ &ch->qrx_pkt->hdr->src_conn_id))
+ ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR,
+ 0, "handling retry packet");
break;
case QUIC_PKT_TYPE_0RTT:
* be transmitted for this reason.
*/
ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0,
- "internal error");
+ "internal error (txp generate)");
break; /* Internal failure (e.g. allocation, assertion) */
}
/* Determines whether we can support a given poll descriptor. */
static int validate_poll_descriptor(const BIO_POLL_DESCRIPTOR *d)
{
- if (d->type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD && d->value.fd < 0)
+ if (d->type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD && d->value.fd < 0) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
+ }
return 1;
}
* a SCID field that is identical to the DCID field of its initial packet."
*/
if (ossl_quic_conn_id_eq(&ch->init_dcid, retry_scid))
- return 0;
+ return 1;
/* We change to using the SCID in the Retry packet as the DCID. */
if (!ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, retry_scid))
static int ch_enqueue_retire_conn_id(QUIC_CHANNEL *ch, uint64_t seq_num)
{
- BUF_MEM *buf_mem;
+ BUF_MEM *buf_mem = NULL;
WPACKET wpkt;
size_t l;
chan_remove_reset_token(ch, seq_num);
if ((buf_mem = BUF_MEM_new()) == NULL)
- return 0;
+ goto err;
if (!WPACKET_init(&wpkt, buf_mem))
goto err;
if (!expect_quic(s, &ctx))
return 0;
- /* Not supported. */
+ ERR_raise(ERR_LIB_SSL, ERR_R_UNSUPPORTED);
return 0;
}
if (!expect_quic(s, &ctx))
return 0;
- if (desc == NULL || ctx.qc->net_rbio == NULL)
+ if (desc == NULL || ctx.qc->net_rbio == NULL) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
+ }
return BIO_get_rpoll_descriptor(ctx.qc->net_rbio, desc);
}
if (!expect_quic(s, &ctx))
return 0;
- if (desc == NULL || ctx.qc->net_wbio == NULL)
+ if (desc == NULL || ctx.qc->net_wbio == NULL) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
+ }
return BIO_get_wpoll_descriptor(ctx.qc->net_wbio, desc);
}
}
qs = ossl_quic_channel_new_stream_local(qc->ch, is_uni);
- if (qs == NULL)
+ if (qs == NULL) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
goto err;
+ }
xso = create_xso_from_stream(qc, qs);
- if (xso == NULL)
+ if (xso == NULL) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
goto err;
+ }
qc_touch_default_xso(qc); /* inhibits default XSO */
if (need_lock)
break;
default:
+ ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
ret = 0;
break;
}
if (!expect_quic_with_stream_lock(ssl, /*remote_init=*/-1, &ctx))
return 0;
- if (!ossl_quic_stream_has_send(ctx.xso->stream))
+ if (!ossl_quic_stream_has_send(ctx.xso->stream)) {
/* Called on a unidirectional receive-only stream - error. */
+ ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
goto out;
+ }
if (!ossl_quic_stream_has_send_buffer(ctx.xso->stream)) {
/*
goto out;
}
- if (!ossl_quic_sstream_set_buffer_size(ctx.xso->stream->sstream, size))
+ if (!ossl_quic_sstream_set_buffer_size(ctx.xso->stream->sstream, size)) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
goto out;
+ }
ret = 1;
break;
default:
- /* Unknown type - error. */
+ ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
}
}
if (!ossl_quic_rstream_queue_data(rstream, parent_pkt,
- f.offset, f.data, f.len, 0))
+ f.offset, f.data, f.len, 0)) {
+ ossl_quic_channel_raise_protocol_error(ch,
+ QUIC_ERR_INTERNAL_ERROR,
+ OSSL_QUIC_FRAME_TYPE_CRYPTO,
+ "internal error (rstream queue)");
return 0;
+ }
*datalen = f.len;
frame_data.offset,
frame_data.data,
frame_data.len,
- frame_data.is_fin))
+ frame_data.is_fin)) {
+ ossl_quic_channel_raise_protocol_error(ch,
+ QUIC_ERR_INTERNAL_ERROR,
+ frame_type,
+ "internal error (rstream queue)");
return 0;
+ }
/*
* rs_fin will be 1 only if we can read all data up to and including the FIN
* calling ossl_quic_rstream_available() where it is not necessary as it is
* more expensive.
*/
- if (stream->recv_state == QUIC_RSTREAM_STATE_SIZE_KNOWN)
- if (!ossl_quic_rstream_available(stream->rstream, &rs_avail, &rs_fin))
- return 0;
+ if (stream->recv_state == QUIC_RSTREAM_STATE_SIZE_KNOWN
+ && !ossl_quic_rstream_available(stream->rstream, &rs_avail, &rs_fin)) {
+ ossl_quic_channel_raise_protocol_error(ch,
+ QUIC_ERR_INTERNAL_ERROR,
+ frame_type,
+ "internal error (rstream available)");
+ return 0;
+ }
if (rs_fin)
ossl_quic_stream_map_notify_totally_received(&ch->qsm, stream);
return 1;
}
-static int depack_do_frame_conn_close(PACKET *pkt, QUIC_CHANNEL *ch)
+static int depack_do_frame_conn_close(PACKET *pkt, QUIC_CHANNEL *ch,
+ uint64_t frame_type)
{
OSSL_QUIC_FRAME_CONN_CLOSE frame_data;
- if (!ossl_quic_wire_decode_frame_conn_close(pkt, &frame_data))
+ if (!ossl_quic_wire_decode_frame_conn_close(pkt, &frame_data)) {
+ ossl_quic_channel_raise_protocol_error(ch,
+ QUIC_ERR_FRAME_ENCODING_ERROR,
+ frame_type,
+ "decode error");
return 0;
+ }
ossl_quic_channel_on_remote_conn_close(ch, &frame_data);
return 1;
QUIC_CHANNEL *ch,
OSSL_ACKM_RX_PKT *ackm_data)
{
- if (!ossl_quic_wire_decode_frame_handshake_done(pkt))
+ if (!ossl_quic_wire_decode_frame_handshake_done(pkt)) {
+ /* This can fail only with an internal error. */
+ ossl_quic_channel_raise_protocol_error(ch,
+ QUIC_ERR_INTERNAL_ERROR,
+ OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE,
+ "internal error (decode frame handshake done)");
return 0;
+ }
ossl_quic_channel_on_handshake_confirmed(ch);
return 1;
/* FALLTHRU */
case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT:
/* CONN_CLOSE_TRANSPORT frames are valid in all packets */
- if (!depack_do_frame_conn_close(pkt, ch))
+ if (!depack_do_frame_conn_close(pkt, ch, frame_type))
return 0;
break;
&& pkt[QUIC_ENC_LEVEL_HANDSHAKE].h.bytes_appended > 0);
/* Flush & Cleanup */
- res = TX_PACKETISER_RES_NO_PKT;
+ res = pkts_done > 0 ? TX_PACKETISER_RES_SENT_PKT : TX_PACKETISER_RES_NO_PKT;
out:
ossl_qtx_finish_dgram(txp->args.qtx);
++enc_level)
txp_pkt_cleanup(&pkt[enc_level], txp);
- /*
- * If we already successfully did at least one, make sure we report this via
- * the return code.
- */
- return pkts_done > 0 ? TX_PACKETISER_RES_SENT_PKT : res;
+ return res;
}
static const struct archetype_data archetypes[QUIC_ENC_LEVEL_NUM][TX_PACKETISER_ARCHETYPE_NUM] = {