Merge branch 'kazuho/pr/335' into kazuho/server-cipher-preference
diff --git a/include/picotls.h b/include/picotls.h
index a3050c1..b7f13d2 100644
--- a/include/picotls.h
+++ b/include/picotls.h
@@ -736,6 +736,10 @@
*/
unsigned use_raw_public_keys : 1;
/**
+ * boolean indicating if the cipher-suite should be chosen based on server's preference
+ */
+ unsigned server_cipher_preference : 1;
+ /**
*
*/
ptls_encrypt_ticket_t *encrypt_ticket;
diff --git a/lib/picotls.c b/lib/picotls.c
index 210d530..e2894fb 100644
--- a/lib/picotls.c
+++ b/lib/picotls.c
@@ -1571,19 +1571,34 @@
}
static int select_cipher(ptls_cipher_suite_t **selected, ptls_cipher_suite_t **candidates, const uint8_t *src,
- const uint8_t *const end)
+ const uint8_t *const end, int server_preference)
{
int ret;
- while (src != end) {
- uint16_t id;
- if ((ret = ptls_decode16(&id, &src, end)) != 0)
- goto Exit;
+ if (server_preference) {
ptls_cipher_suite_t **c = candidates;
for (; *c != NULL; ++c) {
- if ((*c)->id == id) {
- *selected = *c;
- return 0;
+ while (src != end) {
+ uint16_t id;
+ if ((ret = ptls_decode16(&id, &src, end)) != 0)
+ goto Exit;
+ if ((*c)->id == id) {
+ *selected = *c;
+ return 0;
+ }
+ }
+ }
+ } else {
+ while (src != end) {
+ uint16_t id;
+ if ((ret = ptls_decode16(&id, &src, end)) != 0)
+ goto Exit;
+ ptls_cipher_suite_t **c = candidates;
+ for (; *c != NULL; ++c) {
+ if ((*c)->id == id) {
+ *selected = *c;
+ return 0;
+ }
}
}
}
@@ -1731,7 +1746,7 @@
});
/* cipher-suite */
ptls_decode_open_block(src, end, 2, {
- if ((ret = select_cipher(selected_cipher, ctx->cipher_suites, src, end)) != 0)
+ if ((ret = select_cipher(selected_cipher, ctx->cipher_suites, src, end, ctx->server_cipher_preference)) != 0)
goto Exit;
src = end;
});
@@ -3816,7 +3831,7 @@
{ /* 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)
+ ch->cipher_suites.base + ch->cipher_suites.len, tls->ctx->server_cipher_preference)) != 0)
goto Exit;
if (!is_second_flight) {
tls->cipher_suite = cs;