Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/ngtcp2/lib/ngtcp2_crypto.c')
-rw-r--r--deps/ngtcp2/lib/ngtcp2_crypto.c173
1 files changed, 128 insertions, 45 deletions
diff --git a/deps/ngtcp2/lib/ngtcp2_crypto.c b/deps/ngtcp2/lib/ngtcp2_crypto.c
index dd65ff7e303..26eacb87299 100644
--- a/deps/ngtcp2/lib/ngtcp2_crypto.c
+++ b/deps/ngtcp2/lib/ngtcp2_crypto.c
@@ -72,6 +72,7 @@ int ngtcp2_crypto_km_nocopy_new(ngtcp2_crypto_km **pckm, size_t secretlen,
(*pckm)->iv.base = p;
(*pckm)->iv.len = ivlen;
(*pckm)->pkt_num = -1;
+ (*pckm)->use_count = 0;
(*pckm)->flags = NGTCP2_CRYPTO_KM_FLAG_NONE;
return 0;
@@ -118,6 +119,33 @@ static uint8_t *write_varint_param(uint8_t *p, ngtcp2_transport_param_id id,
return ngtcp2_put_varint(p, value);
}
+/*
+ * cid_paramlen returns the length of a single transport parameter
+ * which has |cid| as value.
+ */
+static size_t cid_paramlen(ngtcp2_transport_param_id id,
+ const ngtcp2_cid *cid) {
+ return ngtcp2_put_varint_len(id) + ngtcp2_put_varint_len(cid->datalen) +
+ cid->datalen;
+}
+
+/*
+ * write_cid_param writes parameter |id| of the given |cid|. It
+ * returns p + the number of bytes written.
+ */
+static uint8_t *write_cid_param(uint8_t *p, ngtcp2_transport_param_id id,
+ const ngtcp2_cid *cid) {
+ assert(cid->datalen == 0 || cid->datalen >= NGTCP2_MIN_CIDLEN);
+ assert(cid->datalen <= NGTCP2_MAX_CIDLEN);
+
+ p = ngtcp2_put_varint(p, id);
+ p = ngtcp2_put_varint(p, cid->datalen);
+ if (cid->datalen) {
+ p = ngtcp2_cpymem(p, cid->data, cid->datalen);
+ }
+ return p;
+}
+
ngtcp2_ssize
ngtcp2_encode_transport_params(uint8_t *dest, size_t destlen,
ngtcp2_transport_params_type exttype,
@@ -131,6 +159,10 @@ ngtcp2_encode_transport_params(uint8_t *dest, size_t destlen,
case NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO:
break;
case NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS:
+ len +=
+ cid_paramlen(NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID,
+ &params->original_dcid);
+
if (params->stateless_reset_token_present) {
len +=
ngtcp2_put_varint_len(NGTCP2_TRANSPORT_PARAM_STATELESS_RESET_TOKEN) +
@@ -138,8 +170,7 @@ ngtcp2_encode_transport_params(uint8_t *dest, size_t destlen,
NGTCP2_STATELESS_RESET_TOKENLEN;
}
if (params->preferred_address_present) {
- assert(params->preferred_address.cid.datalen == 0 ||
- params->preferred_address.cid.datalen >= NGTCP2_MIN_CIDLEN);
+ assert(params->preferred_address.cid.datalen >= NGTCP2_MIN_CIDLEN);
assert(params->preferred_address.cid.datalen <= NGTCP2_MAX_CIDLEN);
preferred_addrlen = 4 /* ipv4Address */ + 2 /* ipv4Port */ +
16 /* ipv6Address */ + 2 /* ipv6Port */
@@ -149,17 +180,18 @@ ngtcp2_encode_transport_params(uint8_t *dest, size_t destlen,
len += ngtcp2_put_varint_len(NGTCP2_TRANSPORT_PARAM_PREFERRED_ADDRESS) +
ngtcp2_put_varint_len(preferred_addrlen) + preferred_addrlen;
}
- if (params->original_connection_id_present) {
- len +=
- ngtcp2_put_varint_len(NGTCP2_TRANSPORT_PARAM_ORIGINAL_CONNECTION_ID) +
- ngtcp2_put_varint_len(params->original_connection_id.datalen) +
- params->original_connection_id.datalen;
+ if (params->retry_scid_present) {
+ len += cid_paramlen(NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID,
+ &params->retry_scid);
}
break;
default:
return NGTCP2_ERR_INVALID_ARGUMENT;
}
+ len += cid_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID,
+ &params->initial_scid);
+
if (params->initial_max_stream_data_bidi_local) {
len += varint_paramlen(
NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL,
@@ -186,9 +218,9 @@ ngtcp2_encode_transport_params(uint8_t *dest, size_t destlen,
len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAMS_UNI,
params->initial_max_streams_uni);
}
- if (params->max_packet_size != NGTCP2_MAX_PKT_SIZE) {
- len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_MAX_PACKET_SIZE,
- params->max_packet_size);
+ if (params->max_udp_payload_size != NGTCP2_DEFAULT_MAX_UDP_PAYLOAD_SIZE) {
+ len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE,
+ params->max_udp_payload_size);
}
if (params->ack_delay_exponent != NGTCP2_DEFAULT_ACK_DELAY_EXPONENT) {
len += varint_paramlen(NGTCP2_TRANSPORT_PARAM_ACK_DELAY_EXPONENT,
@@ -221,6 +253,10 @@ ngtcp2_encode_transport_params(uint8_t *dest, size_t destlen,
p = dest;
if (exttype == NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS) {
+ p = write_cid_param(
+ p, NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID,
+ &params->original_dcid);
+
if (params->stateless_reset_token_present) {
p = ngtcp2_put_varint(p, NGTCP2_TRANSPORT_PARAM_STATELESS_RESET_TOKEN);
p = ngtcp2_put_varint(p, sizeof(params->stateless_reset_token));
@@ -248,14 +284,15 @@ ngtcp2_encode_transport_params(uint8_t *dest, size_t destlen,
p, params->preferred_address.stateless_reset_token,
sizeof(params->preferred_address.stateless_reset_token));
}
- if (params->original_connection_id_present) {
- p = ngtcp2_put_varint(p, NGTCP2_TRANSPORT_PARAM_ORIGINAL_CONNECTION_ID);
- p = ngtcp2_put_varint(p, params->original_connection_id.datalen);
- p = ngtcp2_cpymem(p, params->original_connection_id.data,
- params->original_connection_id.datalen);
+ if (params->retry_scid_present) {
+ p = write_cid_param(p, NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID,
+ &params->retry_scid);
}
}
+ p = write_cid_param(p, NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID,
+ &params->initial_scid);
+
if (params->initial_max_stream_data_bidi_local) {
p = write_varint_param(
p, NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL,
@@ -289,9 +326,9 @@ ngtcp2_encode_transport_params(uint8_t *dest, size_t destlen,
params->initial_max_streams_uni);
}
- if (params->max_packet_size != NGTCP2_MAX_PKT_SIZE) {
- p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_MAX_PACKET_SIZE,
- params->max_packet_size);
+ if (params->max_udp_payload_size != NGTCP2_DEFAULT_MAX_UDP_PAYLOAD_SIZE) {
+ p = write_varint_param(p, NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE,
+ params->max_udp_payload_size);
}
if (params->ack_delay_exponent != NGTCP2_DEFAULT_ACK_DELAY_EXPONENT) {
@@ -371,6 +408,10 @@ static ngtcp2_ssize decode_varint_param(uint64_t *pdest, const uint8_t *p,
p += nread;
+ if (p == end) {
+ return -1;
+ }
+
if ((uint64_t)(end - p) < valuelen) {
return -1;
}
@@ -386,6 +427,37 @@ static ngtcp2_ssize decode_varint_param(uint64_t *pdest, const uint8_t *p,
return (ngtcp2_ssize)(p - begin);
}
+/*
+ * decode_cid_param decodes length prefixed ngtcp2_cid from the buffer
+ * pointed by |p| of length |end - p|. The length is encoded in
+ * varint form. If it decodes a value successfully, it stores the
+ * value in |*pdest| and returns the number of bytes read. Otherwise
+ * it returns -1.
+ */
+static ngtcp2_ssize decode_cid_param(ngtcp2_cid *pdest, const uint8_t *p,
+ const uint8_t *end) {
+ const uint8_t *begin = p;
+ uint64_t valuelen;
+ ngtcp2_ssize nread = decode_varint(&valuelen, p, end);
+
+ if (nread < 0) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+
+ p += nread;
+
+ if ((valuelen != 0 && valuelen < NGTCP2_MIN_CIDLEN) ||
+ valuelen > NGTCP2_MAX_CIDLEN || (size_t)(end - p) < valuelen) {
+ return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ }
+
+ ngtcp2_cid_init(pdest, p, (size_t)valuelen);
+
+ p += valuelen;
+
+ return (ngtcp2_ssize)(p - begin);
+}
+
int ngtcp2_decode_transport_params(ngtcp2_transport_params *params,
ngtcp2_transport_params_type exttype,
const uint8_t *data, size_t datalen) {
@@ -394,37 +466,37 @@ int ngtcp2_decode_transport_params(ngtcp2_transport_params *params,
uint64_t param_type;
uint64_t valuelen;
ngtcp2_ssize nread;
- uint8_t scb[8192];
- size_t scb_idx;
- size_t scb_shift;
+ int initial_scid_present = 0;
+ int original_dcid_present = 0;
p = data;
end = data + datalen;
/* Set default values */
+ memset(params, 0, sizeof(*params));
params->initial_max_streams_bidi = 0;
params->initial_max_streams_uni = 0;
params->initial_max_stream_data_bidi_local = 0;
params->initial_max_stream_data_bidi_remote = 0;
params->initial_max_stream_data_uni = 0;
- params->max_packet_size = NGTCP2_MAX_PKT_SIZE;
+ params->max_udp_payload_size = NGTCP2_DEFAULT_MAX_UDP_PAYLOAD_SIZE;
params->ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
params->stateless_reset_token_present = 0;
params->preferred_address_present = 0;
- memset(&params->preferred_address, 0, sizeof(params->preferred_address));
params->disable_active_migration = 0;
params->max_ack_delay = NGTCP2_DEFAULT_MAX_ACK_DELAY;
params->max_idle_timeout = 0;
params->active_connection_id_limit =
NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
- params->original_connection_id_present = 0;
+ params->retry_scid_present = 0;
+ memset(&params->retry_scid, 0, sizeof(params->retry_scid));
+ memset(&params->initial_scid, 0, sizeof(params->initial_scid));
+ memset(&params->original_dcid, 0, sizeof(params->original_dcid));
if (datalen == 0) {
return 0;
}
- memset(scb, 0, sizeof(scb));
-
for (; (size_t)(end - p) >= 2;) {
nread = decode_varint(&param_type, p, end);
if (nread < 0) {
@@ -432,13 +504,6 @@ int ngtcp2_decode_transport_params(ngtcp2_transport_params *params,
}
p += nread;
- scb_idx = param_type / 8;
- scb_shift = param_type % 8;
-
- if (scb[scb_idx] & (1 << scb_shift)) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
- }
- scb[scb_idx] |= (uint8_t)(1 << scb_shift);
switch (param_type) {
case NGTCP2_TRANSPORT_PARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL:
nread = decode_varint_param(&params->initial_max_stream_data_bidi_local,
@@ -498,8 +563,8 @@ int ngtcp2_decode_transport_params(ngtcp2_transport_params *params,
params->max_idle_timeout *= NGTCP2_MILLISECONDS;
p += nread;
break;
- case NGTCP2_TRANSPORT_PARAM_MAX_PACKET_SIZE:
- nread = decode_varint_param(&params->max_packet_size, p, end);
+ case NGTCP2_TRANSPORT_PARAM_MAX_UDP_PAYLOAD_SIZE:
+ nread = decode_varint_param(&params->max_udp_payload_size, p, end);
if (nread < 0) {
return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
}
@@ -570,8 +635,7 @@ int ngtcp2_decode_transport_params(ngtcp2_transport_params *params,
len += params->preferred_address.cid.datalen;
if (valuelen != len ||
params->preferred_address.cid.datalen > NGTCP2_MAX_CIDLEN ||
- (params->preferred_address.cid.datalen != 0 &&
- params->preferred_address.cid.datalen < NGTCP2_MIN_CIDLEN)) {
+ params->preferred_address.cid.datalen < NGTCP2_MIN_CIDLEN) {
return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
}
if (params->preferred_address.cid.datalen) {
@@ -594,22 +658,35 @@ int ngtcp2_decode_transport_params(ngtcp2_transport_params *params,
p += nread;
params->disable_active_migration = 1;
break;
- case NGTCP2_TRANSPORT_PARAM_ORIGINAL_CONNECTION_ID:
+ case NGTCP2_TRANSPORT_PARAM_ORIGINAL_DESTINATION_CONNECTION_ID:
if (exttype != NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS) {
return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
}
- nread = decode_varint(&valuelen, p, end);
+ nread = decode_cid_param(&params->original_dcid, p, end);
if (nread < 0) {
- return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
+ return (int)nread;
}
+ original_dcid_present = 1;
p += nread;
- if (valuelen < NGTCP2_MIN_CIDLEN || valuelen > NGTCP2_MAX_CIDLEN ||
- (size_t)(end - p) < valuelen) {
+ break;
+ case NGTCP2_TRANSPORT_PARAM_RETRY_SOURCE_CONNECTION_ID:
+ if (exttype != NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS) {
return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
}
- ngtcp2_cid_init(&params->original_connection_id, p, valuelen);
- params->original_connection_id_present = 1;
- p += valuelen;
+ nread = decode_cid_param(&params->retry_scid, p, end);
+ if (nread < 0) {
+ return (int)nread;
+ }
+ params->retry_scid_present = 1;
+ p += nread;
+ break;
+ case NGTCP2_TRANSPORT_PARAM_INITIAL_SOURCE_CONNECTION_ID:
+ nread = decode_cid_param(&params->initial_scid, p, end);
+ if (nread < 0) {
+ return (int)nread;
+ }
+ initial_scid_present = 1;
+ p += nread;
break;
case NGTCP2_TRANSPORT_PARAM_MAX_ACK_DELAY:
nread = decode_varint_param(&params->max_ack_delay, p, end);
@@ -645,5 +722,11 @@ int ngtcp2_decode_transport_params(ngtcp2_transport_params *params,
return NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM;
}
+ if (!initial_scid_present ||
+ (exttype == NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS &&
+ !original_dcid_present)) {
+ return NGTCP2_ERR_REQUIRED_TRANSPORT_PARAM;
+ }
+
return 0;
}