Merge pull request #315 from h2o/kazuho/stack-usage
reduce stack usage
diff --git a/lib/picotls.c b/lib/picotls.c
index 774b879..e6bd528 100644
--- a/lib/picotls.c
+++ b/lib/picotls.c
@@ -1236,7 +1236,7 @@
return setup_traffic_protection(tls, is_enc, NULL, 2, 1);
}
-static inline void log_client_random(ptls_t *tls)
+static void log_client_random(ptls_t *tls)
{
PTLS_PROBE(CLIENT_RANDOM, tls,
ptls_hexdump(alloca(sizeof(tls->client_random) * 2 + 1), tls->client_random, sizeof(tls->client_random)));
@@ -2385,21 +2385,24 @@
return ret;
}
-static int handle_unknown_extension(ptls_t *tls, ptls_handshake_properties_t *properties, uint16_t type, const uint8_t *src,
- const uint8_t *const end, ptls_raw_extension_t *slots)
+static int should_collect_unknown_extension(ptls_t *tls, ptls_handshake_properties_t *properties, uint16_t type)
{
- if (properties != NULL && properties->collect_extension != NULL && properties->collect_extension(tls, properties, type)) {
- size_t i;
- for (i = 0; slots[i].type != UINT16_MAX; ++i) {
- assert(i < MAX_UNKNOWN_EXTENSIONS);
- if (slots[i].type == type)
- return PTLS_ALERT_ILLEGAL_PARAMETER;
- }
- if (i < MAX_UNKNOWN_EXTENSIONS) {
- slots[i].type = type;
- slots[i].data = ptls_iovec_init(src, end - src);
- slots[i + 1].type = UINT16_MAX;
- }
+ return properties != NULL && properties->collect_extension != NULL && properties->collect_extension(tls, properties, type);
+}
+
+static int collect_unknown_extension(ptls_t *tls, uint16_t type, const uint8_t *src, const uint8_t *const end,
+ ptls_raw_extension_t *slots)
+{
+ size_t i;
+ for (i = 0; slots[i].type != UINT16_MAX; ++i) {
+ assert(i < MAX_UNKNOWN_EXTENSIONS);
+ if (slots[i].type == type)
+ return PTLS_ALERT_ILLEGAL_PARAMETER;
+ }
+ if (i < MAX_UNKNOWN_EXTENSIONS) {
+ slots[i].type = type;
+ slots[i].data = ptls_iovec_init(src, end - src);
+ slots[i + 1].type = UINT16_MAX;
}
return 0;
}
@@ -2418,11 +2421,10 @@
{
const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len, *esni_nonce = NULL;
uint16_t type;
- ptls_raw_extension_t unknown_extensions[MAX_UNKNOWN_EXTENSIONS + 1];
+ static const ptls_raw_extension_t no_unknown_extensions = {UINT16_MAX};
+ ptls_raw_extension_t *unknown_extensions = (ptls_raw_extension_t *)&no_unknown_extensions;
int ret, skip_early_data = 1;
- unknown_extensions[0].type = UINT16_MAX;
-
decode_extensions(src, end, PTLS_HANDSHAKE_TYPE_ENCRYPTED_EXTENSIONS, &type, {
if (tls->ctx->on_extension != NULL &&
(ret = tls->ctx->on_extension->cb(tls->ctx->on_extension, tls, PTLS_HANDSHAKE_TYPE_ENCRYPTED_EXTENSIONS, type,
@@ -2477,7 +2479,17 @@
skip_early_data = 0;
break;
default:
- handle_unknown_extension(tls, properties, type, src, end, unknown_extensions);
+ if (should_collect_unknown_extension(tls, properties, type)) {
+ if (unknown_extensions == &no_unknown_extensions) {
+ if ((unknown_extensions = malloc(sizeof(*unknown_extensions) * (MAX_UNKNOWN_EXTENSIONS + 1))) == NULL) {
+ ret = PTLS_ERROR_NO_MEMORY;
+ goto Exit;
+ }
+ unknown_extensions[0].type = UINT16_MAX;
+ }
+ if ((ret = collect_unknown_extension(tls, type, src, end, unknown_extensions)) != 0)
+ goto Exit;
+ }
break;
}
src = end;
@@ -2511,6 +2523,8 @@
ret = PTLS_ERROR_IN_PROGRESS;
Exit:
+ if (unknown_extensions != &no_unknown_extensions)
+ free(unknown_extensions);
return ret;
}
@@ -2955,8 +2969,7 @@
/* save the extension, along with the key of myself */
ptls_buffer_t ticket_buf;
- uint8_t ticket_buf_small[512];
- ptls_buffer_init(&ticket_buf, ticket_buf_small, sizeof(ticket_buf_small));
+ ptls_buffer_init(&ticket_buf, "", 0);
ptls_buffer_push64(&ticket_buf, tls->ctx->get_time->cb(tls->ctx->get_time));
ptls_buffer_push16(&ticket_buf, tls->key_share->id);
ptls_buffer_push16(&ticket_buf, tls->cipher_suite->id);
@@ -3401,7 +3414,10 @@
ch->status_request = 1;
break;
default:
- handle_unknown_extension(tls, properties, exttype, src, end, ch->unknown_extensions);
+ if (should_collect_unknown_extension(tls, properties, exttype)) {
+ if ((ret = collect_unknown_extension(tls, exttype, src, end, ch->unknown_extensions)) != 0)
+ goto Exit;
+ }
break;
}
src = end;
@@ -3425,10 +3441,10 @@
uint64_t issue_at, now = tls->ctx->get_time->cb(tls->ctx->get_time);
uint32_t age_add;
uint16_t ticket_key_exchange_id, ticket_csid;
- uint8_t decbuf_small[256], binder_key[PTLS_MAX_DIGEST_SIZE], verify_data[PTLS_MAX_DIGEST_SIZE];
+ uint8_t binder_key[PTLS_MAX_DIGEST_SIZE];
int ret;
- ptls_buffer_init(&decbuf, decbuf_small, sizeof(decbuf_small));
+ ptls_buffer_init(&decbuf, "", 0);
for (*psk_index = 0; *psk_index < ch->psk.identities.count; ++*psk_index) {
struct st_ptls_client_hello_psk_t *identity = ch->psk.identities.list + *psk_index;
@@ -3512,9 +3528,10 @@
if ((ret = derive_secret(tls->key_schedule, binder_key, "res binder")) != 0)
goto Exit;
ptls__key_schedule_update_hash(tls->key_schedule, ch_trunc.base, ch_trunc.len);
- if ((ret = calc_verify_data(verify_data, tls->key_schedule, binder_key)) != 0)
+ if ((ret = calc_verify_data(binder_key /* to conserve space, reuse binder_key for storing verify_data */, tls->key_schedule,
+ binder_key)) != 0)
goto Exit;
- if (!ptls_mem_equal(ch->psk.identities.list[*psk_index].binder.base, verify_data,
+ if (!ptls_mem_equal(ch->psk.identities.list[*psk_index].binder.base, binder_key,
tls->key_schedule->hashes[0].algo->digest_size)) {
ret = PTLS_ALERT_DECRYPT_ERROR;
goto Exit;
@@ -3524,7 +3541,6 @@
Exit:
ptls_buffer_dispose(&decbuf);
ptls_clear_memory(binder_key, sizeof(binder_key));
- ptls_clear_memory(verify_data, sizeof(verify_data));
return ret;
}
@@ -3580,12 +3596,12 @@
} while (0); \
emitter->buf->off += PTLS_HELLO_RANDOM_SIZE; \
ptls_buffer_push_block(emitter->buf, 1, \
- { ptls_buffer_pushv(emitter->buf, ch.legacy_session_id.base, ch.legacy_session_id.len); }); \
+ { ptls_buffer_pushv(emitter->buf, ch->legacy_session_id.base, ch->legacy_session_id.len); }); \
ptls_buffer_push16(emitter->buf, tls->cipher_suite->id); \
ptls_buffer_push(emitter->buf, 0); \
ptls_buffer_push_block(emitter->buf, 2, { \
buffer_push_extension(emitter->buf, PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS, \
- { ptls_buffer_push16(emitter->buf, ch.selected_version); }); \
+ { ptls_buffer_push16(emitter->buf, ch->selected_version); }); \
do { \
extensions \
} while (0); \
@@ -3604,8 +3620,7 @@
additional_extensions \
} while (0); \
})
- struct st_ptls_client_hello_t ch = {0, NULL, {NULL}, {NULL}, 0, {NULL}, {NULL}, {NULL}, {{0}},
- {NULL}, {NULL}, {{{NULL}}}, {{0}}, {{0}}, {{NULL}}, {NULL}, {{UINT16_MAX}}};
+ struct st_ptls_client_hello_t *ch;
struct {
ptls_key_exchange_algorithm_t *algorithm;
ptls_iovec_t peer_key;
@@ -3615,18 +3630,25 @@
ptls_iovec_t pubkey = {0}, ecdh_secret = {0};
int accept_early_data = 0, is_second_flight = tls->state == PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO, ret;
+ if ((ch = malloc(sizeof(*ch))) == NULL) {
+ ret = PTLS_ERROR_NO_MEMORY;
+ goto Exit;
+ }
+ *ch = (struct st_ptls_client_hello_t){0, NULL, {NULL}, {NULL}, 0, {NULL}, {NULL}, {NULL}, {{0}},
+ {NULL}, {NULL}, {{{NULL}}}, {{0}}, {{0}}, {{NULL}}, {NULL}, {{UINT16_MAX}}};
+
/* decode ClientHello */
- if ((ret = decode_client_hello(tls, &ch, message.base + PTLS_HANDSHAKE_HEADER_SIZE, message.base + message.len, properties)) !=
+ if ((ret = decode_client_hello(tls, ch, message.base + PTLS_HANDSHAKE_HEADER_SIZE, message.base + message.len, properties)) !=
0)
goto Exit;
/* bail out if CH cannot be handled as TLS 1.3, providing the application the raw CH and SNI, to help them fallback */
- if (!is_supported_version(ch.selected_version)) {
+ if (!is_supported_version(ch->selected_version)) {
if (!is_second_flight && tls->ctx->on_client_hello != NULL) {
ptls_on_client_hello_parameters_t params = {
- .server_name = ch.server_name,
+ .server_name = ch->server_name,
.raw_message = message,
- .negotiated_protocols = {ch.alpn.list, ch.alpn.count},
+ .negotiated_protocols = {ch->alpn.list, ch->alpn.count},
.incompatible_version = 1,
};
if ((ret = tls->ctx->on_client_hello->cb(tls->ctx->on_client_hello, tls, ¶ms)) != 0)
@@ -3638,67 +3660,67 @@
/* Check TLS 1.3-specific constraints. Hereafter, we might exit without calling on_client_hello. That's fine because this CH is
* ought to be rejected. */
- if (ch.legacy_version <= 0x0300) {
+ if (ch->legacy_version <= 0x0300) {
/* RFC 8446 Appendix D.5: any endpoint receiving a Hello message with legacy_version set to 0x0300 MUST abort the handshake
* with a "protocol_version" alert. */
ret = PTLS_ALERT_PROTOCOL_VERSION;
goto Exit;
}
- if (!(ch.compression_methods.count == 1 && ch.compression_methods.ids[0] == 0)) {
+ if (!(ch->compression_methods.count == 1 && ch->compression_methods.ids[0] == 0)) {
ret = PTLS_ALERT_ILLEGAL_PARAMETER;
goto Exit;
}
/* esni */
- if (ch.esni.cipher != NULL) {
- if (ch.key_shares.base == NULL) {
+ if (ch->esni.cipher != NULL) {
+ if (ch->key_shares.base == NULL) {
ret = PTLS_ALERT_ILLEGAL_PARAMETER;
goto Exit;
}
}
/* pre-shared key */
- if (ch.psk.hash_end != NULL) {
+ if (ch->psk.hash_end != NULL) {
/* PSK must be the last extension */
- if (!ch.psk.is_last_extension) {
+ if (!ch->psk.is_last_extension) {
ret = PTLS_ALERT_ILLEGAL_PARAMETER;
goto Exit;
}
} else {
- if (ch.psk.early_data_indication) {
+ if (ch->psk.early_data_indication) {
ret = PTLS_ALERT_ILLEGAL_PARAMETER;
goto Exit;
}
}
if (tls->ctx->require_dhe_on_psk)
- ch.psk.ke_modes &= ~(1u << PTLS_PSK_KE_MODE_PSK);
+ ch->psk.ke_modes &= ~(1u << PTLS_PSK_KE_MODE_PSK);
/* handle client_random, legacy_session_id, SNI, ESNI */
if (!is_second_flight) {
- memcpy(tls->client_random, ch.random_bytes, sizeof(tls->client_random));
+ memcpy(tls->client_random, ch->random_bytes, sizeof(tls->client_random));
log_client_random(tls);
- if (ch.legacy_session_id.len != 0)
+ if (ch->legacy_session_id.len != 0)
tls->send_change_cipher_spec = 1;
ptls_iovec_t server_name = {NULL};
int is_esni = 0;
- if (ch.esni.cipher != NULL && tls->ctx->esni != NULL) {
- if ((ret = client_hello_decrypt_esni(tls->ctx, &server_name, &tls->esni, &ch)) != 0)
+ if (ch->esni.cipher != NULL && tls->ctx->esni != NULL) {
+ if ((ret = client_hello_decrypt_esni(tls->ctx, &server_name, &tls->esni, ch)) != 0)
goto Exit;
if (tls->ctx->update_esni_key != NULL) {
- if ((ret = tls->ctx->update_esni_key->cb(tls->ctx->update_esni_key, tls, tls->esni->secret, ch.esni.cipher->hash,
+ if ((ret = tls->ctx->update_esni_key->cb(tls->ctx->update_esni_key, tls, tls->esni->secret, ch->esni.cipher->hash,
tls->esni->esni_contents_hash)) != 0)
goto Exit;
}
is_esni = 1;
- } else if (ch.server_name.base != NULL) {
- server_name = ch.server_name;
+ } else if (ch->server_name.base != NULL) {
+ server_name = ch->server_name;
}
if (tls->ctx->on_client_hello != NULL) {
ptls_on_client_hello_parameters_t params = {server_name,
message,
- {ch.alpn.list, ch.alpn.count},
- {ch.signature_algorithms.list, ch.signature_algorithms.count},
- {ch.cert_compression_algos.list, ch.cert_compression_algos.count},
- {ch.client_ciphers.list, ch.client_ciphers.count},
+ {ch->alpn.list, ch->alpn.count},
+ {ch->signature_algorithms.list, ch->signature_algorithms.count},
+ {ch->cert_compression_algos.list, ch->cert_compression_algos.count},
+ {ch->client_ciphers.list, ch->client_ciphers.count},
is_esni};
ret = tls->ctx->on_client_hello->cb(tls->ctx->on_client_hello, tls, ¶ms);
} else {
@@ -3709,13 +3731,13 @@
if (ret != 0)
goto Exit;
} else {
- if (ch.psk.early_data_indication) {
+ if (ch->psk.early_data_indication) {
ret = PTLS_ALERT_DECODE_ERROR;
goto Exit;
}
/* the following check is necessary so that we would be able to track the connection in SSLKEYLOGFILE, even though it
* might not be for the safety of the protocol */
- if (!ptls_mem_equal(tls->client_random, ch.random_bytes, sizeof(tls->client_random))) {
+ if (!ptls_mem_equal(tls->client_random, ch->random_bytes, sizeof(tls->client_random))) {
ret = PTLS_ALERT_HANDSHAKE_FAILURE;
goto Exit;
}
@@ -3723,7 +3745,7 @@
* ignoring the value unless the callback saves the server-name. */
if (tls->server_name != NULL) {
size_t l = strlen(tls->server_name);
- if (!(ch.server_name.len == l && memcmp(ch.server_name.base, tls->server_name, l) == 0)) {
+ if (!(ch->server_name.len == l && memcmp(ch->server_name.base, tls->server_name, l) == 0)) {
ret = PTLS_ALERT_HANDSHAKE_FAILURE;
goto Exit;
}
@@ -3732,8 +3754,8 @@
{ /* select (or check) cipher-suite, create key_schedule */
ptls_cipher_suite_t *cs;
- if ((ret = select_cipher(&cs, tls->ctx->cipher_suites, ch.cipher_suites.base,
- ch.cipher_suites.base + ch.cipher_suites.len)) != 0)
+ if ((ret = select_cipher(&cs, tls->ctx->cipher_suites, ch->cipher_suites.base,
+ ch->cipher_suites.base + ch->cipher_suites.len)) != 0)
goto Exit;
if (!is_second_flight) {
tls->cipher_suite = cs;
@@ -3747,8 +3769,8 @@
}
/* select key_share */
- if (key_share.algorithm == NULL && ch.key_shares.base != NULL) {
- const uint8_t *src = ch.key_shares.base, *const end = src + ch.key_shares.len;
+ if (key_share.algorithm == NULL && ch->key_shares.base != NULL) {
+ const uint8_t *src = ch->key_shares.base, *const end = src + ch->key_shares.len;
ptls_decode_block(src, end, 2, {
if ((ret = select_key_share(&key_share.algorithm, &key_share.peer_key, tls->ctx->key_exchanges, &src, end, 0)) != 0)
goto Exit;
@@ -3756,26 +3778,26 @@
}
if (!is_second_flight) {
- if (ch.cookie.all.len != 0 && key_share.algorithm != NULL) {
+ if (ch->cookie.all.len != 0 && key_share.algorithm != NULL) {
/* use cookie to check the integrity of the handshake, and update the context */
- uint8_t sig[PTLS_MAX_DIGEST_SIZE];
size_t sigsize = tls->ctx->cipher_suites[0]->hash->digest_size;
- if ((ret = calc_cookie_signature(tls, properties, key_share.algorithm, ch.cookie.tbs, sig)) != 0)
+ uint8_t *sig = alloca(sigsize);
+ if ((ret = calc_cookie_signature(tls, properties, key_share.algorithm, ch->cookie.tbs, sig)) != 0)
goto Exit;
- if (!(ch.cookie.signature.len == sigsize && ptls_mem_equal(ch.cookie.signature.base, sig, sigsize))) {
+ if (!(ch->cookie.signature.len == sigsize && ptls_mem_equal(ch->cookie.signature.base, sig, sigsize))) {
ret = PTLS_ALERT_HANDSHAKE_FAILURE;
goto Exit;
}
/* integrity check passed; update states */
key_schedule_update_ch1hash_prefix(tls->key_schedule);
- ptls__key_schedule_update_hash(tls->key_schedule, ch.cookie.ch1_hash.base, ch.cookie.ch1_hash.len);
+ ptls__key_schedule_update_hash(tls->key_schedule, ch->cookie.ch1_hash.base, ch->cookie.ch1_hash.len);
key_schedule_extract(tls->key_schedule, ptls_iovec_init(NULL, 0));
/* ... reusing sendbuf to rebuild HRR for hash calculation */
size_t hrr_start = emitter->buf->off;
- EMIT_HELLO_RETRY_REQUEST(tls->key_schedule, ch.cookie.sent_key_share ? key_share.algorithm : NULL, {
+ EMIT_HELLO_RETRY_REQUEST(tls->key_schedule, ch->cookie.sent_key_share ? key_share.algorithm : NULL, {
buffer_push_extension(emitter->buf, PTLS_EXTENSION_TYPE_COOKIE,
- { ptls_buffer_pushv(emitter->buf, ch.cookie.all.base, ch.cookie.all.len); });
+ { ptls_buffer_pushv(emitter->buf, ch->cookie.all.base, ch->cookie.all.len); });
});
emitter->buf->off = hrr_start;
is_second_flight = 1;
@@ -3783,13 +3805,13 @@
} else if (key_share.algorithm == NULL || (properties != NULL && properties->server.enforce_retry)) {
/* send HelloRetryRequest */
- if (ch.negotiated_groups.base == NULL) {
+ if (ch->negotiated_groups.base == NULL) {
ret = PTLS_ALERT_MISSING_EXTENSION;
goto Exit;
}
ptls_key_exchange_algorithm_t *negotiated_group;
- if ((ret = select_negotiated_group(&negotiated_group, tls->ctx->key_exchanges, ch.negotiated_groups.base,
- ch.negotiated_groups.base + ch.negotiated_groups.len)) != 0)
+ if ((ret = select_negotiated_group(&negotiated_group, tls->ctx->key_exchanges, ch->negotiated_groups.base,
+ ch->negotiated_groups.base + ch->negotiated_groups.len)) != 0)
goto Exit;
ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len);
assert(tls->key_schedule->generation == 0);
@@ -3841,7 +3863,7 @@
if ((ret = push_change_cipher_spec(tls, emitter)) != 0)
goto Exit;
tls->state = PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO;
- if (ch.psk.early_data_indication)
+ if (ch->psk.early_data_indication)
tls->server.early_data_skipped_bytes = 0;
ret = PTLS_ERROR_IN_PROGRESS;
}
@@ -3850,15 +3872,15 @@
}
/* handle unknown extensions */
- if ((ret = report_unknown_extensions(tls, properties, ch.unknown_extensions)) != 0)
+ if ((ret = report_unknown_extensions(tls, properties, ch->unknown_extensions)) != 0)
goto Exit;
/* try psk handshake */
- if (!is_second_flight && ch.psk.hash_end != 0 &&
- (ch.psk.ke_modes & ((1u << PTLS_PSK_KE_MODE_PSK) | (1u << PTLS_PSK_KE_MODE_PSK_DHE))) != 0 &&
+ if (!is_second_flight && ch->psk.hash_end != 0 &&
+ (ch->psk.ke_modes & ((1u << PTLS_PSK_KE_MODE_PSK) | (1u << PTLS_PSK_KE_MODE_PSK_DHE))) != 0 &&
tls->ctx->encrypt_ticket != NULL && !tls->ctx->require_client_authentication) {
- if ((ret = try_psk_handshake(tls, &psk_index, &accept_early_data, &ch,
- ptls_iovec_init(message.base, ch.psk.hash_end - message.base))) != 0) {
+ if ((ret = try_psk_handshake(tls, &psk_index, &accept_early_data, ch,
+ ptls_iovec_init(message.base, ch->psk.hash_end - message.base))) != 0) {
goto Exit;
}
}
@@ -3879,16 +3901,16 @@
if (properties != NULL)
properties->server.selected_psk_binder.len = 0;
} else {
- ptls__key_schedule_update_hash(tls->key_schedule, ch.psk.hash_end, message.base + message.len - ch.psk.hash_end);
- if ((ch.psk.ke_modes & (1u << PTLS_PSK_KE_MODE_PSK)) != 0) {
+ ptls__key_schedule_update_hash(tls->key_schedule, ch->psk.hash_end, message.base + message.len - ch->psk.hash_end);
+ if ((ch->psk.ke_modes & (1u << PTLS_PSK_KE_MODE_PSK)) != 0) {
mode = HANDSHAKE_MODE_PSK;
} else {
- assert((ch.psk.ke_modes & (1u << PTLS_PSK_KE_MODE_PSK_DHE)) != 0);
+ assert((ch->psk.ke_modes & (1u << PTLS_PSK_KE_MODE_PSK_DHE)) != 0);
mode = HANDSHAKE_MODE_PSK_DHE;
}
tls->is_psk_handshake = 1;
if (properties != NULL) {
- ptls_iovec_t *selected = &ch.psk.identities.list[psk_index].binder;
+ ptls_iovec_t *selected = &ch->psk.identities.list[psk_index].binder;
memcpy(properties->server.selected_psk_binder.base, selected->base, selected->len);
properties->server.selected_psk_binder.len = selected->len;
}
@@ -3908,7 +3930,7 @@
/* run key-exchange, to obtain pubkey and secret */
if (mode != HANDSHAKE_MODE_PSK) {
if (key_share.algorithm == NULL) {
- ret = ch.key_shares.base != NULL ? PTLS_ALERT_HANDSHAKE_FAILURE : PTLS_ALERT_MISSING_EXTENSION;
+ ret = ch->key_shares.base != NULL ? PTLS_ALERT_HANDSHAKE_FAILURE : PTLS_ALERT_MISSING_EXTENSION;
goto Exit;
}
if ((ret = key_share.algorithm->exchange(key_share.algorithm, &pubkey, &ecdh_secret, key_share.peer_key)) != 0)
@@ -3949,7 +3971,7 @@
} else {
if ((ret = setup_traffic_protection(tls, 0, "c hs traffic", 2, 0)) != 0)
goto Exit;
- if (ch.psk.early_data_indication)
+ if (ch->psk.early_data_indication)
tls->server.early_data_skipped_bytes = 0;
}
@@ -3959,7 +3981,7 @@
ptls_buffer_push_block(sendbuf, 2, {
if (tls->esni != NULL) {
/* the extension is sent even if the application does not handle server name, because otherwise the handshake
- * would fail (FIXME ch.esni.nonce will be zero on HRR) */
+ * would fail (FIXME ch->esni.nonce will be zero on HRR) */
buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ENCRYPTED_SERVER_NAME, {
uint8_t response_type = PTLS_ESNI_RESPONSE_TYPE_ACCEPT;
ptls_buffer_pushv(sendbuf, &response_type, 1);
@@ -4010,9 +4032,9 @@
}
}
- ret = send_certificate_and_certificate_verify(tls, emitter, &ch.signature_algorithms, ptls_iovec_init(NULL, 0),
- PTLS_SERVER_CERTIFICATE_VERIFY_CONTEXT_STRING, ch.status_request,
- ch.cert_compression_algos.list, ch.cert_compression_algos.count);
+ ret = send_certificate_and_certificate_verify(tls, emitter, &ch->signature_algorithms, ptls_iovec_init(NULL, 0),
+ PTLS_SERVER_CERTIFICATE_VERIFY_CONTEXT_STRING, ch->status_request,
+ ch->cert_compression_algos.list, ch->cert_compression_algos.count);
if (ret != 0) {
goto Exit;
@@ -4047,7 +4069,7 @@
}
/* send session ticket if necessary */
- if (ch.psk.ke_modes != 0 && tls->ctx->ticket_lifetime != 0) {
+ if (ch->psk.ke_modes != 0 && tls->ctx->ticket_lifetime != 0) {
if ((ret = send_session_ticket(tls, emitter)) != 0)
goto Exit;
}
@@ -4064,6 +4086,7 @@
ptls_clear_memory(ecdh_secret.base, ecdh_secret.len);
free(ecdh_secret.base);
}
+ free(ch);
return ret;
#undef EMIT_SERVER_HELLO
@@ -4747,9 +4770,8 @@
const uint8_t *src = input, *const src_end = src + *inlen;
ptls_buffer_t decryptbuf;
- uint8_t decryptbuf_small[256];
- ptls_buffer_init(&decryptbuf, decryptbuf_small, sizeof(decryptbuf_small));
+ ptls_buffer_init(&decryptbuf, "", 0);
/* perform handhake until completion or until all the input has been swallowed */
ret = PTLS_ERROR_IN_PROGRESS;
@@ -5063,7 +5085,7 @@
ptls_iovec_t hash_value, const char *label_prefix)
{
ptls_buffer_t hkdf_label;
- uint8_t hkdf_label_buf[512];
+ uint8_t hkdf_label_buf[80];
int ret;
assert(label_prefix != NULL);