* Decodes a QUIC CRYPTO frame.
*
* f->data is set to point inside the packet buffer inside the PACKET, therefore
- * it is safe to access for as long as the packet buffer exists.
+ * it is safe to access for as long as the packet buffer exists. If nodata is
+ * set to 1 then reading the PACKET stops after the frame header and f->data is
+ * set to NULL.
*/
-int ossl_quic_wire_decode_frame_crypto(PACKET *pkt,
+int ossl_quic_wire_decode_frame_crypto(PACKET *pkt, int nodata,
OSSL_QUIC_FRAME_CRYPTO *f);
/*
/*
* Decodes a QUIC STREAM frame.
*
+ * If nodata is set to 1 then reading the PACKET stops after the frame header
+ * and f->data is set to NULL. In this case f->len will also be 0 in the event
+ * that "has_explicit_len" is 0.
+ *
* If the frame did not contain an offset field, f->offset is set to 0, as the
* absence of an offset field is equivalent to an offset of 0.
*
* f->is_fin is set according to whether the frame was marked as ending the
* stream.
*/
-int ossl_quic_wire_decode_frame_stream(PACKET *pkt,
+int ossl_quic_wire_decode_frame_stream(PACKET *pkt, int nodata,
OSSL_QUIC_FRAME_STREAM *f);
/*
*datalen = 0;
- if (!ossl_quic_wire_decode_frame_crypto(pkt, &f)) {
+ if (!ossl_quic_wire_decode_frame_crypto(pkt, 0, &f)) {
ossl_quic_channel_raise_protocol_error(ch,
QUIC_ERR_FRAME_ENCODING_ERROR,
OSSL_QUIC_FRAME_TYPE_CRYPTO,
*datalen = 0;
- if (!ossl_quic_wire_decode_frame_stream(pkt, &frame_data)) {
+ if (!ossl_quic_wire_decode_frame_stream(pkt, 0, &frame_data)) {
ossl_quic_channel_raise_protocol_error(ch,
QUIC_ERR_FRAME_ENCODING_ERROR,
frame_type,
{
OSSL_QUIC_FRAME_CRYPTO frame_data;
- if (!ossl_quic_wire_decode_frame_crypto(pkt, &frame_data))
+ if (!ossl_quic_wire_decode_frame_crypto(pkt, 1, &frame_data))
return 0;
BIO_printf(bio, " Offset: %lu\n", frame_data.offset);
return 0;
}
- if (!ossl_quic_wire_decode_frame_stream(pkt, &frame_data))
+ if (!ossl_quic_wire_decode_frame_stream(pkt, 1, &frame_data))
return 0;
BIO_printf(bio, " Stream id: %lu\n", frame_data.stream_id);
BIO_printf(bio, " Offset: %lu\n", frame_data.offset);
- BIO_printf(bio, " Len: %lu\n", frame_data.len);
+ /*
+ * It would be nice to find a way of passing the implicit length through
+ * to the msg_callback. But this is not currently possible.
+ */
+ if (frame_data.has_explicit_len)
+ BIO_printf(bio, " Len: %lu\n", frame_data.len);
+ else
+ BIO_puts(bio, " Len: <implicit length>\n");
return 1;
}
case SSL3_RT_QUIC_FRAME_PADDING:
case SSL3_RT_QUIC_FRAME_FULL:
+ case SSL3_RT_QUIC_FRAME_HEADER:
{
BIO_puts(bio, write_p ? "Sent" : "Received");
BIO_puts(bio, " Frame: ");
}
break;
- case SSL3_RT_QUIC_FRAME_HEADER:
- {
- BIO_puts(bio, write_p ? "Sent" : "Received");
- BIO_puts(bio, " Frame Data\n");
-
- /* TODO(QUIC): Implement me */
- BIO_puts(bio, " <content skipped>\n");
- }
- break;
-
default:
/* Unrecognised content_type. We defer to SSL_trace */
return 0;
}
int ossl_quic_wire_decode_frame_crypto(PACKET *pkt,
+ int nodata,
OSSL_QUIC_FRAME_CRYPTO *f)
{
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)
|| f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */)
return 0;
- if (PACKET_remaining(pkt) < f->len)
- return 0;
+ if (nodata) {
+ f->data = NULL;
+ } else {
+ if (PACKET_remaining(pkt) < f->len)
+ return 0;
- f->data = PACKET_data(pkt);
+ f->data = PACKET_data(pkt);
- if (!PACKET_forward(pkt, (size_t)f->len))
- return 0;
+ if (!PACKET_forward(pkt, (size_t)f->len))
+ return 0;
+ }
return 1;
}
}
int ossl_quic_wire_decode_frame_stream(PACKET *pkt,
+ int nodata,
OSSL_QUIC_FRAME_STREAM *f)
{
uint64_t frame_type;
if (!PACKET_get_quic_vlint(pkt, &f->len))
return 0;
} else {
- f->len = PACKET_remaining(pkt);
+ if (nodata)
+ f->len = 0;
+ else
+ f->len = PACKET_remaining(pkt);
}
- f->data = PACKET_data(pkt);
+ if (nodata) {
+ f->data = NULL;
+ } else {
+ f->data = PACKET_data(pkt);
- if (f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */
- || !PACKET_forward(pkt, (size_t)f->len))
- return 0;
+ if (f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */
+ || !PACKET_forward(pkt, (size_t)f->len))
+ return 0;
+ }
return 1;
}
goto err;
break;
case OSSL_QUIC_FRAME_TYPE_CRYPTO:
- if (!TEST_true(ossl_quic_wire_decode_frame_crypto(&h.pkt, &h.frame.crypto)))
+ if (!TEST_true(ossl_quic_wire_decode_frame_crypto(&h.pkt, 0, &h.frame.crypto)))
goto err;
break;
case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN:
case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN:
case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN:
- if (!TEST_true(ossl_quic_wire_decode_frame_stream(&h.pkt, &h.frame.stream)))
+ if (!TEST_true(ossl_quic_wire_decode_frame_stream(&h.pkt, 0, &h.frame.stream)))
goto err;
break;
{
OSSL_QUIC_FRAME_CRYPTO f = {0};
- if (!TEST_int_eq(ossl_quic_wire_decode_frame_crypto(pkt, &f), fail < 0))
+ if (!TEST_int_eq(ossl_quic_wire_decode_frame_crypto(pkt, 0, &f), fail < 0))
return 0;
if (fail >= 0)
*/
return 1;
- if (!TEST_int_eq(ossl_quic_wire_decode_frame_stream(pkt, &f), fail < 0))
+ if (!TEST_int_eq(ossl_quic_wire_decode_frame_stream(pkt, 0, &f), fail < 0))
return 0;
if (fail >= 0)
{
OSSL_QUIC_FRAME_STREAM f = {0};
- if (!TEST_int_eq(ossl_quic_wire_decode_frame_stream(pkt, &f), fail < 0))
+ if (!TEST_int_eq(ossl_quic_wire_decode_frame_stream(pkt, 0, &f), fail < 0))
return 0;
if (fail >= 0)