Coverage Report

Created: 2026-09-13 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/picotls/lib/picotls.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to
6
 * deal in the Software without restriction, including without limitation the
7
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
 * sell copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
 * IN THE SOFTWARE.
21
 */
22
#ifdef _WINDOWS
23
#include "wincompat.h"
24
#endif
25
#include <assert.h>
26
#include <stdarg.h>
27
#include <stddef.h>
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <string.h>
31
#ifndef _WINDOWS
32
#include <errno.h>
33
#include <pthread.h>
34
#include <unistd.h>
35
#include <sys/socket.h>
36
#include <arpa/inet.h>
37
#include <netinet/in.h>
38
#include <sys/time.h>
39
#include <sys/types.h>
40
#endif
41
#ifdef __linux__
42
#include <sys/syscall.h>
43
#endif
44
#ifdef __APPLE__
45
#include <AvailabilityMacros.h>
46
#endif
47
#include "picotls.h"
48
#if PICOTLS_USE_DTRACE
49
#include "picotls-probes.h"
50
#endif
51
52
42.9k
#define PTLS_MAX_PLAINTEXT_RECORD_SIZE 16384
53
12.4k
#define PTLS_MAX_ENCRYPTED_RECORD_SIZE (16384 + 256)
54
55
0
#define PTLS_RECORD_VERSION_MAJOR 3
56
0
#define PTLS_RECORD_VERSION_MINOR 3
57
58
54.7k
#define PTLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC 20
59
12.8k
#define PTLS_CONTENT_TYPE_ALERT 21
60
112k
#define PTLS_CONTENT_TYPE_HANDSHAKE 22
61
204k
#define PTLS_CONTENT_TYPE_APPDATA 23
62
63
108
#define PTLS_PSK_KE_MODE_PSK 0
64
108
#define PTLS_PSK_KE_MODE_PSK_DHE 1
65
66
5.31k
#define PTLS_HANDSHAKE_HEADER_SIZE 4
67
68
#define PTLS_EXTENSION_TYPE_SERVER_NAME 0
69
#define PTLS_EXTENSION_TYPE_STATUS_REQUEST 5
70
#define PTLS_EXTENSION_TYPE_SUPPORTED_GROUPS 10
71
#define PTLS_EXTENSION_TYPE_SIGNATURE_ALGORITHMS 13
72
#define PTLS_EXTENSION_TYPE_ALPN 16
73
#define PTLS_EXTENSION_TYPE_SERVER_CERTIFICATE_TYPE 20
74
#define PTLS_EXTENSION_TYPE_COMPRESS_CERTIFICATE 27
75
#define PTLS_EXTENSION_TYPE_PRE_SHARED_KEY 41
76
#define PTLS_EXTENSION_TYPE_EARLY_DATA 42
77
#define PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS 43
78
#define PTLS_EXTENSION_TYPE_COOKIE 44
79
#define PTLS_EXTENSION_TYPE_PSK_KEY_EXCHANGE_MODES 45
80
#define PTLS_EXTENSION_TYPE_CERTIFICATE_AUTHORITIES 47
81
#define PTLS_EXTENSION_TYPE_KEY_SHARE 51
82
#define PTLS_EXTENSION_TYPE_TICKET_REQUEST 58
83
#define PTLS_EXTENSION_TYPE_ECH_OUTER_EXTENSIONS 0xfd00
84
#define PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO 0xfe0d
85
86
#define PTLS_SERVER_NAME_TYPE_HOSTNAME 0
87
88
#define PTLS_ECH_CONFIG_VERSION 0xfe0d
89
31
#define PTLS_ECH_CLIENT_HELLO_TYPE_OUTER 0
90
0
#define PTLS_ECH_CLIENT_HELLO_TYPE_INNER 1
91
92
0
#define PTLS_ECH_CONFIRM_LENGTH 8
93
94
static const char ech_info_prefix[8] = "tls ech";
95
96
253
#define PTLS_SERVER_CERTIFICATE_VERIFY_CONTEXT_STRING "TLS 1.3, server CertificateVerify"
97
0
#define PTLS_CLIENT_CERTIFICATE_VERIFY_CONTEXT_STRING "TLS 1.3, client CertificateVerify"
98
#define PTLS_MAX_CERTIFICATE_VERIFY_SIGNDATA_SIZE                                                                                  \
99
    (64 + sizeof(PTLS_SERVER_CERTIFICATE_VERIFY_CONTEXT_STRING) + PTLS_MAX_DIGEST_SIZE * 2)
100
101
95
#define PTLS_EARLY_DATA_MAX_DELAY 10000 /* max. RTT (in msec) to permit early data */
102
103
#ifndef PTLS_MAX_EARLY_DATA_SKIP_SIZE
104
10.6k
#define PTLS_MAX_EARLY_DATA_SKIP_SIZE 65536
105
#endif
106
#if defined(PTLS_DEBUG) && PTLS_DEBUG
107
#define PTLS_DEBUGF(...) fprintf(stderr, __VA_ARGS__)
108
#else
109
#define PTLS_DEBUGF(...)
110
#endif
111
112
#ifndef PTLS_MEMORY_DEBUG
113
386k
#define PTLS_MEMORY_DEBUG 0
114
#endif
115
116
#if PICOTLS_USE_DTRACE
117
#define PTLS_PROBE0(LABEL, tls)                                                                                                    \
118
    do {                                                                                                                           \
119
        if (PTLS_UNLIKELY(PICOTLS_##LABEL##_ENABLED()))                                                                            \
120
            PICOTLS_##LABEL(tls);                                                                                                  \
121
    } while (0)
122
#define PTLS_PROBE(LABEL, tls, ...)                                                                                                \
123
    do {                                                                                                                           \
124
        if (PTLS_UNLIKELY(PICOTLS_##LABEL##_ENABLED()))                                                                            \
125
            PICOTLS_##LABEL((tls), __VA_ARGS__);                                                                                   \
126
    } while (0)
127
#else
128
#define PTLS_PROBE0(LABEL, tls)
129
#define PTLS_PROBE(LABEL, tls, ...)
130
#endif
131
132
/**
133
 * list of supported versions in the preferred order
134
 */
135
static const uint16_t supported_versions[] = {PTLS_PROTOCOL_VERSION_TLS13};
136
137
static const uint8_t hello_retry_random[PTLS_HELLO_RANDOM_SIZE] = {0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C,
138
                                                                   0x02, 0x1E, 0x65, 0xB8, 0x91, 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB,
139
                                                                   0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C};
140
141
struct st_ptls_traffic_protection_t {
142
    uint8_t secret[PTLS_MAX_DIGEST_SIZE];
143
    size_t epoch;
144
    /* the following fields are not used if the key_change callback is set */
145
    ptls_aead_context_t *aead;
146
    uint64_t seq;
147
    unsigned tls12 : 1;
148
    uint64_t tls12_enc_record_iv;
149
};
150
151
struct st_ptls_record_message_emitter_t {
152
    ptls_message_emitter_t super;
153
    size_t rec_start;
154
};
155
156
struct st_ptls_signature_algorithms_t {
157
    uint16_t list[PTLS_MAX_SIGNATURE_ALGORITHMS];
158
    size_t count;
159
};
160
161
struct st_ptls_certificate_request_t {
162
    /**
163
     * context.base becomes non-NULL when a CertificateRequest is pending for processing
164
     */
165
    ptls_iovec_t context;
166
    struct st_ptls_signature_algorithms_t signature_algorithms;
167
};
168
169
struct st_decoded_ech_config_t {
170
    uint8_t id;
171
    ptls_hpke_kem_t *kem;
172
    ptls_iovec_t public_key;
173
    ptls_hpke_cipher_suite_t *cipher;
174
    uint8_t max_name_length;
175
    ptls_iovec_t public_name;
176
    ptls_iovec_t bytes;
177
};
178
179
/**
180
 * Properties for ECH. Iff ECH is used and not rejected, `aead` is non-NULL.
181
 */
182
struct st_ptls_ech_t {
183
    /**
184
     * ECH state for this connection. `OFFERED` and `ACCEPTED` are used on both client and server; `GREASE` is client-only (server
185
     * cannot distinguish GREASE from a config mismatch, both are simply ECH that fails to decrypt).
186
     */
187
    enum en_ptls_ech_state_t {
188
        PTLS_ECH_STATE_NONE = 0,
189
        PTLS_ECH_STATE_OFFERED,
190
        PTLS_ECH_STATE_ACCEPTED,
191
        PTLS_ECH_STATE_GREASE
192
    } state;
193
    uint8_t config_id;
194
    ptls_hpke_kem_t *kem;
195
    ptls_hpke_cipher_suite_t *cipher;
196
    ptls_aead_context_t *aead;
197
    uint8_t inner_client_random[PTLS_HELLO_RANDOM_SIZE];
198
    struct {
199
        ptls_iovec_t enc;
200
        uint8_t max_name_length;
201
        char *public_name;
202
        /**
203
         * retains a copy of entire ECH extension so that it can be replayed in the 2nd CH when ECH is rejected via HRR
204
         */
205
        ptls_iovec_t first_ech;
206
    } client;
207
};
208
209
struct st_ptls_t {
210
    /**
211
     * the context
212
     */
213
    ptls_context_t *ctx;
214
    /**
215
     * the state
216
     */
217
    enum en_ptls_state_t {
218
        PTLS_STATE_CLIENT_HANDSHAKE_START,
219
        PTLS_STATE_CLIENT_EXPECT_SERVER_HELLO,
220
        PTLS_STATE_CLIENT_EXPECT_SECOND_SERVER_HELLO,
221
        PTLS_STATE_CLIENT_EXPECT_ENCRYPTED_EXTENSIONS,
222
        PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_REQUEST_OR_CERTIFICATE,
223
        PTLS_STATE_CLIENT_EXPECT_CERTIFICATE,
224
        PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_VERIFY,
225
        PTLS_STATE_CLIENT_EXPECT_FINISHED,
226
        PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO,
227
        PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO,
228
        PTLS_STATE_SERVER_GENERATING_CERTIFICATE_VERIFY,
229
        PTLS_STATE_SERVER_EXPECT_CERTIFICATE,
230
        PTLS_STATE_SERVER_EXPECT_CERTIFICATE_VERIFY,
231
        /* ptls_send can be called if the state is below here */
232
        PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA,
233
        PTLS_STATE_SERVER_EXPECT_FINISHED,
234
        PTLS_STATE_POST_HANDSHAKE_MIN,
235
        PTLS_STATE_CLIENT_POST_HANDSHAKE = PTLS_STATE_POST_HANDSHAKE_MIN,
236
        PTLS_STATE_SERVER_POST_HANDSHAKE
237
    } state;
238
    /**
239
     * receive buffers
240
     */
241
    struct {
242
        ptls_buffer_t rec;
243
        ptls_buffer_t mess;
244
    } recvbuf;
245
    /**
246
     * key schedule
247
     */
248
    ptls_key_schedule_t *key_schedule;
249
    /**
250
     * values used for record protection
251
     */
252
    struct {
253
        struct st_ptls_traffic_protection_t dec;
254
        struct st_ptls_traffic_protection_t enc;
255
    } traffic_protection;
256
    /**
257
     * server-name passed using SNI
258
     */
259
    char *server_name;
260
    /**
261
     * result of ALPN
262
     */
263
    char *negotiated_protocol;
264
    /**
265
     * selected key-exchange
266
     */
267
    ptls_key_exchange_algorithm_t *key_share;
268
    /**
269
     * selected cipher-suite
270
     */
271
    ptls_cipher_suite_t *cipher_suite;
272
    /**
273
     * ClientHello.random that appears on the wire. When ECH is used, that of inner CH is retained separately.
274
     */
275
    uint8_t client_random[PTLS_HELLO_RANDOM_SIZE];
276
    /**
277
     * exporter master secret (either 0rtt or 1rtt)
278
     */
279
    struct {
280
        uint8_t *early;
281
        uint8_t *one_rtt;
282
    } exporter_master_secret;
283
    /**
284
     * ECH
285
     */
286
    struct st_ptls_ech_t ech;
287
    /* flags */
288
    unsigned is_server : 1;
289
    unsigned is_psk_handshake : 1;
290
    unsigned send_change_cipher_spec : 1;
291
    unsigned needs_key_update : 1;
292
    unsigned key_update_send_request : 1;
293
#if PTLS_HAVE_LOG
294
    /**
295
     * see ptls_log
296
     */
297
    ptls_log_conn_state_t log_state;
298
#endif
299
    struct {
300
        uint32_t active_conns;
301
        uint32_t generation;
302
    } log_sni;
303
    /**
304
     * misc.
305
     */
306
    union {
307
        struct {
308
            ptls_iovec_t legacy_session_id;
309
            uint8_t legacy_session_id_buf[32];
310
            ptls_key_exchange_context_t *key_share_ctx;
311
            unsigned offered_psk : 1;
312
            /**
313
             * if 1-RTT write key is active
314
             */
315
            unsigned using_early_data : 1;
316
            struct st_ptls_certificate_request_t certificate_request;
317
        } client;
318
        struct {
319
            uint8_t pending_traffic_secret[PTLS_MAX_DIGEST_SIZE];
320
            uint32_t early_data_skipped_bytes; /* if not UINT32_MAX, the server is skipping early data */
321
            uint8_t num_tickets_to_send;
322
            ptls_async_job_t *async_job;
323
        } server;
324
    };
325
    /**
326
     * certificate verify; will be used by the client and the server (if require_client_authentication is set)
327
     */
328
    struct {
329
        int (*cb)(void *verify_ctx, uint16_t algo, ptls_iovec_t data, ptls_iovec_t signature);
330
        void *verify_ctx;
331
    } certificate_verify;
332
    /**
333
     * handshake traffic secret to be commisioned (an array of `uint8_t [PTLS_MAX_DIGEST_SIZE]` or NULL)
334
     */
335
    uint8_t *pending_handshake_secret;
336
    /**
337
     * user data
338
     */
339
    void *data_ptr;
340
};
341
342
struct st_ptls_record_t {
343
    uint8_t type;
344
    uint16_t version;
345
    size_t length;
346
    const uint8_t *fragment;
347
};
348
349
0
#define MAX_UNKNOWN_EXTENSIONS 16
350
#define MAX_CERTIFICATE_TYPES 8
351
352
struct st_ptls_client_hello_t {
353
    uint16_t legacy_version;
354
    const uint8_t *random_bytes;
355
    ptls_iovec_t legacy_session_id;
356
    struct {
357
        const uint8_t *ids;
358
        size_t count;
359
    } compression_methods;
360
    uint16_t selected_version;
361
    ptls_iovec_t cipher_suites;
362
    ptls_iovec_t negotiated_groups;
363
    ptls_iovec_t key_shares;
364
    struct st_ptls_signature_algorithms_t signature_algorithms;
365
    ptls_iovec_t server_name;
366
    struct {
367
        ptls_iovec_t list[16];
368
        size_t count;
369
    } alpn;
370
    struct {
371
        uint16_t list[16];
372
        size_t count;
373
    } cert_compression_algos;
374
    struct {
375
        ptls_iovec_t all;
376
        ptls_iovec_t tbs;
377
        ptls_iovec_t ch1_hash;
378
        ptls_iovec_t signature;
379
        unsigned sent_key_share : 1;
380
    } cookie;
381
    struct {
382
        uint8_t list[MAX_CERTIFICATE_TYPES];
383
        size_t count;
384
    } server_certificate_types;
385
    unsigned status_request : 1;
386
    struct {
387
        uint8_t new_session_count;
388
        uint8_t resumption_count;
389
    } ticket_request;
390
    /**
391
     * ECH: payload.base != NULL indicates that the extension was received
392
     */
393
    struct {
394
        uint8_t type;
395
        uint8_t config_id;
396
        ptls_hpke_cipher_suite_id_t cipher_suite;
397
        ptls_iovec_t enc;
398
        ptls_iovec_t payload;
399
    } ech;
400
    struct {
401
        const uint8_t *hash_end;
402
        struct {
403
            ptls_client_hello_psk_identity_t list[4];
404
            size_t count;
405
        } identities;
406
        unsigned ke_modes;
407
        unsigned early_data_indication : 1;
408
        unsigned is_last_extension : 1;
409
    } psk;
410
    ptls_raw_extension_t unknown_extensions[MAX_UNKNOWN_EXTENSIONS + 1];
411
    size_t first_extension_at;
412
};
413
414
struct st_ptls_server_hello_t {
415
    uint8_t random_[PTLS_HELLO_RANDOM_SIZE];
416
    ptls_iovec_t legacy_session_id;
417
    int is_retry_request;
418
    union {
419
        ptls_iovec_t peerkey;
420
        struct {
421
            uint16_t selected_group;
422
            ptls_iovec_t cookie;
423
            const uint8_t *ech;
424
        } retry_request;
425
    };
426
};
427
428
struct st_ptls_key_schedule_t {
429
    unsigned generation; /* early secret (1), hanshake secret (2), master secret (3) */
430
    uint8_t secret[PTLS_MAX_DIGEST_SIZE];
431
    size_t num_hashes;
432
    struct {
433
        ptls_hash_algorithm_t *algo;
434
        ptls_hash_context_t *ctx, *ctx_outer;
435
    } hashes[1];
436
};
437
438
struct st_ptls_extension_decoder_t {
439
    uint16_t type;
440
    int (*cb)(ptls_t *tls, void *arg, const uint8_t *src, const uint8_t *const end);
441
};
442
443
struct st_ptls_extension_bitmap_t {
444
    uint64_t bits;
445
};
446
447
static const uint8_t zeroes_of_max_digest_size[PTLS_MAX_DIGEST_SIZE] = {0};
448
449
static ptls_aead_context_t *new_aead(ptls_aead_algorithm_t *aead, ptls_hash_algorithm_t *hash, int is_enc, const void *secret,
450
                                     ptls_iovec_t hash_value, const char *label_prefix);
451
static int server_finish_handshake(ptls_t *tls, ptls_message_emitter_t *emitter, int send_cert_verify,
452
                                   struct st_ptls_signature_algorithms_t *signature_algorithms);
453
454
static int is_supported_version(uint16_t v)
455
2.05k
{
456
2.05k
    size_t i;
457
2.19k
    for (i = 0; i != PTLS_ELEMENTSOF(supported_versions); ++i)
458
2.05k
        if (supported_versions[i] == v)
459
1.91k
            return 1;
460
140
    return 0;
461
2.05k
}
462
463
static int extension_bitmap_testandset(struct st_ptls_extension_bitmap_t *bitmap, int hstype, uint16_t extid)
464
12.1k
{
465
91.4k
#define HSTYPE_TO_BIT(hstype) ((uint64_t)1 << ((hstype) + 1)) /* min(hstype) is -1 (PSEUDO_HRR) */
466
84.9k
#define DEFINE_BIT(abbrev, hstype) static const uint64_t abbrev = HSTYPE_TO_BIT(PTLS_HANDSHAKE_TYPE_##hstype)
467
12.1k
#define EXT(candext, allowed_bits)                                                                                                 \
468
137k
    do {                                                                                                                           \
469
137k
        if (PTLS_UNLIKELY(extid == PTLS_EXTENSION_TYPE_##candext)) {                                                               \
470
6.54k
            allowed_hs_bits = allowed_bits;                                                                                        \
471
6.54k
            goto Found;                                                                                                            \
472
6.54k
        }                                                                                                                          \
473
137k
        ext_bitmap_mask <<= 1;                                                                                                     \
474
131k
    } while (0)
475
476
12.1k
    DEFINE_BIT(CH, CLIENT_HELLO);
477
12.1k
    DEFINE_BIT(SH, SERVER_HELLO);
478
12.1k
    DEFINE_BIT(HRR, PSEUDO_HRR);
479
12.1k
    DEFINE_BIT(EE, ENCRYPTED_EXTENSIONS);
480
12.1k
    DEFINE_BIT(CR, CERTIFICATE_REQUEST);
481
12.1k
    DEFINE_BIT(CT, CERTIFICATE);
482
12.1k
    DEFINE_BIT(NST, NEW_SESSION_TICKET);
483
484
12.1k
    uint64_t allowed_hs_bits, ext_bitmap_mask = 1;
485
486
    /* clang-format off */
487
    /* RFC 8446 section 4.2: "The table below indicates the messages where a given extension may appear... If an implementation
488
     * receives an extension which it recognizes and which is not specified for the message in which it appears, it MUST abort the
489
     * handshake with an "illegal_parameter" alert.
490
     *
491
     * +-------------------------+---------------+
492
     * +        Extension        |    Allowed    |
493
     * +-------------------------+---------------+ */
494
12.1k
    EXT( SERVER_NAME             , CH + EE       );
495
11.9k
    EXT( STATUS_REQUEST          , CH + CR + CT  );
496
11.5k
    EXT( SUPPORTED_GROUPS        , CH + EE       );
497
11.2k
    EXT( SIGNATURE_ALGORITHMS    , CH + CR       );
498
10.9k
    EXT( ALPN                    , CH + EE       );
499
10.7k
    EXT( SERVER_CERTIFICATE_TYPE , CH + EE       );
500
10.6k
    EXT( KEY_SHARE               , CH + SH + HRR );
501
8.90k
    EXT( PRE_SHARED_KEY          , CH + SH       );
502
8.47k
    EXT( PSK_KEY_EXCHANGE_MODES  , CH            );
503
8.16k
    EXT( EARLY_DATA              , CH + EE + NST );
504
7.96k
    EXT( COOKIE                  , CH + HRR      );
505
7.88k
    EXT( SUPPORTED_VERSIONS      , CH + SH + HRR );
506
5.81k
    EXT( COMPRESS_CERTIFICATE    , CH + CR       ); /* from RFC 8879 */
507
5.73k
    EXT( ENCRYPTED_CLIENT_HELLO  , CH + HRR + EE ); /* from draft-ietf-tls-esni-15 */
508
5.60k
    EXT( ECH_OUTER_EXTENSIONS    , 0             );
509
    /* +-----------------------------------------+ */
510
    /* clang-format on */
511
512
5.59k
    return 1;
513
514
6.54k
Found:
515
6.54k
    if ((allowed_hs_bits & HSTYPE_TO_BIT(hstype)) == 0)
516
101
        return 0;
517
6.44k
    if ((bitmap->bits & ext_bitmap_mask) != 0)
518
52
        return 0;
519
6.38k
    bitmap->bits |= ext_bitmap_mask;
520
6.38k
    return 1;
521
522
6.44k
#undef HSTYPE_TO_BIT
523
6.44k
#undef DEFINE_ABBREV
524
6.44k
#undef EXT
525
6.44k
}
526
527
#ifndef ntoh16
528
static uint16_t ntoh16(const uint8_t *src)
529
169k
{
530
169k
    return (uint16_t)src[0] << 8 | src[1];
531
169k
}
532
#endif
533
534
#ifndef ntoh24
535
static uint32_t ntoh24(const uint8_t *src)
536
18.0k
{
537
18.0k
    return (uint32_t)src[0] << 16 | (uint32_t)src[1] << 8 | src[2];
538
18.0k
}
539
#endif
540
541
#ifndef ntoh32
542
static uint32_t ntoh32(const uint8_t *src)
543
1.45k
{
544
1.45k
    return (uint32_t)src[0] << 24 | (uint32_t)src[1] << 16 | (uint32_t)src[2] << 8 | src[3];
545
1.45k
}
546
#endif
547
548
#ifndef ntoh64
549
static uint64_t ntoh64(const uint8_t *src)
550
144
{
551
144
    return (uint64_t)src[0] << 56 | (uint64_t)src[1] << 48 | (uint64_t)src[2] << 40 | (uint64_t)src[3] << 32 |
552
144
           (uint64_t)src[4] << 24 | (uint64_t)src[5] << 16 | (uint64_t)src[6] << 8 | src[7];
553
144
}
554
#endif
555
556
static void encode64(uint8_t *dst, uint64_t v)
557
0
{
558
0
    for (size_t i = 0; i < 8; ++i)
559
0
        dst[i] = (uint8_t)(v >> (56 - 8 * i));
560
0
}
561
562
static char *duplicate_as_str(const void *src, size_t len)
563
28
{
564
28
    char *dst;
565
566
28
    if ((dst = malloc(len + 1)) == NULL)
567
0
        return NULL;
568
28
    memcpy(dst, src, len);
569
28
    dst[len] = '\0';
570
28
    return dst;
571
28
}
572
573
void ptls_buffer__release_memory(ptls_buffer_t *buf)
574
123k
{
575
123k
    ptls_clear_memory(buf->base, buf->off);
576
123k
    if (buf->is_allocated) {
577
#ifdef _WINDOWS
578
        if (buf->align_bits != 0) {
579
            _aligned_free(buf->base);
580
        } else {
581
            free(buf->base);
582
        }
583
#else
584
8.34k
        free(buf->base);
585
8.34k
#endif
586
8.34k
    }
587
123k
}
588
589
int ptls_buffer_reserve(ptls_buffer_t *buf, size_t delta)
590
192k
{
591
192k
    return ptls_buffer_reserve_aligned(buf, delta, 0);
592
192k
}
593
594
int ptls_buffer_reserve_aligned(ptls_buffer_t *buf, size_t delta, uint8_t align_bits)
595
193k
{
596
193k
    if (buf->base == NULL)
597
0
        return PTLS_ERROR_NO_MEMORY;
598
599
193k
    if (PTLS_MEMORY_DEBUG || buf->capacity < buf->off + delta ||
600
185k
        (buf->align_bits < align_bits && ((uintptr_t)buf->base & (((uintptr_t)1 << align_bits) - 1)) != 0)) {
601
8.34k
        void *newp;
602
8.34k
        size_t new_capacity = buf->capacity;
603
8.34k
        if (new_capacity < 1024)
604
7.62k
            new_capacity = 1024;
605
10.2k
        while (new_capacity < buf->off + delta) {
606
1.94k
            new_capacity *= 2;
607
1.94k
        }
608
8.34k
        if (align_bits != 0) {
609
#ifdef _WINDOWS
610
            if ((newp = _aligned_malloc(new_capacity, (size_t)1 << align_bits)) == NULL)
611
                return PTLS_ERROR_NO_MEMORY;
612
#else
613
0
            if (posix_memalign(&newp, 1 << align_bits, new_capacity) != 0)
614
0
                return PTLS_ERROR_NO_MEMORY;
615
0
#endif
616
8.34k
        } else {
617
8.34k
            if ((newp = malloc(new_capacity)) == NULL)
618
0
                return PTLS_ERROR_NO_MEMORY;
619
8.34k
        }
620
8.34k
        memcpy(newp, buf->base, buf->off);
621
8.34k
        ptls_buffer__release_memory(buf);
622
8.34k
        buf->base = newp;
623
8.34k
        buf->capacity = new_capacity;
624
8.34k
        buf->is_allocated = 1;
625
8.34k
        buf->align_bits = align_bits;
626
8.34k
    }
627
628
193k
    return 0;
629
193k
}
630
631
int ptls_buffer__do_pushv(ptls_buffer_t *buf, const void *src, size_t len)
632
171k
{
633
171k
    int ret;
634
635
171k
    if (len == 0)
636
8.65k
        return 0;
637
163k
    if ((ret = ptls_buffer_reserve(buf, len)) != 0)
638
0
        return ret;
639
163k
    memcpy(buf->base + buf->off, src, len);
640
163k
    buf->off += len;
641
163k
    return 0;
642
163k
}
643
644
int ptls_buffer__adjust_quic_blocksize(ptls_buffer_t *buf, size_t body_size)
645
0
{
646
0
    uint8_t sizebuf[PTLS_ENCODE_QUICINT_CAPACITY];
647
0
    size_t sizelen = ptls_encode_quicint(sizebuf, body_size) - sizebuf;
648
649
    /* adjust amount of space before body_size to `sizelen` bytes */
650
0
    if (sizelen != 1) {
651
0
        int ret;
652
0
        if ((ret = ptls_buffer_reserve(buf, sizelen - 1)) != 0)
653
0
            return ret;
654
0
        memmove(buf->base + buf->off - body_size - 1 + sizelen, buf->base + buf->off - body_size, body_size);
655
0
        buf->off += sizelen - 1;
656
0
    }
657
658
    /* write the size */
659
0
    memcpy(buf->base + buf->off - body_size - sizelen, sizebuf, sizelen);
660
661
0
    return 0;
662
0
}
663
664
int ptls_buffer__adjust_asn1_blocksize(ptls_buffer_t *buf, size_t body_size)
665
0
{
666
0
    fprintf(stderr, "unimplemented\n");
667
0
    abort();
668
0
}
669
670
int ptls_buffer_push_asn1_ubigint(ptls_buffer_t *buf, const void *bignum, size_t size)
671
0
{
672
0
    const uint8_t *p = bignum, *const end = p + size;
673
0
    int ret;
674
675
    /* skip zeroes */
676
0
    for (; end - p >= 1; ++p)
677
0
        if (*p != 0)
678
0
            break;
679
680
    /* emit */
681
0
    ptls_buffer_push(buf, 2);
682
0
    ptls_buffer_push_asn1_block(buf, {
683
0
        if (*p >= 0x80)
684
0
            ptls_buffer_push(buf, 0);
685
0
        if (p != end) {
686
0
            ptls_buffer_pushv(buf, p, end - p);
687
0
        } else {
688
0
            ptls_buffer_pushv(buf, "", 1);
689
0
        }
690
0
    });
691
0
    ret = 0;
692
693
0
Exit:
694
0
    return ret;
695
0
}
696
697
#if PTLS_FUZZ_HANDSHAKE
698
699
static size_t aead_encrypt(struct st_ptls_traffic_protection_t *ctx, void *output, const void *input, size_t inlen,
700
                           uint8_t content_type)
701
875
{
702
875
    memcpy(output, input, inlen);
703
875
    memcpy(output + inlen, &content_type, 1);
704
875
    return inlen + 1 + 16;
705
875
}
706
707
static int aead_decrypt(struct st_ptls_traffic_protection_t *ctx, void *output, size_t *outlen, const void *input, size_t inlen)
708
11.9k
{
709
11.9k
    if (inlen < 16) {
710
10.2k
        return PTLS_ALERT_BAD_RECORD_MAC;
711
10.2k
    }
712
1.69k
    memcpy(output, input, inlen - 16);
713
1.69k
    *outlen = inlen - 16; /* removing the 16 bytes of tag */
714
1.69k
    return 0;
715
11.9k
}
716
717
#else
718
719
static void build_aad(uint8_t aad[5], size_t reclen)
720
{
721
    aad[0] = PTLS_CONTENT_TYPE_APPDATA;
722
    aad[1] = PTLS_RECORD_VERSION_MAJOR;
723
    aad[2] = PTLS_RECORD_VERSION_MINOR;
724
    aad[3] = (uint8_t)(reclen >> 8);
725
    aad[4] = (uint8_t)reclen;
726
}
727
728
static size_t aead_encrypt(struct st_ptls_traffic_protection_t *ctx, void *output, const void *input, size_t inlen,
729
                           uint8_t content_type)
730
{
731
    ptls_iovec_t invec[2] = {ptls_iovec_init(input, inlen), ptls_iovec_init(&content_type, 1)};
732
    uint8_t aad[5];
733
734
    build_aad(aad, inlen + 1 + ctx->aead->algo->tag_size);
735
    ptls_aead_encrypt_v(ctx->aead, output, invec, PTLS_ELEMENTSOF(invec), ctx->seq++, aad, sizeof(aad));
736
737
    return inlen + 1 + ctx->aead->algo->tag_size;
738
}
739
740
static int aead_decrypt(struct st_ptls_traffic_protection_t *ctx, void *output, size_t *outlen, const void *input, size_t inlen)
741
{
742
    uint8_t aad[5];
743
744
    build_aad(aad, inlen);
745
    if ((*outlen = ptls_aead_decrypt(ctx->aead, output, input, inlen, ctx->seq, aad, sizeof(aad))) == SIZE_MAX)
746
        return PTLS_ALERT_BAD_RECORD_MAC;
747
    ++ctx->seq;
748
    return 0;
749
}
750
751
#endif /* #if PTLS_FUZZ_HANDSHAKE */
752
753
static void build_tls12_aad(uint8_t *aad, uint8_t type, uint64_t seq, uint16_t length)
754
0
{
755
0
    for (size_t i = 0; i < 8; ++i)
756
0
        aad[i] = (uint8_t)(seq >> (56 - i * 8));
757
0
    aad[8] = type;
758
0
    aad[9] = PTLS_RECORD_VERSION_MAJOR;
759
0
    aad[10] = PTLS_RECORD_VERSION_MINOR;
760
0
    aad[11] = length >> 8;
761
0
    aad[12] = (uint8_t)length;
762
0
}
763
764
#define buffer_push_record(buf, type, block)                                                                                       \
765
3.47k
    do {                                                                                                                           \
766
3.47k
        ptls_buffer_push((buf), (type), PTLS_RECORD_VERSION_MAJOR, PTLS_RECORD_VERSION_MINOR);                                     \
767
3.47k
        ptls_buffer_push_block((buf), 2, block);                                                                                   \
768
3.47k
    } while (0)
769
770
static int buffer_push_encrypted_records(ptls_buffer_t *buf, uint8_t type, const uint8_t *src, size_t len,
771
                                         struct st_ptls_traffic_protection_t *enc)
772
0
{
773
0
    int ret = 0;
774
775
0
    while (len != 0) {
776
0
        size_t chunk_size = len;
777
0
        if (chunk_size > PTLS_MAX_PLAINTEXT_RECORD_SIZE)
778
0
            chunk_size = PTLS_MAX_PLAINTEXT_RECORD_SIZE;
779
0
        if (enc->tls12) {
780
0
            buffer_push_record(buf, type, {
781
                /* reserve memory */
782
0
                if ((ret = ptls_buffer_reserve_aligned(
783
0
                         buf, enc->aead->algo->tls12.record_iv_size + chunk_size + enc->aead->algo->tag_size,
784
0
                         enc->aead->algo->align_bits)) != 0)
785
0
                    goto Exit;
786
                /* determine nonce, as well as prepending that walue as the record IV (AES-GCM) */
787
0
                uint64_t nonce;
788
0
                if (enc->aead->algo->tls12.record_iv_size != 0) {
789
0
                    assert(enc->aead->algo->tls12.record_iv_size == 8);
790
0
                    nonce = enc->tls12_enc_record_iv++;
791
0
                    encode64(buf->base + buf->off, nonce);
792
0
                    buf->off += 8;
793
0
                } else {
794
0
                    nonce = enc->seq;
795
0
                }
796
                /* build AAD */
797
0
                uint8_t aad[PTLS_TLS12_AAD_SIZE];
798
0
                build_tls12_aad(aad, type, enc->seq, (uint16_t)chunk_size);
799
                /* encrypt */
800
0
                buf->off += ptls_aead_encrypt(enc->aead, buf->base + buf->off, src, chunk_size, nonce, aad, sizeof(aad));
801
0
                ++enc->seq;
802
0
            });
803
0
        } else {
804
0
            buffer_push_record(buf, PTLS_CONTENT_TYPE_APPDATA, {
805
0
                if ((ret = ptls_buffer_reserve_aligned(buf, chunk_size + enc->aead->algo->tag_size + 1,
806
0
                                                       enc->aead->algo->align_bits)) != 0)
807
0
                    goto Exit;
808
0
                buf->off += aead_encrypt(enc, buf->base + buf->off, src, chunk_size, type);
809
0
            });
810
0
        }
811
0
        src += chunk_size;
812
0
        len -= chunk_size;
813
0
    }
814
815
0
Exit:
816
0
    return ret;
817
0
}
818
819
static int buffer_encrypt_record(ptls_buffer_t *buf, size_t rec_start, struct st_ptls_traffic_protection_t *enc)
820
875
{
821
875
    size_t bodylen = buf->off - rec_start - 5;
822
875
    uint8_t *tmpbuf, type = buf->base[rec_start];
823
875
    int ret;
824
825
    /* Fast path: do in-place encryption if only one record needs to be emitted. (For simplicity, do not take this path if TLS 1.2
826
     * is used, as this function will be called no more than once per connection, for encrypting an alert.) */
827
875
    if (!enc->tls12 && bodylen <= PTLS_MAX_PLAINTEXT_RECORD_SIZE) {
828
875
        size_t overhead = 1 + enc->aead->algo->tag_size;
829
875
        if ((ret = ptls_buffer_reserve_aligned(buf, overhead, enc->aead->algo->align_bits)) != 0)
830
0
            return ret;
831
875
        size_t encrypted_len = aead_encrypt(enc, buf->base + rec_start + 5, buf->base + rec_start + 5, bodylen, type);
832
875
        assert(encrypted_len == bodylen + overhead);
833
875
        buf->off += overhead;
834
875
        buf->base[rec_start] = PTLS_CONTENT_TYPE_APPDATA;
835
875
        buf->base[rec_start + 3] = (encrypted_len >> 8) & 0xff;
836
875
        buf->base[rec_start + 4] = encrypted_len & 0xff;
837
875
        return 0;
838
875
    }
839
840
    /* move plaintext to temporary buffer */
841
0
    if ((tmpbuf = malloc(bodylen)) == NULL) {
842
0
        ret = PTLS_ERROR_NO_MEMORY;
843
0
        goto Exit;
844
0
    }
845
0
    memcpy(tmpbuf, buf->base + rec_start + 5, bodylen);
846
0
    ptls_clear_memory(buf->base + rec_start, bodylen + 5);
847
0
    buf->off = rec_start;
848
849
    /* push encrypted records */
850
0
    ret = buffer_push_encrypted_records(buf, type, tmpbuf, bodylen, enc);
851
852
0
Exit:
853
0
    if (tmpbuf != NULL) {
854
0
        ptls_clear_memory(tmpbuf, bodylen);
855
0
        free(tmpbuf);
856
0
    }
857
0
    return ret;
858
0
}
859
860
static int begin_record_message(ptls_message_emitter_t *_self)
861
3.30k
{
862
3.30k
    struct st_ptls_record_message_emitter_t *self = (void *)_self;
863
3.30k
    int ret;
864
865
3.30k
    self->rec_start = self->super.buf->off;
866
3.30k
    ptls_buffer_push(self->super.buf, PTLS_CONTENT_TYPE_HANDSHAKE, PTLS_RECORD_VERSION_MAJOR, PTLS_RECORD_VERSION_MINOR, 0, 0);
867
3.30k
    ret = 0;
868
3.30k
Exit:
869
3.30k
    return ret;
870
3.30k
}
871
872
static int commit_record_message(ptls_message_emitter_t *_self)
873
3.30k
{
874
3.30k
    struct st_ptls_record_message_emitter_t *self = (void *)_self;
875
3.30k
    int ret;
876
877
3.30k
    if (self->super.enc->aead != NULL) {
878
865
        ret = buffer_encrypt_record(self->super.buf, self->rec_start, self->super.enc);
879
2.43k
    } else {
880
        /* TODO allow CH,SH,HRR above 16KB */
881
2.43k
        size_t sz = self->super.buf->off - self->rec_start - 5;
882
2.43k
        assert(sz <= PTLS_MAX_PLAINTEXT_RECORD_SIZE);
883
2.43k
        self->super.buf->base[self->rec_start + 3] = (uint8_t)(sz >> 8);
884
2.43k
        self->super.buf->base[self->rec_start + 4] = (uint8_t)(sz);
885
2.43k
        ret = 0;
886
2.43k
    }
887
888
3.30k
    return ret;
889
3.30k
}
890
891
#define buffer_push_extension(buf, type, block)                                                                                    \
892
0
    do {                                                                                                                           \
893
0
        ptls_buffer_push16((buf), (type));                                                                                         \
894
0
        ptls_buffer_push_block((buf), 2, block);                                                                                   \
895
0
    } while (0);
896
897
#define decode_open_extensions(src, end, hstype, exttype, block)                                                                   \
898
4.51k
    do {                                                                                                                           \
899
4.51k
        struct st_ptls_extension_bitmap_t bitmap = {0};                                                                            \
900
4.51k
        ptls_decode_open_block((src), end, 2, {                                                                                    \
901
4.51k
            while ((src) != end) {                                                                                                 \
902
4.51k
                if ((ret = ptls_decode16((exttype), &(src), end)) != 0)                                                            \
903
4.51k
                    goto Exit;                                                                                                     \
904
4.51k
                if (!extension_bitmap_testandset(&bitmap, (hstype), *(exttype))) {                                                 \
905
4.51k
                    ret = PTLS_ALERT_ILLEGAL_PARAMETER;                                                                            \
906
4.51k
                    goto Exit;                                                                                                     \
907
4.51k
                }                                                                                                                  \
908
4.51k
                ptls_decode_open_block((src), end, 2, block);                                                                      \
909
4.51k
            }                                                                                                                      \
910
4.51k
        });                                                                                                                        \
911
4.51k
    } while (0)
912
913
#define decode_extensions(src, end, hstype, exttype, block)                                                                        \
914
4.51k
    do {                                                                                                                           \
915
4.51k
        decode_open_extensions((src), end, hstype, exttype, block);                                                                \
916
4.51k
        ptls_decode_assert_block_close((src), end);                                                                                \
917
2.76k
    } while (0)
918
919
int ptls_decode8(uint8_t *value, const uint8_t **src, const uint8_t *end)
920
5.13k
{
921
5.13k
    if (*src == end)
922
23
        return PTLS_ALERT_DECODE_ERROR;
923
5.10k
    *value = *(*src)++;
924
5.10k
    return 0;
925
5.13k
}
926
927
int ptls_decode16(uint16_t *value, const uint8_t **src, const uint8_t *end)
928
60.4k
{
929
60.4k
    if (end - *src < 2)
930
188
        return PTLS_ALERT_DECODE_ERROR;
931
60.2k
    *value = ntoh16(*src);
932
60.2k
    *src += 2;
933
60.2k
    return 0;
934
60.4k
}
935
936
int ptls_decode24(uint32_t *value, const uint8_t **src, const uint8_t *end)
937
0
{
938
0
    if (end - *src < 3)
939
0
        return PTLS_ALERT_DECODE_ERROR;
940
0
    *value = ((uint32_t)(*src)[0] << 16) | ((uint32_t)(*src)[1] << 8) | (*src)[2];
941
0
    *src += 3;
942
0
    return 0;
943
0
}
944
945
int ptls_decode32(uint32_t *value, const uint8_t **src, const uint8_t *end)
946
1.45k
{
947
1.45k
    if (end - *src < 4)
948
6
        return PTLS_ALERT_DECODE_ERROR;
949
1.45k
    *value = ntoh32(*src);
950
1.45k
    *src += 4;
951
1.45k
    return 0;
952
1.45k
}
953
954
int ptls_decode64(uint64_t *value, const uint8_t **src, const uint8_t *end)
955
144
{
956
144
    if (end - *src < 8)
957
0
        return PTLS_ALERT_DECODE_ERROR;
958
144
    *value = ntoh64(*src);
959
144
    *src += 8;
960
144
    return 0;
961
144
}
962
963
uint64_t ptls_decode_quicint(const uint8_t **src, const uint8_t *end)
964
0
{
965
0
    if (PTLS_UNLIKELY(*src == end))
966
0
        return UINT64_MAX;
967
968
0
    uint8_t b = *(*src)++;
969
970
0
    if (PTLS_LIKELY(b <= 0x3f))
971
0
        return b;
972
973
0
    uint64_t v = b & 0x3f;
974
0
    unsigned bytes_left = (1 << (b >> 6)) - 1;
975
0
    if (PTLS_UNLIKELY((size_t)(end - *src) < bytes_left))
976
0
        return UINT64_MAX;
977
0
    do {
978
0
        v = (v << 8) | *(*src)++;
979
0
    } while (--bytes_left != 0);
980
0
    return v;
981
0
}
982
983
static void log_secret(ptls_t *tls, const char *type, ptls_iovec_t secret)
984
2.74k
{
985
2.74k
    char hexbuf[PTLS_MAX_DIGEST_SIZE * 2 + 1];
986
987
2.74k
    PTLS_PROBE(NEW_SECRET, tls, type, ptls_hexdump(hexbuf, secret.base, secret.len));
988
2.74k
    PTLS_LOG_CONN(new_secret, tls, { PTLS_LOG_ELEMENT_SAFESTR(label, type); });
989
990
2.74k
    if (tls->ctx->log_event != NULL)
991
0
        tls->ctx->log_event->cb(tls->ctx->log_event, tls, type, "%s", ptls_hexdump(hexbuf, secret.base, secret.len));
992
2.74k
}
993
994
/**
995
 * This function preserves the flags and  modes (e.g., `offered`, `accepted`, `cipher`), they can be used afterwards.
996
 */
997
static void clear_ech(struct st_ptls_ech_t *ech, int is_server)
998
5.41k
{
999
5.41k
    if (ech->aead != NULL) {
1000
0
        ptls_aead_free(ech->aead);
1001
0
        ech->aead = NULL;
1002
0
    }
1003
5.41k
    ptls_clear_memory(ech->inner_client_random, PTLS_HELLO_RANDOM_SIZE);
1004
5.41k
    if (!is_server) {
1005
3.04k
        free(ech->client.enc.base);
1006
3.04k
        ech->client.enc = ptls_iovec_init(NULL, 0);
1007
3.04k
        if (ech->client.public_name != NULL) {
1008
0
            free(ech->client.public_name);
1009
0
            ech->client.public_name = NULL;
1010
0
        }
1011
3.04k
        free(ech->client.first_ech.base);
1012
3.04k
        ech->client.first_ech = ptls_iovec_init(NULL, 0);
1013
3.04k
    }
1014
5.41k
}
1015
1016
/**
1017
 * Decodes one ECHConfigContents (tls-esni-15 section 4). `decoded->kem` and `cipher` may be NULL even when the function returns
1018
 * zero, if the corresponding entries are not found.
1019
 */
1020
static int decode_one_ech_config(ptls_hpke_kem_t **kems, ptls_hpke_cipher_suite_t **ciphers,
1021
                                 struct st_decoded_ech_config_t *decoded, const uint8_t **src, const uint8_t *const end)
1022
0
{
1023
0
    char *public_name_buf = NULL;
1024
0
    int ret;
1025
1026
0
    *decoded = (struct st_decoded_ech_config_t){0};
1027
1028
0
    if ((ret = ptls_decode8(&decoded->id, src, end)) != 0)
1029
0
        goto Exit;
1030
0
    uint16_t kem_id;
1031
0
    if ((ret = ptls_decode16(&kem_id, src, end)) != 0)
1032
0
        goto Exit;
1033
0
    for (size_t i = 0; kems[i] != NULL; ++i) {
1034
0
        if (kems[i]->id == kem_id) {
1035
0
            decoded->kem = kems[i];
1036
0
            break;
1037
0
        }
1038
0
    }
1039
0
    ptls_decode_open_block(*src, end, 2, {
1040
0
        if (*src == end) {
1041
0
            ret = PTLS_ALERT_DECODE_ERROR;
1042
0
            goto Exit;
1043
0
        }
1044
0
        decoded->public_key = ptls_iovec_init(*src, end - *src);
1045
0
        *src = end;
1046
0
    });
1047
0
    ptls_decode_open_block(*src, end, 2, {
1048
0
        do {
1049
0
            uint16_t kdf_id;
1050
0
            uint16_t aead_id;
1051
0
            if ((ret = ptls_decode16(&kdf_id, src, end)) != 0)
1052
0
                goto Exit;
1053
0
            if ((ret = ptls_decode16(&aead_id, src, end)) != 0)
1054
0
                goto Exit;
1055
0
            if (decoded->cipher == NULL) {
1056
0
                for (size_t i = 0; ciphers[i] != NULL; ++i) {
1057
0
                    if (ciphers[i]->id.kdf == kdf_id && ciphers[i]->id.aead == aead_id) {
1058
0
                        decoded->cipher = ciphers[i];
1059
0
                        break;
1060
0
                    }
1061
0
                }
1062
0
            }
1063
0
        } while (*src != end);
1064
0
    });
1065
0
    if ((ret = ptls_decode8(&decoded->max_name_length, src, end)) != 0)
1066
0
        goto Exit;
1067
1068
0
#define SKIP_DECODED()                                                                                                             \
1069
0
    do {                                                                                                                           \
1070
0
        decoded->kem = NULL;                                                                                                       \
1071
0
        decoded->cipher = NULL;                                                                                                    \
1072
0
    } while (0)
1073
1074
    /* Decode public_name. The specification requires clients to ignore (upon parsing ESNIConfigList) or reject (upon handshake)
1075
     * public names that are not DNS names or IPv4 addresses. We ignore IPv4 and v6 addresses during parsing (IPv6 addresses never
1076
     * looks like DNS names), and delegate the responsibility of rejecting non-DNS names to the certificate verify callback. */
1077
0
    ptls_decode_open_block(*src, end, 1, {
1078
0
        if (*src == end) {
1079
0
            ret = PTLS_ALERT_DECODE_ERROR;
1080
0
            goto Exit;
1081
0
        }
1082
0
        if ((public_name_buf = duplicate_as_str(*src, end - *src)) == NULL) {
1083
0
            ret = PTLS_ERROR_NO_MEMORY;
1084
0
            goto Exit;
1085
0
        }
1086
0
        if (ptls_server_name_is_ipaddr(public_name_buf)) {
1087
0
            SKIP_DECODED();
1088
0
        } else {
1089
0
            decoded->public_name = ptls_iovec_init(*src, end - *src);
1090
0
        }
1091
0
        *src = end;
1092
0
    });
1093
1094
0
    ptls_decode_block(*src, end, 2, {
1095
0
        while (*src < end) {
1096
0
            uint16_t type;
1097
0
            if ((ret = ptls_decode16(&type, src, end)) != 0)
1098
0
                goto Exit;
1099
0
            ptls_decode_open_block(*src, end, 2, { *src = end; });
1100
            /* if a critital extension is found, indicate that the config cannot be used */
1101
0
            if ((type & 0x8000) != 0)
1102
0
                SKIP_DECODED();
1103
0
        }
1104
0
    });
1105
1106
0
#undef SKIP_DECODED
1107
1108
0
Exit:
1109
0
    free(public_name_buf);
1110
0
    return ret;
1111
0
}
1112
1113
static int client_decode_ech_config_list(ptls_context_t *ctx, struct st_decoded_ech_config_t *decoded, ptls_iovec_t config_list)
1114
0
{
1115
0
    const uint8_t *src = config_list.base, *const end = src + config_list.len;
1116
0
    int match_found = 0, ret;
1117
1118
0
    *decoded = (struct st_decoded_ech_config_t){0};
1119
1120
0
    ptls_decode_block(src, end, 2, {
1121
0
        do {
1122
0
            const uint8_t *config_start = src;
1123
0
            uint16_t version;
1124
0
            if ((ret = ptls_decode16(&version, &src, end)) != 0)
1125
0
                goto Exit;
1126
0
            ptls_decode_open_block(src, end, 2, {
1127
                /* If the block is the one that we recognize, parse it, then adopt if if possible. Otherwise, skip. */
1128
0
                if (version == PTLS_ECH_CONFIG_VERSION) {
1129
0
                    struct st_decoded_ech_config_t thisconf;
1130
0
                    if ((ret = decode_one_ech_config(ctx->ech.client.kems, ctx->ech.client.ciphers, &thisconf, &src, end)) != 0)
1131
0
                        goto Exit;
1132
0
                    if (!match_found && thisconf.kem != NULL && thisconf.cipher != NULL) {
1133
0
                        *decoded = thisconf;
1134
0
                        decoded->bytes = ptls_iovec_init(config_start, end - config_start);
1135
0
                        match_found = 1;
1136
0
                    }
1137
0
                } else {
1138
0
                    src = end;
1139
0
                }
1140
0
            });
1141
0
        } while (src != end);
1142
0
    });
1143
0
    ret = 0;
1144
1145
0
Exit:
1146
0
    if (ret != 0)
1147
0
        *decoded = (struct st_decoded_ech_config_t){0};
1148
0
    return ret;
1149
0
}
1150
1151
static int client_setup_ech(struct st_ptls_ech_t *ech, struct st_decoded_ech_config_t *decoded,
1152
                            void (*random_bytes)(void *, size_t))
1153
0
{
1154
0
    ptls_buffer_t infobuf;
1155
0
    uint8_t infobuf_smallbuf[256];
1156
0
    int ret;
1157
1158
    /* setup `enc` and `aead` by running HPKE */
1159
0
    ptls_buffer_init(&infobuf, infobuf_smallbuf, sizeof(infobuf_smallbuf));
1160
0
    ptls_buffer_pushv(&infobuf, ech_info_prefix, sizeof(ech_info_prefix));
1161
0
    ptls_buffer_pushv(&infobuf, decoded->bytes.base, decoded->bytes.len);
1162
0
    if ((ret = ptls_hpke_setup_base_s(decoded->kem, decoded->cipher, &ech->client.enc, &ech->aead, decoded->public_key,
1163
0
                                      ptls_iovec_init(infobuf.base, infobuf.off))) != 0)
1164
0
        goto Exit;
1165
1166
    /* setup the rest */
1167
0
    ech->config_id = decoded->id;
1168
0
    ech->kem = decoded->kem;
1169
0
    ech->cipher = decoded->cipher;
1170
0
    random_bytes(ech->inner_client_random, PTLS_HELLO_RANDOM_SIZE);
1171
0
    ech->client.max_name_length = decoded->max_name_length;
1172
0
    if ((ech->client.public_name = duplicate_as_str(decoded->public_name.base, decoded->public_name.len)) == NULL) {
1173
0
        ret = PTLS_ERROR_NO_MEMORY;
1174
0
        goto Exit;
1175
0
    }
1176
1177
0
Exit:
1178
0
    if (ret != 0)
1179
0
        clear_ech(ech, 0);
1180
0
    return ret;
1181
0
}
1182
1183
static void client_setup_ech_grease(struct st_ptls_ech_t *ech, void (*random_bytes)(void *, size_t), ptls_hpke_kem_t **kems,
1184
                                    ptls_hpke_cipher_suite_t **ciphers, const char *sni_name)
1185
0
{
1186
0
    static const size_t x25519_key_size = 32;
1187
0
    uint8_t random_secret[PTLS_AES128_KEY_SIZE + PTLS_AES_IV_SIZE];
1188
1189
    /* pick up X25519, AES-128-GCM or bail out */
1190
0
    for (size_t i = 0; kems[i] != NULL; ++i) {
1191
0
        if (kems[i]->id == PTLS_HPKE_KEM_X25519_SHA256) {
1192
0
            ech->kem = kems[i];
1193
0
            break;
1194
0
        }
1195
0
    }
1196
0
    for (size_t i = 0; ciphers[i] != NULL; ++i) {
1197
0
        if (ciphers[i]->id.kdf == PTLS_HPKE_HKDF_SHA256 && ciphers[i]->id.aead == PTLS_HPKE_AEAD_AES_128_GCM) {
1198
0
            ech->cipher = ciphers[i];
1199
0
            break;
1200
0
        }
1201
0
    }
1202
0
    if (ech->kem == NULL || ech->cipher == NULL)
1203
0
        goto Fail;
1204
1205
    /* aead is generated from random */
1206
0
    random_bytes(random_secret, sizeof(random_secret));
1207
0
    ech->aead = ptls_aead_new_direct(ech->cipher->aead, 1, random_secret, random_secret + PTLS_AES128_KEY_SIZE);
1208
1209
    /* `enc` is random bytes */
1210
0
    if ((ech->client.enc.base = malloc(x25519_key_size)) == NULL)
1211
0
        goto Fail;
1212
0
    ech->client.enc.len = x25519_key_size;
1213
0
    random_bytes(ech->client.enc.base, ech->client.enc.len);
1214
1215
    /* setup the rest (inner_client_random is left zeros) */
1216
0
    random_bytes(&ech->config_id, sizeof(ech->config_id));
1217
0
    ech->client.max_name_length = 64;
1218
0
    if ((ech->client.public_name = duplicate_as_str(sni_name, strlen(sni_name))) == NULL)
1219
0
        goto Fail;
1220
1221
0
    return;
1222
1223
0
Fail:
1224
0
    clear_ech(ech, 0);
1225
0
}
1226
1227
0
#define ECH_CONFIRMATION_SERVER_HELLO "ech accept confirmation"
1228
0
#define ECH_CONFIRMATION_HRR "hrr ech accept confirmation"
1229
static int ech_calc_confirmation(ptls_key_schedule_t *sched, void *dst, const uint8_t *inner_random, const char *label,
1230
                                 ptls_iovec_t message)
1231
0
{
1232
0
    ptls_hash_context_t *hash = NULL;
1233
0
    uint8_t secret[PTLS_MAX_DIGEST_SIZE], transcript_hash[PTLS_MAX_DIGEST_SIZE];
1234
0
    int ret;
1235
1236
    /* calc transcript hash using the modified ServerHello / HRR */
1237
0
    if ((hash = sched->hashes[0].ctx->clone_(sched->hashes[0].ctx)) == NULL) {
1238
0
        ret = PTLS_ERROR_NO_MEMORY;
1239
0
        goto Exit;
1240
0
    }
1241
0
    hash->update(hash, message.base, message.len);
1242
0
    hash->final(hash, transcript_hash, PTLS_HASH_FINAL_MODE_FREE);
1243
0
    hash = NULL;
1244
1245
    /* HKDF extract and expand */
1246
0
    if ((ret = ptls_hkdf_extract(sched->hashes[0].algo, secret, ptls_iovec_init(NULL, 0),
1247
0
                                 ptls_iovec_init(inner_random, PTLS_HELLO_RANDOM_SIZE))) != 0)
1248
0
        goto Exit;
1249
0
    if ((ret = ptls_hkdf_expand_label(sched->hashes[0].algo, dst, 8, ptls_iovec_init(secret, sched->hashes[0].algo->digest_size),
1250
0
                                      label, ptls_iovec_init(transcript_hash, sched->hashes[0].algo->digest_size), NULL)) != 0)
1251
0
        goto Exit;
1252
1253
0
Exit:
1254
0
    ptls_clear_memory(secret, sizeof(secret));
1255
0
    ptls_clear_memory(transcript_hash, sizeof(transcript_hash));
1256
0
    if (hash != NULL)
1257
0
        hash->final(hash, NULL, PTLS_HASH_FINAL_MODE_FREE);
1258
0
    return ret;
1259
0
}
1260
1261
static void key_schedule_free(ptls_key_schedule_t *sched)
1262
2.62k
{
1263
2.62k
    size_t i;
1264
2.62k
    ptls_clear_memory(sched->secret, sizeof(sched->secret));
1265
5.24k
    for (i = 0; i != sched->num_hashes; ++i) {
1266
2.62k
        sched->hashes[i].ctx->final(sched->hashes[i].ctx, NULL, PTLS_HASH_FINAL_MODE_FREE);
1267
2.62k
        if (sched->hashes[i].ctx_outer != NULL)
1268
0
            sched->hashes[i].ctx_outer->final(sched->hashes[i].ctx_outer, NULL, PTLS_HASH_FINAL_MODE_FREE);
1269
2.62k
    }
1270
2.62k
    free(sched);
1271
2.62k
}
1272
1273
static ptls_key_schedule_t *key_schedule_new(ptls_cipher_suite_t *preferred, ptls_cipher_suite_t **offered, int use_outer)
1274
2.62k
{
1275
2.62k
#define FOREACH_HASH(block)                                                                                                        \
1276
5.24k
    do {                                                                                                                           \
1277
5.24k
        ptls_cipher_suite_t *cs;                                                                                                   \
1278
5.24k
        if ((cs = preferred) != NULL) {                                                                                            \
1279
1.88k
            block                                                                                                                  \
1280
1.25k
        }                                                                                                                          \
1281
5.24k
        if (offered != NULL) {                                                                                                     \
1282
3.98k
            size_t i, j;                                                                                                           \
1283
7.96k
            for (i = 0; (cs = offered[i]) != NULL; ++i) {                                                                          \
1284
3.98k
                if (preferred == NULL || cs->hash != preferred->hash) {                                                            \
1285
3.98k
                    for (j = 0; j != i; ++j)                                                                                       \
1286
3.98k
                        if (cs->hash == offered[j]->hash)                                                                          \
1287
0
                            break;                                                                                                 \
1288
3.98k
                    if (j == i) {                                                                                                  \
1289
5.97k
                        block                                                                                                      \
1290
3.98k
                    }                                                                                                              \
1291
3.98k
                }                                                                                                                  \
1292
3.98k
            }                                                                                                                      \
1293
3.98k
        }                                                                                                                          \
1294
5.24k
    } while (0)
1295
1296
2.62k
    ptls_key_schedule_t *sched;
1297
1298
2.62k
    { /* allocate */
1299
2.62k
        size_t num_hashes = 0;
1300
2.62k
        FOREACH_HASH({ ++num_hashes; });
1301
2.62k
        if ((sched = malloc(offsetof(ptls_key_schedule_t, hashes) + sizeof(sched->hashes[0]) * num_hashes)) == NULL)
1302
0
            return NULL;
1303
2.62k
        *sched = (ptls_key_schedule_t){0};
1304
2.62k
    }
1305
1306
    /* setup the hash algos and contexts */
1307
2.62k
    FOREACH_HASH({
1308
2.62k
        sched->hashes[sched->num_hashes].algo = cs->hash;
1309
2.62k
        if ((sched->hashes[sched->num_hashes].ctx = cs->hash->create()) == NULL)
1310
2.62k
            goto Fail;
1311
2.62k
        if (use_outer) {
1312
2.62k
            if ((sched->hashes[sched->num_hashes].ctx_outer = cs->hash->create()) == NULL)
1313
2.62k
                goto Fail;
1314
2.62k
        } else {
1315
2.62k
            sched->hashes[sched->num_hashes].ctx_outer = NULL;
1316
2.62k
        }
1317
2.62k
        ++sched->num_hashes;
1318
2.62k
    });
1319
1320
2.62k
    return sched;
1321
0
Fail:
1322
0
    key_schedule_free(sched);
1323
0
    return NULL;
1324
1325
2.62k
#undef FOREACH_HASH
1326
2.62k
}
1327
1328
static int key_schedule_extract(ptls_key_schedule_t *sched, ptls_iovec_t ikm)
1329
3.94k
{
1330
3.94k
    int ret;
1331
1332
3.94k
    if (ikm.base == NULL)
1333
2.67k
        ikm = ptls_iovec_init(zeroes_of_max_digest_size, sched->hashes[0].algo->digest_size);
1334
1335
3.94k
    if (sched->generation != 0 &&
1336
1.47k
        (ret = ptls_hkdf_expand_label(sched->hashes[0].algo, sched->secret, sched->hashes[0].algo->digest_size,
1337
1.47k
                                      ptls_iovec_init(sched->secret, sched->hashes[0].algo->digest_size), "derived",
1338
1.47k
                                      ptls_iovec_init(sched->hashes[0].algo->empty_digest, sched->hashes[0].algo->digest_size),
1339
1.47k
                                      NULL)) != 0)
1340
0
        return ret;
1341
1342
3.94k
    ++sched->generation;
1343
3.94k
    ret = ptls_hkdf_extract(sched->hashes[0].algo, sched->secret,
1344
3.94k
                            ptls_iovec_init(sched->secret, sched->hashes[0].algo->digest_size), ikm);
1345
3.94k
    PTLS_DEBUGF("%s: %u, %02x%02x\n", __FUNCTION__, sched->generation, (int)sched->secret[0], (int)sched->secret[1]);
1346
3.94k
    return ret;
1347
3.94k
}
1348
1349
static int key_schedule_select_cipher(ptls_key_schedule_t *sched, ptls_cipher_suite_t *cs, int reset, ptls_iovec_t reset_ikm)
1350
1.15k
{
1351
1.15k
    size_t found_slot = SIZE_MAX, i;
1352
1.15k
    int ret;
1353
1354
1.15k
    assert(sched->generation == 1);
1355
1356
    /* find the one, while freeing others */
1357
2.30k
    for (i = 0; i != sched->num_hashes; ++i) {
1358
1.15k
        if (sched->hashes[i].algo == cs->hash) {
1359
1.15k
            assert(found_slot == SIZE_MAX);
1360
1.15k
            found_slot = i;
1361
1.15k
        } else {
1362
0
            sched->hashes[i].ctx->final(sched->hashes[i].ctx, NULL, PTLS_HASH_FINAL_MODE_FREE);
1363
0
            if (sched->hashes[i].ctx_outer != NULL)
1364
0
                sched->hashes[i].ctx_outer->final(sched->hashes[i].ctx_outer, NULL, PTLS_HASH_FINAL_MODE_FREE);
1365
0
        }
1366
1.15k
    }
1367
1.15k
    assert(found_slot != SIZE_MAX);
1368
1.15k
    if (found_slot != 0) {
1369
0
        sched->hashes[0] = sched->hashes[found_slot];
1370
0
        reset = 1;
1371
0
    }
1372
1.15k
    sched->num_hashes = 1;
1373
1374
    /* recalculate the hash if a different hash as been selected than the one we used for calculating the early secrets */
1375
1.15k
    if (reset) {
1376
0
        --sched->generation;
1377
0
        memset(sched->secret, 0, sizeof(sched->secret));
1378
0
        if ((ret = key_schedule_extract(sched, reset_ikm)) != 0)
1379
0
            goto Exit;
1380
0
    }
1381
1382
1.15k
    ret = 0;
1383
1.15k
Exit:
1384
1.15k
    return ret;
1385
1.15k
}
1386
1387
static void key_schedule_select_outer(ptls_key_schedule_t *sched)
1388
0
{
1389
    /* This function is called when receiving a cleartext message (Server Hello), after the cipher-suite is determined (and hence
1390
     * the hash also), if ECH was offered */
1391
0
    assert(sched->generation == 1);
1392
0
    assert(sched->num_hashes == 1);
1393
0
    assert(sched->hashes[0].ctx_outer != NULL);
1394
1395
0
    sched->hashes[0].ctx->final(sched->hashes[0].ctx, NULL, PTLS_HASH_FINAL_MODE_FREE);
1396
0
    sched->hashes[0].ctx = sched->hashes[0].ctx_outer;
1397
0
    sched->hashes[0].ctx_outer = NULL;
1398
0
}
1399
1400
void ptls__key_schedule_update_hash(ptls_key_schedule_t *sched, const uint8_t *msg, size_t msglen, int use_outer)
1401
5.93k
{
1402
5.93k
    size_t i;
1403
1404
5.93k
    PTLS_DEBUGF("%s:%p:len=%zu\n", __FUNCTION__, sched, msglen);
1405
11.8k
    for (i = 0; i != sched->num_hashes; ++i) {
1406
5.93k
        ptls_hash_context_t *ctx = use_outer ? sched->hashes[i].ctx_outer : sched->hashes[i].ctx;
1407
5.93k
        ctx->update(ctx, msg, msglen);
1408
#if defined(PTLS_DEBUG) && PTLS_DEBUG
1409
        {
1410
            uint8_t digest[PTLS_MAX_DIGEST_SIZE];
1411
            ctx->final(ctx, digest, PTLS_HASH_FINAL_MODE_SNAPSHOT);
1412
            PTLS_DEBUGF("  %zu: %02x%02x%02x%02x\n", i, digest[0], digest[1], digest[2], digest[3]);
1413
        }
1414
#endif
1415
5.93k
    }
1416
5.93k
}
1417
1418
static void key_schedule_update_ch1hash_prefix(ptls_key_schedule_t *sched)
1419
0
{
1420
0
    uint8_t prefix[4] = {PTLS_HANDSHAKE_TYPE_MESSAGE_HASH, 0, 0, (uint8_t)sched->hashes[0].algo->digest_size};
1421
0
    ptls__key_schedule_update_hash(sched, prefix, sizeof(prefix), 0);
1422
0
}
1423
1424
static void key_schedule_extract_ch1hash(ptls_key_schedule_t *sched, uint8_t *hash)
1425
0
{
1426
0
    assert(sched->hashes[0].ctx_outer == NULL);
1427
0
    sched->hashes[0].ctx->final(sched->hashes[0].ctx, hash, PTLS_HASH_FINAL_MODE_RESET);
1428
0
}
1429
1430
static void key_schedule_transform_post_ch1hash(ptls_key_schedule_t *sched)
1431
254
{
1432
254
    size_t digest_size = sched->hashes[0].algo->digest_size;
1433
254
    ptls_hash_context_t *hashes[3] = {sched->hashes[0].ctx, sched->hashes[0].ctx_outer, NULL};
1434
254
    uint8_t ch1hash[PTLS_MAX_DIGEST_SIZE];
1435
254
    uint8_t prefix[4] = {PTLS_HANDSHAKE_TYPE_MESSAGE_HASH, 0, 0, (uint8_t)digest_size};
1436
1437
508
    for (size_t i = 0; hashes[i] != NULL; ++i) {
1438
254
        hashes[i]->final(hashes[i], ch1hash, PTLS_HASH_FINAL_MODE_RESET);
1439
254
        hashes[i]->update(hashes[i], prefix, sizeof(prefix));
1440
254
        hashes[i]->update(hashes[i], ch1hash, digest_size);
1441
254
    }
1442
1443
254
    ptls_clear_memory(ch1hash, sizeof(ch1hash));
1444
254
}
1445
1446
static int derive_secret_with_hash(ptls_key_schedule_t *sched, void *secret, const char *label, const uint8_t *hash)
1447
3.17k
{
1448
3.17k
    int ret = ptls_hkdf_expand_label(sched->hashes[0].algo, secret, sched->hashes[0].algo->digest_size,
1449
3.17k
                                     ptls_iovec_init(sched->secret, sched->hashes[0].algo->digest_size), label,
1450
3.17k
                                     ptls_iovec_init(hash, sched->hashes[0].algo->digest_size), NULL);
1451
3.17k
    PTLS_DEBUGF("%s: (label=%s, hash=%02x%02x) => %02x%02x\n", __FUNCTION__, label, hash[0], hash[1], ((uint8_t *)secret)[0],
1452
3.17k
                ((uint8_t *)secret)[1]);
1453
3.17k
    return ret;
1454
3.17k
}
1455
1456
static int derive_secret(ptls_key_schedule_t *sched, void *secret, const char *label)
1457
3.17k
{
1458
3.17k
    uint8_t hash_value[PTLS_MAX_DIGEST_SIZE];
1459
1460
3.17k
    sched->hashes[0].ctx->final(sched->hashes[0].ctx, hash_value, PTLS_HASH_FINAL_MODE_SNAPSHOT);
1461
3.17k
    int ret = derive_secret_with_hash(sched, secret, label, hash_value);
1462
3.17k
    ptls_clear_memory(hash_value, sizeof(hash_value));
1463
3.17k
    return ret;
1464
3.17k
}
1465
1466
static int derive_secret_with_empty_digest(ptls_key_schedule_t *sched, void *secret, const char *label)
1467
2
{
1468
2
    return derive_secret_with_hash(sched, secret, label, sched->hashes[0].algo->empty_digest);
1469
2
}
1470
1471
static int derive_exporter_secret(ptls_t *tls, int is_early)
1472
212
{
1473
212
    int ret;
1474
1475
212
    if (!tls->ctx->use_exporter)
1476
212
        return 0;
1477
1478
0
    uint8_t **slot = is_early ? &tls->exporter_master_secret.early : &tls->exporter_master_secret.one_rtt;
1479
0
    assert(*slot == NULL);
1480
0
    if ((*slot = malloc(tls->key_schedule->hashes[0].algo->digest_size)) == NULL)
1481
0
        return PTLS_ERROR_NO_MEMORY;
1482
1483
0
    if ((ret = derive_secret(tls->key_schedule, *slot, is_early ? "e exp master" : "exp master")) != 0)
1484
0
        return ret;
1485
1486
0
    log_secret(tls, is_early ? "EARLY_EXPORTER_SECRET" : "EXPORTER_SECRET",
1487
0
               ptls_iovec_init(*slot, tls->key_schedule->hashes[0].algo->digest_size));
1488
1489
0
    return 0;
1490
0
}
1491
1492
static void free_exporter_master_secret(ptls_t *tls, int is_early)
1493
8.29k
{
1494
8.29k
    uint8_t *slot = is_early ? tls->exporter_master_secret.early : tls->exporter_master_secret.one_rtt;
1495
8.29k
    if (slot == NULL)
1496
8.29k
        return;
1497
8.29k
    assert(tls->key_schedule != NULL);
1498
0
    ptls_clear_memory(slot, tls->key_schedule->hashes[0].algo->digest_size);
1499
0
    free(slot);
1500
0
}
1501
1502
static int derive_resumption_secret(ptls_key_schedule_t *sched, uint8_t *secret, ptls_iovec_t nonce)
1503
219
{
1504
219
    int ret;
1505
1506
219
    if ((ret = derive_secret(sched, secret, "res master")) != 0)
1507
0
        goto Exit;
1508
219
    if ((ret = ptls_hkdf_expand_label(sched->hashes[0].algo, secret, sched->hashes[0].algo->digest_size,
1509
219
                                      ptls_iovec_init(secret, sched->hashes[0].algo->digest_size), "resumption", nonce, NULL)) != 0)
1510
0
        goto Exit;
1511
1512
219
Exit:
1513
219
    if (ret != 0)
1514
0
        ptls_clear_memory(secret, sched->hashes[0].algo->digest_size);
1515
219
    return ret;
1516
219
}
1517
1518
static int decode_new_session_ticket(ptls_t *tls, uint32_t *lifetime, uint32_t *age_add, ptls_iovec_t *nonce, ptls_iovec_t *ticket,
1519
                                     int *early_data, uint32_t *max_early_data_size, const uint8_t *src, const uint8_t *const end)
1520
0
{
1521
0
    uint16_t exttype;
1522
0
    int ret;
1523
1524
0
    if ((ret = ptls_decode32(lifetime, &src, end)) != 0)
1525
0
        goto Exit;
1526
0
    if ((ret = ptls_decode32(age_add, &src, end)) != 0)
1527
0
        goto Exit;
1528
0
    ptls_decode_open_block(src, end, 1, {
1529
0
        *nonce = ptls_iovec_init(src, end - src);
1530
0
        src = end;
1531
0
    });
1532
0
    ptls_decode_open_block(src, end, 2, {
1533
0
        if (src == end) {
1534
0
            ret = PTLS_ALERT_DECODE_ERROR;
1535
0
            goto Exit;
1536
0
        }
1537
0
        *ticket = ptls_iovec_init(src, end - src);
1538
0
        src = end;
1539
0
    });
1540
1541
0
    *early_data = 0;
1542
0
    *max_early_data_size = 0;
1543
0
    decode_extensions(src, end, PTLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET, &exttype, {
1544
0
        if (tls->ctx->on_extension != NULL &&
1545
0
            (ret = tls->ctx->on_extension->cb(tls->ctx->on_extension, tls, PTLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET, exttype,
1546
0
                                              ptls_iovec_init(src, end - src)) != 0))
1547
0
            goto Exit;
1548
0
        switch (exttype) {
1549
0
        case PTLS_EXTENSION_TYPE_EARLY_DATA:
1550
0
            *early_data = 1;
1551
0
            if ((ret = ptls_decode32(max_early_data_size, &src, end)) != 0)
1552
0
                goto Exit;
1553
0
            break;
1554
0
        default:
1555
0
            src = end;
1556
0
            break;
1557
0
        }
1558
0
    });
1559
1560
0
    ret = 0;
1561
0
Exit:
1562
0
    return ret;
1563
0
}
1564
1565
static int decode_stored_session_ticket(ptls_t *tls, ptls_key_exchange_algorithm_t **key_share, ptls_cipher_suite_t **cs,
1566
                                        ptls_iovec_t *secret, uint32_t *obfuscated_ticket_age, ptls_iovec_t *ticket,
1567
                                        uint32_t *max_early_data_size, const uint8_t *src, const uint8_t *const end)
1568
0
{
1569
0
    uint16_t kxid, csid;
1570
0
    uint32_t lifetime, age_add;
1571
0
    uint64_t obtained_at, now;
1572
0
    ptls_iovec_t nonce;
1573
0
    int early_data;
1574
0
    int ret;
1575
1576
    /* decode */
1577
0
    if ((ret = ptls_decode64(&obtained_at, &src, end)) != 0)
1578
0
        goto Exit;
1579
0
    if ((ret = ptls_decode16(&kxid, &src, end)) != 0)
1580
0
        goto Exit;
1581
0
    if ((ret = ptls_decode16(&csid, &src, end)) != 0)
1582
0
        goto Exit;
1583
0
    ptls_decode_open_block(src, end, 3, {
1584
0
        if ((ret = decode_new_session_ticket(tls, &lifetime, &age_add, &nonce, ticket, &early_data, max_early_data_size, src,
1585
0
                                             end)) != 0)
1586
0
            goto Exit;
1587
0
        src = end;
1588
0
    });
1589
0
    ptls_decode_block(src, end, 2, {
1590
0
        *secret = ptls_iovec_init(src, end - src);
1591
0
        src = end;
1592
0
    });
1593
1594
0
    { /* determine the key-exchange */
1595
0
        ptls_key_exchange_algorithm_t **cand;
1596
0
        for (cand = tls->ctx->key_exchanges; *cand != NULL; ++cand)
1597
0
            if ((*cand)->id == kxid)
1598
0
                break;
1599
0
        if (*cand == NULL) {
1600
0
            ret = PTLS_ERROR_LIBRARY;
1601
0
            goto Exit;
1602
0
        }
1603
0
        *key_share = *cand;
1604
0
    }
1605
1606
0
    { /* determine the cipher-suite */
1607
0
        ptls_cipher_suite_t **cand;
1608
0
        for (cand = tls->ctx->cipher_suites; *cand != NULL; ++cand)
1609
0
            if ((*cand)->id == csid)
1610
0
                break;
1611
0
        if (*cand == NULL) {
1612
0
            ret = PTLS_ERROR_LIBRARY;
1613
0
            goto Exit;
1614
0
        }
1615
0
        *cs = *cand;
1616
0
    }
1617
1618
    /* calculate obfuscated_ticket_age */
1619
0
    now = tls->ctx->get_time->cb(tls->ctx->get_time);
1620
0
    if (!(obtained_at <= now && now - obtained_at < 7 * 86400 * 1000)) {
1621
0
        ret = PTLS_ERROR_LIBRARY;
1622
0
        goto Exit;
1623
0
    }
1624
0
    *obfuscated_ticket_age = (uint32_t)(now - obtained_at) + age_add;
1625
1626
0
    ret = 0;
1627
0
Exit:
1628
0
    return ret;
1629
0
}
1630
1631
static int get_traffic_key(ptls_hash_algorithm_t *algo, void *key, size_t key_size, int is_iv, const void *secret,
1632
                           ptls_iovec_t hash_value, const char *label_prefix)
1633
5.48k
{
1634
5.48k
    return ptls_hkdf_expand_label(algo, key, key_size, ptls_iovec_init(secret, algo->digest_size), is_iv ? "iv" : "key", hash_value,
1635
5.48k
                                  label_prefix);
1636
5.48k
}
1637
1638
static int get_traffic_keys(ptls_aead_algorithm_t *aead, ptls_hash_algorithm_t *hash, void *key, void *iv, const void *secret,
1639
                            ptls_iovec_t hash_value, const char *label_prefix)
1640
2.74k
{
1641
2.74k
    int ret;
1642
1643
2.74k
    if ((ret = get_traffic_key(hash, key, aead->key_size, 0, secret, hash_value, label_prefix)) != 0 ||
1644
2.74k
        (ret = get_traffic_key(hash, iv, aead->iv_size, 1, secret, hash_value, label_prefix)) != 0) {
1645
0
        ptls_clear_memory(key, aead->key_size);
1646
0
        ptls_clear_memory(iv, aead->iv_size);
1647
0
    }
1648
1649
2.74k
    return ret;
1650
2.74k
}
1651
1652
static int setup_traffic_protection(ptls_t *tls, int is_enc, const char *secret_label, size_t epoch, uint64_t seq, int skip_notify)
1653
2.74k
{
1654
2.74k
    static const char *log_labels[2][4] = {
1655
2.74k
        {NULL, "CLIENT_EARLY_TRAFFIC_SECRET", "CLIENT_HANDSHAKE_TRAFFIC_SECRET", "CLIENT_TRAFFIC_SECRET_0"},
1656
2.74k
        {NULL, NULL, "SERVER_HANDSHAKE_TRAFFIC_SECRET", "SERVER_TRAFFIC_SECRET_0"}};
1657
2.74k
    struct st_ptls_traffic_protection_t *ctx = is_enc ? &tls->traffic_protection.enc : &tls->traffic_protection.dec;
1658
1659
2.74k
    if (secret_label != NULL) {
1660
2.74k
        int ret;
1661
2.74k
        if ((ret = derive_secret(tls->key_schedule, ctx->secret, secret_label)) != 0)
1662
0
            return ret;
1663
2.74k
    }
1664
1665
2.74k
    ctx->epoch = epoch;
1666
1667
2.74k
    log_secret(tls, log_labels[ptls_is_server(tls) == is_enc][epoch],
1668
2.74k
               ptls_iovec_init(ctx->secret, tls->key_schedule->hashes[0].algo->digest_size));
1669
1670
    /* special path for applications having their own record layer */
1671
2.74k
    if (tls->ctx->update_traffic_key != NULL) {
1672
0
        if (skip_notify)
1673
0
            return 0;
1674
0
        return tls->ctx->update_traffic_key->cb(tls->ctx->update_traffic_key, tls, is_enc, epoch, ctx->secret);
1675
0
    }
1676
1677
2.74k
    if (ctx->aead != NULL)
1678
212
        ptls_aead_free(ctx->aead);
1679
2.74k
    if ((ctx->aead = ptls_aead_new(tls->cipher_suite->aead, tls->cipher_suite->hash, is_enc, ctx->secret,
1680
2.74k
                                   tls->ctx->hkdf_label_prefix__obsolete)) == NULL)
1681
0
        return PTLS_ERROR_NO_MEMORY; /* TODO obtain error from ptls_aead_new */
1682
2.74k
    ctx->seq = seq;
1683
1684
#if defined(PTLS_DEBUG) && PTLS_DEBUG
1685
    {
1686
        uint8_t static_iv[PTLS_MAX_IV_SIZE];
1687
        ptls_aead_get_iv(ctx->aead, static_iv);
1688
        PTLS_DEBUGF("[%s] %02x%02x,%02x%02x\n", log_labels[ptls_is_server(tls)][epoch], (unsigned)ctx->secret[0],
1689
                    (unsigned)ctx->secret[1], static_iv[0], static_iv[1]);
1690
    }
1691
#endif
1692
1693
2.74k
    return 0;
1694
2.74k
}
1695
1696
static int commission_handshake_secret(ptls_t *tls)
1697
0
{
1698
0
    int is_enc = !ptls_is_server(tls);
1699
1700
0
    assert(tls->pending_handshake_secret != NULL);
1701
0
    memcpy((is_enc ? &tls->traffic_protection.enc : &tls->traffic_protection.dec)->secret, tls->pending_handshake_secret,
1702
0
           PTLS_MAX_DIGEST_SIZE);
1703
0
    ptls_clear_memory(tls->pending_handshake_secret, PTLS_MAX_DIGEST_SIZE);
1704
0
    free(tls->pending_handshake_secret);
1705
0
    tls->pending_handshake_secret = NULL;
1706
1707
0
    return setup_traffic_protection(tls, is_enc, NULL, 2, 0, 1);
1708
0
}
1709
1710
static void log_client_random(ptls_t *tls)
1711
2.66k
{
1712
#if PICOTLS_USE_DTRACE
1713
    char buf[sizeof(tls->client_random) * 2 + 1];
1714
#endif
1715
1716
2.66k
    PTLS_PROBE(CLIENT_RANDOM, tls, ptls_hexdump(buf, tls->client_random, sizeof(tls->client_random)));
1717
2.66k
    PTLS_LOG_CONN(client_random, tls, { PTLS_LOG_ELEMENT_HEXDUMP(bytes, tls->client_random, sizeof(tls->client_random)); });
1718
2.66k
}
1719
1720
#define SESSION_IDENTIFIER_MAGIC "ptls0001" /* the number should be changed upon incompatible format change */
1721
#define SESSION_IDENTIFIER_MAGIC_SIZE (sizeof(SESSION_IDENTIFIER_MAGIC) - 1)
1722
1723
static int encode_session_identifier(ptls_context_t *ctx, ptls_buffer_t *buf, uint32_t ticket_age_add, ptls_iovec_t ticket_nonce,
1724
                                     ptls_key_schedule_t *sched, const char *server_name, uint16_t key_exchange_id, uint16_t csid,
1725
                                     const char *negotiated_protocol)
1726
219
{
1727
219
    int ret = 0;
1728
1729
219
    ptls_buffer_push_block(buf, 2, {
1730
        /* format id */
1731
219
        ptls_buffer_pushv(buf, SESSION_IDENTIFIER_MAGIC, SESSION_IDENTIFIER_MAGIC_SIZE);
1732
        /* date */
1733
219
        ptls_buffer_push64(buf, ctx->get_time->cb(ctx->get_time));
1734
        /* resumption master secret */
1735
219
        ptls_buffer_push_block(buf, 2, {
1736
219
            if ((ret = ptls_buffer_reserve(buf, sched->hashes[0].algo->digest_size)) != 0)
1737
219
                goto Exit;
1738
219
            if ((ret = derive_resumption_secret(sched, buf->base + buf->off, ticket_nonce)) != 0)
1739
219
                goto Exit;
1740
219
            buf->off += sched->hashes[0].algo->digest_size;
1741
219
        });
1742
        /* key-exchange */
1743
219
        ptls_buffer_push16(buf, key_exchange_id);
1744
        /* cipher-suite */
1745
219
        ptls_buffer_push16(buf, csid);
1746
        /* ticket_age_add */
1747
219
        ptls_buffer_push32(buf, ticket_age_add);
1748
        /* session ID context */
1749
219
        ptls_buffer_push_block(buf, 2, {
1750
219
            if (ctx->ticket_context.is_set) {
1751
219
                ptls_buffer_pushv(buf, ctx->ticket_context.bytes, sizeof(ctx->ticket_context.bytes));
1752
219
            } else if (server_name != NULL) {
1753
219
                ptls_buffer_pushv(buf, server_name, strlen(server_name));
1754
219
            }
1755
219
        });
1756
        /* alpn */
1757
219
        ptls_buffer_push_block(buf, 1, {
1758
219
            if (negotiated_protocol != NULL)
1759
219
                ptls_buffer_pushv(buf, negotiated_protocol, strlen(negotiated_protocol));
1760
219
        });
1761
219
    });
1762
1763
219
Exit:
1764
219
    return ret;
1765
219
}
1766
1767
int decode_session_identifier(uint64_t *issued_at, ptls_iovec_t *psk, uint32_t *ticket_age_add, ptls_iovec_t *ticket_ctx,
1768
                              uint16_t *key_exchange_id, uint16_t *csid, ptls_iovec_t *negotiated_protocol, const uint8_t *src,
1769
                              const uint8_t *const end)
1770
144
{
1771
144
    int ret = 0;
1772
1773
144
    ptls_decode_block(src, end, 2, {
1774
144
        if (end - src < SESSION_IDENTIFIER_MAGIC_SIZE ||
1775
144
            memcmp(src, SESSION_IDENTIFIER_MAGIC, SESSION_IDENTIFIER_MAGIC_SIZE) != 0) {
1776
144
            ret = PTLS_ALERT_DECODE_ERROR;
1777
144
            goto Exit;
1778
144
        }
1779
144
        src += SESSION_IDENTIFIER_MAGIC_SIZE;
1780
144
        if ((ret = ptls_decode64(issued_at, &src, end)) != 0)
1781
144
            goto Exit;
1782
144
        ptls_decode_open_block(src, end, 2, {
1783
144
            *psk = ptls_iovec_init(src, end - src);
1784
144
            src = end;
1785
144
        });
1786
144
        if ((ret = ptls_decode16(key_exchange_id, &src, end)) != 0)
1787
144
            goto Exit;
1788
144
        if ((ret = ptls_decode16(csid, &src, end)) != 0)
1789
144
            goto Exit;
1790
144
        if ((ret = ptls_decode32(ticket_age_add, &src, end)) != 0)
1791
144
            goto Exit;
1792
144
        ptls_decode_open_block(src, end, 2, {
1793
144
            *ticket_ctx = ptls_iovec_init(src, end - src);
1794
144
            src = end;
1795
144
        });
1796
144
        ptls_decode_open_block(src, end, 1, {
1797
144
            *negotiated_protocol = ptls_iovec_init(src, end - src);
1798
144
            src = end;
1799
144
        });
1800
144
    });
1801
1802
144
Exit:
1803
144
    return ret;
1804
144
}
1805
1806
static size_t build_certificate_verify_signdata(uint8_t *data, ptls_key_schedule_t *sched, const char *context_string)
1807
13
{
1808
13
    size_t datalen = 0;
1809
1810
13
    memset(data + datalen, 32, 64);
1811
13
    datalen += 64;
1812
13
    memcpy(data + datalen, context_string, strlen(context_string) + 1);
1813
13
    datalen += strlen(context_string) + 1;
1814
13
    sched->hashes[0].ctx->final(sched->hashes[0].ctx, data + datalen, PTLS_HASH_FINAL_MODE_SNAPSHOT);
1815
13
    datalen += sched->hashes[0].algo->digest_size;
1816
13
    assert(datalen <= PTLS_MAX_CERTIFICATE_VERIFY_SIGNDATA_SIZE);
1817
1818
13
    return datalen;
1819
13
}
1820
1821
static int calc_verify_data(void *output, ptls_key_schedule_t *sched, const void *secret)
1822
438
{
1823
438
    ptls_hash_context_t *hmac;
1824
438
    uint8_t digest[PTLS_MAX_DIGEST_SIZE];
1825
438
    int ret;
1826
1827
438
    if ((ret = ptls_hkdf_expand_label(sched->hashes[0].algo, digest, sched->hashes[0].algo->digest_size,
1828
438
                                      ptls_iovec_init(secret, sched->hashes[0].algo->digest_size), "finished",
1829
438
                                      ptls_iovec_init(NULL, 0), NULL)) != 0)
1830
0
        return ret;
1831
438
    if ((hmac = ptls_hmac_create(sched->hashes[0].algo, digest, sched->hashes[0].algo->digest_size)) == NULL) {
1832
0
        ptls_clear_memory(digest, sizeof(digest));
1833
0
        return PTLS_ERROR_NO_MEMORY;
1834
0
    }
1835
1836
438
    sched->hashes[0].ctx->final(sched->hashes[0].ctx, digest, PTLS_HASH_FINAL_MODE_SNAPSHOT);
1837
438
    PTLS_DEBUGF("%s: %02x%02x,%02x%02x\n", __FUNCTION__, ((uint8_t *)secret)[0], ((uint8_t *)secret)[1], digest[0], digest[1]);
1838
438
    hmac->update(hmac, digest, sched->hashes[0].algo->digest_size);
1839
438
    ptls_clear_memory(digest, sizeof(digest));
1840
438
    hmac->final(hmac, output, PTLS_HASH_FINAL_MODE_FREE);
1841
1842
438
    return 0;
1843
438
}
1844
1845
static int verify_finished(ptls_t *tls, ptls_iovec_t message)
1846
15
{
1847
15
    uint8_t verify_data[PTLS_MAX_DIGEST_SIZE];
1848
15
    int ret;
1849
1850
15
    if (PTLS_HANDSHAKE_HEADER_SIZE + tls->key_schedule->hashes[0].algo->digest_size != message.len) {
1851
10
        ret = PTLS_ALERT_DECODE_ERROR;
1852
10
        goto Exit;
1853
10
    }
1854
1855
5
    if ((ret = calc_verify_data(verify_data, tls->key_schedule, tls->traffic_protection.dec.secret)) != 0)
1856
0
        goto Exit;
1857
5
    if (!ptls_mem_equal(message.base + PTLS_HANDSHAKE_HEADER_SIZE, verify_data, tls->key_schedule->hashes[0].algo->digest_size)) {
1858
5
        ret = PTLS_ALERT_HANDSHAKE_FAILURE;
1859
5
        goto Exit;
1860
5
    }
1861
1862
15
Exit:
1863
15
    ptls_clear_memory(verify_data, sizeof(verify_data));
1864
15
    return ret;
1865
5
}
1866
1867
static int send_finished(ptls_t *tls, ptls_message_emitter_t *emitter)
1868
212
{
1869
212
    int ret;
1870
1871
212
    ptls_push_message(emitter, tls->key_schedule, PTLS_HANDSHAKE_TYPE_FINISHED, {
1872
212
        if ((ret = ptls_buffer_reserve(emitter->buf, tls->key_schedule->hashes[0].algo->digest_size)) != 0)
1873
212
            goto Exit;
1874
212
        if ((ret = calc_verify_data(emitter->buf->base + emitter->buf->off, tls->key_schedule,
1875
212
                                    tls->traffic_protection.enc.secret)) != 0)
1876
212
            goto Exit;
1877
212
        emitter->buf->off += tls->key_schedule->hashes[0].algo->digest_size;
1878
212
    });
1879
1880
212
Exit:
1881
212
    return ret;
1882
212
}
1883
1884
static int send_session_ticket(ptls_t *tls, ptls_message_emitter_t *emitter)
1885
219
{
1886
219
    ptls_hash_context_t *msghash_backup = tls->key_schedule->hashes[0].ctx->clone_(tls->key_schedule->hashes[0].ctx);
1887
219
    ptls_buffer_t session_id;
1888
219
    char session_id_smallbuf[128];
1889
219
    uint32_t ticket_age_add;
1890
219
    int ret = 0;
1891
1892
219
    assert(tls->ctx->ticket_lifetime != 0);
1893
219
    assert(tls->ctx->encrypt_ticket != NULL);
1894
1895
219
    ptls_buffer_init(&session_id, session_id_smallbuf, sizeof(session_id_smallbuf));
1896
1897
219
    { /* calculate verify-data that will be sent by the client */
1898
219
        size_t orig_off = emitter->buf->off;
1899
219
        if (tls->pending_handshake_secret != NULL && !tls->ctx->omit_end_of_early_data) {
1900
0
            assert(tls->state == PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA);
1901
0
            ptls_buffer_push_message_body(emitter->buf, tls->key_schedule, PTLS_HANDSHAKE_TYPE_END_OF_EARLY_DATA, {});
1902
0
            emitter->buf->off = orig_off;
1903
0
        }
1904
219
        ptls_buffer_push_message_body(emitter->buf, tls->key_schedule, PTLS_HANDSHAKE_TYPE_FINISHED, {
1905
219
            if ((ret = ptls_buffer_reserve(emitter->buf, tls->key_schedule->hashes[0].algo->digest_size)) != 0)
1906
219
                goto Exit;
1907
219
            if ((ret = calc_verify_data(emitter->buf->base + emitter->buf->off, tls->key_schedule,
1908
219
                                        tls->pending_handshake_secret != NULL ? tls->pending_handshake_secret
1909
219
                                                                              : tls->traffic_protection.dec.secret)) != 0)
1910
219
                goto Exit;
1911
219
            emitter->buf->off += tls->key_schedule->hashes[0].algo->digest_size;
1912
219
        });
1913
219
        emitter->buf->off = orig_off;
1914
219
    }
1915
1916
0
    tls->ctx->random_bytes(&ticket_age_add, sizeof(ticket_age_add));
1917
1918
    /* build the raw nsk */
1919
219
    if (tls->key_share != NULL && (ret = encode_session_identifier(tls->ctx, &session_id, ticket_age_add, ptls_iovec_init(NULL, 0),
1920
219
                                                                   tls->key_schedule, tls->server_name, tls->key_share->id,
1921
219
                                                                   tls->cipher_suite->id, tls->negotiated_protocol)) != 0)
1922
0
        goto Exit;
1923
1924
    /* encrypt and send */
1925
219
    ptls_push_message(emitter, tls->key_schedule, PTLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET, {
1926
219
        ptls_buffer_push32(emitter->buf, tls->ctx->ticket_lifetime);
1927
219
        ptls_buffer_push32(emitter->buf, ticket_age_add);
1928
219
        ptls_buffer_push_block(emitter->buf, 1, {});
1929
219
        ptls_buffer_push_block(emitter->buf, 2, {
1930
219
            if ((ret = tls->ctx->encrypt_ticket->cb(tls->ctx->encrypt_ticket, tls, 1, emitter->buf,
1931
219
                                                    ptls_iovec_init(session_id.base, session_id.off))) != 0)
1932
219
                goto Exit;
1933
219
        });
1934
219
        ptls_buffer_push_block(emitter->buf, 2, {
1935
219
            if (tls->ctx->max_early_data_size != 0)
1936
219
                buffer_push_extension(emitter->buf, PTLS_EXTENSION_TYPE_EARLY_DATA,
1937
219
                                      { ptls_buffer_push32(emitter->buf, tls->ctx->max_early_data_size); });
1938
219
        });
1939
219
    });
1940
1941
219
Exit:
1942
219
    ptls_buffer_dispose(&session_id);
1943
1944
    /* restore handshake state */
1945
219
    tls->key_schedule->hashes[0].ctx->final(tls->key_schedule->hashes[0].ctx, NULL, PTLS_HASH_FINAL_MODE_FREE);
1946
219
    tls->key_schedule->hashes[0].ctx = msghash_backup;
1947
1948
219
    return ret;
1949
219
}
1950
1951
static int push_change_cipher_spec(ptls_t *tls, ptls_message_emitter_t *emitter)
1952
222
{
1953
222
    int ret;
1954
1955
    /* check if we are requested to (or still need to) */
1956
222
    if (!tls->send_change_cipher_spec) {
1957
163
        ret = 0;
1958
163
        goto Exit;
1959
163
    }
1960
1961
    /* CCS is a record, can only be sent when using a record-based protocol. */
1962
59
    if (emitter->begin_message != begin_record_message) {
1963
0
        ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
1964
0
        goto Exit;
1965
0
    }
1966
1967
    /* emit CCS */
1968
59
    buffer_push_record(emitter->buf, PTLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC, { ptls_buffer_push(emitter->buf, 1); });
1969
1970
59
    tls->send_change_cipher_spec = 0;
1971
59
    ret = 0;
1972
222
Exit:
1973
222
    return ret;
1974
59
}
1975
1976
static int push_additional_extensions(ptls_handshake_properties_t *properties, ptls_buffer_t *sendbuf)
1977
2.28k
{
1978
2.28k
    int ret;
1979
1980
2.28k
    if (properties != NULL && properties->additional_extensions != NULL) {
1981
0
        ptls_raw_extension_t *ext;
1982
0
        for (ext = properties->additional_extensions; ext->type != UINT16_MAX; ++ext) {
1983
0
            buffer_push_extension(sendbuf, ext->type, { ptls_buffer_pushv(sendbuf, ext->data.base, ext->data.len); });
1984
0
        }
1985
0
    }
1986
2.28k
    ret = 0;
1987
2.28k
Exit:
1988
2.28k
    return ret;
1989
2.28k
}
1990
1991
static int push_signature_algorithms(ptls_verify_certificate_t *vc, ptls_buffer_t *sendbuf)
1992
2.06k
{
1993
    /* The list sent when verify callback is not registered */
1994
2.06k
    static const uint16_t default_algos[] = {PTLS_SIGNATURE_RSA_PSS_RSAE_SHA384, PTLS_SIGNATURE_RSA_PSS_RSAE_SHA256,
1995
2.06k
                                             PTLS_SIGNATURE_ECDSA_SECP384R1_SHA384, PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256,
1996
2.06k
                                             PTLS_SIGNATURE_RSA_PKCS1_SHA256, PTLS_SIGNATURE_RSA_PKCS1_SHA1, UINT16_MAX};
1997
2.06k
    int ret;
1998
1999
2.06k
    ptls_buffer_push_block(sendbuf, 2, {
2000
2.06k
        for (const uint16_t *p = vc != NULL ? vc->algos : default_algos; *p != UINT16_MAX; ++p)
2001
2.06k
            ptls_buffer_push16(sendbuf, *p);
2002
2.06k
    });
2003
2004
2.06k
    ret = 0;
2005
2.06k
Exit:
2006
2.06k
    return ret;
2007
2.06k
}
2008
2009
static int decode_signature_algorithms(struct st_ptls_signature_algorithms_t *sa, const uint8_t **src, const uint8_t *end)
2010
369
{
2011
369
    int ret;
2012
2013
369
    ptls_decode_block(*src, end, 2, {
2014
369
        do {
2015
369
            uint16_t id;
2016
369
            if ((ret = ptls_decode16(&id, src, end)) != 0)
2017
369
                goto Exit;
2018
369
            if (sa->count < PTLS_ELEMENTSOF(sa->list))
2019
369
                sa->list[sa->count++] = id;
2020
369
        } while (*src != end);
2021
369
    });
2022
2023
249
    ret = 0;
2024
369
Exit:
2025
369
    return ret;
2026
249
}
2027
2028
/**
2029
 * @param hash optional argument for restricting the underlying hash algorithm
2030
 */
2031
static int select_cipher(ptls_cipher_suite_t **selected, ptls_cipher_suite_t **candidates, const uint8_t *src,
2032
                         const uint8_t *const end, int server_preference, int server_chacha_priority, ptls_hash_algorithm_t *hash)
2033
686
{
2034
686
    size_t found_index = SIZE_MAX;
2035
686
    int ret;
2036
2037
2.34k
    while (src != end) {
2038
2.31k
        uint16_t id;
2039
2.31k
        if ((ret = ptls_decode16(&id, &src, end)) != 0)
2040
0
            goto Exit;
2041
6.02k
        for (size_t i = 0; candidates[i] != NULL; ++i) {
2042
4.36k
            if (candidates[i]->id == id && (hash == NULL || candidates[i]->hash == hash)) {
2043
654
                if (server_preference && !(server_chacha_priority && id == PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256)) {
2044
                    /* preserve smallest matching index, and proceed to the next input */
2045
0
                    if (i < found_index) {
2046
0
                        found_index = i;
2047
0
                        break;
2048
0
                    }
2049
654
                } else {
2050
                    /* return the pointer matching to the first input that can be used */
2051
654
                    *selected = candidates[i];
2052
654
                    goto Exit;
2053
654
                }
2054
654
            }
2055
4.36k
        }
2056
        /* first position of the server list matched (server_preference) */
2057
1.66k
        if (found_index == 0)
2058
0
            break;
2059
        /* server preference is overridden only if the first entry of client-provided list is chachapoly */
2060
1.66k
        server_chacha_priority = 0;
2061
1.66k
    }
2062
32
    if (found_index != SIZE_MAX) {
2063
0
        *selected = candidates[found_index];
2064
0
        ret = 0;
2065
32
    } else {
2066
32
        ret = PTLS_ALERT_HANDSHAKE_FAILURE;
2067
32
    }
2068
2069
686
Exit:
2070
686
    return ret;
2071
32
}
2072
2073
static int push_key_share_entry(ptls_buffer_t *buf, uint16_t group, ptls_iovec_t pubkey)
2074
2.06k
{
2075
2.06k
    int ret;
2076
2077
2.06k
    ptls_buffer_push16(buf, group);
2078
2.06k
    ptls_buffer_push_block(buf, 2, { ptls_buffer_pushv(buf, pubkey.base, pubkey.len); });
2079
2.06k
    ret = 0;
2080
2.06k
Exit:
2081
2.06k
    return ret;
2082
2.06k
}
2083
2084
static int decode_key_share_entry(uint16_t *group, ptls_iovec_t *key_exchange, const uint8_t **src, const uint8_t *const end)
2085
2.73k
{
2086
2.73k
    int ret;
2087
2088
2.73k
    if ((ret = ptls_decode16(group, src, end)) != 0)
2089
18
        goto Exit;
2090
2.71k
    ptls_decode_open_block(*src, end, 2, {
2091
2.71k
        *key_exchange = ptls_iovec_init(*src, end - *src);
2092
2.71k
        *src = end;
2093
2.71k
    });
2094
2095
2.73k
Exit:
2096
2.73k
    return ret;
2097
2.71k
}
2098
2099
static int select_key_share(ptls_key_exchange_algorithm_t **selected, ptls_iovec_t *peer_key,
2100
                            ptls_key_exchange_algorithm_t **candidates, const uint8_t **src, const uint8_t *const end,
2101
                            int expect_one)
2102
502
{
2103
502
    int ret;
2104
2105
502
    *selected = NULL;
2106
2107
502
    if (expect_one && *src == end) {
2108
0
        ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2109
0
        goto Exit;
2110
0
    }
2111
2112
2.06k
    while (*src != end) {
2113
1.62k
        uint16_t group;
2114
1.62k
        ptls_iovec_t key;
2115
1.62k
        if ((ret = decode_key_share_entry(&group, &key, src, end)) != 0)
2116
53
            goto Exit;
2117
1.56k
        ptls_key_exchange_algorithm_t **c = candidates;
2118
3.13k
        for (; *c != NULL; ++c) {
2119
1.56k
            if (*selected == NULL && (*c)->id == group) {
2120
234
                *selected = *c;
2121
234
                *peer_key = key;
2122
234
            }
2123
1.56k
        }
2124
1.56k
        if (expect_one) {
2125
0
            ret = *selected != NULL ? 0 : PTLS_ALERT_ILLEGAL_PARAMETER;
2126
0
            goto Exit;
2127
0
        }
2128
1.56k
    }
2129
2130
449
    ret = 0;
2131
2132
502
Exit:
2133
502
    return ret;
2134
449
}
2135
2136
static int emit_server_name_extension(ptls_buffer_t *buf, const char *server_name)
2137
0
{
2138
0
    int ret;
2139
2140
0
    ptls_buffer_push_block(buf, 2, {
2141
0
        ptls_buffer_push(buf, PTLS_SERVER_NAME_TYPE_HOSTNAME);
2142
0
        ptls_buffer_push_block(buf, 2, { ptls_buffer_pushv(buf, server_name, strlen(server_name)); });
2143
0
    });
2144
2145
0
    ret = 0;
2146
0
Exit:
2147
0
    return ret;
2148
0
}
2149
2150
/**
2151
 * Within the outer ECH extension, returns the number of bytes that preceeds the AEAD-encrypted payload.
2152
 */
2153
static inline size_t outer_ech_header_size(size_t enc_size)
2154
0
{
2155
0
    return 10 + enc_size;
2156
0
}
2157
2158
/**
2159
 * Flag to indicate which of ClientHelloInner, EncodedClientHelloInner, ClientHelloOuter is to be generated. When ECH is inactive,
2160
 * only ClientHelloInner is used.
2161
 */
2162
enum encode_ch_mode { ENCODE_CH_MODE_INNER, ENCODE_CH_MODE_ENCODED_INNER, ENCODE_CH_MODE_OUTER };
2163
2164
static int encode_client_hello(ptls_context_t *ctx, ptls_buffer_t *sendbuf, enum encode_ch_mode mode, int is_second_flight,
2165
                               ptls_handshake_properties_t *properties, const void *client_random,
2166
                               ptls_key_exchange_context_t *key_share_ctx, const char *sni_name, ptls_iovec_t legacy_session_id,
2167
                               struct st_ptls_ech_t *ech, size_t *ech_size_offset, ptls_iovec_t ech_replay, ptls_iovec_t psk_secret,
2168
                               ptls_iovec_t psk_identity, uint32_t obfuscated_ticket_age, size_t psk_binder_size,
2169
                               ptls_iovec_t *cookie, int using_early_data)
2170
2.06k
{
2171
2.06k
    int ret;
2172
2173
2.06k
    assert(mode == ENCODE_CH_MODE_INNER || ech != NULL);
2174
2175
2.06k
    ptls_buffer_push_message_body(sendbuf, NULL, PTLS_HANDSHAKE_TYPE_CLIENT_HELLO, {
2176
        /* legacy_version */
2177
2.06k
        ptls_buffer_push16(sendbuf, 0x0303);
2178
        /* random_bytes */
2179
2.06k
        ptls_buffer_pushv(sendbuf, client_random, PTLS_HELLO_RANDOM_SIZE);
2180
        /* lecagy_session_id */
2181
2.06k
        ptls_buffer_push_block(sendbuf, 1, {
2182
2.06k
            if (mode != ENCODE_CH_MODE_ENCODED_INNER)
2183
2.06k
                ptls_buffer_pushv(sendbuf, legacy_session_id.base, legacy_session_id.len);
2184
2.06k
        });
2185
        /* cipher_suites */
2186
2.06k
        ptls_buffer_push_block(sendbuf, 2, {
2187
2.06k
            ptls_cipher_suite_t **cs = ctx->cipher_suites;
2188
2.06k
            for (; *cs != NULL; ++cs)
2189
2.06k
                ptls_buffer_push16(sendbuf, (*cs)->id);
2190
2.06k
        });
2191
        /* legacy_compression_methods */
2192
2.06k
        ptls_buffer_push_block(sendbuf, 1, { ptls_buffer_push(sendbuf, 0); });
2193
        /* extensions */
2194
2.06k
        ptls_buffer_push_block(sendbuf, 2, {
2195
2.06k
            if (mode == ENCODE_CH_MODE_OUTER) {
2196
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO, {
2197
2.06k
                    size_t ext_payload_from = sendbuf->off;
2198
2.06k
                    ptls_buffer_push(sendbuf, PTLS_ECH_CLIENT_HELLO_TYPE_OUTER);
2199
2.06k
                    ptls_buffer_push16(sendbuf, ech->cipher->id.kdf);
2200
2.06k
                    ptls_buffer_push16(sendbuf, ech->cipher->id.aead);
2201
2.06k
                    ptls_buffer_push(sendbuf, ech->config_id);
2202
2.06k
                    ptls_buffer_push_block(sendbuf, 2, {
2203
2.06k
                        if (!is_second_flight)
2204
2.06k
                            ptls_buffer_pushv(sendbuf, ech->client.enc.base, ech->client.enc.len);
2205
2.06k
                    });
2206
2.06k
                    ptls_buffer_push_block(sendbuf, 2, {
2207
2.06k
                        assert(sendbuf->off - ext_payload_from ==
2208
2.06k
                               outer_ech_header_size(is_second_flight ? 0 : ech->client.enc.len));
2209
2.06k
                        if ((ret = ptls_buffer_reserve(sendbuf, *ech_size_offset)) != 0)
2210
2.06k
                            goto Exit;
2211
2.06k
                        memset(sendbuf->base + sendbuf->off, 0, *ech_size_offset);
2212
2.06k
                        sendbuf->off += *ech_size_offset;
2213
2.06k
                        *ech_size_offset = sendbuf->off - *ech_size_offset;
2214
2.06k
                    });
2215
2.06k
                });
2216
2.06k
            } else if (ech->aead != NULL) {
2217
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO,
2218
2.06k
                                      { ptls_buffer_push(sendbuf, PTLS_ECH_CLIENT_HELLO_TYPE_INNER); });
2219
2.06k
            } else if (ech_replay.base != NULL) {
2220
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO,
2221
2.06k
                                      { ptls_buffer_pushv(sendbuf, ech_replay.base, ech_replay.len); });
2222
2.06k
            }
2223
2.06k
            if (mode == ENCODE_CH_MODE_ENCODED_INNER) {
2224
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ECH_OUTER_EXTENSIONS, {
2225
2.06k
                    ptls_buffer_push_block(sendbuf, 1, { ptls_buffer_push16(sendbuf, PTLS_EXTENSION_TYPE_KEY_SHARE); });
2226
2.06k
                });
2227
2.06k
            } else {
2228
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_KEY_SHARE, {
2229
2.06k
                    ptls_buffer_push_block(sendbuf, 2, {
2230
2.06k
                        if (key_share_ctx != NULL &&
2231
2.06k
                            (ret = push_key_share_entry(sendbuf, key_share_ctx->algo->id, key_share_ctx->pubkey)) != 0)
2232
2.06k
                            goto Exit;
2233
2.06k
                    });
2234
2.06k
                });
2235
2.06k
            }
2236
2.06k
            if (sni_name != NULL) {
2237
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SERVER_NAME, {
2238
2.06k
                    if ((ret = emit_server_name_extension(sendbuf, sni_name)) != 0)
2239
2.06k
                        goto Exit;
2240
2.06k
                });
2241
2.06k
            }
2242
2.06k
            if (properties != NULL && properties->client.negotiated_protocols.count != 0) {
2243
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ALPN, {
2244
2.06k
                    ptls_buffer_push_block(sendbuf, 2, {
2245
2.06k
                        size_t i;
2246
2.06k
                        for (i = 0; i != properties->client.negotiated_protocols.count; ++i) {
2247
2.06k
                            ptls_buffer_push_block(sendbuf, 1, {
2248
2.06k
                                ptls_iovec_t p = properties->client.negotiated_protocols.list[i];
2249
2.06k
                                ptls_buffer_pushv(sendbuf, p.base, p.len);
2250
2.06k
                            });
2251
2.06k
                        }
2252
2.06k
                    });
2253
2.06k
                });
2254
2.06k
            }
2255
2.06k
            if (ctx->decompress_certificate != NULL) {
2256
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_COMPRESS_CERTIFICATE, {
2257
2.06k
                    ptls_buffer_push_block(sendbuf, 1, {
2258
2.06k
                        const uint16_t *algo = ctx->decompress_certificate->supported_algorithms;
2259
2.06k
                        assert(*algo != UINT16_MAX);
2260
2.06k
                        for (; *algo != UINT16_MAX; ++algo)
2261
2.06k
                            ptls_buffer_push16(sendbuf, *algo);
2262
2.06k
                    });
2263
2.06k
                });
2264
2.06k
            }
2265
2.06k
            buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS, {
2266
2.06k
                ptls_buffer_push_block(sendbuf, 1, {
2267
2.06k
                    size_t i;
2268
2.06k
                    for (i = 0; i != PTLS_ELEMENTSOF(supported_versions); ++i)
2269
2.06k
                        ptls_buffer_push16(sendbuf, supported_versions[i]);
2270
2.06k
                });
2271
2.06k
            });
2272
2.06k
            buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SIGNATURE_ALGORITHMS, {
2273
2.06k
                if ((ret = push_signature_algorithms(ctx->verify_certificate, sendbuf)) != 0)
2274
2.06k
                    goto Exit;
2275
2.06k
            });
2276
2.06k
            if (ctx->key_exchanges != NULL) {
2277
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SUPPORTED_GROUPS, {
2278
2.06k
                    ptls_key_exchange_algorithm_t **algo = ctx->key_exchanges;
2279
2.06k
                    ptls_buffer_push_block(sendbuf, 2, {
2280
2.06k
                        for (; *algo != NULL; ++algo)
2281
2.06k
                            ptls_buffer_push16(sendbuf, (*algo)->id);
2282
2.06k
                    });
2283
2.06k
                });
2284
2.06k
            }
2285
2.06k
            if (cookie != NULL && cookie->base != NULL) {
2286
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_COOKIE, {
2287
2.06k
                    ptls_buffer_push_block(sendbuf, 2, { ptls_buffer_pushv(sendbuf, cookie->base, cookie->len); });
2288
2.06k
                });
2289
2.06k
            }
2290
2.06k
            if (ctx->use_raw_public_keys) {
2291
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SERVER_CERTIFICATE_TYPE, {
2292
2.06k
                    ptls_buffer_push_block(sendbuf, 1, { ptls_buffer_push(sendbuf, PTLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY); });
2293
2.06k
                });
2294
2.06k
            }
2295
2.06k
            if (ctx->save_ticket != NULL &&
2296
2.06k
                (ctx->ticket_requests.client.new_session_count != 0 || ctx->ticket_requests.client.resumption_count != 0)) {
2297
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_TICKET_REQUEST, {
2298
2.06k
                    ptls_buffer_push(sendbuf, ctx->ticket_requests.client.new_session_count,
2299
2.06k
                                     ctx->ticket_requests.client.resumption_count);
2300
2.06k
                });
2301
2.06k
            }
2302
2.06k
            if ((ret = push_additional_extensions(properties, sendbuf)) != 0)
2303
2.06k
                goto Exit;
2304
2.06k
            if (ctx->save_ticket != NULL || psk_secret.base != NULL) {
2305
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_PSK_KEY_EXCHANGE_MODES, {
2306
2.06k
                    ptls_buffer_push_block(sendbuf, 1, {
2307
2.06k
                        if (!ctx->require_dhe_on_psk)
2308
2.06k
                            ptls_buffer_push(sendbuf, PTLS_PSK_KE_MODE_PSK);
2309
2.06k
                        ptls_buffer_push(sendbuf, PTLS_PSK_KE_MODE_PSK_DHE);
2310
2.06k
                    });
2311
2.06k
                });
2312
2.06k
            }
2313
2.06k
            if (psk_secret.base != NULL) {
2314
2.06k
                if (using_early_data && !is_second_flight)
2315
2.06k
                    buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_EARLY_DATA, {});
2316
                /* pre-shared key "MUST be the last extension in the ClientHello" (draft-17 section 4.2.6) */
2317
2.06k
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_PRE_SHARED_KEY, {
2318
2.06k
                    ptls_buffer_push_block(sendbuf, 2, {
2319
2.06k
                        ptls_buffer_push_block(sendbuf, 2, {
2320
2.06k
                            if (mode == ENCODE_CH_MODE_OUTER && ech->state != PTLS_ECH_STATE_GREASE) {
2321
2.06k
                                if ((ret = ptls_buffer_reserve(sendbuf, psk_identity.len)) != 0)
2322
2.06k
                                    goto Exit;
2323
2.06k
                                ctx->random_bytes(sendbuf->base + sendbuf->off, psk_identity.len);
2324
2.06k
                                sendbuf->off += psk_identity.len;
2325
2.06k
                            } else {
2326
2.06k
                                ptls_buffer_pushv(sendbuf, psk_identity.base, psk_identity.len);
2327
2.06k
                            }
2328
2.06k
                        });
2329
2.06k
                        uint32_t age;
2330
2.06k
                        if (mode == ENCODE_CH_MODE_OUTER && ech->state != PTLS_ECH_STATE_GREASE) {
2331
2.06k
                            ctx->random_bytes(&age, sizeof(age));
2332
2.06k
                        } else {
2333
2.06k
                            age = obfuscated_ticket_age;
2334
2.06k
                        }
2335
2.06k
                        ptls_buffer_push32(sendbuf, age);
2336
2.06k
                    });
2337
                    /* allocate space for PSK binder. The space is filled initially filled by a random value (meeting the
2338
                     * requirement of ClientHelloOuter), and later gets filled with the correct binder value if necessary. */
2339
2.06k
                    ptls_buffer_push_block(sendbuf, 2, {
2340
2.06k
                        ptls_buffer_push_block(sendbuf, 1, {
2341
2.06k
                            if ((ret = ptls_buffer_reserve(sendbuf, psk_binder_size)) != 0)
2342
2.06k
                                goto Exit;
2343
2.06k
                            ctx->random_bytes(sendbuf->base + sendbuf->off, psk_binder_size);
2344
2.06k
                            sendbuf->off += psk_binder_size;
2345
2.06k
                        });
2346
2.06k
                    });
2347
2.06k
                });
2348
2.06k
            }
2349
2.06k
        });
2350
2.06k
    });
2351
2352
2.06k
Exit:
2353
2.06k
    return ret;
2354
2.06k
}
2355
2356
/**
2357
 * Feeds the CH message into the hash, computing the PSK binder if necessary. `binder_key` must be derived before calling this
2358
 * function.
2359
 */
2360
static int update_ch_hash_and_binder(ptls_key_schedule_t *ks, uint8_t *ch, size_t ch_start, size_t ch_end, int has_psk,
2361
                                     uint8_t *binder_key, int is_outer)
2362
2.06k
{
2363
2.06k
    int ret = 0;
2364
2.06k
    size_t hash_off = ch_start;
2365
2366
2.06k
    if (has_psk) {
2367
0
        size_t psk_binder_off = ch_end - (3 + ks->hashes[0].algo->digest_size);
2368
0
        ptls__key_schedule_update_hash(ks, ch + hash_off, psk_binder_off - hash_off, is_outer);
2369
0
        hash_off = psk_binder_off;
2370
0
        if ((ret = calc_verify_data(ch + psk_binder_off + 3, ks, binder_key)) != 0)
2371
0
            return ret;
2372
0
    }
2373
2.06k
    ptls__key_schedule_update_hash(ks, ch + hash_off, ch_end - hash_off, is_outer);
2374
2375
2.06k
    return ret;
2376
2.06k
}
2377
2378
static int send_client_hello(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_handshake_properties_t *properties,
2379
                             ptls_iovec_t *cookie)
2380
2.06k
{
2381
2.06k
    struct {
2382
2.06k
        ptls_iovec_t secret;
2383
2.06k
        ptls_iovec_t identity;
2384
2.06k
        const char *label;
2385
2.06k
    } psk = {{NULL}};
2386
2.06k
    uint32_t obfuscated_ticket_age = 0;
2387
2.06k
    const char *sni_name = NULL;
2388
2.06k
    size_t mess_start;
2389
2.06k
    uint8_t binder_key[PTLS_MAX_DIGEST_SIZE];
2390
2.06k
    ptls_buffer_t encoded_ch_inner;
2391
2.06k
    int ret, is_second_flight = tls->key_schedule != NULL;
2392
2393
2.06k
    ptls_buffer_init(&encoded_ch_inner, "", 0);
2394
2395
2.06k
    if (tls->server_name != NULL && !ptls_server_name_is_ipaddr(tls->server_name))
2396
0
        sni_name = tls->server_name;
2397
2398
    /* try to use ECH (ignore broken ECHConfigList; it is delivered insecurely) */
2399
2.06k
    if (properties != NULL) {
2400
2.06k
        if (!is_second_flight && sni_name != NULL && tls->ctx->ech.client.ciphers != NULL) {
2401
0
            if (properties->client.ech.configs.len != 0) {
2402
0
                struct st_decoded_ech_config_t decoded;
2403
0
                client_decode_ech_config_list(tls->ctx, &decoded, properties->client.ech.configs);
2404
0
                if (decoded.kem != NULL && decoded.cipher != NULL) {
2405
0
                    if ((ret = client_setup_ech(&tls->ech, &decoded, tls->ctx->random_bytes)) != 0)
2406
0
                        goto Exit;
2407
0
                }
2408
0
            } else if (properties->client.ech.configs.base != NULL) {
2409
                /* zero-length config with non-NULL base indicates ECH greasing; NULL base means no ECH */
2410
0
                client_setup_ech_grease(&tls->ech, tls->ctx->random_bytes, tls->ctx->ech.client.kems, tls->ctx->ech.client.ciphers,
2411
0
                                        sni_name);
2412
0
                tls->ech.state = PTLS_ECH_STATE_GREASE;
2413
0
            }
2414
0
        }
2415
2.06k
    }
2416
2417
    /* use external PSK if provided */
2418
2.06k
    if (tls->ctx->pre_shared_key.identity.base != NULL) {
2419
0
        if (!is_second_flight) {
2420
0
            tls->client.offered_psk = 1;
2421
0
            for (size_t i = 0; tls->ctx->cipher_suites[i] != NULL; ++i) {
2422
0
                if (tls->ctx->cipher_suites[i]->hash == tls->ctx->pre_shared_key.hash) {
2423
0
                    tls->cipher_suite = tls->ctx->cipher_suites[i];
2424
0
                    break;
2425
0
                }
2426
0
            }
2427
0
            assert(tls->cipher_suite != NULL && "no compatible cipher-suite provided that matches psk.hash");
2428
0
            if (properties != NULL && properties->client.max_early_data_size != NULL) {
2429
0
                tls->client.using_early_data = 1;
2430
0
                *properties->client.max_early_data_size = SIZE_MAX;
2431
0
            }
2432
0
        } else {
2433
0
            assert(tls->cipher_suite != NULL && tls->cipher_suite->hash == tls->ctx->pre_shared_key.hash);
2434
0
        }
2435
0
        psk.secret = tls->ctx->pre_shared_key.secret;
2436
0
        psk.identity = tls->ctx->pre_shared_key.identity;
2437
0
        psk.label = "ext binder";
2438
0
    }
2439
2440
    /* try to setup resumption-related data, unless external PSK is used */
2441
2.06k
    if (psk.secret.base == NULL && properties != NULL && properties->client.session_ticket.base != NULL &&
2442
0
        tls->ctx->key_exchanges != NULL) {
2443
0
        ptls_key_exchange_algorithm_t *key_share = NULL;
2444
0
        ptls_cipher_suite_t *cipher_suite = NULL;
2445
0
        uint32_t max_early_data_size;
2446
0
        if (decode_stored_session_ticket(tls, &key_share, &cipher_suite, &psk.secret, &obfuscated_ticket_age, &psk.identity,
2447
0
                                         &max_early_data_size, properties->client.session_ticket.base,
2448
0
                                         properties->client.session_ticket.base + properties->client.session_ticket.len) == 0) {
2449
0
            psk.label = "res binder";
2450
0
            tls->client.offered_psk = 1;
2451
            /* key-share selected by HRR should not be overridden */
2452
0
            if (tls->key_share == NULL)
2453
0
                tls->key_share = key_share;
2454
0
            tls->cipher_suite = cipher_suite;
2455
0
            if (!is_second_flight && max_early_data_size != 0 && properties->client.max_early_data_size != NULL) {
2456
0
                tls->client.using_early_data = 1;
2457
0
                *properties->client.max_early_data_size = max_early_data_size;
2458
0
            }
2459
0
        } else {
2460
0
            psk.secret = ptls_iovec_init(NULL, 0);
2461
0
        }
2462
0
    }
2463
2464
    /* send 0-RTT related signals back to the client */
2465
2.06k
    if (properties != NULL) {
2466
2.06k
        if (tls->client.using_early_data) {
2467
0
            properties->client.early_data_acceptance = PTLS_EARLY_DATA_ACCEPTANCE_UNKNOWN;
2468
2.06k
        } else {
2469
2.06k
            if (properties->client.max_early_data_size != NULL)
2470
0
                *properties->client.max_early_data_size = 0;
2471
2.06k
            properties->client.early_data_acceptance = PTLS_EARLY_DATA_REJECTED;
2472
2.06k
        }
2473
2.06k
    }
2474
2475
    /* use the default key share if still not undetermined */
2476
2.06k
    if (tls->key_share == NULL && tls->ctx->key_exchanges != NULL &&
2477
1.99k
        !(properties != NULL && properties->client.negotiate_before_key_exchange))
2478
1.99k
        tls->key_share = tls->ctx->key_exchanges[0];
2479
2480
    /* instantiate key share context */
2481
2.06k
    assert(tls->client.key_share_ctx == NULL);
2482
2.06k
    if (tls->key_share != NULL) {
2483
2.06k
        if ((ret = tls->key_share->create(tls->key_share, &tls->client.key_share_ctx)) != 0)
2484
0
            goto Exit;
2485
2.06k
    }
2486
2487
    /* initialize key schedule */
2488
2.06k
    if (!is_second_flight) {
2489
1.99k
        if ((tls->key_schedule = key_schedule_new(tls->cipher_suite, tls->ctx->cipher_suites, tls->ech.aead != NULL)) == NULL) {
2490
0
            ret = PTLS_ERROR_NO_MEMORY;
2491
0
            goto Exit;
2492
0
        }
2493
1.99k
        if ((ret = key_schedule_extract(tls->key_schedule, psk.secret)) != 0)
2494
0
            goto Exit;
2495
1.99k
    }
2496
2497
    /* start generating CH */
2498
2.06k
    if ((ret = emitter->begin_message(emitter)) != 0)
2499
0
        goto Exit;
2500
2.06k
    mess_start = emitter->buf->off;
2501
2502
    /* generate true (inner) CH */
2503
2.06k
    if ((ret = encode_client_hello(tls->ctx, emitter->buf, ENCODE_CH_MODE_INNER, is_second_flight, properties,
2504
2.06k
                                   tls->ech.aead != NULL ? tls->ech.inner_client_random : tls->client_random,
2505
2.06k
                                   tls->client.key_share_ctx, sni_name, tls->client.legacy_session_id, &tls->ech, NULL,
2506
2.06k
                                   tls->ech.client.first_ech, psk.secret, psk.identity, obfuscated_ticket_age,
2507
2.06k
                                   tls->key_schedule->hashes[0].algo->digest_size, cookie, tls->client.using_early_data)) != 0)
2508
0
        goto Exit;
2509
2510
    /* update the message hash, filling in the PSK binder HMAC if necessary */
2511
2.06k
    if (psk.secret.base != NULL) {
2512
0
        if ((ret = derive_secret_with_empty_digest(tls->key_schedule, binder_key, psk.label)) != 0)
2513
0
            goto Exit;
2514
0
    }
2515
2.06k
    if ((ret = update_ch_hash_and_binder(tls->key_schedule, emitter->buf->base, mess_start, emitter->buf->off,
2516
2.06k
                                         psk.secret.base != NULL, binder_key, 0)) != 0)
2517
0
        goto Exit;
2518
2519
    /* ECH */
2520
2.06k
    if (tls->ech.aead != NULL) {
2521
        /* build EncodedCHInner */
2522
0
        if ((ret = encode_client_hello(tls->ctx, &encoded_ch_inner, ENCODE_CH_MODE_ENCODED_INNER, is_second_flight, properties,
2523
0
                                       tls->ech.inner_client_random, tls->client.key_share_ctx, sni_name,
2524
0
                                       tls->client.legacy_session_id, &tls->ech, NULL, ptls_iovec_init(NULL, 0), psk.secret,
2525
0
                                       psk.identity, obfuscated_ticket_age, tls->key_schedule->hashes[0].algo->digest_size, cookie,
2526
0
                                       tls->client.using_early_data)) != 0)
2527
0
            goto Exit;
2528
0
        if (psk.secret.base != NULL)
2529
0
            memcpy(encoded_ch_inner.base + encoded_ch_inner.off - tls->key_schedule->hashes[0].algo->digest_size,
2530
0
                   emitter->buf->base + emitter->buf->off - tls->key_schedule->hashes[0].algo->digest_size,
2531
0
                   tls->key_schedule->hashes[0].algo->digest_size);
2532
0
        { /* pad EncodedCHInner (following draft-ietf-tls-esni-15 6.1.3) */
2533
0
            size_t padding_len;
2534
0
            if (sni_name != NULL) {
2535
0
                padding_len = strlen(sni_name);
2536
0
                if (padding_len < tls->ech.client.max_name_length)
2537
0
                    padding_len = tls->ech.client.max_name_length;
2538
0
            } else {
2539
0
                padding_len = tls->ech.client.max_name_length + 9;
2540
0
            }
2541
0
            size_t final_len = encoded_ch_inner.off - PTLS_HANDSHAKE_HEADER_SIZE + padding_len;
2542
0
            final_len = (final_len + 31) / 32 * 32;
2543
0
            padding_len = final_len - (encoded_ch_inner.off - PTLS_HANDSHAKE_HEADER_SIZE);
2544
0
            if (padding_len != 0) {
2545
0
                if ((ret = ptls_buffer_reserve(&encoded_ch_inner, padding_len)) != 0)
2546
0
                    goto Exit;
2547
0
                memset(encoded_ch_inner.base + encoded_ch_inner.off, 0, padding_len);
2548
0
                encoded_ch_inner.off += padding_len;
2549
0
            }
2550
0
        }
2551
        /* flush CHInner, build CHOuterAAD */
2552
0
        emitter->buf->off = mess_start;
2553
0
        size_t ech_payload_size = encoded_ch_inner.off - PTLS_HANDSHAKE_HEADER_SIZE + tls->ech.aead->algo->tag_size,
2554
0
               ech_size_offset = ech_payload_size;
2555
0
        if ((ret = encode_client_hello(tls->ctx, emitter->buf, ENCODE_CH_MODE_OUTER, is_second_flight, properties,
2556
0
                                       tls->client_random, tls->client.key_share_ctx, tls->ech.client.public_name,
2557
0
                                       tls->client.legacy_session_id, &tls->ech, &ech_size_offset, ptls_iovec_init(NULL, 0),
2558
0
                                       psk.secret, psk.identity, obfuscated_ticket_age,
2559
0
                                       tls->key_schedule->hashes[0].algo->digest_size, cookie, tls->client.using_early_data)) != 0)
2560
0
            goto Exit;
2561
        /* overwrite ECH payload */
2562
0
        ptls_aead_encrypt(tls->ech.aead, emitter->buf->base + ech_size_offset, encoded_ch_inner.base + PTLS_HANDSHAKE_HEADER_SIZE,
2563
0
                          encoded_ch_inner.off - PTLS_HANDSHAKE_HEADER_SIZE, is_second_flight,
2564
0
                          emitter->buf->base + mess_start + PTLS_HANDSHAKE_HEADER_SIZE,
2565
0
                          emitter->buf->off - (mess_start + PTLS_HANDSHAKE_HEADER_SIZE));
2566
        /* keep the copy of the 1st ECH extension so that we can send it again in 2nd CH in response to rejection with HRR */
2567
0
        if (!is_second_flight) {
2568
0
            size_t len = outer_ech_header_size(tls->ech.client.enc.len) + ech_payload_size;
2569
0
            if ((tls->ech.client.first_ech.base = malloc(len)) == NULL) {
2570
0
                ret = PTLS_ERROR_NO_MEMORY;
2571
0
                goto Exit;
2572
0
            }
2573
0
            memcpy(tls->ech.client.first_ech.base,
2574
0
                   emitter->buf->base + ech_size_offset - outer_ech_header_size(tls->ech.client.enc.len), len);
2575
0
            tls->ech.client.first_ech.len = len;
2576
0
            if (tls->ech.state != PTLS_ECH_STATE_GREASE)
2577
0
                tls->ech.state = PTLS_ECH_STATE_OFFERED;
2578
0
        }
2579
0
        if (tls->ech.state == PTLS_ECH_STATE_GREASE) {
2580
            /* For grease ECH, the server sees the outer CH. Discard the inner state and adopt the outer, then compute the PSK
2581
             * binder over the outer CH using the standard flow. */
2582
0
            for (size_t i = 0; i < tls->key_schedule->num_hashes; ++i) {
2583
0
                tls->key_schedule->hashes[i].ctx->final(tls->key_schedule->hashes[i].ctx, NULL, PTLS_HASH_FINAL_MODE_FREE);
2584
0
                tls->key_schedule->hashes[i].ctx = tls->key_schedule->hashes[i].ctx_outer;
2585
0
                tls->key_schedule->hashes[i].ctx_outer = NULL;
2586
0
            }
2587
0
            ptls_aead_free(tls->ech.aead);
2588
0
            tls->ech.aead = NULL;
2589
0
            if ((ret = update_ch_hash_and_binder(tls->key_schedule, emitter->buf->base, mess_start, emitter->buf->off,
2590
0
                                                     psk.secret.base != NULL, binder_key, 0)) != 0)
2591
0
                goto Exit;
2592
0
        } else {
2593
            /* update outer hash */
2594
0
            ptls__key_schedule_update_hash(tls->key_schedule, emitter->buf->base + mess_start, emitter->buf->off - mess_start, 1);
2595
0
        }
2596
0
    }
2597
2598
    /* commit CH to the record layer */
2599
2.06k
    if ((ret = emitter->commit_message(emitter)) != 0)
2600
0
        goto Exit;
2601
2602
2.06k
    if (tls->client.using_early_data) {
2603
0
        assert(!is_second_flight);
2604
0
        if ((ret = setup_traffic_protection(tls, 1, "c e traffic", 1, 0, 0)) != 0)
2605
0
            goto Exit;
2606
0
        if ((ret = push_change_cipher_spec(tls, emitter)) != 0)
2607
0
            goto Exit;
2608
0
    }
2609
2.06k
    if (psk.secret.base != NULL && !is_second_flight) {
2610
0
        if ((ret = derive_exporter_secret(tls, 1)) != 0)
2611
0
            goto Exit;
2612
0
    }
2613
2.06k
    tls->state = cookie == NULL ? PTLS_STATE_CLIENT_EXPECT_SERVER_HELLO : PTLS_STATE_CLIENT_EXPECT_SECOND_SERVER_HELLO;
2614
2.06k
    ret = PTLS_ERROR_IN_PROGRESS;
2615
2616
2.06k
Exit:
2617
2.06k
    ptls_buffer_dispose(&encoded_ch_inner);
2618
2.06k
    ptls_clear_memory(binder_key, sizeof(binder_key));
2619
2.06k
    return ret;
2620
2.06k
}
2621
2622
ptls_cipher_suite_t *ptls_find_cipher_suite(ptls_cipher_suite_t **cipher_suites, uint16_t id)
2623
1.55k
{
2624
1.55k
    ptls_cipher_suite_t **cs;
2625
1.55k
    if (cipher_suites == NULL)
2626
0
        return NULL;
2627
1.59k
    for (cs = cipher_suites; *cs != NULL && (*cs)->id != id; ++cs)
2628
33
        ;
2629
1.55k
    return *cs;
2630
1.55k
}
2631
2632
static int decode_server_hello(ptls_t *tls, struct st_ptls_server_hello_t *sh, const uint8_t *src, const uint8_t *const end)
2633
1.73k
{
2634
1.73k
    int ret;
2635
2636
1.73k
    *sh = (struct st_ptls_server_hello_t){{0}};
2637
2638
    /* ignore legacy-version */
2639
1.73k
    if (end - src < 2) {
2640
5
        ret = PTLS_ALERT_DECODE_ERROR;
2641
5
        goto Exit;
2642
5
    }
2643
1.73k
    src += 2;
2644
2645
    /* random */
2646
1.73k
    if (end - src < PTLS_HELLO_RANDOM_SIZE) {
2647
9
        ret = PTLS_ALERT_DECODE_ERROR;
2648
9
        goto Exit;
2649
9
    }
2650
1.72k
    sh->is_retry_request = memcmp(src, hello_retry_random, PTLS_HELLO_RANDOM_SIZE) == 0;
2651
1.72k
    src += PTLS_HELLO_RANDOM_SIZE;
2652
1.72k
    if (sh->is_retry_request && tls->state == PTLS_STATE_CLIENT_EXPECT_SECOND_SERVER_HELLO) {
2653
1
        ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
2654
1
        goto Exit;
2655
1
    }
2656
2657
    /* legacy_session_id */
2658
1.72k
    ptls_decode_open_block(src, end, 1, {
2659
1.72k
        if (end - src > 32) {
2660
1.72k
            ret = PTLS_ALERT_DECODE_ERROR;
2661
1.72k
            goto Exit;
2662
1.72k
        }
2663
1.72k
        sh->legacy_session_id = ptls_iovec_init(src, end - src);
2664
1.72k
        src = end;
2665
1.72k
    });
2666
2667
1.60k
    { /* select cipher_suite */
2668
1.60k
        uint16_t csid;
2669
1.60k
        if ((ret = ptls_decode16(&csid, &src, end)) != 0)
2670
9
            goto Exit;
2671
1.59k
        if (tls->state == PTLS_STATE_CLIENT_EXPECT_SERVER_HELLO) {
2672
1.55k
            if ((tls->cipher_suite = ptls_find_cipher_suite(tls->ctx->cipher_suites, csid)) == NULL) {
2673
33
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2674
33
                goto Exit;
2675
33
            }
2676
1.55k
        } else {
2677
33
            assert(tls->state == PTLS_STATE_CLIENT_EXPECT_SECOND_SERVER_HELLO);
2678
33
            if (tls->cipher_suite->id != csid) {
2679
22
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2680
22
                goto Exit;
2681
22
            }
2682
33
        }
2683
1.59k
    }
2684
2685
1.53k
    { /* legacy_compression_method */
2686
1.53k
        uint8_t method;
2687
1.53k
        if ((ret = ptls_decode8(&method, &src, end)) != 0)
2688
4
            goto Exit;
2689
1.53k
        if (method != 0) {
2690
8
            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2691
8
            goto Exit;
2692
8
        }
2693
1.53k
    }
2694
2695
1.52k
    if (sh->is_retry_request)
2696
157
        sh->retry_request.selected_group = UINT16_MAX;
2697
2698
1.52k
    uint16_t exttype, found_version = UINT16_MAX, selected_psk_identity = UINT16_MAX;
2699
1.52k
    decode_extensions(src, end, sh->is_retry_request ? PTLS_HANDSHAKE_TYPE_PSEUDO_HRR : PTLS_HANDSHAKE_TYPE_SERVER_HELLO, &exttype,
2700
1.52k
                      {
2701
1.52k
                          if (tls->ctx->on_extension != NULL &&
2702
1.52k
                              (ret = tls->ctx->on_extension->cb(tls->ctx->on_extension, tls, PTLS_HANDSHAKE_TYPE_SERVER_HELLO,
2703
1.52k
                                                                exttype, ptls_iovec_init(src, end - src)) != 0))
2704
1.52k
                              goto Exit;
2705
1.52k
                          switch (exttype) {
2706
1.52k
                          case PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS:
2707
1.52k
                              if ((ret = ptls_decode16(&found_version, &src, end)) != 0)
2708
1.52k
                                  goto Exit;
2709
1.52k
                              break;
2710
1.52k
                          case PTLS_EXTENSION_TYPE_KEY_SHARE:
2711
1.52k
                              if (tls->ctx->key_exchanges == NULL) {
2712
1.52k
                                  ret = PTLS_ALERT_HANDSHAKE_FAILURE;
2713
1.52k
                                  goto Exit;
2714
1.52k
                              }
2715
1.52k
                              if (sh->is_retry_request) {
2716
1.52k
                                  if ((ret = ptls_decode16(&sh->retry_request.selected_group, &src, end)) != 0)
2717
1.52k
                                      goto Exit;
2718
1.52k
                              } else {
2719
1.52k
                                  uint16_t group;
2720
1.52k
                                  if ((ret = decode_key_share_entry(&group, &sh->peerkey, &src, end)) != 0)
2721
1.52k
                                      goto Exit;
2722
1.52k
                                  if (src != end) {
2723
1.52k
                                      ret = PTLS_ALERT_DECODE_ERROR;
2724
1.52k
                                      goto Exit;
2725
1.52k
                                  }
2726
1.52k
                                  if (tls->key_share == NULL || tls->key_share->id != group) {
2727
1.52k
                                      ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2728
1.52k
                                      goto Exit;
2729
1.52k
                                  }
2730
1.52k
                              }
2731
1.52k
                              break;
2732
1.52k
                          case PTLS_EXTENSION_TYPE_COOKIE:
2733
1.52k
                              assert(sh->is_retry_request);
2734
1.52k
                              ptls_decode_block(src, end, 2, {
2735
1.52k
                                  if (src == end) {
2736
1.52k
                                      ret = PTLS_ALERT_DECODE_ERROR;
2737
1.52k
                                      goto Exit;
2738
1.52k
                                  }
2739
1.52k
                                  sh->retry_request.cookie = ptls_iovec_init(src, end - src);
2740
1.52k
                                  src = end;
2741
1.52k
                              });
2742
1.52k
                              break;
2743
1.52k
                          case PTLS_EXTENSION_TYPE_PRE_SHARED_KEY:
2744
1.52k
                              assert(!sh->is_retry_request);
2745
1.52k
                              if ((ret = ptls_decode16(&selected_psk_identity, &src, end)) != 0)
2746
1.52k
                                  goto Exit;
2747
1.52k
                              break;
2748
1.52k
                          case PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO:
2749
1.52k
                              assert(sh->is_retry_request);
2750
1.52k
                              if (tls->ech.state == PTLS_ECH_STATE_NONE) {
2751
1.52k
                                  ret = PTLS_ALERT_UNSUPPORTED_EXTENSION;
2752
1.52k
                                  goto Exit;
2753
1.52k
                              }
2754
1.52k
                              if (end - src != PTLS_ECH_CONFIRM_LENGTH) {
2755
1.52k
                                  ret = PTLS_ALERT_DECODE_ERROR;
2756
1.52k
                                  goto Exit;
2757
1.52k
                              }
2758
1.52k
                              sh->retry_request.ech = src;
2759
1.52k
                              src = end;
2760
1.52k
                              break;
2761
1.52k
                          default:
2762
1.52k
                              src = end;
2763
1.52k
                              break;
2764
1.52k
                          }
2765
1.52k
                      });
2766
2767
1.22k
    if (!is_supported_version(found_version)) {
2768
36
        ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2769
36
        goto Exit;
2770
36
    }
2771
1.18k
    if (!sh->is_retry_request) {
2772
1.07k
        if (selected_psk_identity != UINT16_MAX) {
2773
25
            if (!tls->client.offered_psk) {
2774
25
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2775
25
                goto Exit;
2776
25
            }
2777
0
            if (selected_psk_identity != 0) {
2778
0
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2779
0
                goto Exit;
2780
0
            }
2781
0
            tls->is_psk_handshake = 1;
2782
0
        }
2783
1.05k
        if (sh->peerkey.base == NULL && !tls->is_psk_handshake) {
2784
4
            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2785
4
            goto Exit;
2786
4
        }
2787
1.05k
    }
2788
2789
1.15k
    ret = 0;
2790
1.73k
Exit:
2791
1.73k
    return ret;
2792
1.15k
}
2793
2794
static int handle_hello_retry_request(ptls_t *tls, ptls_message_emitter_t *emitter, struct st_ptls_server_hello_t *sh,
2795
                                      ptls_iovec_t message, ptls_handshake_properties_t *properties)
2796
104
{
2797
104
    int ret;
2798
2799
104
    if (tls->client.key_share_ctx != NULL) {
2800
104
        tls->client.key_share_ctx->on_exchange(&tls->client.key_share_ctx, 1, NULL, ptls_iovec_init(NULL, 0));
2801
104
        tls->client.key_share_ctx = NULL;
2802
104
    }
2803
104
    if (tls->client.using_early_data) {
2804
        /* release traffic encryption key so that 2nd CH goes out in cleartext, but keep the epoch at 1 since we've already
2805
         * called derive-secret */
2806
0
        if (tls->ctx->update_traffic_key == NULL) {
2807
0
            assert(tls->traffic_protection.enc.aead != NULL);
2808
0
            ptls_aead_free(tls->traffic_protection.enc.aead);
2809
0
            tls->traffic_protection.enc.aead = NULL;
2810
0
        }
2811
0
        tls->client.using_early_data = 0;
2812
0
    }
2813
2814
104
    if (sh->retry_request.selected_group != UINT16_MAX) {
2815
        /* we offer the first key_exchanges[0] as KEY_SHARE unless client.negotiate_before_key_exchange is set */
2816
30
        ptls_key_exchange_algorithm_t **cand;
2817
59
        for (cand = tls->ctx->key_exchanges; *cand != NULL; ++cand)
2818
30
            if ((*cand)->id == sh->retry_request.selected_group)
2819
1
                break;
2820
30
        if (*cand == NULL) {
2821
29
            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2822
29
            goto Exit;
2823
29
        }
2824
1
        if (tls->key_share != NULL && sh->retry_request.selected_group == tls->key_share->id) {
2825
1
            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2826
1
            goto Exit;
2827
1
        }
2828
0
        tls->key_share = *cand;
2829
74
    } else if (tls->key_share != NULL) {
2830
        /* retain the key-share using in first CH, if server does not specify one */
2831
74
    } else {
2832
0
        ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2833
0
        goto Exit;
2834
0
    }
2835
2836
74
    ret = send_client_hello(tls, emitter, properties, &sh->retry_request.cookie);
2837
2838
104
Exit:
2839
104
    return ret;
2840
74
}
2841
2842
static int client_ech_select_hello(ptls_t *tls, ptls_iovec_t message, size_t confirm_hash_off, const char *label)
2843
0
{
2844
0
    uint8_t confirm_hash_delivered[PTLS_ECH_CONFIRM_LENGTH], confirm_hash_expected[PTLS_ECH_CONFIRM_LENGTH];
2845
0
    int ret = 0;
2846
2847
    /* Determine if ECH has been accepted by checking the confirmation hash. `confirm_hash_off` set to zero indicates that HRR was
2848
     * received wo. ECH extension, which is an indication that ECH was rejected. */
2849
0
    if (confirm_hash_off != 0) {
2850
0
        memcpy(confirm_hash_delivered, message.base + confirm_hash_off, sizeof(confirm_hash_delivered));
2851
0
        memset(message.base + confirm_hash_off, 0, sizeof(confirm_hash_delivered));
2852
0
        if ((ret = ech_calc_confirmation(tls->key_schedule, confirm_hash_expected, tls->ech.inner_client_random, label, message)) !=
2853
0
            0)
2854
0
            goto Exit;
2855
0
        int accepted = ptls_mem_equal(confirm_hash_delivered, confirm_hash_expected, sizeof(confirm_hash_delivered));
2856
0
        memcpy(message.base + confirm_hash_off, confirm_hash_delivered, sizeof(confirm_hash_delivered));
2857
0
        if (accepted) {
2858
0
            tls->ech.state = PTLS_ECH_STATE_ACCEPTED;
2859
0
            goto Exit;
2860
0
        } else if (tls->ech.state == PTLS_ECH_STATE_ACCEPTED) {
2861
            /* Per RFC 9849 Section 6.1.5: if HRR confirmed ECH acceptance, ServerHello MUST also confirm it. */
2862
0
            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2863
0
            goto Exit;
2864
0
        }
2865
0
    }
2866
2867
    /* dispose ECH AEAD state to indicate rejection, adopting outer CH for the rest of the handshake */
2868
0
    ptls_aead_free(tls->ech.aead);
2869
0
    tls->ech.aead = NULL;
2870
0
    key_schedule_select_outer(tls->key_schedule);
2871
2872
0
Exit:
2873
0
    PTLS_PROBE(ECH_SELECTION, tls, tls->ech.state == PTLS_ECH_STATE_ACCEPTED);
2874
0
    PTLS_LOG_CONN(ech_selection, tls, { PTLS_LOG_ELEMENT_BOOL(is_ech, tls->ech.state == PTLS_ECH_STATE_ACCEPTED); });
2875
0
    ptls_clear_memory(confirm_hash_expected, sizeof(confirm_hash_expected));
2876
0
    return ret;
2877
0
}
2878
2879
static int client_handle_hello(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_iovec_t message,
2880
                               ptls_handshake_properties_t *properties)
2881
1.73k
{
2882
1.73k
    struct st_ptls_server_hello_t sh;
2883
1.73k
    ptls_iovec_t ecdh_secret = {NULL};
2884
1.73k
    int ret;
2885
2886
1.73k
    if ((ret = decode_server_hello(tls, &sh, message.base + PTLS_HANDSHAKE_HEADER_SIZE, message.base + message.len)) != 0)
2887
583
        goto Exit;
2888
1.15k
    if (!(sh.legacy_session_id.len == tls->client.legacy_session_id.len &&
2889
1.15k
          ptls_mem_equal(sh.legacy_session_id.base, tls->client.legacy_session_id.base, tls->client.legacy_session_id.len))) {
2890
4
        ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2891
4
        goto Exit;
2892
4
    }
2893
2894
1.15k
    if (sh.is_retry_request) {
2895
104
        if ((ret = key_schedule_select_cipher(tls->key_schedule, tls->cipher_suite, 0, tls->ctx->pre_shared_key.secret)) != 0)
2896
0
            goto Exit;
2897
104
        key_schedule_transform_post_ch1hash(tls->key_schedule);
2898
104
        if (tls->ech.aead != NULL) {
2899
0
            size_t confirm_hash_off = 0;
2900
0
            if (tls->ech.state != PTLS_ECH_STATE_GREASE) {
2901
0
                if (sh.retry_request.ech != NULL)
2902
0
                    confirm_hash_off = sh.retry_request.ech - message.base;
2903
0
            }
2904
0
            if ((ret = client_ech_select_hello(tls, message, confirm_hash_off, ECH_CONFIRMATION_HRR)) != 0)
2905
0
                goto Exit;
2906
0
        }
2907
104
        ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
2908
104
        return handle_hello_retry_request(tls, emitter, &sh, message, properties);
2909
104
    }
2910
2911
1.04k
    if ((ret = key_schedule_select_cipher(tls->key_schedule, tls->cipher_suite, tls->client.offered_psk && !tls->is_psk_handshake,
2912
1.04k
                                          ptls_iovec_init(NULL, 0))) != 0)
2913
0
        goto Exit;
2914
2915
    /* check if ECH is accepted */
2916
1.04k
    if (tls->ech.aead != NULL) {
2917
0
        size_t confirm_hash_off = 0;
2918
0
        if (tls->ech.state != PTLS_ECH_STATE_GREASE) {
2919
0
            confirm_hash_off =
2920
0
                PTLS_HANDSHAKE_HEADER_SIZE + 2 /* legacy_version */ + PTLS_HELLO_RANDOM_SIZE - PTLS_ECH_CONFIRM_LENGTH;
2921
0
        }
2922
0
        if ((ret = client_ech_select_hello(tls, message, confirm_hash_off, ECH_CONFIRMATION_SERVER_HELLO)) != 0)
2923
0
            goto Exit;
2924
0
    }
2925
2926
    /* clear sensitive and space-consuming ECH state, now that are done with handling sending and decoding Hellos */
2927
1.04k
    clear_ech(&tls->ech, 0);
2928
1.04k
    if (tls->key_schedule->hashes[0].ctx_outer != NULL) {
2929
0
        tls->key_schedule->hashes[0].ctx_outer->final(tls->key_schedule->hashes[0].ctx_outer, NULL, PTLS_HASH_FINAL_MODE_FREE);
2930
0
        tls->key_schedule->hashes[0].ctx_outer = NULL;
2931
0
    }
2932
2933
    /* if the client offered external PSK but the server did not use that, we call it a handshake failure */
2934
1.04k
    if (tls->ctx->pre_shared_key.identity.base != NULL && !tls->is_psk_handshake) {
2935
0
        ret = PTLS_ALERT_HANDSHAKE_FAILURE;
2936
0
        goto Exit;
2937
0
    }
2938
2939
1.04k
    ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
2940
2941
1.04k
    if (sh.peerkey.base != NULL) {
2942
1.04k
        if ((ret = tls->client.key_share_ctx->on_exchange(&tls->client.key_share_ctx, 1, &ecdh_secret, sh.peerkey)) != 0) {
2943
5
            assert(ecdh_secret.base == NULL);
2944
5
            goto Exit;
2945
5
        }
2946
1.04k
    }
2947
2948
1.04k
    if ((ret = key_schedule_extract(tls->key_schedule, ecdh_secret)) != 0)
2949
0
        goto Exit;
2950
1.04k
    if ((ret = setup_traffic_protection(tls, 0, "s hs traffic", 2, 0, 0)) != 0)
2951
0
        goto Exit;
2952
1.04k
    if (tls->client.using_early_data) {
2953
0
        if ((tls->pending_handshake_secret = malloc(PTLS_MAX_DIGEST_SIZE)) == NULL) {
2954
0
            ret = PTLS_ERROR_NO_MEMORY;
2955
0
            goto Exit;
2956
0
        }
2957
0
        if ((ret = derive_secret(tls->key_schedule, tls->pending_handshake_secret, "c hs traffic")) != 0)
2958
0
            goto Exit;
2959
0
        if (tls->ctx->update_traffic_key != NULL &&
2960
0
            (ret = tls->ctx->update_traffic_key->cb(tls->ctx->update_traffic_key, tls, 1, 2, tls->pending_handshake_secret)) != 0)
2961
0
            goto Exit;
2962
1.04k
    } else {
2963
1.04k
        if ((ret = setup_traffic_protection(tls, 1, "c hs traffic", 2, 0, 0)) != 0)
2964
0
            goto Exit;
2965
1.04k
    }
2966
2967
1.04k
    tls->state = PTLS_STATE_CLIENT_EXPECT_ENCRYPTED_EXTENSIONS;
2968
1.04k
    ret = PTLS_ERROR_IN_PROGRESS;
2969
2970
1.63k
Exit:
2971
1.63k
    if (ecdh_secret.base != NULL) {
2972
1.04k
        ptls_clear_memory(ecdh_secret.base, ecdh_secret.len);
2973
1.04k
        free(ecdh_secret.base);
2974
1.04k
    }
2975
1.63k
    return ret;
2976
1.04k
}
2977
2978
static int should_collect_unknown_extension(ptls_t *tls, ptls_handshake_properties_t *properties, uint16_t type)
2979
1.53k
{
2980
1.53k
    return properties != NULL && properties->collect_extension != NULL && properties->collect_extension(tls, properties, type);
2981
1.53k
}
2982
2983
static int collect_unknown_extension(ptls_t *tls, uint16_t type, const uint8_t *src, const uint8_t *const end,
2984
                                     ptls_raw_extension_t *slots)
2985
0
{
2986
0
    size_t i;
2987
0
    for (i = 0; slots[i].type != UINT16_MAX; ++i) {
2988
0
        assert(i < MAX_UNKNOWN_EXTENSIONS);
2989
0
        if (slots[i].type == type)
2990
0
            return PTLS_ALERT_ILLEGAL_PARAMETER;
2991
0
    }
2992
0
    if (i < MAX_UNKNOWN_EXTENSIONS) {
2993
0
        slots[i].type = type;
2994
0
        slots[i].data = ptls_iovec_init(src, end - src);
2995
0
        slots[i + 1].type = UINT16_MAX;
2996
0
    }
2997
0
    return 0;
2998
0
}
2999
3000
static int report_unknown_extensions(ptls_t *tls, ptls_handshake_properties_t *properties, ptls_raw_extension_t *slots)
3001
1.02k
{
3002
1.02k
    if (properties != NULL && properties->collect_extension != NULL) {
3003
0
        assert(properties->collected_extensions != NULL);
3004
0
        return properties->collected_extensions(tls, properties, slots);
3005
1.02k
    } else {
3006
1.02k
        return 0;
3007
1.02k
    }
3008
1.02k
}
3009
3010
static int client_handle_encrypted_extensions(ptls_t *tls, ptls_iovec_t message, ptls_handshake_properties_t *properties)
3011
952
{
3012
952
    const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len;
3013
952
    uint16_t type;
3014
952
    static const ptls_raw_extension_t no_unknown_extensions = {UINT16_MAX};
3015
952
    ptls_raw_extension_t *unknown_extensions = (ptls_raw_extension_t *)&no_unknown_extensions;
3016
952
    int ret, skip_early_data = 1;
3017
952
    uint8_t server_offered_cert_type = PTLS_CERTIFICATE_TYPE_X509;
3018
3019
952
    decode_extensions(src, end, PTLS_HANDSHAKE_TYPE_ENCRYPTED_EXTENSIONS, &type, {
3020
952
        if (tls->ctx->on_extension != NULL &&
3021
952
            (ret = tls->ctx->on_extension->cb(tls->ctx->on_extension, tls, PTLS_HANDSHAKE_TYPE_ENCRYPTED_EXTENSIONS, type,
3022
952
                                              ptls_iovec_init(src, end - src)) != 0))
3023
952
            goto Exit;
3024
952
        switch (type) {
3025
952
        case PTLS_EXTENSION_TYPE_SERVER_NAME:
3026
952
            if (src != end) {
3027
952
                ret = PTLS_ALERT_DECODE_ERROR;
3028
952
                goto Exit;
3029
952
            }
3030
952
            if (!(tls->server_name != NULL && !ptls_server_name_is_ipaddr(tls->server_name))) {
3031
952
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
3032
952
                goto Exit;
3033
952
            }
3034
952
            break;
3035
952
        case PTLS_EXTENSION_TYPE_ALPN:
3036
952
            ptls_decode_block(src, end, 2, {
3037
952
                ptls_decode_open_block(src, end, 1, {
3038
952
                    if (src == end) {
3039
952
                        ret = PTLS_ALERT_DECODE_ERROR;
3040
952
                        goto Exit;
3041
952
                    }
3042
952
                    if ((ret = ptls_set_negotiated_protocol(tls, (const char *)src, end - src)) != 0)
3043
952
                        goto Exit;
3044
952
                    src = end;
3045
952
                });
3046
952
                if (src != end) {
3047
952
                    ret = PTLS_ALERT_HANDSHAKE_FAILURE;
3048
952
                    goto Exit;
3049
952
                }
3050
952
            });
3051
952
            break;
3052
952
        case PTLS_EXTENSION_TYPE_EARLY_DATA:
3053
952
            if (!tls->client.using_early_data) {
3054
952
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
3055
952
                goto Exit;
3056
952
            }
3057
952
            skip_early_data = 0;
3058
952
            break;
3059
952
        case PTLS_EXTENSION_TYPE_SERVER_CERTIFICATE_TYPE:
3060
952
            if (end - src != 1) {
3061
952
                ret = PTLS_ALERT_DECODE_ERROR;
3062
952
                goto Exit;
3063
952
            }
3064
952
            server_offered_cert_type = *src;
3065
952
            src = end;
3066
952
            break;
3067
952
        case PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO: {
3068
            /* accept retry_configs only if we offered ECH (or grease) but rejected */
3069
952
            if (!(tls->ech.state == PTLS_ECH_STATE_OFFERED || tls->ech.state == PTLS_ECH_STATE_GREASE)) {
3070
952
                ret = PTLS_ALERT_UNSUPPORTED_EXTENSION;
3071
952
                goto Exit;
3072
952
            }
3073
            /* parse retry_config, and if it is applicable, provide that to the application (grease clients just verify syntax) */
3074
952
            struct st_decoded_ech_config_t decoded;
3075
952
            if ((ret = client_decode_ech_config_list(tls->ctx, &decoded, ptls_iovec_init(src, end - src))) != 0)
3076
952
                goto Exit;
3077
952
            if (tls->ech.state == PTLS_ECH_STATE_GREASE) {
3078
                /* GREASE clients ignore retry_configs after verifying the syntax */
3079
952
            } else if (decoded.kem != NULL && decoded.cipher != NULL && properties != NULL &&
3080
952
                       properties->client.ech.retry_configs != NULL) {
3081
952
                if ((properties->client.ech.retry_configs->base = malloc(end - src)) == NULL) {
3082
952
                    ret = PTLS_ERROR_NO_MEMORY;
3083
952
                    goto Exit;
3084
952
                }
3085
952
                memcpy(properties->client.ech.retry_configs->base, src, end - src);
3086
952
                properties->client.ech.retry_configs->len = end - src;
3087
952
            }
3088
952
            src = end;
3089
952
        } break;
3090
952
        default:
3091
952
            if (should_collect_unknown_extension(tls, properties, type)) {
3092
952
                if (unknown_extensions == &no_unknown_extensions) {
3093
952
                    if ((unknown_extensions = malloc(sizeof(*unknown_extensions) * (MAX_UNKNOWN_EXTENSIONS + 1))) == NULL) {
3094
952
                        ret = PTLS_ERROR_NO_MEMORY;
3095
952
                        goto Exit;
3096
952
                    }
3097
952
                    unknown_extensions[0].type = UINT16_MAX;
3098
952
                }
3099
952
                if ((ret = collect_unknown_extension(tls, type, src, end, unknown_extensions)) != 0)
3100
952
                    goto Exit;
3101
952
            }
3102
952
            break;
3103
952
        }
3104
952
        src = end;
3105
952
    });
3106
3107
686
    if (server_offered_cert_type !=
3108
686
        (tls->ctx->use_raw_public_keys ? PTLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY : PTLS_CERTIFICATE_TYPE_X509)) {
3109
11
        ret = PTLS_ALERT_UNSUPPORTED_CERTIFICATE;
3110
11
        goto Exit;
3111
11
    }
3112
3113
675
    if (tls->client.using_early_data) {
3114
0
        if (skip_early_data)
3115
0
            tls->client.using_early_data = 0;
3116
0
        if (properties != NULL)
3117
0
            properties->client.early_data_acceptance = skip_early_data ? PTLS_EARLY_DATA_REJECTED : PTLS_EARLY_DATA_ACCEPTED;
3118
0
    }
3119
675
    if ((ret = report_unknown_extensions(tls, properties, unknown_extensions)) != 0)
3120
0
        goto Exit;
3121
3122
675
    ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
3123
675
    tls->state =
3124
675
        tls->is_psk_handshake ? PTLS_STATE_CLIENT_EXPECT_FINISHED : PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_REQUEST_OR_CERTIFICATE;
3125
675
    ret = PTLS_ERROR_IN_PROGRESS;
3126
3127
952
Exit:
3128
952
    if (unknown_extensions != &no_unknown_extensions)
3129
0
        free(unknown_extensions);
3130
952
    return ret;
3131
675
}
3132
3133
static int decode_certificate_request(ptls_t *tls, struct st_ptls_certificate_request_t *cr, const uint8_t *src,
3134
                                      const uint8_t *const end)
3135
264
{
3136
264
    int ret;
3137
264
    uint16_t exttype = 0;
3138
3139
    /* certificate request context */
3140
264
    ptls_decode_open_block(src, end, 1, {
3141
264
        size_t len = end - src;
3142
264
        if (len > 255) {
3143
264
            ret = PTLS_ALERT_DECODE_ERROR;
3144
264
            goto Exit;
3145
264
        }
3146
264
        if ((cr->context.base = malloc(len != 0 ? len : 1)) == NULL) {
3147
264
            ret = PTLS_ERROR_NO_MEMORY;
3148
264
            goto Exit;
3149
264
        }
3150
264
        cr->context.len = len;
3151
264
        memcpy(cr->context.base, src, len);
3152
264
        src = end;
3153
264
    });
3154
3155
    /* decode extensions */
3156
260
    decode_extensions(src, end, PTLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST, &exttype, {
3157
260
        if (tls->ctx->on_extension != NULL &&
3158
260
            (ret = tls->ctx->on_extension->cb(tls->ctx->on_extension, tls, PTLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST, exttype,
3159
260
                                              ptls_iovec_init(src, end - src)) != 0))
3160
260
            goto Exit;
3161
260
        switch (exttype) {
3162
260
        case PTLS_EXTENSION_TYPE_SIGNATURE_ALGORITHMS:
3163
260
            if ((ret = decode_signature_algorithms(&cr->signature_algorithms, &src, end)) != 0)
3164
260
                goto Exit;
3165
260
            break;
3166
260
        }
3167
260
        src = end;
3168
260
    });
3169
3170
27
    if (cr->signature_algorithms.count == 0) {
3171
16
        ret = PTLS_ALERT_MISSING_EXTENSION;
3172
16
        goto Exit;
3173
16
    }
3174
3175
11
    ret = 0;
3176
264
Exit:
3177
264
    return ret;
3178
11
}
3179
3180
int ptls_build_certificate_message(ptls_buffer_t *buf, ptls_iovec_t context, ptls_iovec_t *certificates, size_t num_certificates,
3181
                                   ptls_iovec_t ocsp_status)
3182
212
{
3183
212
    int ret;
3184
3185
212
    ptls_buffer_push_block(buf, 1, { ptls_buffer_pushv(buf, context.base, context.len); });
3186
212
    ptls_buffer_push_block(buf, 3, {
3187
212
        size_t i;
3188
212
        for (i = 0; i != num_certificates; ++i) {
3189
212
            ptls_buffer_push_block(buf, 3, { ptls_buffer_pushv(buf, certificates[i].base, certificates[i].len); });
3190
212
            ptls_buffer_push_block(buf, 2, {
3191
212
                if (i == 0 && ocsp_status.len != 0) {
3192
212
                    buffer_push_extension(buf, PTLS_EXTENSION_TYPE_STATUS_REQUEST, {
3193
212
                        ptls_buffer_push(buf, 1); /* status_type == ocsp */
3194
212
                        ptls_buffer_push_block(buf, 3, { ptls_buffer_pushv(buf, ocsp_status.base, ocsp_status.len); });
3195
212
                    });
3196
212
                }
3197
212
            });
3198
212
        }
3199
212
    });
3200
3201
212
    ret = 0;
3202
212
Exit:
3203
212
    return ret;
3204
212
}
3205
3206
static int default_emit_certificate_cb(ptls_emit_certificate_t *_self, ptls_t *tls, ptls_message_emitter_t *emitter,
3207
                                       ptls_key_schedule_t *key_sched, ptls_iovec_t context, int push_status_request,
3208
                                       const uint16_t *compress_algos, size_t num_compress_algos)
3209
212
{
3210
212
    int ret;
3211
3212
212
    ptls_push_message(emitter, key_sched, PTLS_HANDSHAKE_TYPE_CERTIFICATE, {
3213
212
        if ((ret = ptls_build_certificate_message(emitter->buf, context, tls->ctx->certificates.list, tls->ctx->certificates.count,
3214
212
                                                  ptls_iovec_init(NULL, 0))) != 0)
3215
212
            goto Exit;
3216
212
    });
3217
3218
212
    ret = 0;
3219
212
Exit:
3220
212
    return ret;
3221
212
}
3222
3223
static int send_certificate(ptls_t *tls, ptls_message_emitter_t *emitter,
3224
                            struct st_ptls_signature_algorithms_t *signature_algorithms, ptls_iovec_t context,
3225
                            int push_status_request, const uint16_t *compress_algos, size_t num_compress_algos)
3226
222
{
3227
222
    int ret;
3228
3229
222
    if (signature_algorithms->count == 0) {
3230
10
        ret = PTLS_ALERT_MISSING_EXTENSION;
3231
10
        goto Exit;
3232
10
    }
3233
3234
212
    { /* send Certificate (or the equivalent) */
3235
212
        static ptls_emit_certificate_t default_emit_certificate = {default_emit_certificate_cb};
3236
212
        ptls_emit_certificate_t *emit_certificate =
3237
212
            tls->ctx->emit_certificate != NULL ? tls->ctx->emit_certificate : &default_emit_certificate;
3238
212
    Redo:
3239
212
        if ((ret = emit_certificate->cb(emit_certificate, tls, emitter, tls->key_schedule, context, push_status_request,
3240
212
                                        compress_algos, num_compress_algos)) != 0) {
3241
0
            if (ret == PTLS_ERROR_DELEGATE) {
3242
0
                assert(emit_certificate != &default_emit_certificate);
3243
0
                emit_certificate = &default_emit_certificate;
3244
0
                goto Redo;
3245
0
            }
3246
0
            goto Exit;
3247
0
        }
3248
212
    }
3249
3250
222
Exit:
3251
222
    return ret;
3252
212
}
3253
3254
static int send_certificate_verify(ptls_t *tls, ptls_message_emitter_t *emitter,
3255
                                   struct st_ptls_signature_algorithms_t *signature_algorithms, const char *context_string)
3256
212
{
3257
212
    size_t start_off = emitter->buf->off;
3258
212
    int ret;
3259
3260
212
    if (tls->ctx->sign_certificate == NULL)
3261
212
        return 0;
3262
    /* build and send CertificateVerify */
3263
0
    ptls_push_message(emitter, tls->key_schedule, PTLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY, {
3264
0
        ptls_buffer_t *sendbuf = emitter->buf;
3265
0
        size_t algo_off = sendbuf->off;
3266
0
        ptls_buffer_push16(sendbuf, 0); /* filled in later */
3267
0
        ptls_buffer_push_block(sendbuf, 2, {
3268
0
            uint16_t algo;
3269
0
            uint8_t data[PTLS_MAX_CERTIFICATE_VERIFY_SIGNDATA_SIZE];
3270
0
            size_t datalen = build_certificate_verify_signdata(data, tls->key_schedule, context_string);
3271
0
            if ((ret = tls->ctx->sign_certificate->cb(
3272
0
                     tls->ctx->sign_certificate, tls, tls->is_server ? &tls->server.async_job : NULL, &algo, sendbuf,
3273
0
                     ptls_iovec_init(data, datalen), signature_algorithms != NULL ? signature_algorithms->list : NULL,
3274
0
                     signature_algorithms != NULL ? signature_algorithms->count : 0)) == PTLS_ERROR_ASYNC_OPERATION) {
3275
0
                assert(tls->is_server || !"async operation only supported on the server-side");
3276
0
                assert(tls->server.async_job != NULL);
3277
                /* Reset the output to the end of the previous handshake message. CertificateVerify will be rebuilt when the async
3278
                 * operation completes. */
3279
0
                emitter->buf->off = start_off;
3280
0
                goto Exit;
3281
0
            }
3282
0
            assert(!tls->is_server || tls->server.async_job == NULL);
3283
0
            if (ret != 0)
3284
0
                goto Exit;
3285
0
            sendbuf->base[algo_off] = (uint8_t)(algo >> 8);
3286
0
            sendbuf->base[algo_off + 1] = (uint8_t)algo;
3287
0
        });
3288
0
    });
3289
0
Exit:
3290
0
    return ret;
3291
0
}
3292
3293
static int client_handle_certificate_request(ptls_t *tls, ptls_iovec_t message, ptls_handshake_properties_t *properties)
3294
264
{
3295
264
    const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len;
3296
264
    int ret = 0;
3297
3298
264
    assert(!tls->is_psk_handshake && "state machine asserts that this message is never delivered when PSK is used");
3299
3300
264
    if ((ret = decode_certificate_request(tls, &tls->client.certificate_request, src, end)) != 0)
3301
253
        return ret;
3302
3303
    /* This field SHALL be zero length unless used for the post-handshake authentication exchanges (section 4.3.2) */
3304
11
    if (tls->client.certificate_request.context.len != 0)
3305
5
        return PTLS_ALERT_ILLEGAL_PARAMETER;
3306
3307
6
    tls->state = PTLS_STATE_CLIENT_EXPECT_CERTIFICATE;
3308
6
    ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
3309
3310
6
    return PTLS_ERROR_IN_PROGRESS;
3311
11
}
3312
3313
static int handle_certificate(ptls_t *tls, const uint8_t *src, const uint8_t *end, int *got_certs)
3314
375
{
3315
375
    ptls_iovec_t certs[16];
3316
375
    size_t num_certs = 0;
3317
375
    int ret = 0;
3318
3319
    /* certificate request context */
3320
375
    ptls_decode_open_block(src, end, 1, {
3321
375
        if (src != end) {
3322
375
            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
3323
375
            goto Exit;
3324
375
        }
3325
375
    });
3326
    /* certificate_list */
3327
357
    ptls_decode_block(src, end, 3, {
3328
357
        while (src != end) {
3329
357
            ptls_decode_open_block(src, end, 3, {
3330
357
                if (num_certs < PTLS_ELEMENTSOF(certs))
3331
357
                    certs[num_certs++] = ptls_iovec_init(src, end - src);
3332
357
                src = end;
3333
357
            });
3334
357
            uint16_t type;
3335
357
            decode_open_extensions(src, end, PTLS_HANDSHAKE_TYPE_CERTIFICATE, &type, {
3336
357
                if (tls->ctx->on_extension != NULL &&
3337
357
                    (ret = tls->ctx->on_extension->cb(tls->ctx->on_extension, tls, PTLS_HANDSHAKE_TYPE_CERTIFICATE, type,
3338
357
                                                      ptls_iovec_init(src, end - src)) != 0))
3339
357
                    goto Exit;
3340
357
                src = end;
3341
357
            });
3342
357
        }
3343
357
    });
3344
3345
64
    if (tls->ctx->verify_certificate != NULL) {
3346
0
        const char *server_name = NULL;
3347
0
        if (!ptls_is_server(tls)) {
3348
0
            if (tls->ech.state == PTLS_ECH_STATE_OFFERED) {
3349
0
                server_name = tls->ech.client.public_name;
3350
0
            } else {
3351
0
                server_name = tls->server_name;
3352
0
            }
3353
0
        }
3354
0
        if ((ret = tls->ctx->verify_certificate->cb(tls->ctx->verify_certificate, tls, server_name, &tls->certificate_verify.cb,
3355
0
                                                    &tls->certificate_verify.verify_ctx, certs, num_certs)) != 0)
3356
0
            goto Exit;
3357
0
    }
3358
3359
64
    *got_certs = num_certs != 0;
3360
3361
375
Exit:
3362
375
    return ret;
3363
64
}
3364
3365
static int client_do_handle_certificate(ptls_t *tls, const uint8_t *src, const uint8_t *end)
3366
375
{
3367
375
    int got_certs, ret;
3368
3369
375
    if ((ret = handle_certificate(tls, src, end, &got_certs)) != 0)
3370
311
        return ret;
3371
64
    if (!got_certs)
3372
1
        return PTLS_ALERT_ILLEGAL_PARAMETER;
3373
3374
63
    return 0;
3375
64
}
3376
3377
static int client_handle_certificate(ptls_t *tls, ptls_iovec_t message)
3378
375
{
3379
375
    int ret;
3380
3381
375
    if ((ret = client_do_handle_certificate(tls, message.base + PTLS_HANDSHAKE_HEADER_SIZE, message.base + message.len)) != 0)
3382
312
        return ret;
3383
3384
63
    ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
3385
3386
63
    tls->state = PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_VERIFY;
3387
63
    return PTLS_ERROR_IN_PROGRESS;
3388
375
}
3389
3390
static int client_handle_compressed_certificate(ptls_t *tls, ptls_iovec_t message)
3391
2
{
3392
2
    const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len;
3393
2
    uint16_t algo;
3394
2
    uint32_t uncompressed_size;
3395
2
    uint8_t *uncompressed = NULL;
3396
2
    int ret;
3397
3398
2
    if (tls->ctx->decompress_certificate == NULL) {
3399
2
        ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
3400
2
        goto Exit;
3401
2
    }
3402
3403
    /* decode */
3404
0
    if ((ret = ptls_decode16(&algo, &src, end)) != 0)
3405
0
        goto Exit;
3406
0
    if ((ret = ptls_decode24(&uncompressed_size, &src, end)) != 0)
3407
0
        goto Exit;
3408
0
    if (uncompressed_size > 65536) { /* TODO find a sensible number */
3409
0
        ret = PTLS_ALERT_BAD_CERTIFICATE;
3410
0
        goto Exit;
3411
0
    }
3412
0
    if ((uncompressed = malloc(uncompressed_size)) == NULL) {
3413
0
        ret = PTLS_ERROR_NO_MEMORY;
3414
0
        goto Exit;
3415
0
    }
3416
0
    ptls_decode_block(src, end, 3, {
3417
0
        if ((ret = tls->ctx->decompress_certificate->cb(tls->ctx->decompress_certificate, tls, algo,
3418
0
                                                        ptls_iovec_init(uncompressed, uncompressed_size),
3419
0
                                                        ptls_iovec_init(src, end - src))) != 0)
3420
0
            goto Exit;
3421
0
        src = end;
3422
0
    });
3423
3424
    /* handle */
3425
0
    if ((ret = client_do_handle_certificate(tls, uncompressed, uncompressed + uncompressed_size)) != 0)
3426
0
        goto Exit;
3427
3428
0
    ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
3429
0
    tls->state = PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_VERIFY;
3430
0
    ret = PTLS_ERROR_IN_PROGRESS;
3431
3432
2
Exit:
3433
2
    free(uncompressed);
3434
2
    return ret;
3435
0
}
3436
3437
static int server_handle_certificate(ptls_t *tls, ptls_iovec_t message)
3438
0
{
3439
0
    int got_certs, ret;
3440
3441
0
    if ((ret = handle_certificate(tls, message.base + PTLS_HANDSHAKE_HEADER_SIZE, message.base + message.len, &got_certs)) != 0)
3442
0
        return ret;
3443
3444
0
    ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
3445
3446
0
    if (got_certs) {
3447
0
        tls->state = PTLS_STATE_SERVER_EXPECT_CERTIFICATE_VERIFY;
3448
0
    } else {
3449
        /* Client did not provide certificate, and the verifier says we can fail open. Therefore, the next message is Finished. */
3450
0
        tls->state = PTLS_STATE_SERVER_EXPECT_FINISHED;
3451
0
    }
3452
3453
0
    return PTLS_ERROR_IN_PROGRESS;
3454
0
}
3455
3456
static int handle_certificate_verify(ptls_t *tls, ptls_iovec_t message, const char *context_string)
3457
41
{
3458
41
    const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len;
3459
41
    uint16_t algo;
3460
41
    ptls_iovec_t signature;
3461
41
    uint8_t signdata[PTLS_MAX_CERTIFICATE_VERIFY_SIGNDATA_SIZE];
3462
41
    size_t signdata_size;
3463
41
    int ret;
3464
3465
    /* decode */
3466
41
    if ((ret = ptls_decode16(&algo, &src, end)) != 0)
3467
1
        goto Exit;
3468
40
    ptls_decode_block(src, end, 2, {
3469
40
        signature = ptls_iovec_init(src, end - src);
3470
40
        src = end;
3471
40
    });
3472
3473
13
    signdata_size = build_certificate_verify_signdata(signdata, tls->key_schedule, context_string);
3474
13
    if (tls->certificate_verify.cb != NULL) {
3475
0
        ret = tls->certificate_verify.cb(tls->certificate_verify.verify_ctx, algo, ptls_iovec_init(signdata, signdata_size),
3476
0
                                         signature);
3477
13
    } else {
3478
13
        ret = 0;
3479
13
    }
3480
13
    ptls_clear_memory(signdata, signdata_size);
3481
13
    tls->certificate_verify.cb = NULL;
3482
13
    if (ret != 0) {
3483
0
        goto Exit;
3484
0
    }
3485
3486
13
    ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
3487
3488
41
Exit:
3489
41
    return ret;
3490
13
}
3491
3492
static int client_handle_certificate_verify(ptls_t *tls, ptls_iovec_t message)
3493
41
{
3494
41
    int ret = handle_certificate_verify(tls, message, PTLS_SERVER_CERTIFICATE_VERIFY_CONTEXT_STRING);
3495
3496
41
    if (ret == 0) {
3497
13
        tls->state = PTLS_STATE_CLIENT_EXPECT_FINISHED;
3498
13
        ret = PTLS_ERROR_IN_PROGRESS;
3499
13
    }
3500
3501
41
    return ret;
3502
41
}
3503
3504
static int server_handle_certificate_verify(ptls_t *tls, ptls_iovec_t message)
3505
0
{
3506
0
    int ret = handle_certificate_verify(tls, message, PTLS_CLIENT_CERTIFICATE_VERIFY_CONTEXT_STRING);
3507
3508
0
    if (ret == 0) {
3509
0
        tls->state = PTLS_STATE_SERVER_EXPECT_FINISHED;
3510
0
        ret = PTLS_ERROR_IN_PROGRESS;
3511
0
    }
3512
3513
0
    return ret;
3514
0
}
3515
3516
static int client_handle_finished(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_iovec_t message)
3517
7
{
3518
7
    uint8_t send_secret[PTLS_MAX_DIGEST_SIZE];
3519
7
    int alert_ech_required = tls->ech.state == PTLS_ECH_STATE_OFFERED, ret;
3520
3521
7
    if ((ret = verify_finished(tls, message)) != 0)
3522
7
        goto Exit;
3523
0
    ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
3524
3525
    /* update traffic keys by using messages upto ServerFinished, but commission them after sending ClientFinished */
3526
0
    if ((ret = key_schedule_extract(tls->key_schedule, ptls_iovec_init(NULL, 0))) != 0)
3527
0
        goto Exit;
3528
0
    if ((ret = setup_traffic_protection(tls, 0, "s ap traffic", 3, 0, 0)) != 0)
3529
0
        goto Exit;
3530
0
    if ((ret = derive_secret(tls->key_schedule, send_secret, "c ap traffic")) != 0)
3531
0
        goto Exit;
3532
0
    if ((ret = derive_exporter_secret(tls, 0)) != 0)
3533
0
        goto Exit;
3534
3535
    /* if sending early data, emit EOED and commision the client handshake traffic secret */
3536
0
    if (tls->pending_handshake_secret != NULL) {
3537
0
        assert(tls->traffic_protection.enc.aead != NULL || tls->ctx->update_traffic_key != NULL);
3538
0
        if (tls->client.using_early_data && !tls->ctx->omit_end_of_early_data)
3539
0
            ptls_push_message(emitter, tls->key_schedule, PTLS_HANDSHAKE_TYPE_END_OF_EARLY_DATA, {});
3540
0
        tls->client.using_early_data = 0;
3541
0
        if ((ret = commission_handshake_secret(tls)) != 0)
3542
0
            goto Exit;
3543
0
    }
3544
3545
0
    if ((ret = push_change_cipher_spec(tls, emitter)) != 0)
3546
0
        goto Exit;
3547
3548
0
    if (!alert_ech_required && tls->client.certificate_request.context.base != NULL) {
3549
0
        if ((ret = send_certificate(tls, emitter, &tls->client.certificate_request.signature_algorithms,
3550
0
                                    tls->client.certificate_request.context, 0, NULL, 0)) == 0)
3551
0
            ret = send_certificate_verify(tls, emitter, &tls->client.certificate_request.signature_algorithms,
3552
0
                                          PTLS_CLIENT_CERTIFICATE_VERIFY_CONTEXT_STRING);
3553
0
        free(tls->client.certificate_request.context.base);
3554
0
        tls->client.certificate_request.context = ptls_iovec_init(NULL, 0);
3555
0
        if (ret != 0)
3556
0
            goto Exit;
3557
0
    }
3558
3559
0
    ret = send_finished(tls, emitter);
3560
3561
0
    memcpy(tls->traffic_protection.enc.secret, send_secret, sizeof(send_secret));
3562
0
    if ((ret = setup_traffic_protection(tls, 1, NULL, 3, 0, 0)) != 0)
3563
0
        goto Exit;
3564
3565
0
    tls->state = PTLS_STATE_CLIENT_POST_HANDSHAKE;
3566
3567
    /* if ECH was rejected, close the connection with ECH_REQUIRED alert after verifying messages up to Finished */
3568
0
    if (alert_ech_required)
3569
0
        ret = PTLS_ALERT_ECH_REQUIRED;
3570
3571
7
Exit:
3572
7
    ptls_clear_memory(send_secret, sizeof(send_secret));
3573
7
    return ret;
3574
0
}
3575
3576
static int client_handle_new_session_ticket(ptls_t *tls, ptls_iovec_t message)
3577
0
{
3578
0
    const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len;
3579
0
    ptls_iovec_t ticket_nonce;
3580
0
    uint32_t ticket_lifetime, max_early_data_size;
3581
0
    int early_data;
3582
0
    int ret;
3583
3584
0
    { /* verify the format */
3585
0
        uint32_t ticket_age_add;
3586
0
        ptls_iovec_t ticket;
3587
0
        if ((ret = decode_new_session_ticket(tls, &ticket_lifetime, &ticket_age_add, &ticket_nonce, &ticket, &early_data,
3588
0
                                             &max_early_data_size, src, end)) != 0)
3589
0
            return ret;
3590
0
    }
3591
3592
    /* do nothing if use of session ticket is disabled */
3593
0
    if (tls->ctx->save_ticket == NULL)
3594
0
        return 0;
3595
3596
    /* save the extension, along with the key of myself */
3597
0
    ptls_buffer_t ticket_buf;
3598
0
    ptls_buffer_init(&ticket_buf, "", 0);
3599
0
    ptls_buffer_push64(&ticket_buf, tls->ctx->get_time->cb(tls->ctx->get_time));
3600
0
    ptls_buffer_push16(&ticket_buf, tls->key_share->id);
3601
0
    ptls_buffer_push16(&ticket_buf, tls->cipher_suite->id);
3602
0
    ptls_buffer_push_block(&ticket_buf, 3, { ptls_buffer_pushv(&ticket_buf, src, end - src); });
3603
0
    ptls_buffer_push_block(&ticket_buf, 2, {
3604
0
        if ((ret = ptls_buffer_reserve(&ticket_buf, tls->key_schedule->hashes[0].algo->digest_size)) != 0)
3605
0
            goto Exit;
3606
0
        if ((ret = derive_resumption_secret(tls->key_schedule, ticket_buf.base + ticket_buf.off, ticket_nonce)) != 0)
3607
0
            goto Exit;
3608
0
        ticket_buf.off += tls->key_schedule->hashes[0].algo->digest_size;
3609
0
    });
3610
3611
0
    ptls_save_ticket_properties_t properties = {
3612
0
        .lifetime = ticket_lifetime, .early_data = early_data, .max_early_data_size = max_early_data_size};
3613
0
    if ((ret = tls->ctx->save_ticket->cb(tls->ctx->save_ticket, tls, ptls_iovec_init(ticket_buf.base, ticket_buf.off),
3614
0
                                         &properties)) != 0)
3615
0
        goto Exit;
3616
3617
0
    ret = 0;
3618
0
Exit:
3619
0
    ptls_buffer_dispose(&ticket_buf);
3620
0
    return ret;
3621
0
}
3622
3623
static int client_hello_decode_server_name(ptls_iovec_t *name, const uint8_t **src, const uint8_t *const end)
3624
140
{
3625
140
    int ret = 0;
3626
3627
140
    ptls_decode_open_block(*src, end, 2, {
3628
140
        do {
3629
140
            uint8_t type;
3630
140
            if ((ret = ptls_decode8(&type, src, end)) != 0)
3631
140
                goto Exit;
3632
140
            ptls_decode_open_block(*src, end, 2, {
3633
140
                switch (type) {
3634
140
                case PTLS_SERVER_NAME_TYPE_HOSTNAME:
3635
140
                    if (end - *src == 0) {
3636
140
                        ret = PTLS_ALERT_DECODE_ERROR;
3637
140
                        goto Exit;
3638
140
                    }
3639
140
                    if (memchr(*src, '\0', end - *src) != 0) {
3640
140
                        ret = PTLS_ALERT_ILLEGAL_PARAMETER;
3641
140
                        goto Exit;
3642
140
                    }
3643
140
                    *name = ptls_iovec_init(*src, end - *src);
3644
140
                    break;
3645
140
                default:
3646
140
                    break;
3647
140
                }
3648
140
                *src = end;
3649
140
            });
3650
140
        } while (*src != end);
3651
140
    });
3652
3653
140
Exit:
3654
140
    return ret;
3655
140
}
3656
3657
static int select_negotiated_group(ptls_key_exchange_algorithm_t **selected, ptls_key_exchange_algorithm_t **candidates,
3658
                                   const uint8_t *src, const uint8_t *const end)
3659
209
{
3660
209
    int ret;
3661
3662
209
    ptls_decode_block(src, end, 2, {
3663
209
        while (src != end) {
3664
209
            uint16_t group;
3665
209
            if ((ret = ptls_decode16(&group, &src, end)) != 0)
3666
209
                goto Exit;
3667
209
            ptls_key_exchange_algorithm_t **c = candidates;
3668
209
            for (; *c != NULL; ++c) {
3669
209
                if ((*c)->id == group) {
3670
209
                    *selected = *c;
3671
209
                    return 0;
3672
209
                }
3673
209
            }
3674
209
        }
3675
209
    });
3676
3677
21
    ret = PTLS_ALERT_HANDSHAKE_FAILURE;
3678
3679
59
Exit:
3680
59
    return ret;
3681
21
}
3682
3683
static int decode_client_hello(ptls_context_t *ctx, struct st_ptls_client_hello_t *ch, const uint8_t *src, const uint8_t *const end,
3684
                               ptls_handshake_properties_t *properties, ptls_t *tls_cbarg)
3685
1.92k
{
3686
1.92k
    const uint8_t *start = src;
3687
1.92k
    uint16_t exttype = 0;
3688
1.92k
    int ret;
3689
3690
    /* decode protocol version (do not bare to decode something older than TLS 1.0) */
3691
1.92k
    if ((ret = ptls_decode16(&ch->legacy_version, &src, end)) != 0)
3692
6
        goto Exit;
3693
1.91k
    if (ch->legacy_version < 0x0301) {
3694
13
        ret = PTLS_ALERT_PROTOCOL_VERSION;
3695
13
        goto Exit;
3696
13
    }
3697
3698
    /* skip random */
3699
1.90k
    if (end - src < PTLS_HELLO_RANDOM_SIZE) {
3700
25
        ret = PTLS_ALERT_DECODE_ERROR;
3701
25
        goto Exit;
3702
25
    }
3703
1.88k
    ch->random_bytes = src;
3704
1.88k
    src += PTLS_HELLO_RANDOM_SIZE;
3705
3706
    /* skip legacy_session_id */
3707
1.88k
    ptls_decode_open_block(src, end, 1, {
3708
1.88k
        if (end - src > 32) {
3709
1.88k
            ret = PTLS_ALERT_DECODE_ERROR;
3710
1.88k
            goto Exit;
3711
1.88k
        }
3712
1.88k
        ch->legacy_session_id = ptls_iovec_init(src, end - src);
3713
1.88k
        src = end;
3714
1.88k
    });
3715
3716
    /* decode and select from ciphersuites */
3717
1.85k
    ptls_decode_open_block(src, end, 2, {
3718
1.85k
        if ((end - src) % 2 != 0) {
3719
1.85k
            ret = PTLS_ALERT_DECODE_ERROR;
3720
1.85k
            goto Exit;
3721
1.85k
        }
3722
1.85k
        ch->cipher_suites = ptls_iovec_init(src, end - src);
3723
1.85k
        src = end;
3724
1.85k
    });
3725
3726
    /* decode legacy_compression_methods */
3727
1.81k
    ptls_decode_open_block(src, end, 1, {
3728
1.81k
        if (src == end) {
3729
1.81k
            ret = PTLS_ALERT_DECODE_ERROR;
3730
1.81k
            goto Exit;
3731
1.81k
        }
3732
1.81k
        ch->compression_methods.ids = src;
3733
1.81k
        ch->compression_methods.count = end - src;
3734
1.81k
        src = end;
3735
1.81k
    });
3736
3737
    /* In TLS versions 1.2 and earlier CH might not have an extensions block (or they might, see what OpenSSL 1.0.0 sends); so bail
3738
     * out if that is the case after parsing the main variables. Zero is returned as it is a valid ClientHello. However
3739
     * `ptls_t::selected_version` remains zero indicating that no compatible version were found. */
3740
1.79k
    if (src == end) {
3741
11
        ret = 0;
3742
11
        goto Exit;
3743
11
    }
3744
3745
    /* decode extensions */
3746
1.78k
    ch->first_extension_at = src - start + 2;
3747
1.78k
    decode_extensions(src, end, PTLS_HANDSHAKE_TYPE_CLIENT_HELLO, &exttype, {
3748
1.78k
        ch->psk.is_last_extension = 0;
3749
1.78k
        if (ctx->on_extension != NULL && tls_cbarg != NULL &&
3750
1.78k
            (ret = ctx->on_extension->cb(ctx->on_extension, tls_cbarg, PTLS_HANDSHAKE_TYPE_CLIENT_HELLO, exttype,
3751
1.78k
                                         ptls_iovec_init(src, end - src)) != 0))
3752
1.78k
            goto Exit;
3753
1.78k
        switch (exttype) {
3754
1.78k
        case PTLS_EXTENSION_TYPE_SERVER_NAME:
3755
1.78k
            if ((ret = client_hello_decode_server_name(&ch->server_name, &src, end)) != 0)
3756
1.78k
                goto Exit;
3757
1.78k
            if (src != end) {
3758
1.78k
                ret = PTLS_ALERT_DECODE_ERROR;
3759
1.78k
                goto Exit;
3760
1.78k
            }
3761
1.78k
            break;
3762
1.78k
        case PTLS_EXTENSION_TYPE_ALPN:
3763
1.78k
            ptls_decode_block(src, end, 2, {
3764
1.78k
                do {
3765
1.78k
                    ptls_decode_open_block(src, end, 1, {
3766
                        /* rfc7301 3.1: empty strings MUST NOT be included */
3767
1.78k
                        if (src == end) {
3768
1.78k
                            ret = PTLS_ALERT_DECODE_ERROR;
3769
1.78k
                            goto Exit;
3770
1.78k
                        }
3771
1.78k
                        if (ch->alpn.count < PTLS_ELEMENTSOF(ch->alpn.list))
3772
1.78k
                            ch->alpn.list[ch->alpn.count++] = ptls_iovec_init(src, end - src);
3773
1.78k
                        src = end;
3774
1.78k
                    });
3775
1.78k
                } while (src != end);
3776
1.78k
            });
3777
1.78k
            break;
3778
1.78k
        case PTLS_EXTENSION_TYPE_SERVER_CERTIFICATE_TYPE:
3779
1.78k
            ptls_decode_block(src, end, 1, {
3780
1.78k
                size_t list_size = end - src;
3781
3782
                /* RFC7250 4.1: No empty list, no list with single x509 element */
3783
1.78k
                if (list_size == 0 || (list_size == 1 && *src == PTLS_CERTIFICATE_TYPE_X509)) {
3784
1.78k
                    ret = PTLS_ALERT_DECODE_ERROR;
3785
1.78k
                    goto Exit;
3786
1.78k
                }
3787
3788
1.78k
                do {
3789
1.78k
                    if (ch->server_certificate_types.count < PTLS_ELEMENTSOF(ch->server_certificate_types.list))
3790
1.78k
                        ch->server_certificate_types.list[ch->server_certificate_types.count++] = *src;
3791
1.78k
                    src++;
3792
1.78k
                } while (src != end);
3793
1.78k
            });
3794
1.78k
            break;
3795
1.78k
        case PTLS_EXTENSION_TYPE_COMPRESS_CERTIFICATE:
3796
1.78k
            ptls_decode_block(src, end, 1, {
3797
1.78k
                do {
3798
1.78k
                    uint16_t id;
3799
1.78k
                    if ((ret = ptls_decode16(&id, &src, end)) != 0)
3800
1.78k
                        goto Exit;
3801
1.78k
                    if (ch->cert_compression_algos.count < PTLS_ELEMENTSOF(ch->cert_compression_algos.list))
3802
1.78k
                        ch->cert_compression_algos.list[ch->cert_compression_algos.count++] = id;
3803
1.78k
                } while (src != end);
3804
1.78k
            });
3805
1.78k
            break;
3806
1.78k
        case PTLS_EXTENSION_TYPE_SUPPORTED_GROUPS:
3807
1.78k
            ch->negotiated_groups = ptls_iovec_init(src, end - src);
3808
1.78k
            break;
3809
1.78k
        case PTLS_EXTENSION_TYPE_SIGNATURE_ALGORITHMS:
3810
1.78k
            if ((ret = decode_signature_algorithms(&ch->signature_algorithms, &src, end)) != 0)
3811
1.78k
                goto Exit;
3812
1.78k
            break;
3813
1.78k
        case PTLS_EXTENSION_TYPE_KEY_SHARE:
3814
1.78k
            ch->key_shares = ptls_iovec_init(src, end - src);
3815
1.78k
            break;
3816
1.78k
        case PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS:
3817
1.78k
            ptls_decode_block(src, end, 1, {
3818
1.78k
                size_t selected_index = PTLS_ELEMENTSOF(supported_versions);
3819
1.78k
                do {
3820
1.78k
                    size_t i;
3821
1.78k
                    uint16_t v;
3822
1.78k
                    if ((ret = ptls_decode16(&v, &src, end)) != 0)
3823
1.78k
                        goto Exit;
3824
1.78k
                    for (i = 0; i != selected_index; ++i) {
3825
1.78k
                        if (supported_versions[i] == v) {
3826
1.78k
                            selected_index = i;
3827
1.78k
                            break;
3828
1.78k
                        }
3829
1.78k
                    }
3830
1.78k
                } while (src != end);
3831
1.78k
                if (selected_index != PTLS_ELEMENTSOF(supported_versions))
3832
1.78k
                    ch->selected_version = supported_versions[selected_index];
3833
1.78k
            });
3834
1.78k
            break;
3835
1.78k
        case PTLS_EXTENSION_TYPE_COOKIE:
3836
1.78k
            if (properties == NULL || properties->server.cookie.key == NULL) {
3837
1.78k
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
3838
1.78k
                goto Exit;
3839
1.78k
            }
3840
1.78k
            ch->cookie.all = ptls_iovec_init(src, end - src);
3841
1.78k
            ptls_decode_block(src, end, 2, {
3842
1.78k
                ch->cookie.tbs.base = (void *)src;
3843
1.78k
                ptls_decode_open_block(src, end, 2, {
3844
1.78k
                    ptls_decode_open_block(src, end, 1, {
3845
1.78k
                        ch->cookie.ch1_hash = ptls_iovec_init(src, end - src);
3846
1.78k
                        src = end;
3847
1.78k
                    });
3848
1.78k
                    uint8_t sent_key_share;
3849
1.78k
                    if ((ret = ptls_decode8(&sent_key_share, &src, end)) != 0)
3850
1.78k
                        goto Exit;
3851
1.78k
                    switch (sent_key_share) {
3852
1.78k
                    case 0:
3853
1.78k
                        assert(!ch->cookie.sent_key_share);
3854
1.78k
                        break;
3855
1.78k
                    case 1:
3856
1.78k
                        ch->cookie.sent_key_share = 1;
3857
1.78k
                        break;
3858
1.78k
                    default:
3859
1.78k
                        ret = PTLS_ALERT_DECODE_ERROR;
3860
1.78k
                        goto Exit;
3861
1.78k
                    }
3862
1.78k
                });
3863
1.78k
                ch->cookie.tbs.len = src - ch->cookie.tbs.base;
3864
1.78k
                ptls_decode_block(src, end, 1, {
3865
1.78k
                    ch->cookie.signature = ptls_iovec_init(src, end - src);
3866
1.78k
                    src = end;
3867
1.78k
                });
3868
1.78k
            });
3869
1.78k
            break;
3870
1.78k
        case PTLS_EXTENSION_TYPE_PRE_SHARED_KEY: {
3871
1.78k
            size_t num_identities = 0;
3872
1.78k
            ptls_decode_open_block(src, end, 2, {
3873
1.78k
                do {
3874
1.78k
                    ptls_client_hello_psk_identity_t psk = {{NULL}};
3875
1.78k
                    ptls_decode_open_block(src, end, 2, {
3876
1.78k
                        if (end - src < 1) {
3877
1.78k
                            ret = PTLS_ALERT_DECODE_ERROR;
3878
1.78k
                            goto Exit;
3879
1.78k
                        }
3880
1.78k
                        psk.identity = ptls_iovec_init(src, end - src);
3881
1.78k
                        src = end;
3882
1.78k
                    });
3883
1.78k
                    if ((ret = ptls_decode32(&psk.obfuscated_ticket_age, &src, end)) != 0)
3884
1.78k
                        goto Exit;
3885
1.78k
                    if (ch->psk.identities.count < PTLS_ELEMENTSOF(ch->psk.identities.list))
3886
1.78k
                        ch->psk.identities.list[ch->psk.identities.count++] = psk;
3887
1.78k
                    ++num_identities;
3888
1.78k
                } while (src != end);
3889
1.78k
            });
3890
1.78k
            ch->psk.hash_end = src;
3891
1.78k
            ptls_decode_block(src, end, 2, {
3892
1.78k
                size_t num_binders = 0;
3893
1.78k
                do {
3894
1.78k
                    ptls_decode_open_block(src, end, 1, {
3895
1.78k
                        if (num_binders < ch->psk.identities.count)
3896
1.78k
                            ch->psk.identities.list[num_binders].binder = ptls_iovec_init(src, end - src);
3897
1.78k
                        src = end;
3898
1.78k
                    });
3899
1.78k
                    ++num_binders;
3900
1.78k
                } while (src != end);
3901
1.78k
                if (num_identities != num_binders) {
3902
1.78k
                    ret = PTLS_ALERT_ILLEGAL_PARAMETER;
3903
1.78k
                    goto Exit;
3904
1.78k
                }
3905
1.78k
            });
3906
1.78k
            ch->psk.is_last_extension = 1;
3907
1.78k
        } break;
3908
1.78k
        case PTLS_EXTENSION_TYPE_PSK_KEY_EXCHANGE_MODES:
3909
1.78k
            ptls_decode_block(src, end, 1, {
3910
1.78k
                do {
3911
1.78k
                    uint8_t mode;
3912
1.78k
                    if ((ret = ptls_decode8(&mode, &src, end)) != 0)
3913
1.78k
                        goto Exit;
3914
1.78k
                    if (mode < sizeof(ch->psk.ke_modes) * 8)
3915
1.78k
                        ch->psk.ke_modes |= 1u << mode;
3916
1.78k
                } while (src != end);
3917
1.78k
            });
3918
1.78k
            break;
3919
1.78k
        case PTLS_EXTENSION_TYPE_EARLY_DATA:
3920
1.78k
            ch->psk.early_data_indication = 1;
3921
1.78k
            break;
3922
1.78k
        case PTLS_EXTENSION_TYPE_STATUS_REQUEST:
3923
1.78k
            ch->status_request = 1;
3924
1.78k
            break;
3925
1.78k
        case PTLS_EXTENSION_TYPE_TICKET_REQUEST:
3926
1.78k
            if (end - src != 2) {
3927
1.78k
                ret = PTLS_ALERT_DECODE_ERROR;
3928
1.78k
                goto Exit;
3929
1.78k
            }
3930
1.78k
            ch->ticket_request.new_session_count = *src++;
3931
1.78k
            ch->ticket_request.resumption_count = *src++;
3932
1.78k
            break;
3933
1.78k
        case PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO:
3934
1.78k
            if ((ret = ptls_decode8(&ch->ech.type, &src, end)) != 0)
3935
1.78k
                goto Exit;
3936
1.78k
            switch (ch->ech.type) {
3937
1.78k
            case PTLS_ECH_CLIENT_HELLO_TYPE_OUTER:
3938
1.78k
                if ((ret = ptls_decode16(&ch->ech.cipher_suite.kdf, &src, end)) != 0 ||
3939
1.78k
                    (ret = ptls_decode16(&ch->ech.cipher_suite.aead, &src, end)) != 0)
3940
1.78k
                    goto Exit;
3941
1.78k
                if ((ret = ptls_decode8(&ch->ech.config_id, &src, end)) != 0)
3942
1.78k
                    goto Exit;
3943
1.78k
                ptls_decode_open_block(src, end, 2, {
3944
1.78k
                    ch->ech.enc = ptls_iovec_init(src, end - src);
3945
1.78k
                    src = end;
3946
1.78k
                });
3947
1.78k
                ptls_decode_open_block(src, end, 2, {
3948
1.78k
                    if (src == end) {
3949
1.78k
                        ret = PTLS_ALERT_DECODE_ERROR;
3950
1.78k
                        goto Exit;
3951
1.78k
                    }
3952
1.78k
                    ch->ech.payload = ptls_iovec_init(src, end - src);
3953
1.78k
                    src = end;
3954
1.78k
                });
3955
1.78k
                break;
3956
1.78k
            case PTLS_ECH_CLIENT_HELLO_TYPE_INNER:
3957
1.78k
                if (src != end) {
3958
1.78k
                    ret = PTLS_ALERT_DECODE_ERROR;
3959
1.78k
                    goto Exit;
3960
1.78k
                }
3961
1.78k
                ch->ech.payload = ptls_iovec_init("", 0); /* non-zero base indicates that the extension was received */
3962
1.78k
                break;
3963
1.78k
            default:
3964
1.78k
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
3965
1.78k
                goto Exit;
3966
1.78k
            }
3967
1.78k
            src = end;
3968
1.78k
            break;
3969
1.78k
        default:
3970
1.78k
            if (tls_cbarg != NULL && should_collect_unknown_extension(tls_cbarg, properties, exttype)) {
3971
1.78k
                if ((ret = collect_unknown_extension(tls_cbarg, exttype, src, end, ch->unknown_extensions)) != 0)
3972
1.78k
                    goto Exit;
3973
1.78k
            }
3974
1.78k
            break;
3975
1.78k
        }
3976
1.78k
        src = end;
3977
1.78k
    });
3978
3979
835
    ret = 0;
3980
1.92k
Exit:
3981
1.92k
    return ret;
3982
835
}
3983
3984
static int rebuild_ch_inner_extensions(ptls_buffer_t *buf, const uint8_t **src, const uint8_t *const end, const uint8_t *outer_ext,
3985
                                       const uint8_t *outer_ext_end)
3986
0
{
3987
0
    int ret;
3988
3989
0
    ptls_buffer_push_block(buf, 2, {
3990
0
        ptls_decode_open_block(*src, end, 2, {
3991
0
            while (*src != end) {
3992
0
                uint16_t exttype;
3993
0
                if ((ret = ptls_decode16(&exttype, src, end)) != 0)
3994
0
                    goto Exit;
3995
0
                ptls_decode_open_block(*src, end, 2, {
3996
0
                    if (exttype == PTLS_EXTENSION_TYPE_ECH_OUTER_EXTENSIONS) {
3997
0
                        ptls_decode_open_block(*src, end, 1, {
3998
0
                            do {
3999
0
                                uint16_t reftype;
4000
0
                                uint16_t outertype;
4001
0
                                uint16_t outersize;
4002
0
                                if ((ret = ptls_decode16(&reftype, src, end)) != 0)
4003
0
                                    goto Exit;
4004
0
                                if (reftype == PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO) {
4005
0
                                    ret = PTLS_ALERT_ILLEGAL_PARAMETER;
4006
0
                                    goto Exit;
4007
0
                                }
4008
0
                                while (1) {
4009
0
                                    if (ptls_decode16(&outertype, &outer_ext, outer_ext_end) != 0 ||
4010
0
                                        ptls_decode16(&outersize, &outer_ext, outer_ext_end) != 0) {
4011
0
                                        ret = PTLS_ALERT_ILLEGAL_PARAMETER;
4012
0
                                        goto Exit;
4013
0
                                    }
4014
0
                                    assert(outer_ext_end - outer_ext >= outersize);
4015
0
                                    if (outertype == reftype)
4016
0
                                        break;
4017
0
                                    outer_ext += outersize;
4018
0
                                }
4019
0
                                buffer_push_extension(buf, reftype, {
4020
0
                                    ptls_buffer_pushv(buf, outer_ext, outersize);
4021
0
                                    outer_ext += outersize;
4022
0
                                });
4023
0
                            } while (*src != end);
4024
0
                        });
4025
0
                    } else {
4026
0
                        buffer_push_extension(buf, exttype, {
4027
0
                            ptls_buffer_pushv(buf, *src, end - *src);
4028
0
                            *src = end;
4029
0
                        });
4030
0
                    }
4031
0
                });
4032
0
            }
4033
0
        });
4034
0
    });
4035
4036
0
Exit:
4037
0
    return ret;
4038
0
}
4039
4040
static int rebuild_ch_inner(ptls_buffer_t *buf, const uint8_t *src, const uint8_t *const end,
4041
                            struct st_ptls_client_hello_t *outer_ch, const uint8_t *outer_ext, const uint8_t *outer_ext_end)
4042
0
{
4043
0
#define COPY_BLOCK(capacity)                                                                                                       \
4044
0
    do {                                                                                                                           \
4045
0
        ptls_decode_open_block(src, end, (capacity), {                                                                             \
4046
0
            ptls_buffer_push_block(buf, (capacity), { ptls_buffer_pushv(buf, src, end - src); });                                  \
4047
0
            src = end;                                                                                                             \
4048
0
        });                                                                                                                        \
4049
0
    } while (0)
4050
4051
0
    int ret;
4052
4053
0
    ptls_buffer_push_message_body(buf, NULL, PTLS_HANDSHAKE_TYPE_CLIENT_HELLO, {
4054
0
        { /* legacy_version */
4055
0
            uint16_t legacy_version;
4056
0
            if ((ret = ptls_decode16(&legacy_version, &src, end)) != 0)
4057
0
                goto Exit;
4058
0
            ptls_buffer_push16(buf, legacy_version);
4059
0
        }
4060
4061
        /* hello random */
4062
0
        if (end - src < PTLS_HELLO_RANDOM_SIZE) {
4063
0
            ret = PTLS_ALERT_DECODE_ERROR;
4064
0
            goto Exit;
4065
0
        }
4066
0
        ptls_buffer_pushv(buf, src, PTLS_HELLO_RANDOM_SIZE);
4067
0
        src += PTLS_HELLO_RANDOM_SIZE;
4068
4069
0
        ptls_decode_open_block(src, end, 1, {
4070
0
            if (src != end) {
4071
0
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
4072
0
                goto Exit;
4073
0
            }
4074
0
        });
4075
0
        ptls_buffer_push_block(buf, 1,
4076
0
                               { ptls_buffer_pushv(buf, outer_ch->legacy_session_id.base, outer_ch->legacy_session_id.len); });
4077
4078
        /* cipher-suites and legacy-compression-methods */
4079
0
        COPY_BLOCK(2);
4080
0
        COPY_BLOCK(1);
4081
4082
        /* extensions */
4083
0
        if ((ret = rebuild_ch_inner_extensions(buf, &src, end, outer_ext, outer_ext_end)) != 0)
4084
0
            goto Exit;
4085
0
    });
4086
4087
    /* padding must be all zero */
4088
0
    for (; src != end; ++src) {
4089
0
        if (*src != '\0') {
4090
0
            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
4091
0
            goto Exit;
4092
0
        }
4093
0
    }
4094
4095
0
Exit:
4096
0
    return ret;
4097
4098
0
#undef COPY_BLOCK
4099
0
}
4100
4101
/* Wrapper function for invoking the on_client_hello callback, taking an exhaustive list of parameters as arguments. The intention
4102
 * is to not miss setting them as we add new parameters to the struct. */
4103
static inline int call_on_client_hello_cb(ptls_t *tls, ptls_iovec_t server_name, ptls_iovec_t raw_message,
4104
                                          ptls_iovec_t cipher_suites, ptls_iovec_t *alpns, size_t num_alpns,
4105
                                          const uint16_t *sig_algos, size_t num_sig_algos, const uint16_t *cert_comp_algos,
4106
                                          size_t num_cert_comp_algos, const uint8_t *server_cert_types,
4107
                                          size_t num_server_cert_types, const ptls_client_hello_psk_identity_t *psk_identities,
4108
                                          size_t num_psk_identities, int incompatible_version)
4109
772
{
4110
772
    if (tls->ctx->on_client_hello == NULL)
4111
772
        return 0;
4112
4113
0
    ptls_on_client_hello_parameters_t params = {server_name,
4114
0
                                                raw_message,
4115
0
                                                cipher_suites,
4116
0
                                                {alpns, num_alpns},
4117
0
                                                {sig_algos, num_sig_algos},
4118
0
                                                {cert_comp_algos, num_cert_comp_algos},
4119
0
                                                {server_cert_types, num_server_cert_types},
4120
0
                                                {psk_identities, num_psk_identities},
4121
0
                                                incompatible_version};
4122
0
    return tls->ctx->on_client_hello->cb(tls->ctx->on_client_hello, tls, &params);
4123
772
}
4124
4125
static int check_client_hello_constraints(ptls_context_t *ctx, struct st_ptls_client_hello_t *ch, const void *prev_random,
4126
                                          int ech_is_inner_ch, ptls_iovec_t raw_message, ptls_t *tls_cbarg)
4127
846
{
4128
846
    int is_second_flight = prev_random != 0;
4129
4130
    /* The following check is necessary so that we would be able to track the connection in SSLKEYLOGFILE, even though it might not
4131
     * be for the safety of the protocol. */
4132
846
    if (is_second_flight && !ptls_mem_equal(ch->random_bytes, prev_random, PTLS_HELLO_RANDOM_SIZE))
4133
14
        return PTLS_ALERT_HANDSHAKE_FAILURE;
4134
4135
    /* bail out if CH cannot be handled as TLS 1.3 */
4136
832
    if (!is_supported_version(ch->selected_version)) {
4137
        /* ECH: server MUST abort with an "illegal_parameter" alert if the client offers TLS 1.2 or below (draft-15 7.1) */
4138
104
        if (ech_is_inner_ch)
4139
0
            return PTLS_ALERT_ILLEGAL_PARAMETER;
4140
        /* fail with PROTOCOL_VERSION alert, after providing the applications the raw CH and SNI to help them fallback */
4141
104
        if (!is_second_flight) {
4142
103
            int ret;
4143
103
            if ((ret = call_on_client_hello_cb(tls_cbarg, ch->server_name, raw_message, ch->cipher_suites, ch->alpn.list,
4144
103
                                               ch->alpn.count, NULL, 0, NULL, 0, NULL, 0, NULL, 0, 1)) != 0)
4145
0
                return ret;
4146
103
        }
4147
104
        return PTLS_ALERT_PROTOCOL_VERSION;
4148
104
    }
4149
4150
    /* Check TLS 1.3-specific constraints. Hereafter, we might exit without calling on_client_hello. That's fine because this CH is
4151
     * ought to be rejected. */
4152
728
    if (ch->legacy_version <= 0x0300) {
4153
        /* RFC 8446 Appendix D.5: any endpoint receiving a Hello message with legacy_version set to 0x0300 MUST abort the handshake
4154
         * with a "protocol_version" alert. */
4155
0
        return PTLS_ALERT_PROTOCOL_VERSION;
4156
0
    }
4157
728
    if (!(ch->compression_methods.count == 1 && ch->compression_methods.ids[0] == 0))
4158
24
        return PTLS_ALERT_ILLEGAL_PARAMETER;
4159
    /* pre-shared key */
4160
704
    if (ch->psk.hash_end != NULL) {
4161
        /* PSK must be the last extension */
4162
186
        if (!ch->psk.is_last_extension)
4163
1
            return PTLS_ALERT_ILLEGAL_PARAMETER;
4164
518
    } else {
4165
518
        if (ch->psk.early_data_indication)
4166
2
            return PTLS_ALERT_ILLEGAL_PARAMETER;
4167
518
    }
4168
4169
701
    if (ech_is_inner_ch && ch->ech.payload.base == NULL)
4170
0
        return PTLS_ALERT_ILLEGAL_PARAMETER;
4171
701
    if (ch->ech.payload.base != NULL &&
4172
17
        ch->ech.type != (ech_is_inner_ch ? PTLS_ECH_CLIENT_HELLO_TYPE_INNER : PTLS_ECH_CLIENT_HELLO_TYPE_OUTER))
4173
3
        return PTLS_ALERT_ILLEGAL_PARAMETER;
4174
4175
698
    return 0;
4176
701
}
4177
4178
static int vec_is_string(ptls_iovec_t x, const char *y)
4179
0
{
4180
0
    return strncmp((const char *)x.base, y, x.len) == 0 && y[x.len] == '\0';
4181
0
}
4182
4183
/**
4184
 * Looks for a PSK identity that can be used, and if found, updates the handshake state and returns the necessary variables. If
4185
 * `ptls_context_t::pre_shared_key` is set, only tries handshake using those keys provided. Otherwise, tries resumption.
4186
 */
4187
static int try_psk_handshake(ptls_t *tls, size_t *psk_index, int *accept_early_data, struct st_ptls_client_hello_t *ch,
4188
                             ptls_iovec_t ch_trunc, int is_second_flight)
4189
105
{
4190
105
    ptls_buffer_t decbuf;
4191
105
    ptls_iovec_t secret, ticket_ctx, ticket_negotiated_protocol;
4192
105
    uint64_t issue_at, now = tls->ctx->get_time->cb(tls->ctx->get_time);
4193
105
    uint32_t age_add;
4194
105
    uint16_t ticket_key_exchange_id, ticket_csid;
4195
105
    uint8_t binder_key[PTLS_MAX_DIGEST_SIZE];
4196
105
    int ret;
4197
4198
105
    ptls_buffer_init(&decbuf, "", 0);
4199
4200
247
    for (*psk_index = 0; *psk_index < ch->psk.identities.count; ++*psk_index) {
4201
144
        ptls_client_hello_psk_identity_t *identity = ch->psk.identities.list + *psk_index;
4202
4203
        /* negotiate using fixed pre-shared key */
4204
144
        if (tls->ctx->pre_shared_key.identity.base != NULL) {
4205
0
            if (identity->identity.len == tls->ctx->pre_shared_key.identity.len &&
4206
0
                memcmp(identity->identity.base, tls->ctx->pre_shared_key.identity.base, identity->identity.len) == 0) {
4207
0
                *accept_early_data = ch->psk.early_data_indication && *psk_index == 0;
4208
0
                tls->key_share = NULL;
4209
0
                secret = tls->ctx->pre_shared_key.secret;
4210
0
                goto Found;
4211
0
            }
4212
0
            continue;
4213
0
        }
4214
4215
        /* decrypt ticket and decode */
4216
144
        if (tls->ctx->encrypt_ticket == NULL || tls->ctx->key_exchanges == NULL)
4217
0
            continue;
4218
144
        int can_accept_early_data = *psk_index == 0;
4219
144
        decbuf.off = 0;
4220
144
        switch (tls->ctx->encrypt_ticket->cb(tls->ctx->encrypt_ticket, tls, 0, &decbuf, identity->identity)) {
4221
144
        case 0: /* decrypted */
4222
144
            break;
4223
0
        case PTLS_ERROR_REJECT_EARLY_DATA: /* decrypted, but early data is rejected */
4224
0
            can_accept_early_data = 0;
4225
0
            break;
4226
0
        default: /* decryption failure */
4227
0
            continue;
4228
144
        }
4229
144
        if (decode_session_identifier(&issue_at, &secret, &age_add, &ticket_ctx, &ticket_key_exchange_id, &ticket_csid,
4230
144
                                      &ticket_negotiated_protocol, decbuf.base, decbuf.base + decbuf.off) != 0)
4231
0
            continue;
4232
        /* check age */
4233
144
        if (now < issue_at)
4234
0
            continue;
4235
144
        if (now - issue_at > (uint64_t)tls->ctx->ticket_lifetime * 1000)
4236
0
            continue;
4237
144
        *accept_early_data = 0;
4238
144
        if (ch->psk.early_data_indication && can_accept_early_data) {
4239
            /* accept early-data if abs(diff) between the reported age and the actual age is within += 10 seconds */
4240
95
            int64_t delta = (now - issue_at) - (identity->obfuscated_ticket_age - age_add);
4241
95
            if (delta < 0)
4242
0
                delta = -delta;
4243
95
            if (tls->ctx->max_early_data_size != 0 && delta <= PTLS_EARLY_DATA_MAX_DELAY)
4244
0
                *accept_early_data = 1;
4245
95
        }
4246
        /* check ticket context */
4247
144
        if (tls->ctx->ticket_context.is_set) {
4248
0
            if (!(ticket_ctx.len == sizeof(tls->ctx->ticket_context.bytes) &&
4249
0
                  memcmp(ticket_ctx.base, tls->ctx->ticket_context.bytes, ticket_ctx.len) == 0))
4250
0
                continue;
4251
144
        } else {
4252
            /* check server-name */
4253
144
            if (ticket_ctx.len != 0) {
4254
0
                if (tls->server_name == NULL)
4255
0
                    continue;
4256
0
                if (!vec_is_string(ticket_ctx, tls->server_name))
4257
0
                    continue;
4258
144
            } else {
4259
144
                if (tls->server_name != NULL)
4260
0
                    continue;
4261
144
            }
4262
144
        }
4263
144
        { /* check key-exchange */
4264
144
            ptls_key_exchange_algorithm_t **a;
4265
144
            for (a = tls->ctx->key_exchanges; *a != NULL && (*a)->id != ticket_key_exchange_id; ++a)
4266
0
                ;
4267
144
            if (*a == NULL)
4268
0
                continue;
4269
144
            tls->key_share = *a;
4270
144
        }
4271
        /* check cipher-suite */
4272
144
        if (ticket_csid != tls->cipher_suite->id)
4273
70
            continue;
4274
        /* check negotiated-protocol */
4275
74
        if (ticket_negotiated_protocol.len != 0) {
4276
0
            if (tls->negotiated_protocol == NULL)
4277
0
                continue;
4278
0
            if (!vec_is_string(ticket_negotiated_protocol, tls->negotiated_protocol))
4279
0
                continue;
4280
0
        }
4281
        /* check the length of the decrypted psk and the PSK binder */
4282
74
        if (secret.len != tls->key_schedule->hashes[0].algo->digest_size)
4283
0
            continue;
4284
74
        if (ch->psk.identities.list[*psk_index].binder.len != tls->key_schedule->hashes[0].algo->digest_size)
4285
72
            continue;
4286
4287
        /* found */
4288
2
        goto Found;
4289
74
    }
4290
4291
    /* not found */
4292
103
    *psk_index = SIZE_MAX;
4293
103
    *accept_early_data = 0;
4294
103
    tls->key_share = NULL;
4295
103
    ret = 0;
4296
103
    goto Exit;
4297
4298
2
Found:
4299
2
    if (!is_second_flight && (ret = key_schedule_extract(tls->key_schedule, secret)) != 0)
4300
0
        goto Exit;
4301
2
    if ((ret = derive_secret_with_empty_digest(tls->key_schedule, binder_key,
4302
2
                                               tls->ctx->pre_shared_key.secret.base != NULL ? "ext binder" : "res binder")) != 0)
4303
0
        goto Exit;
4304
2
    ptls__key_schedule_update_hash(tls->key_schedule, ch_trunc.base, ch_trunc.len, 0);
4305
2
    if ((ret = calc_verify_data(binder_key /* to conserve space, reuse binder_key for storing verify_data */, tls->key_schedule,
4306
2
                                binder_key)) != 0)
4307
0
        goto Exit;
4308
2
    if (!ptls_mem_equal(ch->psk.identities.list[*psk_index].binder.base, binder_key,
4309
2
                        tls->key_schedule->hashes[0].algo->digest_size)) {
4310
2
        ret = PTLS_ALERT_DECRYPT_ERROR;
4311
2
        goto Exit;
4312
2
    }
4313
0
    ret = 0;
4314
4315
105
Exit:
4316
105
    ptls_buffer_dispose(&decbuf);
4317
105
    ptls_clear_memory(binder_key, sizeof(binder_key));
4318
105
    return ret;
4319
0
}
4320
4321
static int calc_cookie_signature(ptls_t *tls, ptls_handshake_properties_t *properties,
4322
                                 ptls_key_exchange_algorithm_t *negotiated_group, ptls_iovec_t tbs, uint8_t *sig)
4323
0
{
4324
0
    ptls_hash_algorithm_t *algo = tls->ctx->cipher_suites[0]->hash;
4325
0
    ptls_hash_context_t *hctx;
4326
4327
0
    if ((hctx = ptls_hmac_create(algo, properties->server.cookie.key, algo->digest_size)) == NULL)
4328
0
        return PTLS_ERROR_NO_MEMORY;
4329
4330
0
#define UPDATE_BLOCK(p, _len)                                                                                                      \
4331
0
    do {                                                                                                                           \
4332
0
        size_t len = (_len);                                                                                                       \
4333
0
        assert(len < UINT8_MAX);                                                                                                   \
4334
0
        uint8_t len8 = (uint8_t)len;                                                                                               \
4335
0
        hctx->update(hctx, &len8, 1);                                                                                              \
4336
0
        hctx->update(hctx, (p), len);                                                                                              \
4337
0
    } while (0)
4338
0
#define UPDATE16(_v)                                                                                                               \
4339
0
    do {                                                                                                                           \
4340
0
        uint16_t v = (_v);                                                                                                         \
4341
0
        uint8_t b[2] = {v >> 8, v & 0xff};                                                                                         \
4342
0
        hctx->update(hctx, b, 2);                                                                                                  \
4343
0
    } while (0)
4344
4345
0
    UPDATE_BLOCK(tls->client_random, sizeof(tls->client_random));
4346
0
    UPDATE_BLOCK(tls->server_name, tls->server_name != NULL ? strlen(tls->server_name) : 0);
4347
0
    UPDATE16(tls->cipher_suite->id);
4348
0
    UPDATE16(negotiated_group != NULL ? negotiated_group->id : 0);
4349
0
    UPDATE_BLOCK(properties->server.cookie.additional_data.base, properties->server.cookie.additional_data.len);
4350
4351
0
    UPDATE_BLOCK(tbs.base, tbs.len);
4352
4353
0
#undef UPDATE_BLOCK
4354
0
#undef UPDATE16
4355
4356
0
    hctx->final(hctx, sig, PTLS_HASH_FINAL_MODE_FREE);
4357
0
    return 0;
4358
0
}
4359
4360
static int certificate_type_exists(uint8_t *list, size_t count, uint8_t desired_type)
4361
669
{
4362
    /* empty type list means that we default to x509 */
4363
669
    if (desired_type == PTLS_CERTIFICATE_TYPE_X509 && count == 0)
4364
650
        return 1;
4365
56
    for (size_t i = 0; i < count; i++) {
4366
46
        if (list[i] == desired_type)
4367
9
            return 1;
4368
46
    }
4369
10
    return 0;
4370
19
}
4371
4372
static int server_handle_hello(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_iovec_t message,
4373
                               ptls_handshake_properties_t *properties)
4374
1.92k
{
4375
1.92k
#define EMIT_SERVER_HELLO(sched, fill_rand, extensions, post_action)                                                               \
4376
1.92k
    do {                                                                                                                           \
4377
372
        size_t sh_start_off;                                                                                                       \
4378
372
        ptls_push_message(emitter, NULL, PTLS_HANDSHAKE_TYPE_SERVER_HELLO, {                                                       \
4379
372
            sh_start_off = emitter->buf->off - PTLS_HANDSHAKE_HEADER_SIZE;                                                         \
4380
372
            ptls_buffer_push16(emitter->buf, 0x0303 /* legacy version */);                                                         \
4381
372
            if ((ret = ptls_buffer_reserve(emitter->buf, PTLS_HELLO_RANDOM_SIZE)) != 0)                                            \
4382
372
                goto Exit;                                                                                                         \
4383
372
            do {                                                                                                                   \
4384
372
                fill_rand                                                                                                          \
4385
372
            } while (0);                                                                                                           \
4386
372
            emitter->buf->off += PTLS_HELLO_RANDOM_SIZE;                                                                           \
4387
372
            ptls_buffer_push_block(emitter->buf, 1,                                                                                \
4388
372
                                   { ptls_buffer_pushv(emitter->buf, ch->legacy_session_id.base, ch->legacy_session_id.len); });   \
4389
372
            ptls_buffer_push16(emitter->buf, tls->cipher_suite->id);                                                               \
4390
372
            ptls_buffer_push(emitter->buf, 0);                                                                                     \
4391
372
            ptls_buffer_push_block(emitter->buf, 2, {                                                                              \
4392
372
                buffer_push_extension(emitter->buf, PTLS_EXTENSION_TYPE_SUPPORTED_VERSIONS,                                        \
4393
372
                                      { ptls_buffer_push16(emitter->buf, ch->selected_version); });                                \
4394
372
                do {                                                                                                               \
4395
372
                    extensions                                                                                                     \
4396
372
                } while (0);                                                                                                       \
4397
372
            });                                                                                                                    \
4398
372
        });                                                                                                                        \
4399
372
        do {                                                                                                                       \
4400
744
            post_action                                                                                                            \
4401
372
        } while (0);                                                                                                               \
4402
372
        ptls__key_schedule_update_hash((sched), emitter->buf->base + sh_start_off, emitter->buf->off - sh_start_off, 0);           \
4403
372
    } while (0)
4404
4405
1.92k
#define EMIT_HELLO_RETRY_REQUEST(sched, negotiated_group, additional_extensions, post_action)                                      \
4406
1.92k
    EMIT_SERVER_HELLO((sched), { memcpy(emitter->buf->base + emitter->buf->off, hello_retry_random, PTLS_HELLO_RANDOM_SIZE); },    \
4407
150
                      {                                                                                                            \
4408
150
                          ptls_key_exchange_algorithm_t *_negotiated_group = (negotiated_group);                                   \
4409
150
                          if (_negotiated_group != NULL) {                                                                         \
4410
150
                              buffer_push_extension(emitter->buf, PTLS_EXTENSION_TYPE_KEY_SHARE,                                   \
4411
150
                                                    { ptls_buffer_push16(emitter->buf, _negotiated_group->id); });                 \
4412
150
                          }                                                                                                        \
4413
150
                          do {                                                                                                     \
4414
150
                              additional_extensions                                                                                \
4415
150
                          } while (0);                                                                                             \
4416
150
                      },                                                                                                           \
4417
150
                      post_action)
4418
1.92k
    struct st_ptls_client_hello_t *ch;
4419
1.92k
    struct {
4420
1.92k
        ptls_key_exchange_algorithm_t *algorithm;
4421
1.92k
        ptls_iovec_t peer_key;
4422
1.92k
    } key_share = {NULL};
4423
1.92k
    struct {
4424
1.92k
        uint8_t *encoded_ch_inner;
4425
1.92k
        uint8_t *ch_outer_aad;
4426
1.92k
        ptls_buffer_t ch_inner;
4427
1.92k
    } ech = {NULL};
4428
1.92k
    enum { HANDSHAKE_MODE_FULL, HANDSHAKE_MODE_PSK, HANDSHAKE_MODE_PSK_DHE } mode;
4429
1.92k
    size_t psk_index = SIZE_MAX;
4430
1.92k
    ptls_iovec_t pubkey = {0}, ecdh_secret = {0};
4431
1.92k
    int accept_early_data = 0, is_second_flight = tls->state == PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO, ret;
4432
4433
1.92k
    ptls_buffer_init(&ech.ch_inner, "", 0);
4434
4435
1.92k
    if ((ch = malloc(sizeof(*ch))) == NULL) {
4436
0
        ret = PTLS_ERROR_NO_MEMORY;
4437
0
        goto Exit;
4438
0
    }
4439
4440
1.92k
    *ch = (struct st_ptls_client_hello_t){.unknown_extensions = {{UINT16_MAX}}};
4441
4442
    /* decode ClientHello */
4443
1.92k
    if ((ret = decode_client_hello(tls->ctx, ch, message.base + PTLS_HANDSHAKE_HEADER_SIZE, message.base + message.len, properties,
4444
1.92k
                                   tls)) != 0)
4445
1.07k
        goto Exit;
4446
846
    if ((ret = check_client_hello_constraints(tls->ctx, ch, is_second_flight ? tls->client_random : NULL, 0, message, tls)) != 0)
4447
148
        goto Exit;
4448
698
    if (!is_second_flight) {
4449
669
        memcpy(tls->client_random, ch->random_bytes, PTLS_HELLO_RANDOM_SIZE);
4450
669
        log_client_random(tls);
4451
669
    } else {
4452
        /* consistency check for ECH extension in response to HRR */
4453
29
        if (tls->ech.aead != NULL) {
4454
0
            if (ch->ech.payload.base == NULL) {
4455
0
                ret = PTLS_ALERT_MISSING_EXTENSION;
4456
0
                goto Exit;
4457
0
            }
4458
0
            if (!(ch->ech.config_id == tls->ech.config_id && ch->ech.cipher_suite.kdf == tls->ech.cipher->id.kdf &&
4459
0
                  ch->ech.cipher_suite.aead == tls->ech.cipher->id.aead && ch->ech.enc.len == 0)) {
4460
0
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
4461
0
                goto Exit;
4462
0
            }
4463
0
        }
4464
29
    }
4465
4466
    /* ECH */
4467
698
    if (ch->ech.payload.base != NULL) {
4468
14
        if (ch->ech.type != PTLS_ECH_CLIENT_HELLO_TYPE_OUTER) {
4469
0
            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
4470
0
            goto Exit;
4471
0
        }
4472
14
        if (!is_second_flight)
4473
12
            tls->ech.state = PTLS_ECH_STATE_OFFERED;
4474
        /* obtain AEAD context for opening inner CH */
4475
14
        if (!is_second_flight && ch->ech.payload.base != NULL && tls->ctx->ech.server.create_opener != NULL) {
4476
0
            if ((tls->ech.aead = tls->ctx->ech.server.create_opener->cb(
4477
0
                     tls->ctx->ech.server.create_opener, &tls->ech.kem, &tls->ech.cipher, tls, ch->ech.config_id,
4478
0
                     ch->ech.cipher_suite, ch->ech.enc, ptls_iovec_init(ech_info_prefix, sizeof(ech_info_prefix)))) != NULL)
4479
0
                tls->ech.config_id = ch->ech.config_id;
4480
0
        }
4481
14
        if (!is_second_flight) {
4482
12
            PTLS_PROBE(ECH_SELECTION, tls, tls->ech.aead != NULL);
4483
12
            PTLS_LOG_CONN(ech_selection, tls, { PTLS_LOG_ELEMENT_BOOL(is_ech, tls->ech.aead != NULL); });
4484
12
        }
4485
14
        if (tls->ech.aead != NULL) {
4486
            /* now that AEAD context is available, create AAD and decrypt inner CH */
4487
0
            if (ch->ech.payload.len <= tls->ech.aead->algo->tag_size) {
4488
0
                ret = PTLS_ALERT_DECODE_ERROR;
4489
0
                goto Exit;
4490
0
            }
4491
0
            if ((ech.encoded_ch_inner = malloc(ch->ech.payload.len - tls->ech.aead->algo->tag_size)) == NULL ||
4492
0
                (ech.ch_outer_aad = malloc(message.len - PTLS_HANDSHAKE_HEADER_SIZE)) == NULL) {
4493
0
                ret = PTLS_ERROR_NO_MEMORY;
4494
0
                goto Exit;
4495
0
            }
4496
0
            memcpy(ech.ch_outer_aad, message.base + PTLS_HANDSHAKE_HEADER_SIZE, message.len - PTLS_HANDSHAKE_HEADER_SIZE);
4497
0
            memset(ech.ch_outer_aad + (ch->ech.payload.base - (message.base + PTLS_HANDSHAKE_HEADER_SIZE)), 0, ch->ech.payload.len);
4498
0
            if (ptls_aead_decrypt(tls->ech.aead, ech.encoded_ch_inner, ch->ech.payload.base, ch->ech.payload.len, is_second_flight,
4499
0
                                  ech.ch_outer_aad, message.len - PTLS_HANDSHAKE_HEADER_SIZE) != SIZE_MAX) {
4500
0
                tls->ech.state = PTLS_ECH_STATE_ACCEPTED;
4501
                /* successfully decrypted EncodedCHInner, build CHInner */
4502
0
                if ((ret = rebuild_ch_inner(&ech.ch_inner, ech.encoded_ch_inner,
4503
0
                                            ech.encoded_ch_inner + ch->ech.payload.len - tls->ech.aead->algo->tag_size, ch,
4504
0
                                            message.base + PTLS_HANDSHAKE_HEADER_SIZE + ch->first_extension_at,
4505
0
                                            message.base + message.len)) != 0)
4506
0
                    goto Exit;
4507
                /* treat inner ch as the message being received, re-decode it */
4508
0
                message = ptls_iovec_init(ech.ch_inner.base, ech.ch_inner.off);
4509
0
                *ch = (struct st_ptls_client_hello_t){.unknown_extensions = {{UINT16_MAX}}};
4510
0
                if ((ret = decode_client_hello(tls->ctx, ch, ech.ch_inner.base + PTLS_HANDSHAKE_HEADER_SIZE,
4511
0
                                               ech.ch_inner.base + ech.ch_inner.off, properties, tls)) != 0)
4512
0
                    goto Exit;
4513
0
                if ((ret = check_client_hello_constraints(tls->ctx, ch, is_second_flight ? tls->ech.inner_client_random : NULL, 1,
4514
0
                                                          message, tls)) != 0)
4515
0
                    goto Exit;
4516
0
                if (!is_second_flight)
4517
0
                    memcpy(tls->ech.inner_client_random, ch->random_bytes, PTLS_HELLO_RANDOM_SIZE);
4518
0
            } else if (is_second_flight) {
4519
                /* decryption failure of inner CH in 2nd CH is fatal */
4520
0
                ret = PTLS_ALERT_DECRYPT_ERROR;
4521
0
                goto Exit;
4522
0
            } else {
4523
                /* decryption failure of 1st CH indicates key mismatch; dispose of AEAD context to indicate adoption of outerCH */
4524
0
                ptls_aead_free(tls->ech.aead);
4525
0
                tls->ech.aead = NULL;
4526
0
            }
4527
0
        }
4528
684
    } else if (tls->ech.state != PTLS_ECH_STATE_NONE) {
4529
1
        assert(is_second_flight);
4530
1
        ret = PTLS_ALERT_ILLEGAL_PARAMETER;
4531
1
        goto Exit;
4532
1
    }
4533
4534
697
    if (tls->ctx->require_dhe_on_psk)
4535
0
        ch->psk.ke_modes &= ~(1u << PTLS_PSK_KE_MODE_PSK);
4536
4537
    /* handle client_random, legacy_session_id, SNI, ESNI */
4538
697
    if (!is_second_flight) {
4539
669
        if (ch->legacy_session_id.len != 0)
4540
243
            tls->send_change_cipher_spec = 1;
4541
669
        ptls_iovec_t server_name = {NULL};
4542
669
        if (ch->server_name.base != NULL)
4543
3
            server_name = ch->server_name;
4544
669
        if ((ret = call_on_client_hello_cb(tls, server_name, message, ch->cipher_suites, ch->alpn.list, ch->alpn.count,
4545
669
                                           ch->signature_algorithms.list, ch->signature_algorithms.count,
4546
669
                                           ch->cert_compression_algos.list, ch->cert_compression_algos.count,
4547
669
                                           ch->server_certificate_types.list, ch->server_certificate_types.count,
4548
669
                                           ch->psk.identities.list, ch->psk.identities.count, 0)) != 0)
4549
0
            goto Exit;
4550
669
        if (!certificate_type_exists(ch->server_certificate_types.list, ch->server_certificate_types.count,
4551
669
                                     tls->ctx->use_raw_public_keys ? PTLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY
4552
669
                                                                   : PTLS_CERTIFICATE_TYPE_X509)) {
4553
10
            ret = PTLS_ALERT_UNSUPPORTED_CERTIFICATE;
4554
10
            goto Exit;
4555
10
        }
4556
669
    } else {
4557
28
        if (ch->psk.early_data_indication) {
4558
1
            ret = PTLS_ALERT_DECODE_ERROR;
4559
1
            goto Exit;
4560
1
        }
4561
        /* We compare SNI only when the value is saved by the on_client_hello callback. This should be OK because we are
4562
         * ignoring the value unless the callback saves the server-name. */
4563
27
        if (tls->server_name != NULL) {
4564
0
            size_t l = strlen(tls->server_name);
4565
0
            if (!(ch->server_name.len == l && memcmp(ch->server_name.base, tls->server_name, l) == 0)) {
4566
0
                ret = PTLS_ALERT_HANDSHAKE_FAILURE;
4567
0
                goto Exit;
4568
0
            }
4569
0
        }
4570
27
    }
4571
4572
686
    { /* select (or check) cipher-suite, create key_schedule */
4573
686
        ptls_cipher_suite_t *cs;
4574
686
        if ((ret = select_cipher(&cs, tls->ctx->cipher_suites, ch->cipher_suites.base,
4575
686
                                 ch->cipher_suites.base + ch->cipher_suites.len, tls->ctx->server_cipher_preference,
4576
686
                                 tls->ctx->server_cipher_chacha_priority, tls->ctx->pre_shared_key.hash)) != 0)
4577
32
            goto Exit;
4578
654
        if (!is_second_flight) {
4579
628
            tls->cipher_suite = cs;
4580
628
            if ((tls->key_schedule = key_schedule_new(cs, NULL, 0)) == NULL) {
4581
0
                ret = PTLS_ERROR_NO_MEMORY;
4582
0
                goto Exit;
4583
0
            }
4584
628
        } else {
4585
26
            if (tls->cipher_suite != cs) {
4586
2
                ret = PTLS_ALERT_HANDSHAKE_FAILURE;
4587
2
                goto Exit;
4588
2
            }
4589
26
        }
4590
654
    }
4591
4592
    /* select key_share */
4593
652
    if (key_share.algorithm == NULL && ch->key_shares.base != NULL && tls->ctx->key_exchanges != NULL) {
4594
532
        const uint8_t *src = ch->key_shares.base, *const end = src + ch->key_shares.len;
4595
532
        ptls_decode_block(src, end, 2, {
4596
532
            if ((ret = select_key_share(&key_share.algorithm, &key_share.peer_key, tls->ctx->key_exchanges, &src, end, 0)) != 0)
4597
532
                goto Exit;
4598
532
        });
4599
532
    }
4600
4601
565
    if (!is_second_flight) {
4602
541
        if (ch->cookie.all.len != 0 && key_share.algorithm != NULL) {
4603
4604
0
            { /* use cookie to check the integrity of the handshake, and update the context */
4605
0
                uint8_t sig[PTLS_MAX_DIGEST_SIZE];
4606
0
                size_t sigsize = tls->ctx->cipher_suites[0]->hash->digest_size;
4607
0
                if ((ret = calc_cookie_signature(tls, properties, key_share.algorithm, ch->cookie.tbs, sig)) != 0)
4608
0
                    goto Exit;
4609
0
                if (!(ch->cookie.signature.len == sigsize && ptls_mem_equal(ch->cookie.signature.base, sig, sigsize))) {
4610
0
                    ret = PTLS_ALERT_HANDSHAKE_FAILURE;
4611
0
                    goto Exit;
4612
0
                }
4613
0
            }
4614
            /* integrity check passed; update states */
4615
0
            key_schedule_update_ch1hash_prefix(tls->key_schedule);
4616
0
            ptls__key_schedule_update_hash(tls->key_schedule, ch->cookie.ch1_hash.base, ch->cookie.ch1_hash.len, 0);
4617
0
            key_schedule_extract(tls->key_schedule,
4618
0
                                 tls->ctx->pre_shared_key.secret /* this argument will be a zero-length vector unless external PSK
4619
0
                                                                  is used, and that's fine; we never resume when sending HRR */);
4620
            /* ... reusing sendbuf to rebuild HRR for hash calculation */
4621
0
            size_t hrr_start = emitter->buf->off;
4622
0
            EMIT_HELLO_RETRY_REQUEST(tls->key_schedule, ch->cookie.sent_key_share ? key_share.algorithm : NULL,
4623
0
                                     {
4624
0
                                         buffer_push_extension(emitter->buf, PTLS_EXTENSION_TYPE_COOKIE, {
4625
0
                                             ptls_buffer_pushv(emitter->buf, ch->cookie.all.base, ch->cookie.all.len);
4626
0
                                         });
4627
0
                                     },
4628
0
                                     {});
4629
0
            emitter->buf->off = hrr_start;
4630
0
            is_second_flight = 1;
4631
4632
541
        } else if (ch->key_shares.base != NULL && tls->ctx->key_exchanges != NULL &&
4633
423
                   (key_share.algorithm == NULL || (properties != NULL && properties->server.enforce_retry))) {
4634
            /* send HelloRetryRequest, when trying to negotiate the key share but enforced by config or upon key-share mismatch */
4635
215
            if (ch->negotiated_groups.base == NULL) {
4636
6
                ret = PTLS_ALERT_MISSING_EXTENSION;
4637
6
                goto Exit;
4638
6
            }
4639
209
            ptls_key_exchange_algorithm_t *negotiated_group;
4640
209
            if ((ret = select_negotiated_group(&negotiated_group, tls->ctx->key_exchanges, ch->negotiated_groups.base,
4641
209
                                               ch->negotiated_groups.base + ch->negotiated_groups.len)) != 0)
4642
59
                goto Exit;
4643
150
            ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
4644
150
            assert(tls->key_schedule->generation == 0);
4645
4646
            /* Either send a stateless retry (w. cookies) or a stateful one. When sending the latter, run the state machine. At the
4647
             * moment, stateless retry is disabled when ECH is used (do we need to support it?). */
4648
150
            int retry_uses_cookie =
4649
150
                properties != NULL && properties->server.retry_uses_cookie && !ptls_is_ech_handshake(tls, NULL, NULL, NULL);
4650
150
            if (!retry_uses_cookie) {
4651
150
                key_schedule_transform_post_ch1hash(tls->key_schedule);
4652
150
                key_schedule_extract(tls->key_schedule, tls->ctx->pre_shared_key.secret /* see comment above */);
4653
150
            }
4654
150
            size_t ech_confirm_off = 0;
4655
150
            EMIT_HELLO_RETRY_REQUEST(
4656
150
                tls->key_schedule, key_share.algorithm != NULL ? NULL : negotiated_group,
4657
150
                {
4658
150
                    ptls_buffer_t *sendbuf = emitter->buf;
4659
150
                    if (ptls_is_ech_handshake(tls, NULL, NULL, NULL)) {
4660
150
                        buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO, {
4661
150
                            if ((ret = ptls_buffer_reserve(sendbuf, PTLS_ECH_CONFIRM_LENGTH)) != 0)
4662
150
                                goto Exit;
4663
150
                            memset(sendbuf->base + sendbuf->off, 0, PTLS_ECH_CONFIRM_LENGTH);
4664
150
                            ech_confirm_off = sendbuf->off;
4665
150
                            sendbuf->off += PTLS_ECH_CONFIRM_LENGTH;
4666
150
                        });
4667
150
                    }
4668
150
                    if (retry_uses_cookie) {
4669
150
                        buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_COOKIE, {
4670
150
                            ptls_buffer_push_block(sendbuf, 2, {
4671
                                /* push to-be-signed data */
4672
150
                                size_t tbs_start = sendbuf->off;
4673
150
                                ptls_buffer_push_block(sendbuf, 2, {
4674
                                    /* first block of the cookie data is the hash(ch1) */
4675
150
                                    ptls_buffer_push_block(sendbuf, 1, {
4676
150
                                        size_t sz = tls->cipher_suite->hash->digest_size;
4677
150
                                        if ((ret = ptls_buffer_reserve(sendbuf, sz)) != 0)
4678
150
                                            goto Exit;
4679
150
                                        key_schedule_extract_ch1hash(tls->key_schedule, sendbuf->base + sendbuf->off);
4680
150
                                        sendbuf->off += sz;
4681
150
                                    });
4682
                                    /* second is if we have sent key_share extension */
4683
150
                                    ptls_buffer_push(sendbuf, key_share.algorithm == NULL);
4684
                                    /* we can add more data here */
4685
150
                                });
4686
150
                                size_t tbs_len = sendbuf->off - tbs_start;
4687
                                /* push the signature */
4688
150
                                ptls_buffer_push_block(sendbuf, 1, {
4689
150
                                    size_t sz = tls->ctx->cipher_suites[0]->hash->digest_size;
4690
150
                                    if ((ret = ptls_buffer_reserve(sendbuf, sz)) != 0)
4691
150
                                        goto Exit;
4692
150
                                    if ((ret = calc_cookie_signature(tls, properties, negotiated_group,
4693
150
                                                                     ptls_iovec_init(sendbuf->base + tbs_start, tbs_len),
4694
150
                                                                     sendbuf->base + sendbuf->off)) != 0)
4695
150
                                        goto Exit;
4696
150
                                    sendbuf->off += sz;
4697
150
                                });
4698
150
                            });
4699
150
                        });
4700
150
                    }
4701
150
                },
4702
150
                {
4703
150
                    if (ech_confirm_off != 0 &&
4704
150
                        (ret = ech_calc_confirmation(
4705
150
                             tls->key_schedule, emitter->buf->base + ech_confirm_off, tls->ech.inner_client_random,
4706
150
                             ECH_CONFIRMATION_HRR,
4707
150
                             ptls_iovec_init(emitter->buf->base + sh_start_off, emitter->buf->off - sh_start_off))) != 0)
4708
150
                        goto Exit;
4709
150
                });
4710
150
            if (retry_uses_cookie) {
4711
0
                if ((ret = push_change_cipher_spec(tls, emitter)) != 0)
4712
0
                    goto Exit;
4713
0
                ret = PTLS_ERROR_STATELESS_RETRY;
4714
150
            } else {
4715
150
                tls->state = PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO;
4716
150
                if (ch->psk.early_data_indication)
4717
73
                    tls->server.early_data_skipped_bytes = 0;
4718
150
                ret = PTLS_ERROR_IN_PROGRESS;
4719
150
            }
4720
150
            goto Exit;
4721
150
        }
4722
541
    }
4723
4724
    /* handle unknown extensions */
4725
350
    if ((ret = report_unknown_extensions(tls, properties, ch->unknown_extensions)) != 0)
4726
0
        goto Exit;
4727
4728
    /* try psk handshake */
4729
350
    if (ch->psk.hash_end != 0 && (ch->psk.ke_modes & ((1u << PTLS_PSK_KE_MODE_PSK) | (1u << PTLS_PSK_KE_MODE_PSK_DHE))) != 0 &&
4730
106
        !tls->ctx->require_client_authentication &&
4731
106
        ((!is_second_flight && tls->ctx->encrypt_ticket != NULL) || tls->ctx->pre_shared_key.identity.base != NULL)) {
4732
105
        if ((ret = try_psk_handshake(tls, &psk_index, &accept_early_data, ch,
4733
105
                                     ptls_iovec_init(message.base, ch->psk.hash_end - message.base), is_second_flight)) != 0) {
4734
2
            goto Exit;
4735
2
        }
4736
105
    }
4737
4738
    /* If the server was setup to use an external PSK but failed to agree, abort the handshake. Because external PSK is a form of
4739
     * mutual authentication, it makes sense to abort (at least as the default). */
4740
348
    if (tls->ctx->pre_shared_key.identity.base != NULL && psk_index == SIZE_MAX) {
4741
0
        ret = PTLS_ALERT_UNKNOWN_PSK_IDENTITY;
4742
0
        goto Exit;
4743
0
    }
4744
4745
    /* If client authentication is enabled, we always force a full handshake.
4746
     * TODO: Check for `post_handshake_auth` extension and if that is present, do not force full handshake!
4747
     *       Remove also the check `!require_client_authentication` above.
4748
     *
4749
     * adjust key_schedule, determine handshake mode
4750
     */
4751
348
    if (psk_index == SIZE_MAX || tls->ctx->require_client_authentication) {
4752
348
        ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
4753
348
        if (!is_second_flight) {
4754
324
            assert(tls->key_schedule->generation == 0);
4755
324
            key_schedule_extract(tls->key_schedule, ptls_iovec_init(NULL, 0));
4756
324
        }
4757
348
        mode = HANDSHAKE_MODE_FULL;
4758
348
        if (properties != NULL)
4759
348
            properties->server.selected_psk_binder.len = 0;
4760
348
    } else {
4761
0
        ptls__key_schedule_update_hash(tls->key_schedule, ch->psk.hash_end, message.base + message.len - ch->psk.hash_end, 0);
4762
0
        if ((ch->psk.ke_modes & (1u << PTLS_PSK_KE_MODE_PSK)) != 0) {
4763
0
            mode = HANDSHAKE_MODE_PSK;
4764
0
        } else {
4765
0
            assert((ch->psk.ke_modes & (1u << PTLS_PSK_KE_MODE_PSK_DHE)) != 0);
4766
0
            mode = HANDSHAKE_MODE_PSK_DHE;
4767
0
        }
4768
0
        tls->is_psk_handshake = 1;
4769
0
        if (properties != NULL) {
4770
0
            ptls_iovec_t *selected = &ch->psk.identities.list[psk_index].binder;
4771
0
            memcpy(properties->server.selected_psk_binder.base, selected->base, selected->len);
4772
0
            properties->server.selected_psk_binder.len = selected->len;
4773
0
        }
4774
0
    }
4775
4776
    /* determine number of tickets to send */
4777
348
    if (ch->psk.ke_modes != 0 && tls->ctx->ticket_lifetime != 0) {
4778
220
        if (ch->ticket_request.new_session_count != 0) {
4779
64
            tls->server.num_tickets_to_send =
4780
64
                tls->is_psk_handshake ? ch->ticket_request.resumption_count : ch->ticket_request.new_session_count;
4781
156
        } else {
4782
156
            tls->server.num_tickets_to_send = 1;
4783
156
        }
4784
220
        uint8_t max_tickets = tls->ctx->ticket_requests.server.max_count;
4785
220
        if (max_tickets == 0)
4786
220
            max_tickets = PTLS_DEFAULT_MAX_TICKETS_TO_SERVE;
4787
220
        if (tls->server.num_tickets_to_send > max_tickets)
4788
41
            tls->server.num_tickets_to_send = max_tickets;
4789
220
    } else {
4790
128
        tls->server.num_tickets_to_send = 0;
4791
128
    }
4792
4793
348
    if (accept_early_data && tls->ctx->max_early_data_size != 0 && psk_index == 0) {
4794
0
        if ((tls->pending_handshake_secret = malloc(PTLS_MAX_DIGEST_SIZE)) == NULL) {
4795
0
            ret = PTLS_ERROR_NO_MEMORY;
4796
0
            goto Exit;
4797
0
        }
4798
0
        if ((ret = derive_exporter_secret(tls, 1)) != 0)
4799
0
            goto Exit;
4800
0
        if ((ret = setup_traffic_protection(tls, 0, "c e traffic", 1, 0, 0)) != 0)
4801
0
            goto Exit;
4802
0
    }
4803
4804
    /* run key-exchange, to obtain pubkey and secret */
4805
348
    if (mode != HANDSHAKE_MODE_PSK) {
4806
348
        if (key_share.algorithm == NULL) {
4807
121
            ret = ch->key_shares.base != NULL ? PTLS_ALERT_HANDSHAKE_FAILURE : PTLS_ALERT_MISSING_EXTENSION;
4808
121
            goto Exit;
4809
121
        }
4810
227
        if ((ret = key_share.algorithm->exchange(key_share.algorithm, &pubkey, &ecdh_secret, key_share.peer_key)) != 0) {
4811
5
            assert(pubkey.base == NULL);
4812
5
            assert(ecdh_secret.base == NULL);
4813
5
            goto Exit;
4814
5
        }
4815
222
        tls->key_share = key_share.algorithm;
4816
222
    }
4817
4818
222
    { /* send ServerHello */
4819
222
        size_t ech_confirm_off = 0;
4820
222
        EMIT_SERVER_HELLO(
4821
222
            tls->key_schedule,
4822
222
            {
4823
222
                tls->ctx->random_bytes(emitter->buf->base + emitter->buf->off, PTLS_HELLO_RANDOM_SIZE);
4824
                /* when accepting CHInner, last 8 byte of SH.random is zero for the handshake transcript */
4825
222
                if (ptls_is_ech_handshake(tls, NULL, NULL, NULL)) {
4826
222
                    ech_confirm_off = emitter->buf->off + PTLS_HELLO_RANDOM_SIZE - PTLS_ECH_CONFIRM_LENGTH;
4827
222
                    memset(emitter->buf->base + ech_confirm_off, 0, PTLS_ECH_CONFIRM_LENGTH);
4828
222
                }
4829
222
            },
4830
222
            {
4831
222
                ptls_buffer_t *sendbuf = emitter->buf;
4832
222
                if (mode != HANDSHAKE_MODE_PSK) {
4833
222
                    buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_KEY_SHARE, {
4834
222
                        ptls_buffer_push16(sendbuf, key_share.algorithm->id);
4835
222
                        ptls_buffer_push_block(sendbuf, 2, { ptls_buffer_pushv(sendbuf, pubkey.base, pubkey.len); });
4836
222
                    });
4837
222
                }
4838
222
                if (mode != HANDSHAKE_MODE_FULL) {
4839
222
                    buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_PRE_SHARED_KEY,
4840
222
                                          { ptls_buffer_push16(sendbuf, (uint16_t)psk_index); });
4841
222
                }
4842
222
            },
4843
222
            {
4844
222
                if (ech_confirm_off != 0 &&
4845
222
                    (ret = ech_calc_confirmation(
4846
222
                         tls->key_schedule, emitter->buf->base + ech_confirm_off, tls->ech.inner_client_random,
4847
222
                         ECH_CONFIRMATION_SERVER_HELLO,
4848
222
                         ptls_iovec_init(emitter->buf->base + sh_start_off, emitter->buf->off - sh_start_off))) != 0)
4849
222
                    goto Exit;
4850
222
            });
4851
222
    }
4852
4853
    /* processing of ECH is complete; dispose state */
4854
222
    clear_ech(&tls->ech, 1);
4855
4856
222
    if ((ret = push_change_cipher_spec(tls, emitter)) != 0)
4857
0
        goto Exit;
4858
4859
    /* create protection contexts for the handshake */
4860
222
    assert(tls->key_schedule->generation == 1);
4861
222
    key_schedule_extract(tls->key_schedule, ecdh_secret);
4862
222
    if ((ret = setup_traffic_protection(tls, 1, "s hs traffic", 2, 0, 0)) != 0)
4863
0
        goto Exit;
4864
222
    if (tls->pending_handshake_secret != NULL) {
4865
0
        if ((ret = derive_secret(tls->key_schedule, tls->pending_handshake_secret, "c hs traffic")) != 0)
4866
0
            goto Exit;
4867
0
        if (tls->ctx->update_traffic_key != NULL &&
4868
0
            (ret = tls->ctx->update_traffic_key->cb(tls->ctx->update_traffic_key, tls, 0, 2, tls->pending_handshake_secret)) != 0)
4869
0
            goto Exit;
4870
222
    } else {
4871
222
        if ((ret = setup_traffic_protection(tls, 0, "c hs traffic", 2, 0, 0)) != 0)
4872
0
            goto Exit;
4873
222
        if (ch->psk.early_data_indication)
4874
52
            tls->server.early_data_skipped_bytes = 0;
4875
222
    }
4876
4877
    /* send EncryptedExtensions */
4878
222
    ptls_push_message(emitter, tls->key_schedule, PTLS_HANDSHAKE_TYPE_ENCRYPTED_EXTENSIONS, {
4879
222
        ptls_buffer_t *sendbuf = emitter->buf;
4880
222
        ptls_buffer_push_block(sendbuf, 2, {
4881
222
            if (tls->server_name != NULL) {
4882
                /* In this event, the server SHALL include an extension of type "server_name" in the (extended) server hello.
4883
                 * The "extension_data" field of this extension SHALL be empty. (RFC 6066 section 3) */
4884
222
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SERVER_NAME, {});
4885
222
            }
4886
222
            if (tls->ctx->use_raw_public_keys) {
4887
222
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SERVER_CERTIFICATE_TYPE,
4888
222
                                      { ptls_buffer_push(sendbuf, PTLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY); });
4889
222
            }
4890
222
            if (tls->negotiated_protocol != NULL) {
4891
222
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ALPN, {
4892
222
                    ptls_buffer_push_block(sendbuf, 2, {
4893
222
                        ptls_buffer_push_block(sendbuf, 1, {
4894
222
                            ptls_buffer_pushv(sendbuf, tls->negotiated_protocol, strlen(tls->negotiated_protocol));
4895
222
                        });
4896
222
                    });
4897
222
                });
4898
222
            }
4899
222
            if (tls->pending_handshake_secret != NULL)
4900
222
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_EARLY_DATA, {});
4901
            /* send ECH retry_configs, if ECH was offered by rejected, even though we (the server) could have accepted ECH */
4902
222
            if (tls->ech.state == PTLS_ECH_STATE_OFFERED && tls->ctx->ech.server.create_opener != NULL &&
4903
222
                tls->ctx->ech.server.retry_configs.len != 0)
4904
222
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO, {
4905
222
                    ptls_buffer_pushv(sendbuf, tls->ctx->ech.server.retry_configs.base, tls->ctx->ech.server.retry_configs.len);
4906
222
                });
4907
222
            if (ch->ticket_request.new_session_count != 0 && tls->server.num_tickets_to_send != 0)
4908
222
                buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_TICKET_REQUEST,
4909
222
                                      { ptls_buffer_push(sendbuf, tls->server.num_tickets_to_send); });
4910
222
            if ((ret = push_additional_extensions(properties, sendbuf)) != 0)
4911
222
                goto Exit;
4912
222
        });
4913
222
    });
4914
4915
222
    if (mode == HANDSHAKE_MODE_FULL) {
4916
        /* send certificate request if client authentication is activated */
4917
222
        if (tls->ctx->require_client_authentication) {
4918
0
            ptls_push_message(emitter, tls->key_schedule, PTLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST, {
4919
0
                ptls_buffer_t *sendbuf = emitter->buf;
4920
                /* certificate_request_context: this field SHALL be zero length, unless the certificate request is used for post-
4921
                 * handshake authentication. */
4922
0
                ptls_buffer_push(sendbuf, 0);
4923
                /* extensions */
4924
0
                ptls_buffer_push_block(sendbuf, 2, {
4925
0
                    buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_SIGNATURE_ALGORITHMS, {
4926
0
                        if ((ret = push_signature_algorithms(tls->ctx->verify_certificate, sendbuf)) != 0)
4927
0
                            goto Exit;
4928
0
                    });
4929
                    /* certificate authorities entension */
4930
0
                    if (tls->ctx->client_ca_names.count > 0) {
4931
0
                        buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_CERTIFICATE_AUTHORITIES, {
4932
0
                            ptls_buffer_push_block(sendbuf, 2, {
4933
0
                                for (size_t i = 0; i != tls->ctx->client_ca_names.count; ++i) {
4934
0
                                    ptls_buffer_push_block(sendbuf, 2, {
4935
0
                                        ptls_iovec_t name = tls->ctx->client_ca_names.list[i];
4936
0
                                        ptls_buffer_pushv(sendbuf, name.base, name.len);
4937
0
                                    });
4938
0
                                }
4939
0
                            });
4940
0
                        });
4941
0
                    }
4942
0
                });
4943
0
            });
4944
4945
0
            if (ret != 0) {
4946
0
                goto Exit;
4947
0
            }
4948
0
        }
4949
4950
        /* send certificate */
4951
222
        if ((ret = send_certificate(tls, emitter, &ch->signature_algorithms, ptls_iovec_init(NULL, 0), ch->status_request,
4952
222
                                    ch->cert_compression_algos.list, ch->cert_compression_algos.count)) != 0)
4953
10
            goto Exit;
4954
        /* send certificateverify, finished, and complete the handshake */
4955
212
        if ((ret = server_finish_handshake(tls, emitter, 1, &ch->signature_algorithms)) != 0)
4956
0
            goto Exit;
4957
212
    } else {
4958
        /* send finished, and complete the handshake */
4959
0
        if ((ret = server_finish_handshake(tls, emitter, 0, NULL)) != 0)
4960
0
            goto Exit;
4961
0
    }
4962
4963
1.92k
Exit:
4964
1.92k
    free(pubkey.base);
4965
1.92k
    if (ecdh_secret.base != NULL) {
4966
222
        ptls_clear_memory(ecdh_secret.base, ecdh_secret.len);
4967
222
        free(ecdh_secret.base);
4968
222
    }
4969
1.92k
    free(ech.encoded_ch_inner);
4970
1.92k
    free(ech.ch_outer_aad);
4971
1.92k
    ptls_buffer_dispose(&ech.ch_inner);
4972
1.92k
    free(ch);
4973
1.92k
    return ret;
4974
4975
222
#undef EMIT_SERVER_HELLO
4976
222
#undef EMIT_HELLO_RETRY_REQUEST
4977
222
}
4978
4979
static int server_finish_handshake(ptls_t *tls, ptls_message_emitter_t *emitter, int send_cert_verify,
4980
                                   struct st_ptls_signature_algorithms_t *signature_algorithms)
4981
212
{
4982
212
    int ret;
4983
4984
212
    if (send_cert_verify) {
4985
212
        if ((ret = send_certificate_verify(tls, emitter, signature_algorithms, PTLS_SERVER_CERTIFICATE_VERIFY_CONTEXT_STRING)) !=
4986
212
            0) {
4987
0
            if (ret == PTLS_ERROR_ASYNC_OPERATION) {
4988
0
                tls->state = PTLS_STATE_SERVER_GENERATING_CERTIFICATE_VERIFY;
4989
0
            }
4990
0
            goto Exit;
4991
0
        }
4992
212
    }
4993
4994
212
    if ((ret = send_finished(tls, emitter)) != 0)
4995
0
        goto Exit;
4996
4997
212
    assert(tls->key_schedule->generation == 2);
4998
212
    if ((ret = key_schedule_extract(tls->key_schedule, ptls_iovec_init(NULL, 0))) != 0)
4999
0
        goto Exit;
5000
212
    if ((ret = setup_traffic_protection(tls, 1, "s ap traffic", 3, 0, 0)) != 0)
5001
0
        goto Exit;
5002
212
    if ((ret = derive_secret(tls->key_schedule, tls->server.pending_traffic_secret, "c ap traffic")) != 0)
5003
0
        goto Exit;
5004
212
    if ((ret = derive_exporter_secret(tls, 0)) != 0)
5005
0
        goto Exit;
5006
5007
212
    if (tls->pending_handshake_secret != NULL) {
5008
0
        if (tls->ctx->omit_end_of_early_data) {
5009
0
            if ((ret = commission_handshake_secret(tls)) != 0)
5010
0
                goto Exit;
5011
0
            tls->state = PTLS_STATE_SERVER_EXPECT_FINISHED;
5012
0
        } else {
5013
0
            tls->state = PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA;
5014
0
        }
5015
212
    } else if (tls->ctx->require_client_authentication) {
5016
0
        tls->state = PTLS_STATE_SERVER_EXPECT_CERTIFICATE;
5017
212
    } else {
5018
212
        tls->state = PTLS_STATE_SERVER_EXPECT_FINISHED;
5019
212
    }
5020
5021
    /* send session ticket if necessary */
5022
212
    if (tls->server.num_tickets_to_send != 0) {
5023
104
        assert(tls->ctx->ticket_lifetime != 0);
5024
323
        for (uint8_t i = 0; i < tls->server.num_tickets_to_send; ++i)
5025
219
            if ((ret = send_session_ticket(tls, emitter)) != 0)
5026
0
                goto Exit;
5027
104
    }
5028
5029
212
    if (tls->ctx->require_client_authentication) {
5030
0
        ret = PTLS_ERROR_IN_PROGRESS;
5031
212
    } else {
5032
212
        ret = 0;
5033
212
    }
5034
5035
212
Exit:
5036
212
    return ret;
5037
212
}
5038
5039
static int server_handle_end_of_early_data(ptls_t *tls, ptls_iovec_t message)
5040
0
{
5041
0
    int ret;
5042
5043
0
    if ((ret = commission_handshake_secret(tls)) != 0)
5044
0
        goto Exit;
5045
5046
0
    ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
5047
0
    tls->state = PTLS_STATE_SERVER_EXPECT_FINISHED;
5048
0
    ret = PTLS_ERROR_IN_PROGRESS;
5049
5050
0
Exit:
5051
0
    return ret;
5052
0
}
5053
5054
static int server_handle_finished(ptls_t *tls, ptls_iovec_t message)
5055
8
{
5056
8
    int ret;
5057
5058
8
    if ((ret = verify_finished(tls, message)) != 0)
5059
8
        return ret;
5060
5061
0
    memcpy(tls->traffic_protection.dec.secret, tls->server.pending_traffic_secret, sizeof(tls->server.pending_traffic_secret));
5062
0
    ptls_clear_memory(tls->server.pending_traffic_secret, sizeof(tls->server.pending_traffic_secret));
5063
0
    if ((ret = setup_traffic_protection(tls, 0, NULL, 3, 0, 0)) != 0)
5064
0
        return ret;
5065
5066
0
    ptls__key_schedule_update_hash(tls->key_schedule, message.base, message.len, 0);
5067
5068
0
    tls->state = PTLS_STATE_SERVER_POST_HANDSHAKE;
5069
0
    return 0;
5070
0
}
5071
5072
static int update_traffic_key(ptls_t *tls, int is_enc)
5073
0
{
5074
0
    struct st_ptls_traffic_protection_t *tp = is_enc ? &tls->traffic_protection.enc : &tls->traffic_protection.dec;
5075
0
    uint8_t secret[PTLS_MAX_DIGEST_SIZE];
5076
0
    int ret;
5077
5078
0
    ptls_hash_algorithm_t *hash = tls->key_schedule->hashes[0].algo;
5079
0
    if ((ret = ptls_hkdf_expand_label(hash, secret, hash->digest_size, ptls_iovec_init(tp->secret, hash->digest_size),
5080
0
                                      "traffic upd", ptls_iovec_init(NULL, 0), NULL)) != 0)
5081
0
        goto Exit;
5082
0
    memcpy(tp->secret, secret, sizeof(secret));
5083
0
    ret = setup_traffic_protection(tls, is_enc, NULL, 3, 0, 1);
5084
5085
0
Exit:
5086
0
    ptls_clear_memory(secret, sizeof(secret));
5087
0
    return ret;
5088
0
}
5089
5090
static int handle_key_update(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_iovec_t message)
5091
0
{
5092
0
    int ret;
5093
5094
    /* KeyUpdate is not supported when the application owns the record layer. */
5095
0
    if (tls->ctx->update_traffic_key != NULL)
5096
0
        return PTLS_ALERT_UNEXPECTED_MESSAGE;
5097
5098
0
    const uint8_t *src = message.base + PTLS_HANDSHAKE_HEADER_SIZE, *const end = message.base + message.len;
5099
5100
    /* validate */
5101
0
    if (end - src != 1 || *src > 1)
5102
0
        return PTLS_ALERT_DECODE_ERROR;
5103
5104
    /* update receive key */
5105
0
    if ((ret = update_traffic_key(tls, 0)) != 0)
5106
0
        return ret;
5107
5108
0
    if (*src) {
5109
0
        tls->needs_key_update = 1;
5110
0
    }
5111
5112
0
    return 0;
5113
0
}
5114
5115
static int parse_record_header(struct st_ptls_record_t *rec, const uint8_t *src)
5116
54.5k
{
5117
54.5k
    rec->type = src[0];
5118
54.5k
    rec->version = ntoh16(src + 1);
5119
54.5k
    rec->length = ntoh16(src + 3);
5120
5121
54.5k
    if (rec->length >
5122
54.5k
        (size_t)(rec->type == PTLS_CONTENT_TYPE_APPDATA ? PTLS_MAX_ENCRYPTED_RECORD_SIZE : PTLS_MAX_PLAINTEXT_RECORD_SIZE))
5123
9
        return PTLS_ALERT_DECODE_ERROR;
5124
5125
54.5k
    return 0;
5126
54.5k
}
5127
5128
static int parse_record(ptls_t *tls, struct st_ptls_record_t *rec, const uint8_t *src, size_t *len)
5129
54.4k
{
5130
54.4k
    int ret;
5131
5132
54.4k
    assert(*len != 0);
5133
5134
    /* Check if the first byte is something that we can handle, otherwise do not bother parsing / buffering the entire record as it
5135
     * is obviously broken. SSL 2.0 handshakes fall into this path as well. */
5136
54.4k
    if (tls->recvbuf.rec.base == NULL) {
5137
54.4k
        uint8_t type = src[0];
5138
54.4k
        switch (type) {
5139
650
        case PTLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC:
5140
741
        case PTLS_CONTENT_TYPE_ALERT:
5141
41.9k
        case PTLS_CONTENT_TYPE_HANDSHAKE:
5142
54.3k
        case PTLS_CONTENT_TYPE_APPDATA:
5143
54.3k
            break;
5144
95
        default:
5145
95
            return PTLS_ALERT_DECODE_ERROR;
5146
54.4k
        }
5147
54.4k
    }
5148
5149
54.3k
    if (tls->recvbuf.rec.base == NULL && *len >= 5) {
5150
        /* fast path */
5151
54.3k
        if ((ret = parse_record_header(rec, src)) != 0)
5152
9
            return ret;
5153
54.3k
        if (5 + rec->length <= *len) {
5154
54.1k
            rec->fragment = src + 5;
5155
54.1k
            *len = rec->length + 5;
5156
54.1k
            return 0;
5157
54.1k
        }
5158
54.3k
    }
5159
5160
    /* slow path */
5161
235
    const uint8_t *const end = src + *len;
5162
235
    *rec = (struct st_ptls_record_t){0};
5163
5164
235
    if (tls->recvbuf.rec.base == NULL) {
5165
235
        ptls_buffer_init(&tls->recvbuf.rec, "", 0);
5166
235
        if ((ret = ptls_buffer_reserve(&tls->recvbuf.rec, 5)) != 0)
5167
0
            return ret;
5168
235
    }
5169
5170
    /* fill and parse the header */
5171
1.23k
    while (tls->recvbuf.rec.off < 5) {
5172
1.04k
        if (src == end)
5173
49
            return PTLS_ERROR_IN_PROGRESS;
5174
996
        tls->recvbuf.rec.base[tls->recvbuf.rec.off++] = *src++;
5175
996
    }
5176
186
    if ((ret = parse_record_header(rec, tls->recvbuf.rec.base)) != 0)
5177
0
        return ret;
5178
5179
    /* fill the fragment */
5180
186
    size_t addlen = rec->length + 5 - tls->recvbuf.rec.off;
5181
186
    if (addlen != 0) {
5182
186
        if ((ret = ptls_buffer_reserve(&tls->recvbuf.rec, addlen)) != 0)
5183
0
            return ret;
5184
186
        if (addlen > (size_t)(end - src))
5185
186
            addlen = end - src;
5186
186
        if (addlen != 0) {
5187
77
            memcpy(tls->recvbuf.rec.base + tls->recvbuf.rec.off, src, addlen);
5188
77
            tls->recvbuf.rec.off += addlen;
5189
77
            src += addlen;
5190
77
        }
5191
186
    }
5192
5193
    /* set rec->fragment if a complete record has been parsed */
5194
186
    if (tls->recvbuf.rec.off == rec->length + 5) {
5195
0
        rec->fragment = tls->recvbuf.rec.base + 5;
5196
0
        ret = 0;
5197
186
    } else {
5198
186
        ret = PTLS_ERROR_IN_PROGRESS;
5199
186
    }
5200
5201
186
    *len -= end - src;
5202
186
    return ret;
5203
186
}
5204
5205
static void update_open_count(ptls_context_t *ctx, ssize_t delta)
5206
8.29k
{
5207
8.29k
    if (ctx->update_open_count != NULL)
5208
0
        ctx->update_open_count->cb(ctx->update_open_count, delta);
5209
8.29k
}
5210
5211
static ptls_t *new_instance(ptls_context_t *ctx, int is_server)
5212
4.14k
{
5213
4.14k
    ptls_t *tls;
5214
5215
    /* check consistency of `ptls_context_t` before instantiating a connection object */
5216
4.14k
    assert(ctx->get_time != NULL && "please set ctx->get_time to `&ptls_get_time`; see #92");
5217
4.14k
    if (ctx->pre_shared_key.identity.base != NULL) {
5218
0
        assert(ctx->pre_shared_key.identity.len != 0 && ctx->pre_shared_key.secret.base != NULL &&
5219
0
               ctx->pre_shared_key.secret.len != 0 && ctx->pre_shared_key.hash != NULL &&
5220
0
               "`ptls_context_t::pre_shared_key` in incosistent state");
5221
4.14k
    } else {
5222
4.14k
        assert(ctx->pre_shared_key.identity.len == 0 && ctx->pre_shared_key.secret.base == NULL &&
5223
4.14k
               ctx->pre_shared_key.secret.len == 0 && ctx->pre_shared_key.hash == NULL &&
5224
4.14k
               "`ptls_context_t::pre_shared_key` in inconsitent state");
5225
4.14k
    }
5226
5227
4.14k
    if ((tls = malloc(sizeof(*tls))) == NULL)
5228
0
        return NULL;
5229
5230
4.14k
    update_open_count(ctx, 1);
5231
4.14k
    *tls = (ptls_t){ctx};
5232
4.14k
    tls->is_server = is_server;
5233
4.14k
    tls->send_change_cipher_spec = ctx->send_change_cipher_spec;
5234
5235
4.14k
#if PTLS_HAVE_LOG
5236
4.14k
    if (ptls_log_conn_state_override != NULL) {
5237
0
        tls->log_state = *ptls_log_conn_state_override;
5238
4.14k
    } else {
5239
4.14k
        ptls_log_init_conn_state(&tls->log_state, ctx->random_bytes, 0, NULL);
5240
4.14k
    }
5241
4.14k
#endif
5242
5243
4.14k
    return tls;
5244
4.14k
}
5245
5246
ptls_t *ptls_client_new(ptls_context_t *ctx)
5247
1.99k
{
5248
1.99k
    ptls_t *tls = new_instance(ctx, 0);
5249
1.99k
    tls->state = PTLS_STATE_CLIENT_HANDSHAKE_START;
5250
1.99k
    tls->ctx->random_bytes(tls->client_random, sizeof(tls->client_random));
5251
1.99k
    log_client_random(tls);
5252
1.99k
    if (tls->send_change_cipher_spec) {
5253
0
        tls->client.legacy_session_id =
5254
0
            ptls_iovec_init(tls->client.legacy_session_id_buf, sizeof(tls->client.legacy_session_id_buf));
5255
0
        tls->ctx->random_bytes(tls->client.legacy_session_id.base, tls->client.legacy_session_id.len);
5256
0
    }
5257
5258
1.99k
    PTLS_PROBE(NEW, tls, 0);
5259
1.99k
    PTLS_LOG_CONN(new, tls, { PTLS_LOG_ELEMENT_BOOL(is_server, 0); });
5260
1.99k
    return tls;
5261
1.99k
}
5262
5263
ptls_t *ptls_server_new(ptls_context_t *ctx)
5264
2.15k
{
5265
2.15k
    ptls_t *tls = new_instance(ctx, 1);
5266
2.15k
    tls->state = PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO;
5267
2.15k
    tls->server.early_data_skipped_bytes = UINT32_MAX;
5268
5269
2.15k
    PTLS_PROBE(NEW, tls, 1);
5270
2.15k
    PTLS_LOG_CONN(new, tls, { PTLS_LOG_ELEMENT_BOOL(is_server, 1); });
5271
2.15k
    return tls;
5272
2.15k
}
5273
5274
#define export_tls_params(output, is_server, session_reused, protocol_version, cipher, client_random, server_name,                 \
5275
                          negotiated_protocol, ver_block)                                                                          \
5276
0
    do {                                                                                                                           \
5277
0
        const char *_server_name = (server_name);                                                                                  \
5278
0
        ptls_iovec_t _negotiated_protocol = (negotiated_protocol);                                                                 \
5279
0
        ptls_buffer_push_block((output), 2, {                                                                                      \
5280
0
            ptls_buffer_push((output), (is_server));                                                                               \
5281
0
            ptls_buffer_push((output), (session_reused));                                                                          \
5282
0
            ptls_buffer_push16((output), (protocol_version));                                                                      \
5283
0
            ptls_buffer_push16((output), (cipher)->id);                                                                            \
5284
0
            ptls_buffer_pushv((output), (client_random), PTLS_HELLO_RANDOM_SIZE);                                                  \
5285
0
            ptls_buffer_push_block((output), 2, {                                                                                  \
5286
0
                size_t len = _server_name != NULL ? strlen(_server_name) : 0;                                                      \
5287
0
                ptls_buffer_pushv((output), _server_name, len);                                                                    \
5288
0
            });                                                                                                                    \
5289
0
            ptls_buffer_push_block((output), 2,                                                                                    \
5290
0
                                   { ptls_buffer_pushv((output), _negotiated_protocol.base, _negotiated_protocol.len); });         \
5291
0
            ptls_buffer_push_block((output), 2, {ver_block}); /* version-specific block */                                         \
5292
0
            ptls_buffer_push_block((output), 2, {});          /* for future extensions */                                          \
5293
0
        });                                                                                                                        \
5294
0
    } while (0)
5295
5296
static int export_tls12_params(ptls_buffer_t *output, int is_server, int session_reused, ptls_cipher_suite_t *cipher,
5297
                               const void *client_random, const char *server_name, ptls_iovec_t negotiated_protocol,
5298
                               const void *enc_key, const void *enc_iv, uint64_t enc_seq, uint64_t enc_record_iv,
5299
                               const void *dec_key, const void *dec_iv, uint64_t dec_seq)
5300
0
{
5301
0
    int ret;
5302
5303
0
    export_tls_params(output, is_server, session_reused, PTLS_PROTOCOL_VERSION_TLS12, cipher, client_random, server_name,
5304
0
                      negotiated_protocol, {
5305
0
                          ptls_buffer_pushv(output, enc_key, cipher->aead->key_size);
5306
0
                          ptls_buffer_pushv(output, enc_iv, cipher->aead->tls12.fixed_iv_size);
5307
0
                          ptls_buffer_push64(output, enc_seq);
5308
0
                          if (cipher->aead->tls12.record_iv_size != 0)
5309
0
                              ptls_buffer_push64(output, enc_record_iv);
5310
0
                          ptls_buffer_pushv(output, dec_key, cipher->aead->key_size);
5311
0
                          ptls_buffer_pushv(output, dec_iv, cipher->aead->tls12.fixed_iv_size);
5312
0
                          ptls_buffer_push64(output, dec_seq);
5313
0
                      });
5314
0
    ret = 0;
5315
5316
0
Exit:
5317
0
    return ret;
5318
0
}
5319
5320
int ptls_build_tls12_export_params(ptls_context_t *ctx, ptls_buffer_t *output, int is_server, int session_reused,
5321
                                   ptls_cipher_suite_t *cipher, const void *master_secret, const void *hello_randoms,
5322
                                   uint64_t next_send_record_iv, const char *server_name, ptls_iovec_t negotiated_protocol)
5323
0
{
5324
0
    assert(cipher->aead->tls12.fixed_iv_size + cipher->aead->tls12.record_iv_size != 0 || !"given cipher-suite supports TLS/1.2");
5325
5326
0
    uint8_t key_block[(PTLS_MAX_SECRET_SIZE + PTLS_MAX_IV_SIZE) * 2];
5327
0
    size_t key_block_len = (cipher->aead->key_size + cipher->aead->tls12.fixed_iv_size) * 2;
5328
0
    int ret;
5329
5330
0
    assert(key_block_len <= sizeof(key_block));
5331
5332
    /* generate key block */
5333
0
    if ((ret =
5334
0
             ptls_tls12_phash(cipher->hash, key_block, key_block_len, ptls_iovec_init(master_secret, PTLS_TLS12_MASTER_SECRET_SIZE),
5335
0
                              "key expansion", ptls_iovec_init(hello_randoms, PTLS_HELLO_RANDOM_SIZE * 2))) != 0)
5336
0
        goto Exit;
5337
5338
    /* determine key locations */
5339
0
    struct {
5340
0
        const void *key;
5341
0
        const void *iv;
5342
0
    } client_secret, server_secret, *enc_secret = is_server ? &server_secret : &client_secret,
5343
0
                                    *dec_secret = is_server ? &client_secret : &server_secret;
5344
0
    client_secret.key = key_block;
5345
0
    server_secret.key = key_block + cipher->aead->key_size;
5346
0
    client_secret.iv = key_block + cipher->aead->key_size * 2;
5347
0
    server_secret.iv = key_block + cipher->aead->key_size * 2 + cipher->aead->tls12.fixed_iv_size;
5348
5349
    /* Serialize prams. Sequence number of the first application record is 1, because Finished is the only message sent after
5350
     * ChangeCipherSpec. */
5351
0
    ret = export_tls12_params(output, is_server, session_reused, cipher, (uint8_t *)hello_randoms + PTLS_HELLO_RANDOM_SIZE,
5352
0
                              server_name, negotiated_protocol, enc_secret->key, enc_secret->iv, 1, next_send_record_iv,
5353
0
                              dec_secret->key, dec_secret->iv, 1);
5354
5355
0
Exit:
5356
0
    ptls_clear_memory(key_block, sizeof(key_block));
5357
0
    return ret;
5358
0
}
5359
5360
int ptls_export(ptls_t *tls, ptls_buffer_t *output)
5361
0
{
5362
0
    ptls_iovec_t negotiated_protocol =
5363
0
        ptls_iovec_init(tls->negotiated_protocol, tls->negotiated_protocol != NULL ? strlen(tls->negotiated_protocol) : 0);
5364
0
    int ret;
5365
5366
0
    if (tls->state != PTLS_STATE_SERVER_POST_HANDSHAKE) {
5367
0
        ret = PTLS_ERROR_LIBRARY;
5368
0
        goto Exit;
5369
0
    }
5370
5371
0
    if (ptls_get_protocol_version(tls) == PTLS_PROTOCOL_VERSION_TLS13) {
5372
0
        export_tls_params(output, tls->is_server, tls->is_psk_handshake, PTLS_PROTOCOL_VERSION_TLS13, tls->cipher_suite,
5373
0
                          tls->client_random, tls->server_name, negotiated_protocol, {
5374
0
                              ptls_buffer_pushv(output, tls->traffic_protection.enc.secret, tls->cipher_suite->hash->digest_size);
5375
0
                              ptls_buffer_push64(output, tls->traffic_protection.enc.seq);
5376
0
                              ptls_buffer_pushv(output, tls->traffic_protection.dec.secret, tls->cipher_suite->hash->digest_size);
5377
0
                              ptls_buffer_push64(output, tls->traffic_protection.dec.seq);
5378
0
                          });
5379
0
        ret = 0;
5380
0
    } else {
5381
0
        if ((ret = export_tls12_params(output, tls->is_server, tls->is_psk_handshake, tls->cipher_suite, tls->client_random,
5382
0
                                       tls->server_name, negotiated_protocol, tls->traffic_protection.enc.secret,
5383
0
                                       tls->traffic_protection.enc.secret + PTLS_MAX_SECRET_SIZE, tls->traffic_protection.enc.seq,
5384
0
                                       tls->traffic_protection.enc.tls12_enc_record_iv, tls->traffic_protection.dec.secret,
5385
0
                                       tls->traffic_protection.dec.secret + PTLS_MAX_SECRET_SIZE,
5386
0
                                       tls->traffic_protection.dec.seq)) != 0)
5387
0
            goto Exit;
5388
0
    }
5389
5390
0
Exit:
5391
0
    return ret;
5392
0
}
5393
5394
static int import_tls12_traffic_protection(ptls_t *tls, int is_enc, const uint8_t **src, const uint8_t *const end)
5395
0
{
5396
0
    struct st_ptls_traffic_protection_t *tp = is_enc ? &tls->traffic_protection.enc : &tls->traffic_protection.dec;
5397
5398
0
    if ((size_t)(end - *src) < tls->cipher_suite->aead->key_size + tls->cipher_suite->aead->tls12.fixed_iv_size + sizeof(uint64_t))
5399
0
        return PTLS_ALERT_DECODE_ERROR;
5400
5401
    /* set properties */
5402
0
    memcpy(tp->secret, *src, tls->cipher_suite->aead->key_size);
5403
0
    *src += tls->cipher_suite->aead->key_size;
5404
0
    memcpy(tp->secret + PTLS_MAX_SECRET_SIZE, *src, tls->cipher_suite->aead->tls12.fixed_iv_size);
5405
0
    *src += tls->cipher_suite->aead->tls12.fixed_iv_size;
5406
0
    if (ptls_decode64(&tp->seq, src, end) != 0)
5407
0
        return PTLS_ALERT_DECODE_ERROR;
5408
0
    if (is_enc && tls->cipher_suite->aead->tls12.record_iv_size != 0) {
5409
0
        if (ptls_decode64(&tp->tls12_enc_record_iv, src, end) != 0)
5410
0
            return PTLS_ALERT_DECODE_ERROR;
5411
0
    }
5412
0
    tp->tls12 = 1;
5413
5414
    /* instantiate aead */
5415
0
    if ((tp->aead = ptls_aead_new_direct(tls->cipher_suite->aead, is_enc, tp->secret, tp->secret + PTLS_MAX_SECRET_SIZE)) == NULL)
5416
0
        return PTLS_ERROR_NO_MEMORY;
5417
5418
0
    return 0;
5419
0
}
5420
5421
static int import_tls13_traffic_protection(ptls_t *tls, int is_enc, const uint8_t **src, const uint8_t *const end)
5422
0
{
5423
0
    struct st_ptls_traffic_protection_t *tp = is_enc ? &tls->traffic_protection.enc : &tls->traffic_protection.dec;
5424
5425
    /* set properties */
5426
0
    memcpy(tp->secret, *src, tls->cipher_suite->hash->digest_size);
5427
0
    *src += tls->cipher_suite->hash->digest_size;
5428
0
    if (ptls_decode64(&tp->seq, src, end) != 0)
5429
0
        return PTLS_ALERT_DECODE_ERROR;
5430
5431
0
    if (setup_traffic_protection(tls, is_enc, NULL, 3, tp->seq, 0) != 0)
5432
0
        return PTLS_ERROR_INCOMPATIBLE_KEY;
5433
5434
0
    return 0;
5435
0
}
5436
5437
int ptls_import(ptls_context_t *ctx, ptls_t **tls, ptls_iovec_t params)
5438
0
{
5439
0
    const uint8_t *src = params.base, *const end = src + params.len;
5440
0
    uint16_t protocol_version, csid;
5441
0
    int ret;
5442
5443
0
    *tls = NULL;
5444
5445
    /* TODO handle flags like psk_handshake, ech_handshake as we add support for TLS/1.3 import */
5446
0
    ptls_decode_block(src, end, 2, {
5447
        /* instantiate, based on the is_server flag */
5448
0
        if (end - src < 2) {
5449
0
            ret = PTLS_ALERT_DECODE_ERROR;
5450
0
            goto Exit;
5451
0
        }
5452
0
        if ((*tls = new_instance(ctx, *src++)) == NULL) {
5453
0
            ret = PTLS_ERROR_NO_MEMORY;
5454
0
            goto Exit;
5455
0
        }
5456
0
        (*tls)->is_psk_handshake = *src++;
5457
        /* determine protocol version and cipher suite */
5458
0
        if ((ret = ptls_decode16(&protocol_version, &src, end)) != 0)
5459
0
            goto Exit;
5460
0
        if ((ret = ptls_decode16(&csid, &src, end)) != 0)
5461
0
            goto Exit;
5462
        /* other version-independent stuff */
5463
0
        if (end - src < PTLS_HELLO_RANDOM_SIZE) {
5464
0
            ret = PTLS_ALERT_DECODE_ERROR;
5465
0
            goto Exit;
5466
0
        }
5467
0
        memcpy((*tls)->client_random, src, PTLS_HELLO_RANDOM_SIZE);
5468
0
        src += PTLS_HELLO_RANDOM_SIZE;
5469
0
        ptls_decode_open_block(src, end, 2, {
5470
0
            if (src != end) {
5471
0
                if ((ret = ptls_set_server_name(*tls, (const char *)src, end - src)) != 0)
5472
0
                    goto Exit;
5473
0
                src = end;
5474
0
            }
5475
0
        });
5476
0
        ptls_decode_open_block(src, end, 2, {
5477
0
            if (src != end) {
5478
0
                if ((ret = ptls_set_negotiated_protocol(*tls, (const char *)src, end - src)) != 0)
5479
0
                    goto Exit;
5480
0
                src = end;
5481
0
            }
5482
0
        });
5483
        /* version-dependent stuff */
5484
0
        ptls_decode_open_block(src, end, 2, {
5485
0
            switch (protocol_version) {
5486
0
            case PTLS_PROTOCOL_VERSION_TLS12:
5487
0
                (*tls)->cipher_suite = ptls_find_cipher_suite(ctx->tls12_cipher_suites, csid);
5488
0
                if ((*tls)->cipher_suite == NULL) {
5489
0
                    ret = PTLS_ALERT_HANDSHAKE_FAILURE;
5490
0
                    goto Exit;
5491
0
                }
5492
                /* setup AEAD keys */
5493
0
                if ((ret = import_tls12_traffic_protection(*tls, 1, &src, end)) != 0)
5494
0
                    goto Exit;
5495
0
                if ((ret = import_tls12_traffic_protection(*tls, 0, &src, end)) != 0)
5496
0
                    goto Exit;
5497
0
                break;
5498
0
            case PTLS_PROTOCOL_VERSION_TLS13:
5499
0
                (*tls)->cipher_suite = ptls_find_cipher_suite(ctx->cipher_suites, csid);
5500
0
                if ((*tls)->cipher_suite == NULL) {
5501
0
                    ret = PTLS_ALERT_HANDSHAKE_FAILURE;
5502
0
                    goto Exit;
5503
0
                }
5504
                /* setup AEAD keys */
5505
0
                if (((*tls)->key_schedule = key_schedule_new((*tls)->cipher_suite, NULL, (*tls)->ech.aead != NULL)) == NULL) {
5506
0
                    ret = PTLS_ERROR_NO_MEMORY;
5507
0
                    goto Exit;
5508
0
                }
5509
0
                if ((ret = import_tls13_traffic_protection(*tls, 1, &src, end)) != 0)
5510
0
                    goto Exit;
5511
0
                if ((ret = import_tls13_traffic_protection(*tls, 0, &src, end)) != 0)
5512
0
                    goto Exit;
5513
0
                break;
5514
0
            default:
5515
0
                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
5516
0
                goto Exit;
5517
0
            }
5518
0
        });
5519
        /* extensions */
5520
0
        ptls_decode_open_block(src, end, 2, {
5521
0
            src = end; /* unused */
5522
0
        });
5523
0
    });
5524
5525
0
    (*tls)->state = ptls_is_server(*tls) ? PTLS_STATE_SERVER_POST_HANDSHAKE : PTLS_STATE_CLIENT_POST_HANDSHAKE;
5526
5527
0
Exit:
5528
0
    if (ret != 0) {
5529
0
        if (*tls != NULL) {
5530
0
            ptls_free(*tls);
5531
0
            *tls = NULL;
5532
0
        }
5533
0
    }
5534
0
    return ret;
5535
0
}
5536
5537
void ptls_free(ptls_t *tls)
5538
4.14k
{
5539
4.14k
    PTLS_PROBE0(FREE, tls);
5540
4.14k
    PTLS_LOG_CONN(free, tls, {});
5541
5542
4.14k
    ptls_buffer_dispose(&tls->recvbuf.rec);
5543
4.14k
    ptls_buffer_dispose(&tls->recvbuf.mess);
5544
4.14k
    free_exporter_master_secret(tls, 1);
5545
4.14k
    free_exporter_master_secret(tls, 0);
5546
4.14k
    if (tls->key_schedule != NULL)
5547
2.62k
        key_schedule_free(tls->key_schedule);
5548
4.14k
    if (tls->traffic_protection.dec.aead != NULL)
5549
1.26k
        ptls_aead_free(tls->traffic_protection.dec.aead);
5550
4.14k
    if (tls->traffic_protection.enc.aead != NULL)
5551
1.26k
        ptls_aead_free(tls->traffic_protection.enc.aead);
5552
4.14k
    free(tls->server_name);
5553
4.14k
    free(tls->negotiated_protocol);
5554
4.14k
    clear_ech(&tls->ech, tls->is_server);
5555
4.14k
    if (tls->is_server) {
5556
2.15k
        if (tls->server.async_job != NULL)
5557
0
            tls->server.async_job->destroy_(tls->server.async_job);
5558
2.15k
    } else {
5559
1.99k
        if (tls->client.key_share_ctx != NULL)
5560
914
            tls->client.key_share_ctx->on_exchange(&tls->client.key_share_ctx, 1, NULL, ptls_iovec_init(NULL, 0));
5561
1.99k
        if (tls->client.certificate_request.context.base != NULL)
5562
260
            free(tls->client.certificate_request.context.base);
5563
1.99k
    }
5564
4.14k
    if (tls->certificate_verify.cb != NULL)
5565
0
        tls->certificate_verify.cb(tls->certificate_verify.verify_ctx, 0, ptls_iovec_init(NULL, 0), ptls_iovec_init(NULL, 0));
5566
4.14k
    if (tls->pending_handshake_secret != NULL) {
5567
0
        ptls_clear_memory(tls->pending_handshake_secret, PTLS_MAX_DIGEST_SIZE);
5568
0
        free(tls->pending_handshake_secret);
5569
0
    }
5570
4.14k
    update_open_count(tls->ctx, -1);
5571
4.14k
    ptls_clear_memory(tls, sizeof(*tls));
5572
4.14k
    free(tls);
5573
4.14k
}
5574
5575
ptls_context_t *ptls_get_context(ptls_t *tls)
5576
0
{
5577
0
    return tls->ctx;
5578
0
}
5579
5580
void ptls_set_context(ptls_t *tls, ptls_context_t *ctx)
5581
0
{
5582
0
    update_open_count(ctx, 1);
5583
0
    update_open_count(tls->ctx, -1);
5584
0
    tls->ctx = ctx;
5585
0
}
5586
5587
ptls_async_job_t *ptls_get_async_job(ptls_t *tls)
5588
0
{
5589
0
    return tls->server.async_job;
5590
0
}
5591
5592
ptls_iovec_t ptls_get_client_random(ptls_t *tls)
5593
0
{
5594
0
    return ptls_iovec_init(tls->client_random, PTLS_HELLO_RANDOM_SIZE);
5595
0
}
5596
5597
ptls_cipher_suite_t *ptls_get_cipher(ptls_t *tls)
5598
0
{
5599
0
    return tls->cipher_suite;
5600
0
}
5601
5602
uint16_t ptls_get_protocol_version(ptls_t *tls)
5603
0
{
5604
0
    if (tls->traffic_protection.enc.tls12)
5605
0
        return PTLS_PROTOCOL_VERSION_TLS12;
5606
5607
0
    return PTLS_PROTOCOL_VERSION_TLS13;
5608
0
}
5609
5610
int ptls_get_traffic_keys(ptls_t *tls, int is_enc, uint8_t *key, uint8_t *iv, uint64_t *seq)
5611
0
{
5612
0
    struct st_ptls_traffic_protection_t *ctx = is_enc ? &tls->traffic_protection.enc : &tls->traffic_protection.dec;
5613
0
    int ret;
5614
5615
0
    if ((ret = get_traffic_keys(tls->cipher_suite->aead, tls->cipher_suite->hash, key, iv, ctx->secret, ptls_iovec_init(NULL, 0),
5616
0
                                NULL)) != 0)
5617
0
        return ret;
5618
0
    *seq = ctx->seq;
5619
0
    return 0;
5620
0
}
5621
5622
const char *ptls_get_server_name(ptls_t *tls)
5623
0
{
5624
0
    return tls->server_name;
5625
0
}
5626
5627
int ptls_set_server_name(ptls_t *tls, const char *server_name, size_t server_name_len)
5628
0
{
5629
0
    char *duped = NULL;
5630
5631
0
    if (server_name != NULL &&
5632
0
        (duped = duplicate_as_str(server_name, server_name_len != 0 ? server_name_len : strlen(server_name))) == NULL)
5633
0
        return PTLS_ERROR_NO_MEMORY;
5634
5635
0
    free(tls->server_name);
5636
0
    tls->server_name = duped;
5637
5638
0
    return 0;
5639
0
}
5640
5641
const char *ptls_get_negotiated_protocol(ptls_t *tls)
5642
0
{
5643
0
    return tls->negotiated_protocol;
5644
0
}
5645
5646
int ptls_set_negotiated_protocol(ptls_t *tls, const char *protocol, size_t protocol_len)
5647
28
{
5648
28
    char *duped = NULL;
5649
5650
28
    if (protocol != NULL && (duped = duplicate_as_str(protocol, protocol_len != 0 ? protocol_len : strlen(protocol))) == NULL)
5651
0
        return PTLS_ERROR_NO_MEMORY;
5652
5653
28
    free(tls->negotiated_protocol);
5654
28
    tls->negotiated_protocol = duped;
5655
5656
28
    return 0;
5657
28
}
5658
5659
int ptls_handshake_is_complete(ptls_t *tls)
5660
0
{
5661
0
    return tls->state >= PTLS_STATE_POST_HANDSHAKE_MIN;
5662
0
}
5663
5664
int ptls_is_psk_handshake(ptls_t *tls)
5665
0
{
5666
0
    return tls->is_psk_handshake;
5667
0
}
5668
5669
int ptls_is_ech_handshake(ptls_t *tls, uint8_t *config_id, ptls_hpke_kem_t **kem, ptls_hpke_cipher_suite_t **cipher)
5670
372
{
5671
372
    if (tls->ech.state == PTLS_ECH_STATE_ACCEPTED) {
5672
0
        if (config_id != NULL)
5673
0
            *config_id = tls->ech.config_id;
5674
0
        if (kem != NULL)
5675
0
            *kem = tls->ech.kem;
5676
0
        if (cipher != NULL)
5677
0
            *cipher = tls->ech.cipher;
5678
0
        return 1;
5679
0
    }
5680
372
    return 0;
5681
372
}
5682
5683
void **ptls_get_data_ptr(ptls_t *tls)
5684
0
{
5685
0
    return &tls->data_ptr;
5686
0
}
5687
5688
ptls_log_conn_state_t *ptls_get_log_state(ptls_t *tls)
5689
0
{
5690
0
#if PTLS_HAVE_LOG
5691
0
    return &tls->log_state;
5692
#else
5693
    return &ptls_log.dummy_conn_state;
5694
#endif
5695
0
}
5696
5697
static int handle_client_handshake_message(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_iovec_t message, int is_end_of_record,
5698
                                           ptls_handshake_properties_t *properties)
5699
3.44k
{
5700
3.44k
    uint8_t type = message.base[0];
5701
3.44k
    int ret;
5702
5703
3.44k
    switch (tls->state) {
5704
1.73k
    case PTLS_STATE_CLIENT_EXPECT_SERVER_HELLO:
5705
1.77k
    case PTLS_STATE_CLIENT_EXPECT_SECOND_SERVER_HELLO:
5706
1.77k
        if (type == PTLS_HANDSHAKE_TYPE_SERVER_HELLO && is_end_of_record) {
5707
1.73k
            ret = client_handle_hello(tls, emitter, message, properties);
5708
1.73k
        } else {
5709
36
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
5710
36
        }
5711
1.77k
        break;
5712
962
    case PTLS_STATE_CLIENT_EXPECT_ENCRYPTED_EXTENSIONS:
5713
962
        if (type == PTLS_HANDSHAKE_TYPE_ENCRYPTED_EXTENSIONS) {
5714
952
            ret = client_handle_encrypted_extensions(tls, message, properties);
5715
952
        } else {
5716
10
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
5717
10
        }
5718
962
        break;
5719
640
    case PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_REQUEST_OR_CERTIFICATE:
5720
640
        if (type == PTLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) {
5721
264
            ret = client_handle_certificate_request(tls, message, properties);
5722
264
            break;
5723
264
        }
5724
    /* fall through */
5725
379
    case PTLS_STATE_CLIENT_EXPECT_CERTIFICATE:
5726
379
        switch (type) {
5727
375
        case PTLS_HANDSHAKE_TYPE_CERTIFICATE:
5728
375
            ret = client_handle_certificate(tls, message);
5729
375
            break;
5730
2
        case PTLS_HANDSHAKE_TYPE_COMPRESSED_CERTIFICATE:
5731
2
            ret = client_handle_compressed_certificate(tls, message);
5732
2
            break;
5733
2
        default:
5734
2
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
5735
2
            break;
5736
379
        }
5737
379
        break;
5738
379
    case PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_VERIFY:
5739
52
        if (type == PTLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY) {
5740
41
            ret = client_handle_certificate_verify(tls, message);
5741
41
        } else {
5742
11
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
5743
11
        }
5744
52
        break;
5745
9
    case PTLS_STATE_CLIENT_EXPECT_FINISHED:
5746
9
        if (type == PTLS_HANDSHAKE_TYPE_FINISHED && is_end_of_record) {
5747
7
            ret = client_handle_finished(tls, emitter, message);
5748
7
        } else {
5749
2
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
5750
2
        }
5751
9
        break;
5752
0
    case PTLS_STATE_CLIENT_POST_HANDSHAKE:
5753
0
        switch (type) {
5754
0
        case PTLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET:
5755
0
            ret = client_handle_new_session_ticket(tls, message);
5756
0
            break;
5757
0
        case PTLS_HANDSHAKE_TYPE_KEY_UPDATE:
5758
0
            ret = handle_key_update(tls, emitter, message);
5759
0
            break;
5760
0
        default:
5761
0
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
5762
0
            break;
5763
0
        }
5764
0
        break;
5765
0
    default:
5766
0
        assert(!"unexpected state");
5767
0
        ret = PTLS_ALERT_INTERNAL_ERROR;
5768
0
        break;
5769
3.44k
    }
5770
5771
3.44k
    PTLS_PROBE(RECEIVE_MESSAGE, tls, message.base[0], message.base + PTLS_HANDSHAKE_HEADER_SIZE,
5772
3.44k
               message.len - PTLS_HANDSHAKE_HEADER_SIZE, ret);
5773
3.44k
    PTLS_LOG_CONN(receive_message, tls, {
5774
3.44k
        PTLS_LOG_ELEMENT_UNSIGNED(message, message.base[0]);
5775
3.44k
        PTLS_LOG_ELEMENT_UNSIGNED(len, message.len - PTLS_HANDSHAKE_HEADER_SIZE);
5776
3.44k
        PTLS_LOG_ELEMENT_SIGNED(result, ret);
5777
3.44k
    });
5778
5779
3.44k
    return ret;
5780
3.44k
}
5781
5782
static int handle_server_handshake_message(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_iovec_t message, int is_end_of_record,
5783
                                           ptls_handshake_properties_t *properties)
5784
2.00k
{
5785
2.00k
    uint8_t type = message.base[0];
5786
2.00k
    int ret;
5787
5788
2.00k
    switch (tls->state) {
5789
1.89k
    case PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO:
5790
1.97k
    case PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO:
5791
1.97k
        if (type == PTLS_HANDSHAKE_TYPE_CLIENT_HELLO && is_end_of_record) {
5792
1.92k
            ret = server_handle_hello(tls, emitter, message, properties);
5793
1.92k
        } else {
5794
45
            ret = PTLS_ALERT_HANDSHAKE_FAILURE;
5795
45
        }
5796
1.97k
        break;
5797
0
    case PTLS_STATE_SERVER_EXPECT_CERTIFICATE:
5798
0
        if (type == PTLS_HANDSHAKE_TYPE_CERTIFICATE) {
5799
0
            ret = server_handle_certificate(tls, message);
5800
0
        } else {
5801
0
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
5802
0
        }
5803
0
        break;
5804
0
    case PTLS_STATE_SERVER_EXPECT_CERTIFICATE_VERIFY:
5805
0
        if (type == PTLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY) {
5806
0
            ret = server_handle_certificate_verify(tls, message);
5807
0
        } else {
5808
0
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
5809
0
        }
5810
0
        break;
5811
0
    case PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA:
5812
0
        assert(!tls->ctx->omit_end_of_early_data);
5813
0
        if (type == PTLS_HANDSHAKE_TYPE_END_OF_EARLY_DATA) {
5814
0
            ret = server_handle_end_of_early_data(tls, message);
5815
0
        } else {
5816
0
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
5817
0
        }
5818
0
        break;
5819
30
    case PTLS_STATE_SERVER_EXPECT_FINISHED:
5820
30
        if (type == PTLS_HANDSHAKE_TYPE_FINISHED && is_end_of_record) {
5821
8
            ret = server_handle_finished(tls, message);
5822
22
        } else {
5823
22
            ret = PTLS_ALERT_HANDSHAKE_FAILURE;
5824
22
        }
5825
30
        break;
5826
0
    case PTLS_STATE_SERVER_POST_HANDSHAKE:
5827
0
        switch (type) {
5828
0
        case PTLS_HANDSHAKE_TYPE_KEY_UPDATE:
5829
0
            ret = handle_key_update(tls, emitter, message);
5830
0
            break;
5831
0
        default:
5832
0
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
5833
0
            break;
5834
0
        }
5835
0
        break;
5836
0
    default:
5837
0
        assert(!"unexpected state");
5838
0
        ret = PTLS_ALERT_INTERNAL_ERROR;
5839
0
        break;
5840
2.00k
    }
5841
5842
2.00k
    PTLS_PROBE(RECEIVE_MESSAGE, tls, message.base[0], message.base + PTLS_HANDSHAKE_HEADER_SIZE,
5843
2.00k
               message.len - PTLS_HANDSHAKE_HEADER_SIZE, ret);
5844
2.00k
    PTLS_LOG_CONN(receive_message, tls, {
5845
2.00k
        PTLS_LOG_ELEMENT_UNSIGNED(message, message.base[0]);
5846
2.00k
        PTLS_LOG_ELEMENT_UNSIGNED(len, message.len - PTLS_HANDSHAKE_HEADER_SIZE);
5847
2.00k
        PTLS_LOG_ELEMENT_SIGNED(result, ret);
5848
2.00k
    });
5849
5850
2.00k
    return ret;
5851
2.00k
}
5852
5853
static int handle_alert(ptls_t *tls, const uint8_t *src, size_t len)
5854
78
{
5855
78
    if (len != 2)
5856
36
        return PTLS_ALERT_DECODE_ERROR;
5857
5858
42
    uint8_t desc = src[1];
5859
5860
    /* all fatal alerts and USER_CANCELLED warning tears down the connection immediately, regardless of the transmitted level */
5861
42
    return PTLS_ALERT_TO_PEER_ERROR(desc);
5862
78
}
5863
5864
static int message_buffer_is_overflow(ptls_context_t *ctx, size_t size)
5865
30.7k
{
5866
30.7k
    if (ctx->max_buffer_size == 0)
5867
30.7k
        return 0;
5868
0
    if (size <= ctx->max_buffer_size)
5869
0
        return 0;
5870
0
    return 1;
5871
0
}
5872
5873
static int handle_handshake_record(ptls_t *tls,
5874
                                   int (*cb)(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_iovec_t message,
5875
                                             int is_end_of_record, ptls_handshake_properties_t *properties),
5876
                                   ptls_message_emitter_t *emitter, struct st_ptls_record_t *rec,
5877
                                   ptls_handshake_properties_t *properties)
5878
42.6k
{
5879
42.6k
    int ret;
5880
5881
    /* handshake */
5882
42.6k
    if (rec->type != PTLS_CONTENT_TYPE_HANDSHAKE)
5883
28
        return PTLS_ALERT_DECODE_ERROR;
5884
5885
    /* flatten the unhandled messages */
5886
42.6k
    const uint8_t *src, *src_end;
5887
42.6k
    if (tls->recvbuf.mess.base == NULL) {
5888
27.3k
        src = rec->fragment;
5889
27.3k
        src_end = src + rec->length;
5890
27.3k
    } else {
5891
15.2k
        if (message_buffer_is_overflow(tls->ctx, tls->recvbuf.mess.off + rec->length))
5892
0
            return PTLS_ALERT_HANDSHAKE_FAILURE;
5893
15.2k
        if ((ret = ptls_buffer_reserve(&tls->recvbuf.mess, rec->length)) != 0)
5894
0
            return ret;
5895
15.2k
        memcpy(tls->recvbuf.mess.base + tls->recvbuf.mess.off, rec->fragment, rec->length);
5896
15.2k
        tls->recvbuf.mess.off += rec->length;
5897
15.2k
        src = tls->recvbuf.mess.base;
5898
15.2k
        src_end = src + tls->recvbuf.mess.off;
5899
15.2k
    }
5900
5901
    /* handle the messages */
5902
42.6k
    ret = PTLS_ERROR_IN_PROGRESS;
5903
44.8k
    while (src_end - src >= 4) {
5904
18.0k
        size_t mess_len = 4 + ntoh24(src + 1);
5905
18.0k
        if (src_end - src < (int)mess_len)
5906
12.6k
            break;
5907
5.44k
        ret = cb(tls, emitter, ptls_iovec_init(src, mess_len), src_end - src == mess_len, properties);
5908
5.44k
        switch (ret) {
5909
212
        case 0:
5910
212
        case PTLS_ERROR_ASYNC_OPERATION:
5911
2.23k
        case PTLS_ERROR_IN_PROGRESS:
5912
2.23k
            break;
5913
3.20k
        default:
5914
3.20k
            ptls_buffer_dispose(&tls->recvbuf.mess);
5915
3.20k
            return ret;
5916
5.44k
        }
5917
2.23k
        src += mess_len;
5918
2.23k
    }
5919
5920
    /* keep last partial message in buffer */
5921
39.4k
    if (src != src_end) {
5922
15.5k
        size_t new_size = src_end - src;
5923
15.5k
        if (message_buffer_is_overflow(tls->ctx, new_size))
5924
0
            return PTLS_ALERT_HANDSHAKE_FAILURE;
5925
15.5k
        if (tls->recvbuf.mess.base == NULL) {
5926
378
            ptls_buffer_init(&tls->recvbuf.mess, "", 0);
5927
378
            if ((ret = ptls_buffer_reserve(&tls->recvbuf.mess, new_size)) != 0)
5928
0
                return ret;
5929
378
            memcpy(tls->recvbuf.mess.base, src, new_size);
5930
15.1k
        } else {
5931
15.1k
            memmove(tls->recvbuf.mess.base, src, new_size);
5932
15.1k
        }
5933
15.5k
        tls->recvbuf.mess.off = new_size;
5934
15.5k
        ret = PTLS_ERROR_IN_PROGRESS;
5935
23.8k
    } else {
5936
23.8k
        ptls_buffer_dispose(&tls->recvbuf.mess);
5937
23.8k
    }
5938
5939
39.4k
    return ret;
5940
39.4k
}
5941
5942
static int handle_input(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_buffer_t *decryptbuf, const void *input, size_t *inlen,
5943
                        ptls_handshake_properties_t *properties)
5944
54.4k
{
5945
54.4k
    struct st_ptls_record_t rec;
5946
54.4k
    int ret;
5947
5948
    /* extract the record */
5949
54.4k
    if ((ret = parse_record(tls, &rec, input, inlen)) != 0)
5950
339
        return ret;
5951
54.4k
    assert(rec.fragment != NULL);
5952
5953
    /* decrypt the record */
5954
54.1k
    if (rec.type == PTLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
5955
627
        if (tls->state < PTLS_STATE_POST_HANDSHAKE_MIN) {
5956
627
            if (!(rec.length == 1 && rec.fragment[0] == 0x01))
5957
48
                return PTLS_ALERT_UNEXPECTED_MESSAGE;
5958
627
        } else {
5959
0
            return PTLS_ALERT_UNEXPECTED_MESSAGE;
5960
0
        }
5961
579
        ret = PTLS_ERROR_IN_PROGRESS;
5962
579
        goto NextRecord;
5963
627
    }
5964
53.5k
    if (tls->traffic_protection.dec.aead != NULL && rec.type != PTLS_CONTENT_TYPE_ALERT) {
5965
11.9k
        size_t decrypted_length;
5966
11.9k
        if (rec.type != PTLS_CONTENT_TYPE_APPDATA)
5967
10
            return PTLS_ALERT_HANDSHAKE_FAILURE;
5968
11.9k
        if ((ret = ptls_buffer_reserve(decryptbuf, 5 + rec.length)) != 0)
5969
0
            return ret;
5970
11.9k
        if ((ret = aead_decrypt(&tls->traffic_protection.dec, decryptbuf->base + decryptbuf->off, &decrypted_length, rec.fragment,
5971
11.9k
                                rec.length)) != 0) {
5972
10.2k
            if (tls->is_server && tls->server.early_data_skipped_bytes != UINT32_MAX)
5973
10.2k
                goto ServerSkipEarlyData;
5974
13
            return ret;
5975
10.2k
        }
5976
1.69k
        rec.length = decrypted_length;
5977
1.69k
        rec.fragment = decryptbuf->base + decryptbuf->off;
5978
        /* skip padding */
5979
5.87k
        for (; rec.length != 0; --rec.length)
5980
5.86k
            if (rec.fragment[rec.length - 1] != 0)
5981
1.67k
                break;
5982
1.69k
        if (rec.length == 0)
5983
16
            return PTLS_ALERT_UNEXPECTED_MESSAGE;
5984
1.67k
        rec.type = rec.fragment[--rec.length];
5985
1.67k
        if (rec.length == 0 && (rec.type == PTLS_CONTENT_TYPE_ALERT || rec.type == PTLS_CONTENT_TYPE_HANDSHAKE))
5986
12
            return PTLS_ALERT_UNEXPECTED_MESSAGE;
5987
41.5k
    } else if (rec.type == PTLS_CONTENT_TYPE_APPDATA && tls->is_server && tls->server.early_data_skipped_bytes != UINT32_MAX) {
5988
437
        goto ServerSkipEarlyData;
5989
437
    }
5990
5991
42.7k
    if (tls->recvbuf.mess.base != NULL || rec.type == PTLS_CONTENT_TYPE_HANDSHAKE) {
5992
        /* handshake record */
5993
42.6k
        ret = handle_handshake_record(tls, tls->is_server ? handle_server_handshake_message : handle_client_handshake_message,
5994
42.6k
                                      emitter, &rec, properties);
5995
42.6k
    } else {
5996
        /* handling of an alert or an application record */
5997
156
        switch (rec.type) {
5998
16
        case PTLS_CONTENT_TYPE_APPDATA:
5999
16
            if (tls->state >= PTLS_STATE_POST_HANDSHAKE_MIN) {
6000
0
                decryptbuf->off += rec.length;
6001
0
                ret = 0;
6002
16
            } else if (tls->state == PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA) {
6003
0
                if (tls->traffic_protection.dec.aead != NULL)
6004
0
                    decryptbuf->off += rec.length;
6005
0
                ret = 0;
6006
16
            } else {
6007
16
                ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
6008
16
            }
6009
16
            break;
6010
78
        case PTLS_CONTENT_TYPE_ALERT:
6011
78
            ret = handle_alert(tls, rec.fragment, rec.length);
6012
78
            break;
6013
62
        default:
6014
62
            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
6015
62
            break;
6016
156
        }
6017
156
    }
6018
6019
54.0k
NextRecord:
6020
54.0k
    ptls_buffer_dispose(&tls->recvbuf.rec);
6021
54.0k
    return ret;
6022
6023
10.6k
ServerSkipEarlyData:
6024
10.6k
    tls->server.early_data_skipped_bytes += (uint32_t)rec.length;
6025
10.6k
    if (tls->server.early_data_skipped_bytes > PTLS_MAX_EARLY_DATA_SKIP_SIZE)
6026
2
        return PTLS_ALERT_HANDSHAKE_FAILURE;
6027
10.6k
    ret = PTLS_ERROR_IN_PROGRESS;
6028
10.6k
    goto NextRecord;
6029
10.6k
}
6030
6031
static int handle_input_tls12(ptls_t *tls, ptls_buffer_t *decryptbuf, const void *input, size_t *inlen)
6032
0
{
6033
0
    struct st_ptls_record_t rec;
6034
0
    int ret;
6035
6036
    /* extract the record, or bail out */
6037
0
    if ((ret = parse_record(tls, &rec, input, inlen)) != 0)
6038
0
        return ret;
6039
0
    assert(rec.fragment != NULL);
6040
6041
0
    const uint8_t *src = rec.fragment, *end = src + rec.length;
6042
0
    uint64_t nonce;
6043
0
    uint8_t aad[PTLS_TLS12_AAD_SIZE];
6044
6045
    /* determine the nonce */
6046
0
    if (tls->traffic_protection.dec.aead->algo->tls12.record_iv_size != 0) {
6047
0
        assert(tls->traffic_protection.dec.aead->algo->tls12.record_iv_size == 8);
6048
0
        if ((ret = ptls_decode64(&nonce, &src, end)) != 0)
6049
0
            goto Exit;
6050
0
    } else {
6051
0
        nonce = tls->traffic_protection.dec.seq;
6052
0
    }
6053
6054
    /* determine cleartext length */
6055
0
    size_t textlen = end - src;
6056
0
    if (textlen < tls->traffic_protection.dec.aead->algo->tag_size) {
6057
0
        ret = PTLS_ALERT_BAD_RECORD_MAC;
6058
0
        goto Exit;
6059
0
    }
6060
0
    textlen -= tls->traffic_protection.dec.aead->algo->tag_size;
6061
6062
    /* build aad */
6063
0
    build_tls12_aad(aad, rec.type, tls->traffic_protection.dec.seq, (uint16_t)textlen);
6064
6065
    /* decrypt input to decryptbuf */
6066
0
    if ((ret = ptls_buffer_reserve(decryptbuf, textlen)) != 0)
6067
0
        goto Exit;
6068
0
    if (ptls_aead_decrypt(tls->traffic_protection.dec.aead, decryptbuf->base + decryptbuf->off, src, end - src, nonce, aad,
6069
0
                          sizeof(aad)) != textlen) {
6070
0
        ret = PTLS_ALERT_BAD_RECORD_MAC;
6071
0
        goto Exit;
6072
0
    }
6073
0
    ++tls->traffic_protection.dec.seq;
6074
6075
    /* record-type specific action */
6076
0
    switch (rec.type) {
6077
0
    case PTLS_CONTENT_TYPE_APPDATA:
6078
        /* if application data, retain the bytes being decrypted */
6079
0
        decryptbuf->off += textlen;
6080
0
        break;
6081
0
    case PTLS_CONTENT_TYPE_ALERT:
6082
        /* submit alert without adjusting decryptbuf, so that the decrypted data would be dropped after handling the alert */
6083
0
        ret = handle_alert(tls, decryptbuf->base + decryptbuf->off, textlen);
6084
0
        break;
6085
0
    default:
6086
0
        ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
6087
0
        break;
6088
0
    }
6089
6090
0
Exit:
6091
0
    ptls_buffer_dispose(&tls->recvbuf.rec);
6092
0
    ptls_clear_memory(aad, sizeof(aad));
6093
0
    return ret;
6094
0
}
6095
6096
static void init_record_message_emitter(ptls_t *tls, struct st_ptls_record_message_emitter_t *emitter, ptls_buffer_t *sendbuf)
6097
6.13k
{
6098
6.13k
    *emitter = (struct st_ptls_record_message_emitter_t){
6099
6.13k
        {sendbuf, &tls->traffic_protection.enc, 5, begin_record_message, commit_record_message}};
6100
6.13k
}
6101
6102
int ptls_handshake(ptls_t *tls, ptls_buffer_t *_sendbuf, const void *input, size_t *inlen, ptls_handshake_properties_t *properties)
6103
6.13k
{
6104
6.13k
    struct st_ptls_record_message_emitter_t emitter;
6105
6.13k
    int ret;
6106
6107
6.13k
    assert(tls->state < PTLS_STATE_POST_HANDSHAKE_MIN);
6108
6109
6.13k
    init_record_message_emitter(tls, &emitter, _sendbuf);
6110
6.13k
    size_t sendbuf_orig_off = emitter.super.buf->off;
6111
6112
    /* special handlings */
6113
6.13k
    switch (tls->state) {
6114
1.99k
    case PTLS_STATE_CLIENT_HANDSHAKE_START: {
6115
1.99k
        assert(input == NULL || *inlen == 0);
6116
1.99k
        return send_client_hello(tls, &emitter.super, properties, NULL);
6117
1.99k
    }
6118
0
    case PTLS_STATE_SERVER_GENERATING_CERTIFICATE_VERIFY:
6119
0
        return server_finish_handshake(tls, &emitter.super, 1, NULL);
6120
4.14k
    default:
6121
4.14k
        break;
6122
6.13k
    }
6123
6124
4.14k
    const uint8_t *src = input, *const src_end = src + *inlen;
6125
4.14k
    ptls_buffer_t decryptbuf;
6126
6127
4.14k
    ptls_buffer_init(&decryptbuf, "", 0);
6128
6129
    /* perform handhake until completion or until all the input has been swallowed */
6130
4.14k
    ret = PTLS_ERROR_IN_PROGRESS;
6131
47.7k
    while (ret == PTLS_ERROR_IN_PROGRESS && src != src_end) {
6132
43.5k
        size_t consumed = src_end - src;
6133
43.5k
        ret = handle_input(tls, &emitter.super, &decryptbuf, src, &consumed, properties);
6134
43.5k
        src += consumed;
6135
43.5k
        assert(decryptbuf.off == 0);
6136
43.5k
    }
6137
6138
4.14k
    ptls_buffer_dispose(&decryptbuf);
6139
6140
4.14k
    switch (ret) {
6141
212
    case 0:
6142
696
    case PTLS_ERROR_IN_PROGRESS:
6143
696
    case PTLS_ERROR_STATELESS_RETRY:
6144
696
    case PTLS_ERROR_ASYNC_OPERATION:
6145
696
        break;
6146
3.45k
    default:
6147
        /* Flush handshake messages that have been written partially. ECH_REQUIRED sticks out because it is a message sent
6148
         * post-handshake compared to other alerts that are generating *during* the handshake. */
6149
3.45k
        if (ret != PTLS_ALERT_ECH_REQUIRED) {
6150
3.45k
            ptls_clear_memory(emitter.super.buf->base + sendbuf_orig_off, emitter.super.buf->off - sendbuf_orig_off);
6151
3.45k
            emitter.super.buf->off = sendbuf_orig_off;
6152
3.45k
        }
6153
        /* send alert immediately */
6154
3.45k
        if (PTLS_ERROR_GET_CLASS(ret) != PTLS_ERROR_CLASS_PEER_ALERT)
6155
3.41k
            if (ptls_send_alert(tls, emitter.super.buf, PTLS_ALERT_LEVEL_FATAL,
6156
3.41k
                                PTLS_ERROR_GET_CLASS(ret) == PTLS_ERROR_CLASS_SELF_ALERT ? ret : PTLS_ALERT_INTERNAL_ERROR) != 0)
6157
0
                emitter.super.buf->off = sendbuf_orig_off;
6158
3.45k
        break;
6159
4.14k
    }
6160
6161
4.14k
    *inlen -= src_end - src;
6162
4.14k
    return ret;
6163
4.14k
}
6164
6165
int ptls_receive(ptls_t *tls, ptls_buffer_t *decryptbuf, const void *_input, size_t *inlen)
6166
187
{
6167
187
    const uint8_t *input = (const uint8_t *)_input, *const end = input + *inlen;
6168
187
    size_t decryptbuf_orig_size = decryptbuf->off;
6169
187
    int ret = 0;
6170
6171
187
    assert(tls->state >= PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA);
6172
6173
    /* loop until we decrypt some application data (or an error) */
6174
11.0k
    while (ret == 0 && input != end && decryptbuf_orig_size == decryptbuf->off) {
6175
10.8k
        size_t consumed = end - input;
6176
10.8k
        if (tls->traffic_protection.dec.tls12) {
6177
0
            ret = handle_input_tls12(tls, decryptbuf, input, &consumed);
6178
10.8k
        } else {
6179
10.8k
            ret = handle_input(tls, NULL, decryptbuf, input, &consumed, NULL);
6180
10.8k
        }
6181
10.8k
        input += consumed;
6182
6183
10.8k
        switch (ret) {
6184
0
        case 0:
6185
0
            break;
6186
10.7k
        case PTLS_ERROR_IN_PROGRESS:
6187
10.7k
            ret = 0;
6188
10.7k
            break;
6189
1
        case PTLS_ERROR_CLASS_PEER_ALERT + PTLS_ALERT_CLOSE_NOTIFY:
6190
            /* TODO send close alert */
6191
1
            break;
6192
142
        default:
6193
142
            if (PTLS_ERROR_GET_CLASS(ret) == PTLS_ERROR_CLASS_SELF_ALERT) {
6194
                /* TODO send alert */
6195
133
            }
6196
142
            break;
6197
10.8k
        }
6198
10.8k
    }
6199
6200
187
    *inlen -= end - input;
6201
6202
187
    return ret;
6203
187
}
6204
6205
static int update_send_key(ptls_t *tls, ptls_buffer_t *_sendbuf, int request_update)
6206
0
{
6207
0
    struct st_ptls_record_message_emitter_t emitter;
6208
0
    int ret;
6209
6210
0
    init_record_message_emitter(tls, &emitter, _sendbuf);
6211
0
    size_t sendbuf_orig_off = emitter.super.buf->off;
6212
6213
0
    ptls_push_message(&emitter.super, NULL, PTLS_HANDSHAKE_TYPE_KEY_UPDATE,
6214
0
                      { ptls_buffer_push(emitter.super.buf, !!request_update); });
6215
0
    if ((ret = update_traffic_key(tls, 1)) != 0)
6216
0
        goto Exit;
6217
0
    ret = 0;
6218
6219
0
Exit:
6220
0
    if (ret != 0)
6221
0
        emitter.super.buf->off = sendbuf_orig_off;
6222
0
    return ret;
6223
0
}
6224
6225
int ptls_send(ptls_t *tls, ptls_buffer_t *sendbuf, const void *input, size_t inlen)
6226
0
{
6227
0
    if (!(tls->traffic_protection.enc.aead != NULL &&
6228
0
          (tls->traffic_protection.enc.tls12 || tls->traffic_protection.enc.epoch == 1 ||
6229
0
           tls->traffic_protection.enc.epoch == 3)))
6230
0
        return PTLS_ERROR_IN_PROGRESS;
6231
6232
    /* "For AES-GCM, up to 2^24.5 full-size records (about 24 million) may be encrypted on a given connection while keeping a
6233
     * safety margin of approximately 2^-57 for Authenticated Encryption (AE) security." (RFC 8446 section 5.5).
6234
     *
6235
     * Key updates do not happen with tls 1.2, check `key_schedule` to see if we are using tls/1.3
6236
     */
6237
0
    if (tls->traffic_protection.enc.seq >= 16777216 && tls->key_schedule != NULL)
6238
0
        tls->needs_key_update = 1;
6239
6240
0
    if (tls->needs_key_update) {
6241
0
        int ret;
6242
0
        if ((ret = update_send_key(tls, sendbuf, tls->key_update_send_request)) != 0)
6243
0
            return ret;
6244
0
        tls->needs_key_update = 0;
6245
0
        tls->key_update_send_request = 0;
6246
0
    }
6247
6248
0
    return buffer_push_encrypted_records(sendbuf, PTLS_CONTENT_TYPE_APPDATA, input, inlen, &tls->traffic_protection.enc);
6249
0
}
6250
6251
int ptls_update_key(ptls_t *tls, int request_update)
6252
0
{
6253
0
    assert(tls->ctx->update_traffic_key == NULL);
6254
0
    tls->needs_key_update = 1;
6255
0
    tls->key_update_send_request = request_update;
6256
0
    return 0;
6257
0
}
6258
6259
size_t ptls_get_record_overhead(ptls_t *tls)
6260
0
{
6261
0
    ptls_aead_algorithm_t *algo = tls->traffic_protection.enc.aead->algo;
6262
6263
0
    if (tls->traffic_protection.enc.tls12) {
6264
0
        return 5 + algo->tls12.record_iv_size + algo->tag_size;
6265
0
    } else {
6266
0
        return 6 + algo->tag_size;
6267
0
    }
6268
0
}
6269
6270
int ptls_send_alert(ptls_t *tls, ptls_buffer_t *sendbuf, uint8_t level, uint8_t description)
6271
3.41k
{
6272
3.41k
    size_t rec_start = sendbuf->off;
6273
3.41k
    int ret = 0;
6274
6275
3.41k
    buffer_push_record(sendbuf, PTLS_CONTENT_TYPE_ALERT, { ptls_buffer_push(sendbuf, level, description); });
6276
    /* encrypt the alert if we have the encryption keys, unless when it is the early data key */
6277
3.41k
    if (tls->traffic_protection.enc.aead != NULL && !(tls->state <= PTLS_STATE_CLIENT_EXPECT_FINISHED)) {
6278
10
        if ((ret = buffer_encrypt_record(sendbuf, rec_start, &tls->traffic_protection.enc)) != 0)
6279
0
            goto Exit;
6280
10
    }
6281
6282
3.41k
Exit:
6283
3.41k
    return ret;
6284
3.41k
}
6285
6286
int ptls_export_secret(ptls_t *tls, void *output, size_t outlen, const char *label, ptls_iovec_t context_value, int is_early)
6287
0
{
6288
0
    ptls_hash_algorithm_t *algo = tls->key_schedule->hashes[0].algo;
6289
0
    uint8_t *master_secret = is_early ? tls->exporter_master_secret.early : tls->exporter_master_secret.one_rtt,
6290
0
            derived_secret[PTLS_MAX_DIGEST_SIZE], context_value_hash[PTLS_MAX_DIGEST_SIZE];
6291
0
    int ret;
6292
6293
0
    if (master_secret == NULL) {
6294
0
        if (is_early) {
6295
0
            switch (tls->state) {
6296
0
            case PTLS_STATE_CLIENT_HANDSHAKE_START:
6297
0
            case PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO:
6298
0
                ret = PTLS_ERROR_IN_PROGRESS;
6299
0
                break;
6300
0
            default:
6301
0
                ret = PTLS_ERROR_NOT_AVAILABLE;
6302
0
                break;
6303
0
            }
6304
0
        } else {
6305
0
            ret = PTLS_ERROR_IN_PROGRESS;
6306
0
        }
6307
0
        return ret;
6308
0
    }
6309
6310
0
    if ((ret = ptls_calc_hash(algo, context_value_hash, context_value.base, context_value.len)) != 0)
6311
0
        return ret;
6312
6313
0
    if ((ret = ptls_hkdf_expand_label(algo, derived_secret, algo->digest_size, ptls_iovec_init(master_secret, algo->digest_size),
6314
0
                                      label, ptls_iovec_init(algo->empty_digest, algo->digest_size), NULL)) != 0)
6315
0
        goto Exit;
6316
0
    ret = ptls_hkdf_expand_label(algo, output, outlen, ptls_iovec_init(derived_secret, algo->digest_size), "exporter",
6317
0
                                 ptls_iovec_init(context_value_hash, algo->digest_size), NULL);
6318
6319
0
Exit:
6320
0
    ptls_clear_memory(derived_secret, sizeof(derived_secret));
6321
0
    ptls_clear_memory(context_value_hash, sizeof(context_value_hash));
6322
0
    return ret;
6323
0
}
6324
6325
struct st_picotls_hmac_context_t {
6326
    ptls_hash_context_t super;
6327
    ptls_hash_algorithm_t *algo;
6328
    ptls_hash_context_t *hash;
6329
    uint8_t key[1];
6330
};
6331
6332
static void hmac_update(ptls_hash_context_t *_ctx, const void *src, size_t len)
6333
25.9k
{
6334
25.9k
    struct st_picotls_hmac_context_t *ctx = (struct st_picotls_hmac_context_t *)_ctx;
6335
25.9k
    ctx->hash->update(ctx->hash, src, len);
6336
25.9k
}
6337
6338
static void hmac_apply_key(struct st_picotls_hmac_context_t *ctx, uint8_t pad)
6339
41.1k
{
6340
41.1k
    size_t i;
6341
6342
3.26M
    for (i = 0; i != ctx->algo->block_size; ++i)
6343
3.22M
        ctx->key[i] ^= pad;
6344
41.1k
    ctx->hash->update(ctx->hash, ctx->key, ctx->algo->block_size);
6345
3.26M
    for (i = 0; i != ctx->algo->block_size; ++i)
6346
3.22M
        ctx->key[i] ^= pad;
6347
41.1k
}
6348
6349
static void hmac_final(ptls_hash_context_t *_ctx, void *md, ptls_hash_final_mode_t mode)
6350
25.9k
{
6351
25.9k
    struct st_picotls_hmac_context_t *ctx = (struct st_picotls_hmac_context_t *)_ctx;
6352
6353
25.9k
    assert(mode != PTLS_HASH_FINAL_MODE_SNAPSHOT || !"not supported");
6354
6355
25.9k
    if (md != NULL) {
6356
15.1k
        ctx->hash->final(ctx->hash, md, PTLS_HASH_FINAL_MODE_RESET);
6357
15.1k
        hmac_apply_key(ctx, 0x5c);
6358
15.1k
        ctx->hash->update(ctx->hash, md, ctx->algo->digest_size);
6359
15.1k
    }
6360
25.9k
    ctx->hash->final(ctx->hash, md, mode);
6361
6362
25.9k
    switch (mode) {
6363
15.1k
    case PTLS_HASH_FINAL_MODE_FREE:
6364
15.1k
        ptls_clear_memory(ctx->key, ctx->algo->block_size);
6365
15.1k
        free(ctx);
6366
15.1k
        break;
6367
10.7k
    case PTLS_HASH_FINAL_MODE_RESET:
6368
10.7k
        hmac_apply_key(ctx, 0x36);
6369
10.7k
        break;
6370
0
    default:
6371
0
        assert(!"FIXME");
6372
0
        break;
6373
25.9k
    }
6374
25.9k
}
6375
6376
int ptls_calc_hash(ptls_hash_algorithm_t *algo, void *output, const void *src, size_t len)
6377
0
{
6378
0
    ptls_hash_context_t *ctx;
6379
6380
0
    if ((ctx = algo->create()) == NULL)
6381
0
        return PTLS_ERROR_NO_MEMORY;
6382
0
    ctx->update(ctx, src, len);
6383
0
    ctx->final(ctx, output, PTLS_HASH_FINAL_MODE_FREE);
6384
0
    return 0;
6385
0
}
6386
6387
ptls_hash_context_t *ptls_hmac_create(ptls_hash_algorithm_t *algo, const void *key, size_t key_size)
6388
15.1k
{
6389
15.1k
    struct st_picotls_hmac_context_t *ctx;
6390
6391
15.1k
    assert(key_size <= algo->block_size);
6392
6393
15.1k
    if ((ctx = malloc(offsetof(struct st_picotls_hmac_context_t, key) + algo->block_size)) == NULL)
6394
0
        return NULL;
6395
6396
15.1k
    *ctx = (struct st_picotls_hmac_context_t){{hmac_update, hmac_final}, algo};
6397
15.1k
    if ((ctx->hash = algo->create()) == NULL) {
6398
0
        free(ctx);
6399
0
        return NULL;
6400
0
    }
6401
15.1k
    memset(ctx->key, 0, algo->block_size);
6402
15.1k
    memcpy(ctx->key, key, key_size);
6403
6404
15.1k
    hmac_apply_key(ctx, 0x36);
6405
6406
15.1k
    return &ctx->super;
6407
15.1k
}
6408
6409
int ptls_hkdf_extract(ptls_hash_algorithm_t *algo, void *output, ptls_iovec_t salt, ptls_iovec_t ikm)
6410
3.94k
{
6411
3.94k
    ptls_hash_context_t *hash;
6412
6413
3.94k
    if (salt.len == 0)
6414
0
        salt = ptls_iovec_init(zeroes_of_max_digest_size, algo->digest_size);
6415
6416
3.94k
    if ((hash = ptls_hmac_create(algo, salt.base, salt.len)) == NULL)
6417
0
        return PTLS_ERROR_NO_MEMORY;
6418
3.94k
    hash->update(hash, ikm.base, ikm.len);
6419
3.94k
    hash->final(hash, output, PTLS_HASH_FINAL_MODE_FREE);
6420
3.94k
    return 0;
6421
3.94k
}
6422
6423
int ptls_hkdf_expand(ptls_hash_algorithm_t *algo, void *output, size_t outlen, ptls_iovec_t prk, ptls_iovec_t info)
6424
10.7k
{
6425
10.7k
    ptls_hash_context_t *hmac = NULL;
6426
10.7k
    size_t i;
6427
10.7k
    uint8_t digest[PTLS_MAX_DIGEST_SIZE];
6428
6429
21.5k
    for (i = 0; (i * algo->digest_size) < outlen; ++i) {
6430
10.7k
        if (hmac == NULL) {
6431
10.7k
            if ((hmac = ptls_hmac_create(algo, prk.base, prk.len)) == NULL)
6432
0
                return PTLS_ERROR_NO_MEMORY;
6433
10.7k
        } else {
6434
0
            hmac->update(hmac, digest, algo->digest_size);
6435
0
        }
6436
10.7k
        hmac->update(hmac, info.base, info.len);
6437
10.7k
        uint8_t gen = (uint8_t)(i + 1);
6438
10.7k
        hmac->update(hmac, &gen, 1);
6439
10.7k
        hmac->final(hmac, digest, 1);
6440
6441
10.7k
        size_t off_start = i * algo->digest_size, off_end = off_start + algo->digest_size;
6442
10.7k
        if (off_end > outlen)
6443
5.48k
            off_end = outlen;
6444
10.7k
        memcpy((uint8_t *)output + off_start, digest, off_end - off_start);
6445
10.7k
    }
6446
6447
10.7k
    if (hmac != NULL)
6448
10.7k
        hmac->final(hmac, NULL, PTLS_HASH_FINAL_MODE_FREE);
6449
6450
10.7k
    ptls_clear_memory(digest, algo->digest_size);
6451
6452
10.7k
    return 0;
6453
10.7k
}
6454
6455
int ptls_hkdf_expand_label(ptls_hash_algorithm_t *algo, void *output, size_t outlen, ptls_iovec_t secret, const char *label,
6456
                           ptls_iovec_t hash_value, const char *label_prefix)
6457
10.7k
{
6458
10.7k
    ptls_buffer_t hkdf_label;
6459
10.7k
    uint8_t hkdf_label_buf[80];
6460
10.7k
    int ret;
6461
6462
10.7k
    ptls_buffer_init(&hkdf_label, hkdf_label_buf, sizeof(hkdf_label_buf));
6463
6464
10.7k
    ptls_buffer_push16(&hkdf_label, (uint16_t)outlen);
6465
10.7k
    ptls_buffer_push_block(&hkdf_label, 1, {
6466
10.7k
        if (label_prefix == NULL)
6467
10.7k
            label_prefix = PTLS_HKDF_EXPAND_LABEL_PREFIX;
6468
10.7k
        ptls_buffer_pushv(&hkdf_label, label_prefix, strlen(label_prefix));
6469
10.7k
        ptls_buffer_pushv(&hkdf_label, label, strlen(label));
6470
10.7k
    });
6471
10.7k
    ptls_buffer_push_block(&hkdf_label, 1, { ptls_buffer_pushv(&hkdf_label, hash_value.base, hash_value.len); });
6472
6473
10.7k
    ret = ptls_hkdf_expand(algo, output, outlen, secret, ptls_iovec_init(hkdf_label.base, hkdf_label.off));
6474
6475
10.7k
Exit:
6476
10.7k
    ptls_buffer_dispose(&hkdf_label);
6477
10.7k
    return ret;
6478
10.7k
}
6479
6480
int ptls_tls12_phash(ptls_hash_algorithm_t *algo, void *output, size_t outlen, ptls_iovec_t secret, const char *label,
6481
                     ptls_iovec_t seed)
6482
0
{
6483
0
    ptls_hash_context_t *hmac;
6484
0
    uint8_t An[PTLS_MAX_DIGEST_SIZE];
6485
0
    size_t output_off = 0;
6486
6487
0
    if ((hmac = ptls_hmac_create(algo, secret.base, secret.len)) == NULL)
6488
0
        return PTLS_ERROR_NO_MEMORY;
6489
6490
    /* A(1) = HMAC_hash(secret, label + seed) */
6491
0
    if (label != NULL)
6492
0
        hmac->update(hmac, label, strlen(label));
6493
0
    hmac->update(hmac, seed.base, seed.len);
6494
0
    hmac->final(hmac, An, PTLS_HASH_FINAL_MODE_RESET);
6495
6496
0
    while (1) {
6497
        /* output += HMAC_hash(secret, A(i) + label + seed) */
6498
0
        hmac->update(hmac, An, algo->digest_size);
6499
0
        if (label != NULL)
6500
0
            hmac->update(hmac, label, strlen(label));
6501
0
        hmac->update(hmac, seed.base, seed.len);
6502
0
        if (outlen - output_off <= algo->digest_size) {
6503
            /* digest of last chunk is at first written to An then the necessary bytes are copied to output */
6504
0
            hmac->final(hmac, An, PTLS_HASH_FINAL_MODE_FREE);
6505
0
            memcpy((uint8_t *)output + output_off, An, outlen - output_off);
6506
0
            break;
6507
0
        }
6508
0
        hmac->final(hmac, (uint8_t *)output + output_off, PTLS_HASH_FINAL_MODE_RESET);
6509
0
        output_off += algo->digest_size;
6510
6511
        /* A(i) = HMAC_hash(secret, A(i-1)) */
6512
0
        hmac->update(hmac, An, algo->digest_size);
6513
0
        hmac->final(hmac, An, PTLS_HASH_FINAL_MODE_RESET);
6514
0
    }
6515
6516
0
    ptls_clear_memory(An, algo->digest_size);
6517
6518
0
    return 0;
6519
0
}
6520
6521
ptls_cipher_context_t *ptls_cipher_new(ptls_cipher_algorithm_t *algo, int is_enc, const void *key)
6522
0
{
6523
0
    ptls_cipher_context_t *ctx;
6524
6525
0
    if ((ctx = (ptls_cipher_context_t *)malloc(algo->context_size)) == NULL)
6526
0
        return NULL;
6527
0
    *ctx = (ptls_cipher_context_t){algo};
6528
0
    if (algo->setup_crypto(ctx, is_enc, key) != 0) {
6529
0
        free(ctx);
6530
0
        ctx = NULL;
6531
0
    }
6532
0
    return ctx;
6533
0
}
6534
6535
void ptls_cipher_free(ptls_cipher_context_t *ctx)
6536
0
{
6537
0
    ctx->do_dispose(ctx);
6538
0
    free(ctx);
6539
0
}
6540
6541
ptls_aead_context_t *new_aead(ptls_aead_algorithm_t *aead, ptls_hash_algorithm_t *hash, int is_enc, const void *secret,
6542
                              ptls_iovec_t hash_value, const char *label_prefix)
6543
2.74k
{
6544
2.74k
    ptls_aead_context_t *ctx = NULL;
6545
2.74k
    struct {
6546
2.74k
        uint8_t key[PTLS_MAX_SECRET_SIZE];
6547
2.74k
        uint8_t iv[PTLS_MAX_IV_SIZE];
6548
2.74k
    } key_iv;
6549
2.74k
    int ret;
6550
6551
2.74k
    if ((ret = get_traffic_keys(aead, hash, key_iv.key, key_iv.iv, secret, hash_value, label_prefix)) != 0)
6552
0
        goto Exit;
6553
2.74k
    ctx = ptls_aead_new_direct(aead, is_enc, key_iv.key, key_iv.iv);
6554
2.74k
Exit:
6555
2.74k
    ptls_clear_memory(&key_iv, sizeof(key_iv));
6556
2.74k
    return ctx;
6557
2.74k
}
6558
6559
ptls_aead_context_t *ptls_aead_new(ptls_aead_algorithm_t *aead, ptls_hash_algorithm_t *hash, int is_enc, const void *secret,
6560
                                   const char *label_prefix)
6561
2.74k
{
6562
2.74k
    return new_aead(aead, hash, is_enc, secret, ptls_iovec_init(NULL, 0), label_prefix);
6563
2.74k
}
6564
6565
ptls_aead_context_t *ptls_aead_new_direct(ptls_aead_algorithm_t *aead, int is_enc, const void *key, const void *iv)
6566
2.74k
{
6567
2.74k
    ptls_aead_context_t *ctx;
6568
6569
2.74k
    if ((ctx = (ptls_aead_context_t *)malloc(aead->context_size)) == NULL)
6570
0
        return NULL;
6571
6572
2.74k
    *ctx = (ptls_aead_context_t){aead};
6573
6574
2.74k
    if (aead->setup_crypto(ctx, is_enc, key, iv) != 0) {
6575
0
        free(ctx);
6576
0
        return NULL;
6577
0
    }
6578
6579
2.74k
    return ctx;
6580
2.74k
}
6581
6582
void ptls_aead_free(ptls_aead_context_t *ctx)
6583
2.74k
{
6584
2.74k
    ctx->dispose_crypto(ctx);
6585
2.74k
    free(ctx);
6586
2.74k
}
6587
6588
void ptls_aead_xor_iv(ptls_aead_context_t *ctx, const void *_bytes, size_t len)
6589
0
{
6590
0
    const uint8_t *bytes = _bytes;
6591
0
    uint8_t iv[PTLS_MAX_IV_SIZE];
6592
6593
0
    ptls_aead_get_iv(ctx, iv);
6594
0
    for (size_t i = 0; i < len; ++i)
6595
0
        iv[i] ^= bytes[i];
6596
0
    ptls_aead_set_iv(ctx, iv);
6597
0
}
6598
6599
void ptls_aead__build_iv(ptls_aead_algorithm_t *algo, uint8_t *iv, const uint8_t *static_iv, uint64_t seq)
6600
0
{
6601
0
    size_t iv_size = algo->iv_size, i;
6602
0
    const uint8_t *s = static_iv;
6603
0
    uint8_t *d = iv;
6604
6605
    /* build iv */
6606
0
    for (i = iv_size - 8; i != 0; --i)
6607
0
        *d++ = *s++;
6608
0
    i = 64;
6609
0
    do {
6610
0
        i -= 8;
6611
0
        *d++ = *s++ ^ (uint8_t)(seq >> i);
6612
0
    } while (i != 0);
6613
0
}
6614
6615
static void clear_memory(void *p, size_t len)
6616
196k
{
6617
196k
    if (len != 0)
6618
88.1k
        memset(p, 0, len);
6619
196k
}
6620
6621
void (*volatile ptls_clear_memory)(void *p, size_t len) = clear_memory;
6622
6623
static int mem_equal(const void *_x, const void *_y, size_t len)
6624
1.20k
{
6625
1.20k
    const volatile uint8_t *x = _x, *y = _y;
6626
1.20k
    uint8_t t = 0;
6627
6628
2.88k
    for (; len != 0; --len)
6629
1.68k
        t |= *x++ ^ *y++;
6630
6631
1.20k
    return t == 0;
6632
1.20k
}
6633
6634
int (*volatile ptls_mem_equal)(const void *x, const void *y, size_t len) = mem_equal;
6635
6636
static uint64_t get_time(ptls_get_time_t *self)
6637
324
{
6638
324
    struct timeval tv;
6639
324
    gettimeofday(&tv, NULL);
6640
324
    return (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
6641
324
}
6642
6643
ptls_get_time_t ptls_get_time = {get_time};
6644
6645
int ptls_is_server(ptls_t *tls)
6646
2.74k
{
6647
2.74k
    return tls->is_server;
6648
2.74k
}
6649
6650
struct st_ptls_raw_message_emitter_t {
6651
    ptls_message_emitter_t super;
6652
    size_t start_off;
6653
    size_t *epoch_offsets;
6654
};
6655
6656
static int begin_raw_message(ptls_message_emitter_t *_self)
6657
0
{
6658
0
    struct st_ptls_raw_message_emitter_t *self = (void *)_self;
6659
6660
0
    self->start_off = self->super.buf->off;
6661
0
    return 0;
6662
0
}
6663
6664
static int commit_raw_message(ptls_message_emitter_t *_self)
6665
0
{
6666
0
    struct st_ptls_raw_message_emitter_t *self = (void *)_self;
6667
0
    size_t epoch;
6668
6669
    /* epoch is the key epoch, with the only exception being 2nd CH generated after 0-RTT key */
6670
0
    epoch = self->super.enc->epoch;
6671
0
    if (epoch == 1 && self->super.buf->base[self->start_off] == PTLS_HANDSHAKE_TYPE_CLIENT_HELLO)
6672
0
        epoch = 0;
6673
6674
0
    for (++epoch; epoch < 5; ++epoch) {
6675
0
        assert(self->epoch_offsets[epoch] == self->start_off);
6676
0
        self->epoch_offsets[epoch] = self->super.buf->off;
6677
0
    }
6678
6679
0
    self->start_off = SIZE_MAX;
6680
6681
0
    return 0;
6682
0
}
6683
6684
size_t ptls_get_read_epoch(ptls_t *tls)
6685
0
{
6686
0
    switch (tls->state) {
6687
0
    case PTLS_STATE_CLIENT_HANDSHAKE_START:
6688
0
    case PTLS_STATE_CLIENT_EXPECT_SERVER_HELLO:
6689
0
    case PTLS_STATE_CLIENT_EXPECT_SECOND_SERVER_HELLO:
6690
0
    case PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO:
6691
0
    case PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO:
6692
0
        return 0; /* plaintext */
6693
0
    case PTLS_STATE_SERVER_EXPECT_END_OF_EARLY_DATA:
6694
0
        assert(!tls->ctx->omit_end_of_early_data);
6695
0
        return 1; /* 0-rtt */
6696
0
    case PTLS_STATE_CLIENT_EXPECT_ENCRYPTED_EXTENSIONS:
6697
0
    case PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_REQUEST_OR_CERTIFICATE:
6698
0
    case PTLS_STATE_CLIENT_EXPECT_CERTIFICATE:
6699
0
    case PTLS_STATE_CLIENT_EXPECT_CERTIFICATE_VERIFY:
6700
0
    case PTLS_STATE_CLIENT_EXPECT_FINISHED:
6701
0
    case PTLS_STATE_SERVER_GENERATING_CERTIFICATE_VERIFY:
6702
0
    case PTLS_STATE_SERVER_EXPECT_CERTIFICATE:
6703
0
    case PTLS_STATE_SERVER_EXPECT_CERTIFICATE_VERIFY:
6704
0
    case PTLS_STATE_SERVER_EXPECT_FINISHED:
6705
0
        return 2; /* handshake */
6706
0
    case PTLS_STATE_CLIENT_POST_HANDSHAKE:
6707
0
    case PTLS_STATE_SERVER_POST_HANDSHAKE:
6708
0
        return 3; /* 1-rtt */
6709
0
    default:
6710
0
        assert(!"invalid state");
6711
0
        return SIZE_MAX;
6712
0
    }
6713
0
}
6714
6715
int ptls_handle_message(ptls_t *tls, ptls_buffer_t *sendbuf, size_t epoch_offsets[5], size_t in_epoch, const void *input,
6716
                        size_t inlen, ptls_handshake_properties_t *properties)
6717
0
{
6718
0
    return tls->is_server ? ptls_server_handle_message(tls, sendbuf, epoch_offsets, in_epoch, input, inlen, properties)
6719
0
                          : ptls_client_handle_message(tls, sendbuf, epoch_offsets, in_epoch, input, inlen, properties);
6720
0
}
6721
6722
int ptls_client_handle_message(ptls_t *tls, ptls_buffer_t *sendbuf, size_t epoch_offsets[5], size_t in_epoch, const void *input,
6723
                               size_t inlen, ptls_handshake_properties_t *properties)
6724
0
{
6725
0
    assert(!tls->is_server);
6726
6727
0
    struct st_ptls_raw_message_emitter_t emitter = {
6728
0
        {sendbuf, &tls->traffic_protection.enc, 0, begin_raw_message, commit_raw_message}, SIZE_MAX, epoch_offsets};
6729
0
    struct st_ptls_record_t rec = {PTLS_CONTENT_TYPE_HANDSHAKE, 0, inlen, input};
6730
6731
0
    if (input == NULL)
6732
0
        return send_client_hello(tls, &emitter.super, properties, NULL);
6733
6734
0
    if (ptls_get_read_epoch(tls) != in_epoch)
6735
0
        return PTLS_ALERT_UNEXPECTED_MESSAGE;
6736
6737
0
    return handle_handshake_record(tls, handle_client_handshake_message, &emitter.super, &rec, properties);
6738
0
}
6739
6740
int ptls_server_handle_message(ptls_t *tls, ptls_buffer_t *sendbuf, size_t epoch_offsets[5], size_t in_epoch, const void *input,
6741
                               size_t inlen, ptls_handshake_properties_t *properties)
6742
0
{
6743
0
    assert(tls->is_server);
6744
6745
0
    struct st_ptls_raw_message_emitter_t emitter = {
6746
0
        {sendbuf, &tls->traffic_protection.enc, 0, begin_raw_message, commit_raw_message}, SIZE_MAX, epoch_offsets};
6747
0
    struct st_ptls_record_t rec = {PTLS_CONTENT_TYPE_HANDSHAKE, 0, inlen, input};
6748
6749
0
    if (tls->state == PTLS_STATE_SERVER_GENERATING_CERTIFICATE_VERIFY) {
6750
0
        assert(input == NULL || inlen == 0);
6751
0
        return server_finish_handshake(tls, &emitter.super, 1, NULL);
6752
0
    }
6753
6754
0
    assert(input != NULL);
6755
6756
0
    if (ptls_get_read_epoch(tls) != in_epoch)
6757
0
        return PTLS_ALERT_UNEXPECTED_MESSAGE;
6758
6759
0
    return handle_handshake_record(tls, handle_server_handshake_message, &emitter.super, &rec, properties);
6760
0
}
6761
6762
/**
6763
 * checks if given name looks like an IP address
6764
 */
6765
int ptls_server_name_is_ipaddr(const char *name)
6766
0
{
6767
0
#ifdef AF_INET
6768
0
    struct sockaddr_in sin;
6769
0
    if (inet_pton(AF_INET, name, &sin) == 1)
6770
0
        return 1;
6771
0
#endif
6772
0
#ifdef AF_INET6
6773
0
    struct sockaddr_in6 sin6;
6774
0
    if (inet_pton(AF_INET6, name, &sin6) == 1)
6775
0
        return 1;
6776
0
#endif
6777
0
    return 0;
6778
0
}
6779
6780
int ptls_ech_encode_config(ptls_buffer_t *buf, uint8_t config_id, ptls_hpke_kem_t *kem, ptls_iovec_t public_key,
6781
                           ptls_hpke_cipher_suite_t **ciphers, uint8_t max_name_length, const char *public_name)
6782
0
{
6783
0
    int ret;
6784
6785
0
    ptls_buffer_push16(buf, PTLS_ECH_CONFIG_VERSION);
6786
0
    ptls_buffer_push_block(buf, 2, {
6787
0
        ptls_buffer_push(buf, config_id);
6788
0
        ptls_buffer_push16(buf, kem->id);
6789
0
        ptls_buffer_push_block(buf, 2, { ptls_buffer_pushv(buf, public_key.base, public_key.len); });
6790
0
        ptls_buffer_push_block(buf, 2, {
6791
0
            for (size_t i = 0; ciphers[i] != NULL; ++i) {
6792
0
                ptls_buffer_push16(buf, ciphers[i]->id.kdf);
6793
0
                ptls_buffer_push16(buf, ciphers[i]->id.aead);
6794
0
            }
6795
0
        });
6796
0
        ptls_buffer_push(buf, max_name_length);
6797
0
        ptls_buffer_push_block(buf, 1, { ptls_buffer_pushv(buf, public_name, strlen(public_name)); });
6798
0
        ptls_buffer_push_block(buf, 2, {/* extensions */});
6799
0
    });
6800
6801
0
Exit:
6802
0
    return ret;
6803
0
}
6804
6805
static char *byte_to_hex(char *dst, uint8_t v)
6806
0
{
6807
0
    *dst++ = "0123456789abcdef"[v >> 4];
6808
0
    *dst++ = "0123456789abcdef"[v & 0xf];
6809
0
    return dst;
6810
0
}
6811
6812
char *ptls_hexdump(char *dst, const void *_src, size_t len)
6813
0
{
6814
0
    char *buf = dst;
6815
0
    const uint8_t *src = _src;
6816
6817
0
    for (size_t i = 0; i != len; ++i)
6818
0
        dst = byte_to_hex(dst, src[i]);
6819
0
    *dst = '\0';
6820
0
    return buf;
6821
0
}
6822
6823
char *ptls_jsonescape(char *buf, const char *unsafe_str, size_t len)
6824
0
{
6825
0
    char *dst = buf;
6826
0
    const uint8_t *src = (const uint8_t *)unsafe_str, *end = src + len;
6827
6828
0
    for (; src != end; ++src) {
6829
0
        switch (*src) {
6830
0
#define MAP(ch, escaped)                                                                                                           \
6831
0
    case ch:                                                                                                                       \
6832
0
        memcpy(dst, (escaped), sizeof(escaped) - 1);                                                                               \
6833
0
        dst += sizeof(escaped) - 1;                                                                                                \
6834
0
        break
6835
0
            MAP('"', "\\\"");
6836
0
            MAP('\\', "\\\\");
6837
0
            MAP('/', "\\/");
6838
0
            MAP('\b', "\\b");
6839
0
            MAP('\f', "\\f");
6840
0
            MAP('\n', "\\n");
6841
0
            MAP('\r', "\\r");
6842
0
            MAP('\t', "\\t");
6843
0
#undef MAP
6844
0
        default:
6845
0
            if (*src < 0x20 || *src == 0x7f) {
6846
0
                *dst++ = '\\';
6847
0
                *dst++ = 'u';
6848
0
                *dst++ = '0';
6849
0
                *dst++ = '0';
6850
0
                dst = byte_to_hex(dst, *src);
6851
0
            } else {
6852
0
                *dst++ = *src;
6853
0
            }
6854
0
            break;
6855
0
        }
6856
0
    }
6857
0
    *dst = '\0';
6858
6859
0
    return dst;
6860
0
}
6861
6862
void ptls_build_v4_mapped_v6_address(void *v6, const void *v4)
6863
0
{
6864
0
    memset(v6, 0, 10);
6865
0
    memset((uint8_t *)v6 + 10, 0xff, 2);
6866
0
    memcpy((uint8_t *)v6 + 12, v4, 4);
6867
0
}
6868
6869
struct st_ptls_log_t ptls_log = {
6870
    .dummy_conn_state = {.random_ = 1 /* never log */},
6871
    ._generation = 1, /* starts from 1 so that recalc can be forced by setting to zero (i.e., the initial) */
6872
};
6873
PTLS_THREADLOCAL ptls_log_conn_state_t *ptls_log_conn_state_override = NULL;
6874
6875
#if PTLS_HAVE_LOG
6876
6877
static struct {
6878
    /**
6879
     * list of connections; the slot is connected if points != NULL
6880
     */
6881
    struct {
6882
        /**
6883
         * file descriptor
6884
         */
6885
        int fd;
6886
        /**
6887
         * see `ptls_log_add_fd`
6888
         */
6889
        char *points;
6890
        /**
6891
         *
6892
         */
6893
        char *snis;
6894
        /**
6895
         * list of addresses terminated by ip6addr_any
6896
         */
6897
        struct in6_addr *addresses;
6898
        /**
6899
         *
6900
         */
6901
        float sample_ratio;
6902
        /**
6903
         *
6904
         */
6905
        unsigned appdata : 1;
6906
    } conns[sizeof(((struct st_ptls_log_state_t *)NULL)->active_conns) * 8];
6907
    /**
6908
     * counts the number of writes that failed
6909
     */
6910
    size_t num_lost;
6911
    /**
6912
     * anchor of the single-linked list of log points; the tail refers to itself (i.e., point->next == point)
6913
     */
6914
    struct st_ptls_log_point_t *points;
6915
    /**
6916
     *
6917
     */
6918
    pthread_mutex_t mutex;
6919
} logctx = {.mutex = PTHREAD_MUTEX_INITIALIZER};
6920
6921
static PTLS_THREADLOCAL struct {
6922
    ptls_buffer_t buf; /* buf.base == NULL upon failre */
6923
    char smallbuf[128];
6924
    struct {
6925
        char buf[sizeof(",\"tid\":-9223372036854775808")];
6926
        size_t len;
6927
    } tid;
6928
} logbuf;
6929
6930
static void close_log_fd(size_t slot)
6931
0
{
6932
0
    assert(logctx.conns[slot].fd >= 0 && logctx.conns[slot].points != NULL);
6933
6934
0
    close(logctx.conns[slot].fd);
6935
6936
    /* clear the connection information */
6937
0
    logctx.conns[slot].fd = -1;
6938
0
    logctx.conns[slot].sample_ratio = 0;
6939
0
    free(logctx.conns[slot].points);
6940
0
    logctx.conns[slot].points = NULL;
6941
0
    free(logctx.conns[slot].snis);
6942
0
    logctx.conns[slot].snis = NULL;
6943
0
    free(logctx.conns[slot].addresses);
6944
0
    logctx.conns[slot].addresses = NULL;
6945
0
    logctx.conns[slot].appdata = 0;
6946
0
    ++ptls_log._generation;
6947
0
}
6948
6949
static char *duplicate_stringlist(const char *input)
6950
0
{
6951
0
    if (input == NULL)
6952
0
        return strdup("");
6953
6954
0
    char *result;
6955
0
    const char *in_tail;
6956
6957
0
    for (in_tail = input; in_tail[0] != '\0'; in_tail += strlen(in_tail) + 1)
6958
0
        ;
6959
0
    ++in_tail;
6960
0
    if ((result = malloc(in_tail - input)) == NULL)
6961
0
        return NULL;
6962
0
    memcpy(result, input, in_tail - input);
6963
0
    return result;
6964
0
}
6965
6966
static int is_in_stringlist(const char *list, const char *search_for)
6967
0
{
6968
0
    if (list[0] == '\0')
6969
0
        return 1;
6970
6971
0
    if (search_for == NULL)
6972
0
        return 0;
6973
6974
0
    for (const char *element = list; element[0] != '\0'; element += strlen(element) + 1)
6975
0
        if (strcmp(element, search_for) == 0)
6976
0
            return 1;
6977
0
    return 0;
6978
0
}
6979
6980
static int is_in_addresslist(const struct in6_addr *list, const struct in6_addr *search_for)
6981
0
{
6982
0
#define IS_EQUAL(x, y) (memcmp((x), (y), sizeof(struct in6_addr)) == 0)
6983
6984
0
    if (IS_EQUAL(&list[0], &in6addr_any))
6985
0
        return 1;
6986
6987
0
    if (IS_EQUAL(search_for, &in6addr_any))
6988
0
        return 0;
6989
6990
0
    for (const struct in6_addr *element = list; !IS_EQUAL(element, &in6addr_any); ++element)
6991
0
        if (IS_EQUAL(element, search_for))
6992
0
            return 1;
6993
0
    return 0;
6994
6995
0
#undef IS_EQUAL
6996
0
}
6997
6998
void ptls_log__recalc_point(int caller_locked, struct st_ptls_log_point_t *point)
6999
11
{
7000
11
    if (!caller_locked)
7001
11
        pthread_mutex_lock(&logctx.mutex);
7002
7003
11
    if (point->state.generation != ptls_log._generation) {
7004
        /* update active bitmap */
7005
11
        uint32_t new_active = 0;
7006
363
        for (size_t slot = 0; slot < PTLS_ELEMENTSOF(logctx.conns); ++slot)
7007
352
            if (logctx.conns[slot].points != NULL && is_in_stringlist(logctx.conns[slot].points, point->name))
7008
0
                new_active |= (uint32_t)1 << slot;
7009
11
        point->state.active_conns = new_active;
7010
11
        point->state.generation = ptls_log._generation;
7011
11
    }
7012
7013
11
    if (!caller_locked)
7014
11
        pthread_mutex_unlock(&logctx.mutex);
7015
11
}
7016
7017
void ptls_log__recalc_conn(int caller_locked, struct st_ptls_log_conn_state_t *conn, ptls_log_getsni_t getsni)
7018
0
{
7019
0
    if (!caller_locked)
7020
0
        pthread_mutex_lock(&logctx.mutex);
7021
7022
0
    if (conn->state.generation != ptls_log._generation) {
7023
        /* update active bitmap */
7024
0
        uint32_t new_active = 0;
7025
0
        const char *sni = getsni.cb != NULL ? getsni.cb(getsni.arg) : NULL;
7026
0
        for (size_t slot = 0; slot < PTLS_ELEMENTSOF(logctx.conns); ++slot) {
7027
0
            if (logctx.conns[slot].points != NULL && conn->random_ < logctx.conns[slot].sample_ratio &&
7028
0
                is_in_stringlist(logctx.conns[slot].snis, sni) &&
7029
0
                is_in_addresslist(logctx.conns[slot].addresses, (struct in6_addr *)&conn->address)) {
7030
0
                new_active |= (uint32_t)1 << slot;
7031
0
            }
7032
0
        }
7033
0
        conn->state.active_conns = new_active;
7034
0
        conn->state.generation = ptls_log._generation;
7035
0
    }
7036
7037
0
    if (!caller_locked)
7038
0
        pthread_mutex_unlock(&logctx.mutex);
7039
0
}
7040
7041
static int expand_logbuf_or_invalidate(const char *prefix, size_t prefix_len, size_t capacity)
7042
0
{
7043
0
    if (logbuf.buf.base == NULL)
7044
0
        return 0;
7045
7046
0
    if (ptls_buffer_reserve(&logbuf.buf, prefix_len + capacity) != 0) {
7047
0
        ptls_buffer_dispose(&logbuf.buf);
7048
0
        assert(logbuf.buf.base == NULL);
7049
0
        return 0;
7050
0
    }
7051
7052
0
    memcpy(logbuf.buf.base + logbuf.buf.off, prefix, prefix_len);
7053
0
    logbuf.buf.off += prefix_len;
7054
7055
0
    return 1;
7056
0
}
7057
7058
__attribute__((format(printf, 4, 5))) static void pushf_logbuf_or_invalidate(const char *prefix, size_t prefix_len, size_t capacity,
7059
                                                                             const char *fmt, ...)
7060
0
{
7061
0
    if (!expand_logbuf_or_invalidate(prefix, prefix_len, capacity))
7062
0
        return;
7063
7064
0
    va_list args;
7065
0
    va_start(args, fmt);
7066
0
    int l = vsnprintf((char *)logbuf.buf.base + logbuf.buf.off, logbuf.buf.capacity - logbuf.buf.off, fmt, args);
7067
0
    va_end(args);
7068
7069
0
    assert(l < logbuf.buf.capacity - logbuf.buf.off && "insufficent capacity");
7070
0
    logbuf.buf.off += l;
7071
0
}
7072
7073
void ptls_log__do_push_element_safestr(const char *prefix, size_t prefix_len, const char *s, size_t l)
7074
0
{
7075
0
    if (expand_logbuf_or_invalidate(prefix, prefix_len, l + 2)) {
7076
0
        logbuf.buf.base[logbuf.buf.off++] = '"';
7077
0
        memcpy(logbuf.buf.base + logbuf.buf.off, s, l);
7078
0
        logbuf.buf.off += l;
7079
0
        logbuf.buf.base[logbuf.buf.off++] = '"';
7080
0
    }
7081
0
}
7082
7083
void ptls_log__do_push_element_unsafestr(const char *prefix, size_t prefix_len, const char *s, size_t l)
7084
0
{
7085
0
    if (expand_logbuf_or_invalidate(prefix, prefix_len, l * (sizeof("\\uXXXX") - 1) + 2)) {
7086
0
        logbuf.buf.base[logbuf.buf.off++] = '"';
7087
0
        logbuf.buf.off = (uint8_t *)ptls_jsonescape((char *)logbuf.buf.base + logbuf.buf.off, s, l) - logbuf.buf.base;
7088
0
        logbuf.buf.base[logbuf.buf.off++] = '"';
7089
0
    }
7090
0
}
7091
7092
void ptls_log__do_push_element_hexdump(const char *prefix, size_t prefix_len, const void *s, size_t l)
7093
0
{
7094
0
    if (expand_logbuf_or_invalidate(prefix, prefix_len, l * 2 + 2)) {
7095
0
        logbuf.buf.base[logbuf.buf.off++] = '"';
7096
0
        ptls_hexdump((char *)logbuf.buf.base + logbuf.buf.off, s, l);
7097
0
        logbuf.buf.off += l * 2;
7098
0
        logbuf.buf.base[logbuf.buf.off++] = '"';
7099
0
    }
7100
0
}
7101
7102
void ptls_log__do_push_element_signed32(const char *prefix, size_t prefix_len, int32_t v)
7103
0
{
7104
0
    pushf_logbuf_or_invalidate(prefix, prefix_len, sizeof("-2147483648"), "%" PRId32, v);
7105
0
}
7106
7107
void ptls_log__do_push_element_signed64(const char *prefix, size_t prefix_len, int64_t v)
7108
0
{
7109
0
    pushf_logbuf_or_invalidate(prefix, prefix_len, sizeof("-9223372036854775808"), "%" PRId64, v);
7110
0
}
7111
7112
void ptls_log__do_push_element_unsigned32(const char *prefix, size_t prefix_len, uint32_t v)
7113
0
{
7114
0
    pushf_logbuf_or_invalidate(prefix, prefix_len, sizeof("4294967295"), "%" PRIu32, v);
7115
0
}
7116
7117
void ptls_log__do_push_element_unsigned64(const char *prefix, size_t prefix_len, uint64_t v)
7118
0
{
7119
0
    pushf_logbuf_or_invalidate(prefix, prefix_len, sizeof("18446744073709551615"), "%" PRIu64, v);
7120
0
}
7121
7122
void ptls_log__do_push_element_bool(const char *prefix, size_t prefix_len, int v)
7123
0
{
7124
0
    if (expand_logbuf_or_invalidate(prefix, prefix_len, 5)) {
7125
0
        if (v) {
7126
0
            memcpy(logbuf.buf.base + logbuf.buf.off, "true", 4);
7127
0
            logbuf.buf.off += 4;
7128
0
        } else {
7129
0
            memcpy(logbuf.buf.base + logbuf.buf.off, "false", 5);
7130
0
            logbuf.buf.off += 5;
7131
0
        }
7132
0
    }
7133
0
}
7134
7135
void ptls_log__do_write_start(struct st_ptls_log_point_t *point, int add_time)
7136
0
{
7137
0
    assert(logbuf.buf.base == NULL);
7138
0
    ptls_buffer_init(&logbuf.buf, logbuf.smallbuf, sizeof(logbuf.smallbuf));
7139
7140
    /* add module and type name */
7141
0
    const char *colon_at = strchr(point->name, ':');
7142
0
    int written = snprintf((char *)logbuf.buf.base, logbuf.buf.capacity, "{\"module\":\"%.*s\",\"type\":\"%s\"",
7143
0
                           (int)(colon_at - point->name), point->name, colon_at + 1);
7144
7145
    /* obtain and stringify thread id once */
7146
0
    if (logbuf.tid.len == 0) {
7147
0
#if defined(__linux__)
7148
0
        logbuf.tid.len = sprintf(logbuf.tid.buf, ",\"tid\":%" PRId64, (int64_t)syscall(SYS_gettid));
7149
#elif defined(__APPLE__)
7150
        uint64_t t = 0;
7151
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 || defined(__POWERPC__)
7152
        t = pthread_mach_thread_np(pthread_self());
7153
#else
7154
        (void)pthread_threadid_np(NULL, &t);
7155
#endif
7156
        logbuf.tid.len = sprintf(logbuf.tid.buf, ",\"tid\":%" PRIu64, t);
7157
#else
7158
        /* other platforms: skip emitting tid, by keeping logbuf.tid.len == 0 */
7159
#endif
7160
0
    }
7161
    /* append tid */
7162
0
    assert(written > 0 && written + logbuf.tid.len < logbuf.buf.capacity);
7163
0
    memcpy((char *)logbuf.buf.base + written, logbuf.tid.buf, logbuf.tid.len + 1);
7164
0
    written += logbuf.tid.len;
7165
7166
    /* append time if requested */
7167
0
    if (add_time) {
7168
0
        struct timeval tv;
7169
0
        gettimeofday(&tv, NULL);
7170
0
        written += snprintf((char *)logbuf.buf.base + written, logbuf.buf.capacity - written, ",\"time\":%" PRIu64,
7171
0
                            (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000);
7172
0
    }
7173
0
    assert(written > 0 && written < logbuf.buf.capacity && "caller MUST provide smallbuf suffient to emit the prefix");
7174
7175
0
    logbuf.buf.off = (size_t)written;
7176
0
}
7177
7178
int ptls_log__do_write_end(struct st_ptls_log_point_t *point, struct st_ptls_log_conn_state_t *conn, ptls_log_getsni_t getsni,
7179
                           int includes_appdata)
7180
0
{
7181
0
    if (!expand_logbuf_or_invalidate("}\n", 2, 0))
7182
0
        return 0;
7183
7184
0
    int needs_appdata = 0;
7185
7186
0
    pthread_mutex_lock(&logctx.mutex);
7187
7188
    /* calc the active conn bits, updating stale information if necessary */
7189
0
    if (point->state.generation != ptls_log._generation)
7190
0
        ptls_log__recalc_point(1, point);
7191
0
    uint32_t active = point->state.active_conns;
7192
0
    if (conn != NULL && conn->state.generation != ptls_log._generation) {
7193
0
        ptls_log__recalc_conn(1, conn, getsni);
7194
0
        active &= conn->state.active_conns;
7195
0
    }
7196
7197
    /* iterate through the active connctions */
7198
0
    for (size_t slot = 0; active != 0; ++slot, active >>= 1) {
7199
0
        if ((active & 1) == 0)
7200
0
            continue;
7201
7202
0
        assert(logctx.conns[slot].points != NULL);
7203
7204
0
        if (logctx.conns[slot].appdata != includes_appdata) {
7205
0
            if (!includes_appdata && ptls_log.may_include_appdata)
7206
0
                needs_appdata = 1;
7207
0
            continue;
7208
0
        }
7209
7210
        /* write */
7211
0
        ssize_t wret;
7212
0
        while ((wret = write(logctx.conns[slot].fd, logbuf.buf.base, logbuf.buf.off)) == -1 && errno == EINTR)
7213
0
            ;
7214
0
        if (wret == logbuf.buf.off) {
7215
            /* success */
7216
0
        } else if (wret > 0 || (wret == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))) {
7217
            /* partial write or buffer full */
7218
0
            ++logctx.num_lost;
7219
0
        } else {
7220
            /* write error; close and unregister the connection */
7221
0
            close_log_fd(slot);
7222
0
        }
7223
0
    }
7224
7225
0
    pthread_mutex_unlock(&logctx.mutex);
7226
7227
0
    if (includes_appdata)
7228
0
        assert(!needs_appdata);
7229
7230
0
    ptls_buffer_dispose(&logbuf.buf);
7231
0
    assert(logbuf.buf.base == NULL);
7232
0
    return needs_appdata;
7233
0
}
7234
7235
#endif
7236
7237
void ptls_log_init_conn_state(ptls_log_conn_state_t *state, void (*random_bytes)(void *, size_t), uint64_t conn_id, void *_peeraddr)
7238
4.14k
{
7239
4.14k
    struct sockaddr *peeraddr = _peeraddr;
7240
4.14k
    uint32_t r;
7241
4.14k
    random_bytes(&r, sizeof(r));
7242
7243
4.14k
    *state = (ptls_log_conn_state_t){
7244
4.14k
        .random_ = (float)r / ((uint64_t)UINT32_MAX + 1), /* [0..1), so that any(r) < sample_ratio where sample_ratio is [0..1] */
7245
4.14k
        .address = {0}, /* inaddr6_any */
7246
4.14k
        .conn_id = conn_id,
7247
4.14k
    };
7248
4.14k
    if (peeraddr != NULL) {
7249
0
        switch (peeraddr->sa_family) {
7250
0
        case AF_INET: /* store as v6-mapped v4 address */
7251
0
            ptls_build_v4_mapped_v6_address(state->address, &((struct sockaddr_in *)peeraddr)->sin_addr);
7252
0
            break;
7253
0
        case AF_INET6:
7254
0
            memcpy(state->address, ((struct sockaddr_in6 *)peeraddr)->sin6_addr.s6_addr, sizeof(state->address));
7255
0
            break;
7256
0
        default:
7257
0
            break;
7258
0
        }
7259
0
    }
7260
4.14k
}
7261
7262
size_t ptls_log_num_lost(void)
7263
0
{
7264
0
#if PTLS_HAVE_LOG
7265
0
    return logctx.num_lost;
7266
#else
7267
    return 0;
7268
#endif
7269
0
}
7270
7271
int ptls_log_add_fd(int fd, float sample_ratio, const char *_points, const char *_snis, const char *_addresses, int appdata)
7272
0
{
7273
0
#if PTLS_HAVE_LOG
7274
7275
0
    char *points = NULL, *snis = NULL;
7276
0
    struct in6_addr *addresses = NULL;
7277
0
    int ret;
7278
7279
0
    pthread_mutex_lock(&logctx.mutex);
7280
7281
0
    if ((points = duplicate_stringlist(_points)) == NULL) {
7282
0
        ret = PTLS_ERROR_NO_MEMORY;
7283
0
        goto Exit;
7284
0
    }
7285
0
    if ((snis = duplicate_stringlist(_snis)) == NULL) {
7286
0
        ret = PTLS_ERROR_NO_MEMORY;
7287
0
        goto Exit;
7288
0
    }
7289
0
    {
7290
0
        size_t num_addresses = 0;
7291
0
        for (const char *input = _addresses; input != NULL && *input != '\0'; input += strlen(input) + 1)
7292
0
            ++num_addresses;
7293
0
        if ((addresses = malloc(sizeof(*addresses) * (num_addresses + 1))) == NULL) {
7294
0
            ret = PTLS_ERROR_NO_MEMORY;
7295
0
            goto Exit;
7296
0
        }
7297
0
        size_t index = 0;
7298
0
        for (const char *input = _addresses; input != NULL && *input != '\0'; input += strlen(input) + 1) {
7299
            /* note: for consistency to the handling of points, erroneous input is ignored. V4 addresses will use the mapped form
7300
             * (::ffff:192.0.2.1) */
7301
0
            if (!inet_pton(AF_INET6, input, &addresses[index])) {
7302
0
                struct in_addr v4;
7303
0
                if (!inet_pton(AF_INET, input, &v4))
7304
0
                    continue;
7305
0
                ptls_build_v4_mapped_v6_address(&addresses[index], &v4);
7306
0
            }
7307
0
            if (memcmp(&addresses[index], &in6addr_any, sizeof(struct in6_addr)) == 0)
7308
0
                continue;
7309
0
            ++index;
7310
0
        }
7311
0
        addresses[index] = in6addr_any;
7312
0
    }
7313
7314
    /* find slot, or return if not available */
7315
0
    size_t slot_index;
7316
0
    for (slot_index = 0; slot_index < PTLS_ELEMENTSOF(logctx.conns); ++slot_index)
7317
0
        if (logctx.conns[slot_index].points == NULL)
7318
0
            break;
7319
0
    if (slot_index == PTLS_ELEMENTSOF(logctx.conns)) {
7320
0
        ret = PTLS_ERROR_NO_MEMORY;
7321
0
        goto Exit;
7322
0
    }
7323
7324
    /* setup the slot */
7325
0
    logctx.conns[slot_index].fd = fd;
7326
0
    logctx.conns[slot_index].points = points;
7327
0
    logctx.conns[slot_index].snis = snis;
7328
0
    logctx.conns[slot_index].addresses = addresses;
7329
0
    logctx.conns[slot_index].sample_ratio = sample_ratio;
7330
0
    logctx.conns[slot_index].appdata = appdata;
7331
0
    ++ptls_log._generation;
7332
7333
0
    ret = 0; /* success */
7334
7335
0
Exit:
7336
0
    pthread_mutex_unlock(&logctx.mutex);
7337
0
    if (ret != 0) {
7338
0
        free(points);
7339
0
        free(snis);
7340
0
        free(addresses);
7341
0
    }
7342
0
    return ret;
7343
7344
#else
7345
    return PTLS_ERROR_NOT_AVAILABLE;
7346
#endif
7347
0
}