Merge pull request #463 from h2o/kazuho/expose-raw
expose raw cipher-suite list from on_client_hello callback
diff --git a/include/picotls.h b/include/picotls.h
index c98a053..0a42d52 100644
--- a/include/picotls.h
+++ b/include/picotls.h
@@ -607,6 +607,10 @@
*/
ptls_iovec_t raw_message;
/**
+ * points to the cipher-suites section of the raw_message (see above)
+ */
+ ptls_iovec_t cipher_suites;
+ /**
*
*/
struct {
@@ -622,10 +626,6 @@
size_t count;
} certificate_compression_algorithms;
struct {
- const uint16_t *list;
- size_t count;
- } cipher_suites;
- struct {
const uint8_t *list;
size_t count;
} server_certificate_types;
diff --git a/lib/picotls.c b/lib/picotls.c
index f8fff89..29d737f 100644
--- a/lib/picotls.c
+++ b/lib/picotls.c
@@ -328,7 +328,6 @@
};
#define MAX_UNKNOWN_EXTENSIONS 16
-#define MAX_CLIENT_CIPHERS 32
#define MAX_CERTIFICATE_TYPES 8
struct st_ptls_client_hello_t {
@@ -354,10 +353,6 @@
size_t count;
} cert_compression_algos;
struct {
- uint16_t list[MAX_CLIENT_CIPHERS];
- size_t count;
- } client_ciphers;
- struct {
ptls_iovec_t all;
ptls_iovec_t tbs;
ptls_iovec_t ch1_hash;
@@ -3546,18 +3541,12 @@
/* decode and select from ciphersuites */
ptls_decode_open_block(src, end, 2, {
+ if ((end - src) % 2 != 0) {
+ ret = PTLS_ALERT_DECODE_ERROR;
+ goto Exit;
+ }
ch->cipher_suites = ptls_iovec_init(src, end - src);
- uint16_t *id = ch->client_ciphers.list;
- do {
- if ((ret = ptls_decode16(id, &src, end)) != 0)
- goto Exit;
- id++;
- ch->client_ciphers.count++;
- if (id >= ch->client_ciphers.list + MAX_CLIENT_CIPHERS) {
- src = end;
- break;
- }
- } while (src != end);
+ src = end;
});
/* decode legacy_compression_methods */
@@ -3918,10 +3907,10 @@
/* Wrapper function for invoking the on_client_hello callback, taking an exhaustive list of parameters as arguments. The intention
* is to not miss setting them as we add new parameters to the struct. */
-static inline int call_on_client_hello_cb(ptls_t *tls, ptls_iovec_t server_name, ptls_iovec_t raw_message, ptls_iovec_t *alpns,
- size_t num_alpns, const uint16_t *sig_algos, size_t num_sig_algos,
- const uint16_t *cert_comp_algos, size_t num_cert_comp_algos,
- const uint16_t *cipher_suites, size_t num_cipher_suites, const uint8_t *server_cert_types,
+static inline int call_on_client_hello_cb(ptls_t *tls, ptls_iovec_t server_name, ptls_iovec_t raw_message,
+ ptls_iovec_t cipher_suites, ptls_iovec_t *alpns, size_t num_alpns,
+ const uint16_t *sig_algos, size_t num_sig_algos, const uint16_t *cert_comp_algos,
+ size_t num_cert_comp_algos, const uint8_t *server_cert_types,
size_t num_server_cert_types, int incompatible_version)
{
if (tls->ctx->on_client_hello == NULL)
@@ -3929,10 +3918,10 @@
ptls_on_client_hello_parameters_t params = {server_name,
raw_message,
+ cipher_suites,
{alpns, num_alpns},
{sig_algos, num_sig_algos},
{cert_comp_algos, num_cert_comp_algos},
- {cipher_suites, num_cipher_suites},
{server_cert_types, num_server_cert_types},
incompatible_version};
return tls->ctx->on_client_hello->cb(tls->ctx->on_client_hello, tls, ¶ms);
@@ -3956,8 +3945,8 @@
/* fail with PROTOCOL_VERSION alert, after providing the applications the raw CH and SNI to help them fallback */
if (!is_second_flight) {
int ret;
- if ((ret = call_on_client_hello_cb(tls_cbarg, ch->server_name, raw_message, ch->alpn.list, ch->alpn.count, NULL, 0,
- NULL, 0, NULL, 0, NULL, 0, 1)) != 0)
+ if ((ret = call_on_client_hello_cb(tls_cbarg, ch->server_name, raw_message, ch->cipher_suites, ch->alpn.list,
+ ch->alpn.count, NULL, 0, NULL, 0, NULL, 0, 1)) != 0)
return ret;
}
return PTLS_ALERT_PROTOCOL_VERSION;
@@ -4326,9 +4315,9 @@
ptls_iovec_t server_name = {NULL};
if (ch->server_name.base != NULL)
server_name = ch->server_name;
- if ((ret = call_on_client_hello_cb(tls, 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,
+ if ((ret = call_on_client_hello_cb(tls, server_name, message, ch->cipher_suites, 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->server_certificate_types.list, ch->server_certificate_types.count, 0)) != 0)
goto Exit;
if (!certificate_type_exists(ch->server_certificate_types.list, ch->server_certificate_types.count,