Coverage Report

Created: 2026-09-27 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl/src/ssl_api_ext.c
Line
Count
Source
1
/* ssl_api_ext.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#if !defined(WOLFSSL_SSL_API_EXT_INCLUDED)
25
    #ifndef WOLFSSL_IGNORE_FILE_WARN
26
        #warning ssl_api_ext.c does not need to be compiled separately from ssl.c
27
    #endif
28
#else
29
30
#ifndef WOLFCRYPT_ONLY
31
#ifndef NO_TLS
32
33
#ifdef HAVE_SNI
34
35
/* Set the Server Name Indication extension data on the object.
36
 *
37
 * @param [in] ssl   SSL/TLS object.
38
 * @param [in] type  SNI type, e.g. WOLFSSL_SNI_HOST_NAME.
39
 * @param [in] data  SNI data.
40
 * @param [in] size  Length of SNI data in bytes.
41
 * @return  WOLFSSL_SUCCESS on success.
42
 * @return  BAD_FUNC_ARG when ssl is NULL.
43
 * @return  Negative value on error.
44
 */
45
WOLFSSL_ABI
46
int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
47
0
{
48
0
    int ret;
49
50
0
    if (ssl == NULL) {
51
0
        ret = BAD_FUNC_ARG;
52
0
    }
53
0
    else {
54
0
        ret = TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
55
0
    }
56
57
0
    return ret;
58
0
}
59
60
61
/* Set the Server Name Indication extension data on the context.
62
 *
63
 * @param [in] ctx   SSL/TLS context object.
64
 * @param [in] type  SNI type, e.g. WOLFSSL_SNI_HOST_NAME.
65
 * @param [in] data  SNI data.
66
 * @param [in] size  Length of SNI data in bytes.
67
 * @return  WOLFSSL_SUCCESS on success.
68
 * @return  BAD_FUNC_ARG when ctx is NULL.
69
 * @return  Negative value on error.
70
 */
71
WOLFSSL_ABI
72
int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
73
    word16 size)
74
0
{
75
0
    int ret;
76
77
0
    if (ctx == NULL) {
78
0
        ret = BAD_FUNC_ARG;
79
0
    }
80
0
    else {
81
0
        ret = TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
82
0
    }
83
84
0
    return ret;
85
0
}
86
87
#ifndef NO_WOLFSSL_SERVER
88
89
/* Set options for the Server Name Indication extension on the object.
90
 *
91
 * @param [in] ssl      SSL/TLS object.
92
 * @param [in] type     SNI type.
93
 * @param [in] options  Bitmask of SNI options.
94
 */
95
void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
96
0
{
97
0
    if ((ssl != NULL) && (ssl->extensions != NULL)) {
98
0
        TLSX_SNI_SetOptions(ssl->extensions, type, options);
99
0
    }
100
0
}
101
102
103
/* Set options for the Server Name Indication extension on the context.
104
 *
105
 * @param [in] ctx      SSL/TLS context object.
106
 * @param [in] type     SNI type.
107
 * @param [in] options  Bitmask of SNI options.
108
 */
109
void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
110
0
{
111
0
    if ((ctx != NULL) && (ctx->extensions != NULL)) {
112
0
        TLSX_SNI_SetOptions(ctx->extensions, type, options);
113
0
    }
114
0
}
115
116
117
/* Get the status of the Server Name Indication extension on the object.
118
 *
119
 * @param [in] ssl   SSL/TLS object.
120
 * @param [in] type  SNI type.
121
 * @return  SNI status for the type.
122
 */
123
byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
124
0
{
125
0
    return TLSX_SNI_Status((ssl != NULL) ? ssl->extensions : NULL, type);
126
0
}
127
128
129
/* Get the Server Name Indication request data received from the peer.
130
 *
131
 * @param [in]  ssl   SSL/TLS object.
132
 * @param [in]  type  SNI type.
133
 * @param [out] data  Pointer to the SNI request data. May be NULL.
134
 * @return  Length of the SNI request data in bytes, or 0 when none.
135
 */
136
word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
137
0
{
138
0
    word16 ret = 0;
139
140
0
    if (data != NULL) {
141
0
        *data = NULL;
142
0
    }
143
144
0
    if ((ssl != NULL) && (ssl->extensions != NULL)) {
145
0
        ret = TLSX_SNI_GetRequest(ssl->extensions, type, data, 0);
146
0
    }
147
148
0
    return ret;
149
0
}
150
151
152
/* Get the Server Name Indication data from a raw ClientHello buffer.
153
 *
154
 * @param [in]      clientHello  ClientHello message buffer.
155
 * @param [in]      helloSz      Length of the ClientHello in bytes.
156
 * @param [in]      type         SNI type.
157
 * @param [out]     sni          Buffer to hold the SNI data.
158
 * @param [in, out] inOutSz      In: size of buffer. Out: length of SNI data.
159
 * @return  WOLFSSL_SUCCESS on success.
160
 * @return  BAD_FUNC_ARG when an argument is NULL or a size is zero.
161
 */
162
int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
163
                              byte type, byte* sni, word32* inOutSz)
164
0
{
165
0
    int ret;
166
167
0
    if ((clientHello != NULL) && (helloSz > 0) && (sni != NULL) &&
168
0
            (inOutSz != NULL) && (*inOutSz > 0)) {
169
0
        ret = TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
170
0
    }
171
0
    else {
172
0
        ret = BAD_FUNC_ARG;
173
0
    }
174
175
0
    return ret;
176
0
}
177
178
#endif /* !NO_WOLFSSL_SERVER */
179
180
#endif /* HAVE_SNI */
181
182
183
#ifdef HAVE_TRUSTED_CA
184
185
/* Set the Trusted CA Indication extension on the object.
186
 *
187
 * Note this reports success as 0, not WOLFSSL_SUCCESS as most of this file
188
 * does - the result comes straight from TLSX_UseTrustedCA(). The local `ret`
189
 * uses 0 as its "nothing wrong yet" marker for the same reason, so it never
190
 * returns a bare 0 that did not come from there.
191
 *
192
 * @param [in, out] ssl       SSL/TLS object.
193
 * @param [in]      type      Trusted CA identifier type.
194
 * @param [in]      certId    Certificate identifier data.
195
 * @param [in]      certIdSz  Length of certificate identifier in bytes.
196
 * @return  0 on success.
197
 * @return  BAD_FUNC_ARG when ssl is NULL or arguments are inconsistent with
198
 *          the type.
199
 * @return  Other negative value on error.
200
 */
201
int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type,
202
    const byte* certId, word32 certIdSz)
203
{
204
    int ret = 0;
205
206
    if (ssl == NULL) {
207
        ret = BAD_FUNC_ARG;
208
    }
209
    /* Validate the identifier against the type it is announced as. */
210
    else if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED) {
211
        if ((certId != NULL) || (certIdSz != 0)) {
212
            ret = BAD_FUNC_ARG;
213
        }
214
    }
215
    else if (type == WOLFSSL_TRUSTED_CA_X509_NAME) {
216
        if ((certId == NULL) || (certIdSz == 0)) {
217
            ret = BAD_FUNC_ARG;
218
        }
219
    }
220
    #ifndef NO_SHA
221
    else if ((type == WOLFSSL_TRUSTED_CA_KEY_SHA1) ||
222
            (type == WOLFSSL_TRUSTED_CA_CERT_SHA1)) {
223
        if ((certId == NULL) || (certIdSz != WC_SHA_DIGEST_SIZE)) {
224
            ret = BAD_FUNC_ARG;
225
        }
226
    }
227
    #endif
228
    else {
229
        ret = BAD_FUNC_ARG;
230
    }
231
232
    if (ret == 0) {
233
        ret = TLSX_UseTrustedCA(&ssl->extensions, type, certId, certIdSz,
234
            ssl->heap);
235
    }
236
237
    return ret;
238
}
239
240
#endif /* HAVE_TRUSTED_CA */
241
242
243
#ifdef HAVE_MAX_FRAGMENT
244
#ifndef NO_WOLFSSL_CLIENT
245
246
/* Set the Maximum Fragment Length extension on the object.
247
 *
248
 * @param [in, out] ssl  SSL/TLS object.
249
 * @param [in]      mfl  Maximum fragment length code, e.g. WOLFSSL_MFL_2_9.
250
 * @return  WOLFSSL_SUCCESS on success.
251
 * @return  BAD_FUNC_ARG when ssl is NULL.
252
 * @return  Negative value on error.
253
 */
254
int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
255
{
256
    int ret = WOLFSSL_SUCCESS;
257
    /* A separate flag rather than gating on ret: the reconfigure below
258
     * succeeds without an extension being set, and both paths report
259
     * WOLFSSL_SUCCESS. */
260
    int done = 0;
261
262
    if (ssl == NULL) {
263
        ret = BAD_FUNC_ARG;
264
        done = 1;
265
    }
266
267
    #ifdef WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST
268
    /* The following is a non-standard way to reconfigure the max packet size
269
        post-handshake for wolfSSL_write/wolfSSL_read */
270
    if ((!done) && (ssl->options.handShakeState == HANDSHAKE_DONE)) {
271
        switch (mfl) {
272
            case WOLFSSL_MFL_2_8 : ssl->max_fragment =  256; break;
273
            case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
274
            case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
275
            case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
276
            case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
277
            case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
278
            default: ssl->max_fragment = MAX_RECORD_SIZE; break;
279
        }
280
        /* Reconfigured directly, so the extension is not also set below. */
281
        done = 1;
282
    }
283
    #endif /* WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST */
284
285
    if (!done) {
286
        /* This call sets the max fragment TLS extension, which gets sent to
287
            server. The server_hello response is what sets the
288
            `ssl->max_fragment` in TLSX_MFL_Parse */
289
        ret = TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
290
    }
291
292
    return ret;
293
}
294
295
296
/* Set the Maximum Fragment Length extension on the context.
297
 *
298
 * @param [in] ctx  SSL/TLS context object.
299
 * @param [in] mfl  Maximum fragment length code, e.g. WOLFSSL_MFL_2_9.
300
 * @return  WOLFSSL_SUCCESS on success.
301
 * @return  BAD_FUNC_ARG when ctx is NULL.
302
 * @return  Negative value on error.
303
 */
304
int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
305
{
306
    int ret;
307
308
    if (ctx == NULL) {
309
        ret = BAD_FUNC_ARG;
310
    }
311
    else {
312
        ret = TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
313
    }
314
315
    return ret;
316
}
317
318
#endif /* NO_WOLFSSL_CLIENT */
319
#endif /* HAVE_MAX_FRAGMENT */
320
321
#ifdef HAVE_TRUNCATED_HMAC
322
#ifndef NO_WOLFSSL_CLIENT
323
324
/* Set the Truncated HMAC extension on the object.
325
 *
326
 * @param [in] ssl  SSL/TLS object.
327
 * @return  WOLFSSL_SUCCESS on success.
328
 * @return  BAD_FUNC_ARG when ssl is NULL.
329
 * @return  Negative value on error.
330
 */
331
int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
332
{
333
    int ret;
334
335
    if (ssl == NULL) {
336
        ret = BAD_FUNC_ARG;
337
    }
338
    else {
339
        ret = TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
340
    }
341
342
    return ret;
343
}
344
345
346
/* Set the Truncated HMAC extension on the context.
347
 *
348
 * @param [in] ctx  SSL/TLS context object.
349
 * @return  WOLFSSL_SUCCESS on success.
350
 * @return  BAD_FUNC_ARG when ctx is NULL.
351
 * @return  Negative value on error.
352
 */
353
int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
354
{
355
    int ret;
356
357
    if (ctx == NULL) {
358
        ret = BAD_FUNC_ARG;
359
    }
360
    else {
361
        ret = TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
362
    }
363
364
    return ret;
365
}
366
367
#endif /* NO_WOLFSSL_CLIENT */
368
#endif /* HAVE_TRUNCATED_HMAC */
369
370
/* Elliptic Curves */
371
#if defined(HAVE_SUPPORTED_CURVES)
372
373
/* Determine whether a named group is a supported curve or FFDHE group.
374
 *
375
 * @param [in] name  Named group identifier.
376
 * @return  1 when the named group is valid.
377
 * @return  0 otherwise.
378
 */
379
static int isValidCurveGroup(word16 name)
380
0
{
381
0
    int ret;
382
383
0
    switch (name) {
384
0
        case WOLFSSL_ECC_SECP160K1:
385
0
        case WOLFSSL_ECC_SECP160R1:
386
0
        case WOLFSSL_ECC_SECP160R2:
387
0
        case WOLFSSL_ECC_SECP192K1:
388
0
        case WOLFSSL_ECC_SECP192R1:
389
0
        case WOLFSSL_ECC_SECP224K1:
390
0
        case WOLFSSL_ECC_SECP224R1:
391
0
        case WOLFSSL_ECC_SECP256K1:
392
0
        case WOLFSSL_ECC_SECP256R1:
393
0
        case WOLFSSL_ECC_SECP384R1:
394
0
        case WOLFSSL_ECC_SECP521R1:
395
0
        case WOLFSSL_ECC_BRAINPOOLP256R1:
396
0
        case WOLFSSL_ECC_BRAINPOOLP384R1:
397
0
        case WOLFSSL_ECC_BRAINPOOLP512R1:
398
0
        case WOLFSSL_ECC_SM2P256V1:
399
0
        case WOLFSSL_ECC_X25519:
400
0
        case WOLFSSL_ECC_X448:
401
0
        case WOLFSSL_ECC_BRAINPOOLP256R1TLS13:
402
0
        case WOLFSSL_ECC_BRAINPOOLP384R1TLS13:
403
0
        case WOLFSSL_ECC_BRAINPOOLP512R1TLS13:
404
405
0
        case WOLFSSL_FFDHE_2048:
406
0
        case WOLFSSL_FFDHE_3072:
407
0
        case WOLFSSL_FFDHE_4096:
408
0
        case WOLFSSL_FFDHE_6144:
409
0
        case WOLFSSL_FFDHE_8192:
410
411
0
        #ifdef WOLFSSL_HAVE_MLKEM
412
0
        #ifndef WOLFSSL_NO_ML_KEM
413
        #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
414
        case WOLFSSL_ML_KEM_512:
415
        case WOLFSSL_ML_KEM_768:
416
        case WOLFSSL_ML_KEM_1024:
417
        #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */
418
0
        #ifdef WOLFSSL_PQC_HYBRIDS
419
0
        case WOLFSSL_SECP384R1MLKEM1024:
420
0
        case WOLFSSL_X25519MLKEM768:
421
0
        case WOLFSSL_SECP256R1MLKEM768:
422
0
        #endif /* WOLFSSL_PQC_HYBRIDS */
423
        #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
424
        case WOLFSSL_SECP256R1MLKEM512:
425
        case WOLFSSL_SECP384R1MLKEM768:
426
        case WOLFSSL_SECP521R1MLKEM1024:
427
        case WOLFSSL_X25519MLKEM512:
428
        case WOLFSSL_X448MLKEM768:
429
        #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
430
0
        #endif /* !WOLFSSL_NO_ML_KEM */
431
        #ifdef WOLFSSL_MLKEM_KYBER
432
        case WOLFSSL_KYBER_LEVEL1:
433
        case WOLFSSL_KYBER_LEVEL3:
434
        case WOLFSSL_KYBER_LEVEL5:
435
        case WOLFSSL_P256_KYBER_LEVEL1:
436
        case WOLFSSL_P384_KYBER_LEVEL3:
437
        case WOLFSSL_P521_KYBER_LEVEL5:
438
        case WOLFSSL_X25519_KYBER_LEVEL1:
439
        case WOLFSSL_X448_KYBER_LEVEL3:
440
        case WOLFSSL_X25519_KYBER_LEVEL3:
441
        case WOLFSSL_P256_KYBER_LEVEL3:
442
        #endif /* WOLFSSL_MLKEM_KYBER */
443
0
        #endif
444
0
            ret = 1;
445
0
            break;
446
447
0
        default:
448
0
            ret = 0;
449
0
            break;
450
0
    }
451
452
0
    return ret;
453
0
}
454
455
/* Set a named group in the Supported Groups extension on the object.
456
 *
457
 * @param [in, out] ssl   SSL/TLS object.
458
 * @param [in]      name  Named group identifier.
459
 * @return  WOLFSSL_SUCCESS on success.
460
 * @return  BAD_FUNC_ARG when ssl is NULL or the group is invalid.
461
 * @return  WOLFSSL_FAILURE when TLS is not compiled in.
462
 */
463
int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
464
0
{
465
0
    int ret;
466
467
0
    if ((ssl == NULL) || (!isValidCurveGroup(name))) {
468
0
        ret = BAD_FUNC_ARG;
469
0
    }
470
0
    else {
471
0
        ssl->options.userCurves = 1;
472
        #if defined(NO_TLS)
473
        ret = WOLFSSL_FAILURE;
474
        #else
475
0
        ret = TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap,
476
0
                                     ssl->options.side);
477
0
        #endif /* NO_TLS */
478
0
    }
479
480
0
    return ret;
481
0
}
482
483
484
/* Set a named group in the Supported Groups extension on the context.
485
 *
486
 * @param [in] ctx   SSL/TLS context object.
487
 * @param [in] name  Named group identifier.
488
 * @return  WOLFSSL_SUCCESS on success.
489
 * @return  BAD_FUNC_ARG when ctx is NULL or the group is invalid.
490
 * @return  WOLFSSL_FAILURE when TLS is not compiled in.
491
 */
492
int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
493
0
{
494
0
    int ret;
495
496
0
    if ((ctx == NULL) || (!isValidCurveGroup(name))) {
497
0
        ret = BAD_FUNC_ARG;
498
0
    }
499
0
    else {
500
0
        ctx->userCurves = 1;
501
        #if defined(NO_TLS)
502
        ret = WOLFSSL_FAILURE;
503
        #else
504
0
        ret = TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap,
505
0
                                     ctx->method->side);
506
0
        #endif /* NO_TLS */
507
0
    }
508
509
0
    return ret;
510
0
}
511
512
#if defined(OPENSSL_EXTRA)
513
/* Validate a list of group identifiers and translate them into named groups.
514
 *
515
 * Group values may be wolfSSL named groups or curve NIDs (when ECC is
516
 * available).
517
 *
518
 * @param [in]  groups     Array of group identifiers.
519
 * @param [in]  count      Number of groups in the array.
520
 * @param [out] outGroups  Array to hold the named groups. Must have at least
521
 *                         count entries.
522
 * @return  WOLFSSL_SUCCESS on success.
523
 * @return  WOLFSSL_FAILURE when a group is not recognized.
524
 */
525
static int wolfssl_validate_groups(const int* groups, int count, int* outGroups)
526
{
527
    int i;
528
    int ret = WOLFSSL_SUCCESS;
529
530
    for (i = 0; i < count; i++) {
531
        if (isValidCurveGroup((word16)groups[i])) {
532
            outGroups[i] = groups[i];
533
        }
534
        #ifdef HAVE_ECC
535
        else {
536
            /* Groups may be populated with curve NIDs. */
537
            int oid = (int)nid2oid(groups[i], oidCurveType);
538
            int name = (int)GetCurveByOID(oid);
539
            if (name == 0) {
540
                WOLFSSL_MSG("Invalid group name");
541
                ret = WOLFSSL_FAILURE;
542
                break;
543
            }
544
            outGroups[i] = name;
545
        }
546
        #else
547
        else {
548
            WOLFSSL_MSG("Invalid group name");
549
            ret = WOLFSSL_FAILURE;
550
            break;
551
        }
552
        #endif
553
    }
554
555
    return ret;
556
}
557
558
/* Set the list of supported groups on the context.
559
 *
560
 * Group values may be wolfSSL named groups or curve NIDs.
561
 *
562
 * @param [in] ctx     SSL/TLS context object.
563
 * @param [in] groups  Array of group identifiers.
564
 * @param [in] count   Number of groups in the array.
565
 * @return  WOLFSSL_SUCCESS on success.
566
 * @return  WOLFSSL_FAILURE when count is invalid or a group is not recognized.
567
 */
568
int wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups, int count)
569
{
570
    int _groups[WOLFSSL_MAX_GROUP_COUNT];
571
    int ret = WOLFSSL_SUCCESS;
572
573
    WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
574
575
    if ((groups == NULL) || (count <= 0)) {
576
        WOLFSSL_MSG("Groups NULL or count not positive");
577
        ret = WOLFSSL_FAILURE;
578
    }
579
    else if (count > WOLFSSL_MAX_GROUP_COUNT) {
580
        WOLFSSL_MSG("Group count exceeds maximum");
581
        ret = WOLFSSL_FAILURE;
582
    }
583
    else {
584
        /* Translate the input list into named groups, then apply it. */
585
        ret = wolfssl_validate_groups(groups, count, _groups);
586
        if (ret == WOLFSSL_SUCCESS) {
587
            ret = wolfSSL_CTX_set_groups(ctx, _groups, count);
588
            /* Normalize any non-success result to WOLFSSL_FAILURE. */
589
            if (ret != WOLFSSL_SUCCESS) {
590
                ret = WOLFSSL_FAILURE;
591
            }
592
        }
593
    }
594
595
    return ret;
596
}
597
598
/* Set the list of supported groups on the object.
599
 *
600
 * Group values may be wolfSSL named groups or curve NIDs.
601
 *
602
 * @param [in] ssl     SSL/TLS object.
603
 * @param [in] groups  Array of group identifiers.
604
 * @param [in] count   Number of groups in the array.
605
 * @return  WOLFSSL_SUCCESS on success.
606
 * @return  WOLFSSL_FAILURE when count is invalid or a group is not recognized.
607
 */
608
int wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count)
609
{
610
    int _groups[WOLFSSL_MAX_GROUP_COUNT];
611
    int ret = WOLFSSL_SUCCESS;
612
613
    WOLFSSL_ENTER("wolfSSL_set1_groups");
614
615
    if ((groups == NULL) || (count <= 0)) {
616
        WOLFSSL_MSG("Groups NULL or count not positive");
617
        ret = WOLFSSL_FAILURE;
618
    }
619
    else if (count > WOLFSSL_MAX_GROUP_COUNT) {
620
        WOLFSSL_MSG("Group count exceeds maximum");
621
        ret = WOLFSSL_FAILURE;
622
    }
623
    else {
624
        /* Translate the input list into named groups, then apply it. */
625
        ret = wolfssl_validate_groups(groups, count, _groups);
626
        if (ret == WOLFSSL_SUCCESS) {
627
            ret = wolfSSL_set_groups(ssl, _groups, count);
628
            /* Normalize any non-success result to WOLFSSL_FAILURE. */
629
            if (ret != WOLFSSL_SUCCESS) {
630
                ret = WOLFSSL_FAILURE;
631
            }
632
        }
633
    }
634
635
    return ret;
636
}
637
#endif /* OPENSSL_EXTRA */
638
#endif /* HAVE_SUPPORTED_CURVES */
639
640
/* Application-Layer Protocol Negotiation */
641
#ifdef HAVE_ALPN
642
643
/* Set the Application-Layer Protocol Negotiation extension on the object.
644
 *
645
 * @param [in] ssl                   SSL/TLS object.
646
 * @param [in] protocol_name_list    Comma-separated list of protocol names.
647
 * @param [in] protocol_name_listSz  Length of the list in bytes.
648
 * @param [in] options               Bitmask of ALPN options. A mismatch
649
 *          behavior must be set or BAD_FUNC_ARG is returned.
650
 *          WOLFSSL_ALPN_FAILED_ON_MISMATCH sends the fatal
651
 *          no_application_protocol alert and fails the handshake when no
652
 *          protocol matches, per RFC 7301 section 3.2.
653
 *          WOLFSSL_ALPN_CONTINUE_ON_MISMATCH instead continues without an
654
 *          agreed protocol like OpenSSL. That does not send the alert and is
655
 *          therefore not RFC 7301 compliant, so use it only for OpenSSL
656
 *          interop.
657
 * @return  WOLFSSL_SUCCESS on success.
658
 * @return  BAD_FUNC_ARG when an argument is NULL, the list is too long or
659
 *          options are unsupported.
660
 * @return  MEMORY_ERROR on allocation failure.
661
 */
662
WOLFSSL_ABI
663
int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
664
    word32 protocol_name_listSz, byte options)
665
{
666
    char*  list = NULL;
667
    char*  ptr = NULL;
668
    char** token = NULL;
669
    word16 len;
670
    int    idx = 0;
671
    int    ret = WOLFSSL_SUCCESS;
672
    /* Caches ssl->heap once the object is known to be non-NULL, so the
673
     * cleanup at the end can free without dereferencing ssl - the early
674
     * returns that used to skip that cleanup are gone. It stays NULL exactly
675
     * when nothing was allocated. */
676
    void*  heap = NULL;
677
678
    WOLFSSL_ENTER("wolfSSL_UseALPN");
679
680
    if ((ssl == NULL) || (protocol_name_list == NULL)) {
681
        ret = BAD_FUNC_ARG;
682
    }
683
    else if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
684
             WOLFSSL_MAX_ALPN_PROTO_NAME_LEN + WOLFSSL_MAX_ALPN_NUMBER)) {
685
        WOLFSSL_MSG("Invalid arguments, protocol name list too long");
686
        ret = BAD_FUNC_ARG;
687
    }
688
    else if ((!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH)) &&
689
             (!(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH))) {
690
        WOLFSSL_MSG("Invalid arguments, options not supported");
691
        ret = BAD_FUNC_ARG;
692
    }
693
694
    if (ret == WOLFSSL_SUCCESS) {
695
        heap = ssl->heap;
696
        list = (char *)XMALLOC(protocol_name_listSz + 1, heap,
697
                               DYNAMIC_TYPE_ALPN);
698
        token = (char **)XMALLOC(sizeof(char*) * (WOLFSSL_MAX_ALPN_NUMBER + 1),
699
                                 heap, DYNAMIC_TYPE_ALPN);
700
        if ((list == NULL) || (token == NULL)) {
701
            WOLFSSL_MSG("Memory failure");
702
            ret = MEMORY_ERROR;
703
        }
704
    }
705
706
    if (ret == WOLFSSL_SUCCESS) {
707
        XMEMSET(token, 0, sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1));
708
709
        XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
710
        list[protocol_name_listSz] = '\0';
711
712
        /* Read all protocol names from the list. */
713
        token[idx] = XSTRTOK(list, ",", &ptr);
714
        while ((idx < WOLFSSL_MAX_ALPN_NUMBER) && (token[idx] != NULL)) {
715
            token[++idx] = XSTRTOK(NULL, ",", &ptr);
716
        }
717
718
        /* Add the protocol name list to the TLS extension in reverse order. */
719
        while ((idx--) > 0) {
720
            len = (word16)XSTRLEN(token[idx]);
721
722
            ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
723
                heap);
724
            if (ret != WOLFSSL_SUCCESS) {
725
                WOLFSSL_MSG("TLSX_UseALPN failure");
726
                break;
727
            }
728
        }
729
    }
730
731
    XFREE(token, heap, DYNAMIC_TYPE_ALPN);
732
    XFREE(list, heap, DYNAMIC_TYPE_ALPN);
733
734
    return ret;
735
}
736
737
/* Get the ALPN protocol negotiated for the object.
738
 *
739
 * @param [in]  ssl            SSL/TLS object.
740
 * @param [out] protocol_name  Negotiated protocol name.
741
 * @param [out] size           Length of the protocol name in bytes.
742
 * @return  WOLFSSL_SUCCESS on success.
743
 * @return  Negative value on error.
744
 */
745
int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
746
{
747
    return TLSX_ALPN_GetRequest((ssl != NULL) ? ssl->extensions : NULL,
748
                                (void **)protocol_name, size);
749
}
750
751
/* Get the ALPN protocol list offered by the peer as a comma-separated string.
752
 *
753
 * The returned list must be freed with wolfSSL_ALPN_FreePeerProtocol().
754
 *
755
 * @param [in]  ssl     SSL/TLS object.
756
 * @param [out] list    Newly allocated comma-separated protocol list.
757
 * @param [out] listSz  Length of the list string.
758
 * @return  WOLFSSL_SUCCESS on success.
759
 * @return  BAD_FUNC_ARG when an argument is NULL.
760
 * @return  BUFFER_ERROR when the peer offered no protocols.
761
 * @return  MEMORY_ERROR on allocation failure.
762
 */
763
int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
764
{
765
    int ret = WOLFSSL_SUCCESS;
766
    int i;
767
    int len = 0;
768
    char *p = NULL;
769
    byte *s;
770
771
    if ((ssl == NULL) || (list == NULL) || (listSz == NULL)) {
772
        ret = BAD_FUNC_ARG;
773
    }
774
    else if ((ssl->alpn_peer_requested == NULL) ||
775
             (ssl->alpn_peer_requested_length == 0)) {
776
        ret = BUFFER_ERROR;
777
    }
778
    else {
779
        /* ssl->alpn_peer_requested are the original bytes sent in a
780
         * ClientHello, formatted as (len-byte chars+)+. To turn n protocols
781
         * into a comma-separated C string, one needs (n-1) commas and a final
782
         * 0 byte which has the same length as the original.
783
         * The returned length is the strlen() of the C string, so -1 of that.
784
         */
785
        *listSz = ssl->alpn_peer_requested_length-1;
786
        *list = p = (char *)XMALLOC(ssl->alpn_peer_requested_length, ssl->heap,
787
                                    DYNAMIC_TYPE_TLSX);
788
        if (p == NULL) {
789
            ret = MEMORY_ERROR;
790
        }
791
    }
792
793
    if (ret == WOLFSSL_SUCCESS) {
794
        for (i = 0, s = ssl->alpn_peer_requested;
795
             i < ssl->alpn_peer_requested_length;
796
             p += len, i += len)
797
        {
798
            if (i != 0) {
799
                *p++ = ',';
800
            }
801
            len = s[i++];
802
            /* guard against bad length bytes. */
803
            if (i + len > ssl->alpn_peer_requested_length) {
804
                XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
805
                *list = NULL;
806
                ret = WOLFSSL_FAILURE;
807
                break;
808
            }
809
            XMEMCPY(p, s + i, (size_t)len);
810
        }
811
    }
812
813
    if (ret == WOLFSSL_SUCCESS) {
814
        *p = 0;
815
    }
816
817
    return ret;
818
}
819
820
821
/* Free a peer protocol list returned by wolfSSL_ALPN_GetPeerProtocol().
822
 *
823
 * @param [in]      ssl   SSL/TLS object.
824
 * @param [in, out] list  Protocol list to free; set to NULL on return.
825
 * @return  WOLFSSL_SUCCESS on success.
826
 * @return  BAD_FUNC_ARG when ssl is NULL.
827
 */
828
int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
829
{
830
    int ret = WOLFSSL_SUCCESS;
831
832
    if (ssl == NULL) {
833
        ret = BAD_FUNC_ARG;
834
    }
835
    else {
836
        XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
837
        *list = NULL;
838
    }
839
840
    return ret;
841
}
842
843
#endif /* HAVE_ALPN */
844
845
/* Secure Renegotiation */
846
#ifdef HAVE_SERVER_RENEGOTIATION_INFO
847
848
/* Enable the Secure Renegotiation extension on the object.
849
 *
850
 * Use of secure renegotiation is discouraged.
851
 *
852
 * @param [in, out] ssl  SSL/TLS object.
853
 * @return  WOLFSSL_SUCCESS on success.
854
 * @return  BAD_FUNC_ARG when ssl is NULL.
855
 * @return  Negative value on error.
856
 */
857
int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
858
0
{
859
0
    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
860
    #if defined(NO_TLS)
861
    (void)ssl;
862
    #else
863
0
    if (ssl != NULL) {
864
0
        ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
865
0
    }
866
0
    else {
867
0
        ret = BAD_FUNC_ARG;
868
0
    }
869
870
0
    if (ret == WOLFSSL_SUCCESS) {
871
0
        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
872
0
        if (extension != NULL) {
873
0
            ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
874
0
        }
875
0
    }
876
0
    #endif /* !NO_TLS */
877
0
    return ret;
878
0
}
879
880
/* Enable the Secure Renegotiation extension on the context.
881
 *
882
 * Use of secure renegotiation is discouraged.
883
 *
884
 * @param [in] ctx  SSL/TLS context object.
885
 * @return  WOLFSSL_SUCCESS on success.
886
 * @return  BAD_FUNC_ARG when ctx is NULL.
887
 */
888
int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx)
889
0
{
890
0
    int ret = WOLFSSL_SUCCESS;
891
892
0
    if (ctx == NULL) {
893
0
        ret = BAD_FUNC_ARG;
894
0
    }
895
0
    else {
896
0
        ctx->useSecureReneg = 1;
897
0
    }
898
899
0
    return ret;
900
0
}
901
902
#ifdef HAVE_SECURE_RENEGOTIATION
903
/* Get the object ready for a renegotiation handshake.
904
 *
905
 * A renegotiation already under way keeps its handshake state so that it can
906
 * continue. Otherwise the state is reset so a new negotiation starts from the
907
 * beginning. The caller performs the negotiation either way.
908
 *
909
 * Both ssl and ssl->secure_renegotiation must be non-NULL - the second is
910
 * dereferenced without a check, as _Rehandshake() has already established
911
 * both before reaching here.
912
 *
913
 * @param [in, out] ssl  SSL/TLS object.
914
 * @return  WOLFSSL_SUCCESS when the object is ready to negotiate.
915
 * @return  SECURE_RENEGOTIATION_E when the initial handshake has not
916
 *          completed.
917
 * @return  WOLFSSL_FATAL_ERROR on error. ssl->error holds the reason.
918
 */
919
static int wolfssl_rehandshake_prepare(WOLFSSL* ssl)
920
{
921
    int ret = WOLFSSL_SUCCESS;
922
923
    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
924
        if (!ssl->options.handShakeDone) {
925
            WOLFSSL_MSG("Can't renegotiate until initial "
926
                        "handshake complete");
927
            ret = SECURE_RENEGOTIATION_E;
928
        }
929
        else {
930
            /* Leave the state alone - resetting it would discard the
931
             * renegotiation that is already in progress. */
932
            WOLFSSL_MSG("Renegotiation already started. "
933
                        "Moving it forward.");
934
        }
935
    }
936
    else {
937
        /* reset handshake states */
938
        ssl->options.sendVerify = 0;
939
        ssl->options.serverState = NULL_STATE;
940
        ssl->options.clientState = NULL_STATE;
941
        ssl->options.connectState  = CONNECT_BEGIN;
942
        ssl->options.acceptState   = ACCEPT_BEGIN_RENEG;
943
        ssl->options.handShakeState = NULL_STATE;
944
        /* TODO, move states in internal.h */
945
        ssl->options.processReply  = 0;
946
947
        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
948
949
        ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
950
951
        #if !defined(NO_WOLFSSL_SERVER) && !defined(WOLFSSL_NO_TLS12)
952
        if (ssl->options.side == WOLFSSL_SERVER_END) {
953
            int helloRet = SendHelloRequest(ssl);
954
955
            if (helloRet != 0) {
956
                ssl->error = helloRet;
957
                ret = WOLFSSL_FATAL_ERROR;
958
            }
959
        }
960
        #endif /* !NO_WOLFSSL_SERVER && !WOLFSSL_NO_TLS12 */
961
962
        if (ret == WOLFSSL_SUCCESS) {
963
            int hashRet = InitHandshakeHashes(ssl);
964
965
            if (hashRet != 0) {
966
                ssl->error = hashRet;
967
                ret = WOLFSSL_FATAL_ERROR;
968
            }
969
        }
970
    }
971
972
    return ret;
973
}
974
975
/* Perform a secure renegotiation handshake on the object.
976
 *
977
 * User forced; use of secure renegotiation is discouraged.
978
 *
979
 * @param [in, out] ssl  SSL/TLS object.
980
 * @return  WOLFSSL_SUCCESS on success.
981
 * @return  BAD_FUNC_ARG when ssl is NULL.
982
 * @return  SECURE_RENEGOTIATION_E when renegotiation is not allowed.
983
 * @return  WOLFSSL_FATAL_ERROR on error.
984
 */
985
static int _Rehandshake(WOLFSSL* ssl)
986
{
987
    int ret = WOLFSSL_SUCCESS;
988
989
    if (ssl == NULL) {
990
        ret = BAD_FUNC_ARG;
991
    }
992
    else if (IsAtLeastTLSv1_3(ssl->version)) {
993
        WOLFSSL_MSG("Secure Renegotiation not supported in TLS 1.3");
994
        ret = SECURE_RENEGOTIATION_E;
995
    }
996
    else if (ssl->secure_renegotiation == NULL) {
997
        WOLFSSL_MSG("Secure Renegotiation not forced on by user");
998
        ret = SECURE_RENEGOTIATION_E;
999
    }
1000
    else if (ssl->secure_renegotiation->enabled == 0) {
1001
        WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
1002
        ret = SECURE_RENEGOTIATION_E;
1003
    }
1004
    else if (ssl->secure_renegotiation->advertiseOnly) {
1005
        /* Extension was advertised only for the RFC 5746 check; the
1006
         * application did not call wolfSSL_UseSecureRenegotiation(). */
1007
        WOLFSSL_MSG("Secure Renegotiation not forced on by user");
1008
        ret = SECURE_RENEGOTIATION_E;
1009
    }
1010
    #ifdef WOLFSSL_DTLS
1011
    else if ((ssl->options.dtls) && ((ssl->keys.dtls_epoch == 0xFFFF) ||
1012
            (ssl->keys.peerSeq[0].nextEpoch == 0xFFFF))) {
1013
        WOLFSSL_MSG("Secure Renegotiation not allowed. Epoch would wrap");
1014
        ret = SECURE_RENEGOTIATION_E;
1015
    }
1016
    #endif
1017
    /* Prepare, unless this is a server that has already processed a
1018
     * client-initiated hello, in which case there is nothing to prepare. */
1019
    else if ((ssl->options.side != WOLFSSL_SERVER_END) ||
1020
            (ssl->options.acceptState != ACCEPT_FIRST_REPLY_DONE)) {
1021
        ret = wolfssl_rehandshake_prepare(ssl);
1022
    }
1023
1024
    if (ret == WOLFSSL_SUCCESS) {
1025
        ret = wolfSSL_negotiate(ssl);
1026
        if (ret == WOLFSSL_SUCCESS) {
1027
            ssl->secure_rene_count++;
1028
        }
1029
    }
1030
1031
    return ret;
1032
}
1033
1034
1035
/* Perform a secure renegotiation handshake on the object.
1036
 *
1037
 * User forced; use of secure renegotiation is discouraged.
1038
 *
1039
 * @param [in, out] ssl  SSL/TLS object.
1040
 * @return  WOLFSSL_SUCCESS on success.
1041
 * @return  WOLFSSL_FAILURE when ssl is NULL.
1042
 * @return  Negative value on error.
1043
 */
1044
int wolfSSL_Rehandshake(WOLFSSL* ssl)
1045
{
1046
    int ret = WOLFSSL_SUCCESS;
1047
1048
    WOLFSSL_ENTER("wolfSSL_Rehandshake");
1049
1050
    if (ssl == NULL) {
1051
        ret = WOLFSSL_FAILURE;
1052
    }
1053
    else {
1054
        if (ssl->options.side == WOLFSSL_SERVER_END) {
1055
            /* Reset option to send certificate verify. */
1056
            ssl->options.sendVerify = 0;
1057
            /* Reset resuming flag to do full secure handshake. */
1058
            ssl->options.resuming = 0;
1059
        }
1060
        else {
1061
            /* Reset resuming flag to do full secure handshake. */
1062
            ssl->options.resuming = 0;
1063
            #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_CLIENT)
1064
            /* Clearing the ticket. */
1065
            ret = wolfSSL_UseSessionTicket(ssl);
1066
            #endif
1067
        }
1068
        /* CLIENT/SERVER: Reset peer authentication for full secure
1069
         * handshake. */
1070
        ssl->options.peerAuthGood = 0;
1071
1072
        if (ret == WOLFSSL_SUCCESS) {
1073
            ret = _Rehandshake(ssl);
1074
        }
1075
    }
1076
1077
    return ret;
1078
}
1079
1080
1081
#ifndef NO_WOLFSSL_CLIENT
1082
1083
/* Perform a secure resumption handshake on the object.
1084
 *
1085
 * Client side only. User forced; use of secure renegotiation is discouraged.
1086
 *
1087
 * @param [in, out] ssl  SSL/TLS object.
1088
 * @return  WOLFSSL_SUCCESS on success.
1089
 * @return  BAD_FUNC_ARG when ssl is NULL.
1090
 * @return  WOLFSSL_FATAL_ERROR when called on a server.
1091
 */
1092
int wolfSSL_SecureResume(WOLFSSL* ssl)
1093
{
1094
    int ret;
1095
1096
    WOLFSSL_ENTER("wolfSSL_SecureResume");
1097
1098
    if (ssl == NULL) {
1099
        ret = BAD_FUNC_ARG;
1100
    }
1101
    else if (ssl->options.side == WOLFSSL_SERVER_END) {
1102
        ssl->error = SIDE_ERROR;
1103
        ret = WOLFSSL_FATAL_ERROR;
1104
    }
1105
    else {
1106
        ret = _Rehandshake(ssl);
1107
    }
1108
1109
    return ret;
1110
}
1111
1112
#endif /* NO_WOLFSSL_CLIENT */
1113
1114
#endif /* HAVE_SECURE_RENEGOTIATION */
1115
1116
/* Get whether secure renegotiation is enabled for the object.
1117
 *
1118
 * @param [in] ssl  SSL/TLS object.
1119
 * @return  1 when secure renegotiation is enabled.
1120
 * @return  0 when ssl is NULL or it is not enabled.
1121
 */
1122
long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
1123
0
{
1124
0
    WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
1125
1126
0
    return (ssl != NULL) && (ssl->secure_renegotiation != NULL) &&
1127
0
           ssl->secure_renegotiation->enabled;
1128
0
}
1129
1130
#endif /* HAVE_SECURE_RENEGOTIATION_INFO */
1131
1132
#if !defined(NO_WOLFSSL_CLIENT) && !defined(WOLFSSL_NO_TLS12) && \
1133
    defined(HAVE_SERVER_RENEGOTIATION_INFO) && \
1134
    !defined(WOLFSSL_HARDEN_TLS_NO_SCR_CHECK)
1135
/* Get whether the secure renegotiation check is enabled for the object.
1136
 *
1137
 * @param [in] ssl  SSL/TLS object.
1138
 * @return  Non-zero when the check is enabled, 0 otherwise.
1139
 * @return  BAD_FUNC_ARG when ssl is NULL.
1140
 */
1141
int wolfSSL_get_scr_check_enabled(const WOLFSSL* ssl)
1142
0
{
1143
0
    int ret;
1144
1145
0
    WOLFSSL_ENTER("wolfSSL_get_scr_check_enabled");
1146
1147
0
    if (ssl == NULL) {
1148
0
        ret = BAD_FUNC_ARG;
1149
0
    }
1150
0
    else {
1151
0
        ret = ssl->scr_check_enabled;
1152
0
    }
1153
1154
0
    return ret;
1155
0
}
1156
1157
/* Set whether the secure renegotiation check is enabled for the object.
1158
 *
1159
 * @param [in, out] ssl      SSL/TLS object.
1160
 * @param [in]      enabled  Non-zero to enable the check, 0 to disable it.
1161
 * @return  WOLFSSL_SUCCESS on success.
1162
 * @return  BAD_FUNC_ARG when ssl is NULL.
1163
 */
1164
int wolfSSL_set_scr_check_enabled(WOLFSSL* ssl, byte enabled)
1165
0
{
1166
0
    int ret = WOLFSSL_SUCCESS;
1167
1168
0
    WOLFSSL_ENTER("wolfSSL_set_scr_check_enabled");
1169
1170
0
    if (ssl == NULL) {
1171
0
        ret = BAD_FUNC_ARG;
1172
0
    }
1173
0
    else {
1174
0
        ssl->scr_check_enabled = !!enabled;
1175
0
    }
1176
1177
0
    return ret;
1178
0
}
1179
1180
/* Get whether the secure renegotiation check is enabled for the context.
1181
 *
1182
 * @param [in] ctx  SSL/TLS context object.
1183
 * @return  Non-zero when the check is enabled, 0 otherwise.
1184
 * @return  BAD_FUNC_ARG when ctx is NULL.
1185
 */
1186
int wolfSSL_CTX_get_scr_check_enabled(const WOLFSSL_CTX* ctx)
1187
0
{
1188
0
    int ret;
1189
1190
0
    WOLFSSL_ENTER("wolfSSL_CTX_get_scr_check_enabled");
1191
1192
0
    if (ctx == NULL) {
1193
0
        ret = BAD_FUNC_ARG;
1194
0
    }
1195
0
    else {
1196
0
        ret = ctx->scr_check_enabled;
1197
0
    }
1198
1199
0
    return ret;
1200
0
}
1201
1202
/* Set whether the secure renegotiation check is enabled for the context.
1203
 *
1204
 * WOLFSSL objects created from the context inherit this setting. Disabling the
1205
 * check allows connecting to servers that do not support secure renegotiation
1206
 * (RFC 5746), which is not recommended.
1207
 *
1208
 * @param [in] ctx      SSL/TLS context object.
1209
 * @param [in] enabled  Non-zero to enable the check, 0 to disable it.
1210
 * @return  WOLFSSL_SUCCESS on success.
1211
 * @return  BAD_FUNC_ARG when ctx is NULL.
1212
 */
1213
int wolfSSL_CTX_set_scr_check_enabled(WOLFSSL_CTX* ctx, byte enabled)
1214
0
{
1215
0
    int ret = WOLFSSL_SUCCESS;
1216
1217
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_scr_check_enabled");
1218
1219
0
    if (ctx == NULL) {
1220
0
        ret = BAD_FUNC_ARG;
1221
0
    }
1222
0
    else {
1223
0
        ctx->scr_check_enabled = !!enabled;
1224
0
    }
1225
1226
0
    return ret;
1227
0
}
1228
#endif
1229
1230
#if defined(HAVE_SESSION_TICKET)
1231
/* Session Ticket */
1232
1233
#if !defined(NO_WOLFSSL_SERVER)
1234
/* Disable use of session tickets with TLS 1.2 on the context.
1235
 *
1236
 * @param [in] ctx  SSL/TLS context object.
1237
 * @return  WOLFSSL_SUCCESS on success.
1238
 * @return  BAD_FUNC_ARG when ctx is NULL.
1239
 */
1240
int wolfSSL_CTX_NoTicketTLSv12(WOLFSSL_CTX* ctx)
1241
{
1242
    int ret = WOLFSSL_SUCCESS;
1243
1244
    if (ctx == NULL) {
1245
        ret = BAD_FUNC_ARG;
1246
    }
1247
    else {
1248
        ctx->noTicketTls12 = 1;
1249
    }
1250
1251
    return ret;
1252
}
1253
1254
/* Disable use of session tickets with TLS 1.2 on the object.
1255
 *
1256
 * @param [in, out] ssl  SSL/TLS object.
1257
 * @return  WOLFSSL_SUCCESS on success.
1258
 * @return  BAD_FUNC_ARG when ssl is NULL.
1259
 */
1260
int wolfSSL_NoTicketTLSv12(WOLFSSL* ssl)
1261
{
1262
    int ret = WOLFSSL_SUCCESS;
1263
1264
    if (ssl == NULL) {
1265
        ret = BAD_FUNC_ARG;
1266
    }
1267
    else {
1268
        ssl->options.noTicketTls12 = 1;
1269
    }
1270
1271
    return ret;
1272
}
1273
1274
/* Set the session ticket encryption callback on the context.
1275
 *
1276
 * @param [in] ctx  SSL/TLS context object.
1277
 * @param [in] cb   Session ticket encryption callback.
1278
 * @return  WOLFSSL_SUCCESS on success.
1279
 * @return  BAD_FUNC_ARG when ctx is NULL.
1280
 */
1281
int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
1282
{
1283
    int ret = WOLFSSL_SUCCESS;
1284
1285
    if (ctx == NULL) {
1286
        ret = BAD_FUNC_ARG;
1287
    }
1288
    else {
1289
        ctx->ticketEncCb = cb;
1290
    }
1291
1292
    return ret;
1293
}
1294
1295
/* Set the session ticket lifetime hint, in seconds, on the context.
1296
 *
1297
 * @param [in] ctx   SSL/TLS context object.
1298
 * @param [in] hint  Lifetime hint in seconds. No more than 604800 (7 days).
1299
 * @return  WOLFSSL_SUCCESS on success.
1300
 * @return  BAD_FUNC_ARG when ctx is NULL or hint is out of range.
1301
 */
1302
int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
1303
{
1304
    int ret = WOLFSSL_SUCCESS;
1305
1306
    /* RFC8446 Section 4.6.1: Servers MUST NOT use any value greater than
1307
     * 604800 seconds (7 days). */
1308
    if ((ctx == NULL) || (hint < 0) || (hint > 604800)) {
1309
        ret = BAD_FUNC_ARG;
1310
    }
1311
    else {
1312
        ctx->ticketHint = hint;
1313
    }
1314
1315
    return ret;
1316
}
1317
1318
/* Set the user context passed to the session ticket encryption callback.
1319
 *
1320
 * @param [in] ctx      SSL/TLS context object.
1321
 * @param [in] userCtx  User context for the ticket encryption callback.
1322
 * @return  WOLFSSL_SUCCESS on success.
1323
 * @return  BAD_FUNC_ARG when ctx is NULL.
1324
 */
1325
int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
1326
{
1327
    int ret = WOLFSSL_SUCCESS;
1328
1329
    if (ctx == NULL) {
1330
        ret = BAD_FUNC_ARG;
1331
    }
1332
    else {
1333
        ctx->ticketEncCtx = userCtx;
1334
    }
1335
1336
    return ret;
1337
}
1338
1339
/* Get the user context passed to the session ticket encryption callback.
1340
 *
1341
 * @param [in] ctx  SSL/TLS context object.
1342
 * @return  User context on success.
1343
 * @return  NULL when ctx is NULL.
1344
 */
1345
void* wolfSSL_CTX_get_TicketEncCtx(WOLFSSL_CTX* ctx)
1346
{
1347
    void* userCtx = NULL;
1348
1349
    if (ctx != NULL) {
1350
        userCtx = ctx->ticketEncCtx;
1351
    }
1352
1353
    return userCtx;
1354
}
1355
1356
#ifdef WOLFSSL_TLS13
1357
/* Set the maximum number of TLS 1.3 session tickets to send.
1358
 *
1359
 * @param [in] ctx        SSL/TLS context object.
1360
 * @param [in] mxTickets  Maximum number of tickets to send.
1361
 * @return  WOLFSSL_SUCCESS on success.
1362
 * @return  WOLFSSL_FAILURE when ctx is NULL.
1363
 */
1364
int wolfSSL_CTX_set_num_tickets(WOLFSSL_CTX* ctx, size_t mxTickets)
1365
{
1366
    int ret = WOLFSSL_SUCCESS;
1367
1368
    if (ctx == NULL) {
1369
        ret = WOLFSSL_FAILURE;
1370
    }
1371
    else {
1372
        ctx->maxTicketTls13 = (unsigned int)mxTickets;
1373
    }
1374
1375
    return ret;
1376
}
1377
1378
/* Get the maximum number of TLS 1.3 session tickets to send.
1379
 *
1380
 * @param [in] ctx  SSL/TLS context object.
1381
 * @return  Maximum number of tickets to send, or 0 when ctx is NULL.
1382
 */
1383
size_t wolfSSL_CTX_get_num_tickets(WOLFSSL_CTX* ctx)
1384
{
1385
    size_t mxTickets = 0;
1386
1387
    if (ctx != NULL) {
1388
        mxTickets = (size_t)ctx->maxTicketTls13;
1389
    }
1390
1391
    return mxTickets;
1392
}
1393
#endif /* WOLFSSL_TLS13 */
1394
#endif /* !NO_WOLFSSL_SERVER */
1395
1396
#if !defined(NO_WOLFSSL_CLIENT)
1397
/* Enable use of the session ticket extension on the object.
1398
 *
1399
 * @param [in] ssl  SSL/TLS object.
1400
 * @return  WOLFSSL_SUCCESS on success.
1401
 * @return  BAD_FUNC_ARG when ssl is NULL.
1402
 * @return  Negative value on error.
1403
 */
1404
int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
1405
{
1406
    int ret;
1407
1408
    if (ssl == NULL) {
1409
        ret = BAD_FUNC_ARG;
1410
    }
1411
    else {
1412
        ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
1413
    }
1414
1415
    return ret;
1416
}
1417
1418
/* Enable use of the session ticket extension on the context.
1419
 *
1420
 * @param [in] ctx  SSL/TLS context object.
1421
 * @return  WOLFSSL_SUCCESS on success.
1422
 * @return  BAD_FUNC_ARG when ctx is NULL.
1423
 * @return  Negative value on error.
1424
 */
1425
int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
1426
{
1427
    int ret;
1428
1429
    if (ctx == NULL) {
1430
        ret = BAD_FUNC_ARG;
1431
    }
1432
    else {
1433
        ret = TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
1434
    }
1435
1436
    return ret;
1437
}
1438
1439
/* Get the session ticket stored on the object.
1440
 *
1441
 * When buf is NULL and *bufSz is 0, the length required is returned in bufSz.
1442
 *
1443
 * @param [in]      ssl    SSL/TLS object.
1444
 * @param [out]     buf    Buffer to hold the ticket. May be NULL for length.
1445
 * @param [in, out] bufSz  In: size of buffer. Out: length of ticket.
1446
 * @return  WOLFSSL_SUCCESS on success.
1447
 * @return  LENGTH_ONLY_E when buf is NULL and bufSz has been set.
1448
 * @return  BAD_FUNC_ARG when ssl or bufSz is NULL.
1449
 */
1450
int wolfSSL_get_SessionTicket(WOLFSSL* ssl, byte* buf, word32* bufSz)
1451
{
1452
    int ret = WOLFSSL_SUCCESS;
1453
1454
    if ((ssl == NULL) || (bufSz == NULL)) {
1455
        ret = BAD_FUNC_ARG;
1456
    }
1457
    else if ((*bufSz == 0) && (buf == NULL)) {
1458
        /* Report the length needed to hold the ticket. */
1459
        *bufSz = ssl->session->ticketLen;
1460
        ret = LENGTH_ONLY_E;
1461
    }
1462
    else if (buf == NULL) {
1463
        ret = BAD_FUNC_ARG;
1464
    }
1465
    else if (ssl->session->ticketLen <= *bufSz) {
1466
        XMEMCPY(buf, ssl->session->ticket, ssl->session->ticketLen);
1467
        *bufSz = ssl->session->ticketLen;
1468
    }
1469
    else {
1470
        *bufSz = 0;
1471
    }
1472
1473
    return ret;
1474
}
1475
1476
/* Set the session ticket to use on the object.
1477
 *
1478
 * @param [in] ssl    SSL/TLS object.
1479
 * @param [in] buf    Ticket data, may be NULL when bufSz is 0.
1480
 * @param [in] bufSz  Length of ticket data in bytes.
1481
 * @return  WOLFSSL_SUCCESS on success.
1482
 * @return  BAD_FUNC_ARG when ssl is NULL or buf is NULL with bufSz > 0.
1483
 * @return  MEMORY_ERROR on allocation failure.
1484
 */
1485
int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
1486
                                          word32 bufSz)
1487
{
1488
    int ret = WOLFSSL_SUCCESS;
1489
1490
    if ((ssl == NULL) || ((buf == NULL) && (bufSz > 0))) {
1491
        ret = BAD_FUNC_ARG;
1492
    }
1493
1494
    if ((ret == WOLFSSL_SUCCESS) && (bufSz > 0)) {
1495
        /* Ticket will fit into static ticket */
1496
        if (bufSz <= SESSION_TICKET_LEN) {
1497
            if (ssl->session->ticketLenAlloc > 0) {
1498
                XFREE(ssl->session->ticket, ssl->session->heap,
1499
                      DYNAMIC_TYPE_SESSION_TICK);
1500
                ssl->session->ticketLenAlloc = 0;
1501
                ssl->session->ticket = ssl->session->staticTicket;
1502
            }
1503
        }
1504
        else { /* Ticket requires dynamic ticket storage */
1505
            /* is dyn buffer big enough */
1506
            if (ssl->session->ticketLen < bufSz) {
1507
                if (ssl->session->ticketLenAlloc > 0) {
1508
                    XFREE(ssl->session->ticket, ssl->session->heap,
1509
                          DYNAMIC_TYPE_SESSION_TICK);
1510
                }
1511
                ssl->session->ticket = (byte*)XMALLOC(bufSz, ssl->session->heap,
1512
                        DYNAMIC_TYPE_SESSION_TICK);
1513
                if (ssl->session->ticket == NULL) {
1514
                    ssl->session->ticket = ssl->session->staticTicket;
1515
                    ssl->session->ticketLenAlloc = 0;
1516
                    ret = MEMORY_ERROR;
1517
                }
1518
                else {
1519
                    ssl->session->ticketLenAlloc = (word16)bufSz;
1520
                }
1521
            }
1522
        }
1523
1524
        if (ret == WOLFSSL_SUCCESS) {
1525
            XMEMCPY(ssl->session->ticket, buf, bufSz);
1526
        }
1527
    }
1528
1529
    if (ret == WOLFSSL_SUCCESS) {
1530
        ssl->session->ticketLen = (word16)bufSz;
1531
    }
1532
1533
    return ret;
1534
}
1535
1536
1537
/* Set the session ticket callback and user context on the object.
1538
 *
1539
 * @param [in, out] ssl  SSL/TLS object.
1540
 * @param [in]      cb   Session ticket callback.
1541
 * @param [in]      ctx  User context passed to the callback.
1542
 * @return  WOLFSSL_SUCCESS on success.
1543
 * @return  BAD_FUNC_ARG when ssl is NULL.
1544
 */
1545
int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
1546
                                 CallbackSessionTicket cb, void* ctx)
1547
{
1548
    int ret = WOLFSSL_SUCCESS;
1549
1550
    if (ssl == NULL) {
1551
        ret = BAD_FUNC_ARG;
1552
    }
1553
    else {
1554
        ssl->session_ticket_cb = cb;
1555
        ssl->session_ticket_ctx = ctx;
1556
    }
1557
1558
    return ret;
1559
}
1560
#endif /* !NO_WOLFSSL_CLIENT */
1561
1562
#endif /* HAVE_SESSION_TICKET */
1563
1564
1565
#ifdef HAVE_EXTENDED_MASTER
1566
1567
/* EMS applies to (D)TLS 1.0-1.2 only; the same version gate is applied by
1568
 * InitSSL_Ctx and InitSSL_Side when arming the default advertisement. */
1569
static int EmsAllowedForVersion(ProtocolVersion pv)
1570
0
{
1571
0
    int allowed = 0;
1572
1573
0
    if (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR)
1574
0
        allowed = 1;
1575
#ifdef WOLFSSL_DTLS
1576
    if (pv.major == DTLS_MAJOR)
1577
        allowed = 1;
1578
#endif
1579
1580
0
    return allowed;
1581
0
}
1582
1583
1584
/* Disable the Extended Master Secret extension on the context.
1585
 *
1586
 * For a client this stops the extension being advertised. For a server this
1587
 * causes the peer's Extended Master Secret request to be ignored so that a
1588
 * standard master secret is negotiated.
1589
 *
1590
 * @param [in] ctx  SSL/TLS context object.
1591
 * @return  WOLFSSL_SUCCESS on success.
1592
 * @return  BAD_FUNC_ARG when ctx is NULL.
1593
 */
1594
int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
1595
0
{
1596
0
    int ret = WOLFSSL_SUCCESS;
1597
1598
0
    if (ctx == NULL) {
1599
0
        ret = BAD_FUNC_ARG;
1600
0
    }
1601
0
    else {
1602
0
        ctx->haveEMS = 0;
1603
0
        ctx->disableEMS = 1;
1604
        /* Disabling EMS is mutually exclusive with requiring it. */
1605
0
        ctx->requireEMS = 0;
1606
0
    }
1607
1608
0
    return ret;
1609
0
}
1610
1611
1612
/* Disable the Extended Master Secret extension on the object.
1613
 *
1614
 * For a client this stops the extension being advertised. For a server this
1615
 * causes the peer's Extended Master Secret request to be ignored so that a
1616
 * standard master secret is negotiated. Call before the handshake starts, or
1617
 * after wolfSSL_clear.
1618
 *
1619
 * @param [in, out] ssl  SSL/TLS object.
1620
 * @return  WOLFSSL_SUCCESS on success.
1621
 * @return  BAD_FUNC_ARG when ssl is NULL.
1622
 * @return  BAD_STATE_E when the handshake has started.
1623
 */
1624
int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
1625
0
{
1626
0
    int ret = WOLFSSL_SUCCESS;
1627
1628
0
    if (ssl == NULL) {
1629
0
        ret = BAD_FUNC_ARG;
1630
0
    }
1631
0
    else if (ssl->options.connectState != CONNECT_BEGIN ||
1632
0
             ssl->options.acceptState != ACCEPT_BEGIN) {
1633
        /* haveEMS records the negotiated result once the handshake starts. */
1634
0
        ret = BAD_STATE_E;
1635
0
    }
1636
0
    else {
1637
0
        ssl->options.haveEMS = 0;
1638
0
        ssl->options.disableEMS = 1;
1639
        /* Disabling EMS is mutually exclusive with requiring it. */
1640
0
        ssl->options.requireEMS = 0;
1641
0
    }
1642
1643
0
    return ret;
1644
0
}
1645
1646
1647
/* Re-enable the Extended Master Secret extension on the context (default).
1648
 *
1649
 * Undoes a previous disable or require: EMS is used when the peer supports it
1650
 * but is not mandatory.
1651
 *
1652
 * @param [in] ctx  SSL/TLS context object.
1653
 * @return  WOLFSSL_SUCCESS on success.
1654
 * @return  BAD_FUNC_ARG when ctx is NULL.
1655
 */
1656
int wolfSSL_CTX_EnableExtendedMasterSecret(WOLFSSL_CTX* ctx)
1657
0
{
1658
0
    int ret = WOLFSSL_SUCCESS;
1659
1660
0
    if (ctx == NULL) {
1661
0
        ret = BAD_FUNC_ARG;
1662
0
    }
1663
0
    else {
1664
0
        ctx->disableEMS = 0;
1665
0
        ctx->requireEMS = 0;
1666
        /* Re-arm client advertising. A side-less (wolfSSLv23) object is
1667
         * armed by InitSSL_Side instead; arming it here would make a server
1668
         * echo an unsolicited extension. */
1669
0
        if (ctx->method != NULL && ctx->method->side == WOLFSSL_CLIENT_END &&
1670
0
                EmsAllowedForVersion(ctx->method->version))
1671
0
            ctx->haveEMS = 1;
1672
0
    }
1673
1674
0
    return ret;
1675
0
}
1676
1677
1678
/* Re-enable the Extended Master Secret extension on the object (default).
1679
 *
1680
 * Undoes a previous disable or require: EMS is used when the peer supports it
1681
 * but is not mandatory. Call before the handshake starts, or after
1682
 * wolfSSL_clear.
1683
 *
1684
 * @param [in] ssl  SSL/TLS object.
1685
 * @return  WOLFSSL_SUCCESS on success.
1686
 * @return  BAD_FUNC_ARG when ssl is NULL.
1687
 * @return  BAD_STATE_E when the handshake has started.
1688
 */
1689
int wolfSSL_EnableExtendedMasterSecret(WOLFSSL* ssl)
1690
0
{
1691
0
    int ret = WOLFSSL_SUCCESS;
1692
1693
0
    if (ssl == NULL) {
1694
0
        ret = BAD_FUNC_ARG;
1695
0
    }
1696
0
    else if (ssl->options.connectState != CONNECT_BEGIN ||
1697
0
             ssl->options.acceptState != ACCEPT_BEGIN) {
1698
        /* haveEMS records the negotiated result once the handshake starts. */
1699
0
        ret = BAD_STATE_E;
1700
0
    }
1701
0
    else {
1702
0
        ssl->options.disableEMS = 0;
1703
0
        ssl->options.requireEMS = 0;
1704
        /* Re-arm client advertising. A side-less (wolfSSLv23) object is
1705
         * armed by InitSSL_Side instead; arming it here would make a server
1706
         * echo an unsolicited extension. */
1707
0
        if (ssl->options.side == WOLFSSL_CLIENT_END &&
1708
0
                EmsAllowedForVersion(ssl->ctx->method->version))
1709
0
            ssl->options.haveEMS = 1;
1710
0
    }
1711
1712
0
    return ret;
1713
0
}
1714
1715
1716
#ifndef WOLFSSL_NO_TLS12
1717
1718
/* Require the Extended Master Secret extension on the context.
1719
 *
1720
 * If EMS (RFC 7627) is not negotiated the connection is aborted with
1721
 * EXT_MASTER_SECRET_NEEDED_E instead of deriving a standard master secret.
1722
 * TLS 1.3 has its own key schedule and is unaffected.
1723
 *
1724
 * @param [in] ctx  SSL/TLS context object.
1725
 * @return  WOLFSSL_SUCCESS on success.
1726
 * @return  BAD_FUNC_ARG when ctx is NULL.
1727
 */
1728
int wolfSSL_CTX_RequireExtendedMasterSecret(WOLFSSL_CTX* ctx)
1729
0
{
1730
0
    int ret = WOLFSSL_SUCCESS;
1731
1732
0
    if (ctx == NULL) {
1733
0
        ret = BAD_FUNC_ARG;
1734
0
    }
1735
0
    else {
1736
0
        ctx->requireEMS = 1;
1737
        /* Mutually exclusive with disabling EMS. */
1738
0
        ctx->disableEMS = 0;
1739
        /* Re-arm client advertising. A side-less (wolfSSLv23) object is
1740
         * armed by InitSSL_Side instead; arming it here would make a server
1741
         * echo an unsolicited extension. */
1742
0
        if (ctx->method != NULL && ctx->method->side == WOLFSSL_CLIENT_END &&
1743
0
                EmsAllowedForVersion(ctx->method->version))
1744
0
            ctx->haveEMS = 1;
1745
0
    }
1746
1747
0
    return ret;
1748
0
}
1749
1750
1751
/* Require the Extended Master Secret extension on the object.
1752
 *
1753
 * If EMS (RFC 7627) is not negotiated the connection is aborted with
1754
 * EXT_MASTER_SECRET_NEEDED_E instead of deriving a standard master secret.
1755
 * TLS 1.3 has its own key schedule and is unaffected. Call before the
1756
 * handshake starts, or after wolfSSL_clear.
1757
 *
1758
 * @param [in] ssl  SSL/TLS object.
1759
 * @return  WOLFSSL_SUCCESS on success.
1760
 * @return  BAD_FUNC_ARG when ssl is NULL.
1761
 * @return  BAD_STATE_E when the handshake has started.
1762
 */
1763
int wolfSSL_RequireExtendedMasterSecret(WOLFSSL* ssl)
1764
0
{
1765
0
    int ret = WOLFSSL_SUCCESS;
1766
1767
0
    if (ssl == NULL) {
1768
0
        ret = BAD_FUNC_ARG;
1769
0
    }
1770
0
    else if (ssl->options.connectState != CONNECT_BEGIN ||
1771
0
             ssl->options.acceptState != ACCEPT_BEGIN) {
1772
        /* haveEMS records the negotiated result once the handshake starts. */
1773
0
        ret = BAD_STATE_E;
1774
0
    }
1775
0
    else {
1776
0
        ssl->options.requireEMS = 1;
1777
        /* Mutually exclusive with disabling EMS. */
1778
0
        ssl->options.disableEMS = 0;
1779
        /* Re-arm client advertising. A side-less (wolfSSLv23) object is
1780
         * armed by InitSSL_Side instead; arming it here would make a server
1781
         * echo an unsolicited extension. */
1782
0
        if (ssl->options.side == WOLFSSL_CLIENT_END &&
1783
0
                EmsAllowedForVersion(ssl->ctx->method->version))
1784
0
            ssl->options.haveEMS = 1;
1785
0
    }
1786
1787
0
    return ret;
1788
0
}
1789
1790
#endif /* !WOLFSSL_NO_TLS12 */
1791
1792
#endif /* HAVE_EXTENDED_MASTER */
1793
1794
#endif /* !NO_TLS */
1795
/* ---- OpenSSL-compatibility TLS extension APIs (moved from ssl.c) ---- */
1796
1797
#ifdef OPENSSL_EXTRA
1798
1799
/* Set the argument passed to the TLS extension debug callback.
1800
 *
1801
 * @param [in, out] ssl  SSL/TLS object.
1802
 * @param [in]      arg  Debug argument.
1803
 * @return  WOLFSSL_SUCCESS on success.
1804
 * @return  WOLFSSL_FAILURE when ssl is NULL.
1805
 */
1806
long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
1807
{
1808
    long ret = WOLFSSL_SUCCESS;
1809
1810
    if (ssl == NULL) {
1811
        ret = WOLFSSL_FAILURE;
1812
    }
1813
    else {
1814
        ssl->tlsextDebugArg = arg;
1815
    }
1816
1817
    return ret;
1818
}
1819
1820
/* Set the callback invoked for each TLS extension received during the
1821
 * handshake.
1822
 *
1823
 * @param [in, out] ssl  SSL/TLS object.
1824
 * @param [in]      cb   Debug callback, or NULL to disable.
1825
 * @return  WOLFSSL_SUCCESS on success.
1826
 * @return  WOLFSSL_FAILURE when ssl is NULL.
1827
 */
1828
long wolfSSL_set_tlsext_debug_callback(WOLFSSL* ssl,
1829
        WOLFSSL_TLSEXT_DEBUG_CB cb)
1830
{
1831
    long ret = WOLFSSL_SUCCESS;
1832
1833
    if (ssl == NULL) {
1834
        ret = WOLFSSL_FAILURE;
1835
    }
1836
    else {
1837
        ssl->tlsextDebugCb = cb;
1838
    }
1839
1840
    return ret;
1841
}
1842
1843
#ifndef NO_WOLFSSL_STUB
1844
/* Get the certificate status request extensions on the object.
1845
 *
1846
 * Not implemented - stub for OpenSSL compatibility.
1847
 *
1848
 * @param [in] s    SSL/TLS object.
1849
 * @param [in] arg  Ignored.
1850
 * @return  WOLFSSL_FAILURE always.
1851
 */
1852
long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg)
1853
{
1854
    (void)s;
1855
    (void)arg;
1856
    WOLFSSL_STUB("wolfSSL_get_tlsext_status_exts");
1857
    return WOLFSSL_FAILURE;
1858
}
1859
#endif
1860
1861
/* Set the certificate status request extensions on the object.
1862
 *
1863
 * Not implemented - stub for OpenSSL compatibility.
1864
 *
1865
 * @param [in] s    SSL/TLS object.
1866
 * @param [in] arg  Ignored.
1867
 * @return  WOLFSSL_FAILURE always.
1868
 */
1869
#ifndef NO_WOLFSSL_STUB
1870
long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg)
1871
{
1872
    (void)s;
1873
    (void)arg;
1874
    WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts");
1875
    return WOLFSSL_FAILURE;
1876
}
1877
#endif
1878
1879
/* Get the certificate status request responder ids on the object.
1880
 *
1881
 * Not implemented - stub for OpenSSL compatibility.
1882
 *
1883
 * @param [in] s    SSL/TLS object.
1884
 * @param [in] arg  Ignored.
1885
 * @return  WOLFSSL_FAILURE always.
1886
 */
1887
#ifndef NO_WOLFSSL_STUB
1888
long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg)
1889
{
1890
    (void)s;
1891
    (void)arg;
1892
    WOLFSSL_STUB("wolfSSL_get_tlsext_status_ids");
1893
    return WOLFSSL_FAILURE;
1894
}
1895
#endif
1896
1897
/* Set the certificate status request responder ids on the object.
1898
 *
1899
 * Not implemented - stub for OpenSSL compatibility.
1900
 *
1901
 * @param [in] s    SSL/TLS object.
1902
 * @param [in] arg  Ignored.
1903
 * @return  WOLFSSL_FAILURE always.
1904
 */
1905
#ifndef NO_WOLFSSL_STUB
1906
long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg)
1907
{
1908
    (void)s;
1909
    (void)arg;
1910
    WOLFSSL_STUB("wolfSSL_set_tlsext_status_ids");
1911
    return WOLFSSL_FAILURE;
1912
}
1913
#endif
1914
1915
#ifdef HAVE_MAX_FRAGMENT
1916
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
1917
/* Set the Maximum Fragment Length extension on the context.
1918
 *
1919
 * @param [in] c     SSL/TLS context object.
1920
 * @param [in] mode  Maximum fragment length mode, e.g. WOLFSSL_MFL_2_9.
1921
 * @return  WOLFSSL_SUCCESS on success.
1922
 * @return  BAD_FUNC_ARG when c is NULL or mode is out of range.
1923
 */
1924
int wolfSSL_CTX_set_tlsext_max_fragment_length(WOLFSSL_CTX *c,
1925
                                               unsigned char mode)
1926
{
1927
    int ret;
1928
1929
    if ((c == NULL) || (mode < WOLFSSL_MFL_2_9) || (mode > WOLFSSL_MFL_2_12)) {
1930
        ret = BAD_FUNC_ARG;
1931
    }
1932
    else {
1933
        ret = wolfSSL_CTX_UseMaxFragment(c, mode);
1934
    }
1935
1936
    return ret;
1937
}
1938
/* Set the Maximum Fragment Length extension on the object.
1939
 *
1940
 * @param [in] s     SSL/TLS object.
1941
 * @param [in] mode  Maximum fragment length mode, e.g. WOLFSSL_MFL_2_9.
1942
 * @return  WOLFSSL_SUCCESS on success.
1943
 * @return  BAD_FUNC_ARG when s is NULL or mode is out of range.
1944
 */
1945
int wolfSSL_set_tlsext_max_fragment_length(WOLFSSL *s, unsigned char mode)
1946
{
1947
    int ret;
1948
1949
    if ((s == NULL) || (mode < WOLFSSL_MFL_2_9) || (mode > WOLFSSL_MFL_2_12)) {
1950
        ret = BAD_FUNC_ARG;
1951
    }
1952
    else {
1953
        ret = wolfSSL_UseMaxFragment(s, mode);
1954
    }
1955
1956
    return ret;
1957
}
1958
#endif /* !NO_WOLFSSL_CLIENT && !NO_TLS */
1959
#endif /* HAVE_MAX_FRAGMENT */
1960
1961
/* Set the signature algorithms list on the context.
1962
 *
1963
 * @param [in] ctx   SSL/TLS context object.
1964
 * @param [in] list  Colon-separated list of <public key>+<digest> algorithms.
1965
 * @return  WOLFSSL_SUCCESS on success.
1966
 * @return  WOLFSSL_FAILURE when ctx or list is NULL or on error.
1967
 */
1968
int wolfSSL_CTX_set1_sigalgs_list(WOLFSSL_CTX* ctx, const char* list)
1969
{
1970
    int ret = WOLFSSL_SUCCESS;
1971
1972
    WOLFSSL_MSG("wolfSSL_CTX_set1_sigalg_list");
1973
1974
    if ((ctx == NULL) || (list == NULL)) {
1975
        WOLFSSL_MSG("Bad function arguments");
1976
        ret = WOLFSSL_FAILURE;
1977
    }
1978
    else if (AllocateCtxSuites(ctx) != 0) {
1979
        ret = WOLFSSL_FAILURE;
1980
    }
1981
    else {
1982
        ret = SetSuitesHashSigAlgo(ctx->suites, list);
1983
    }
1984
1985
    return ret;
1986
}
1987
1988
/* Set the signature algorithms list on the object.
1989
 *
1990
 * @param [in] ssl   SSL/TLS object.
1991
 * @param [in] list  Colon-separated list of <public key>+<digest> algorithms.
1992
 * @return  WOLFSSL_SUCCESS on success.
1993
 * @return  WOLFSSL_FAILURE when ssl or list is NULL or on error.
1994
 */
1995
int wolfSSL_set1_sigalgs_list(WOLFSSL* ssl, const char* list)
1996
{
1997
    int ret = WOLFSSL_SUCCESS;
1998
1999
    WOLFSSL_MSG("wolfSSL_set1_sigalg_list");
2000
2001
    if ((ssl == NULL) || (list == NULL)) {
2002
        WOLFSSL_MSG("Bad function arguments");
2003
        ret = WOLFSSL_FAILURE;
2004
    }
2005
    else if (AllocateSuites(ssl) != 0) {
2006
        ret = WOLFSSL_FAILURE;
2007
    }
2008
    else {
2009
        ret = SetSuitesHashSigAlgo(ssl->suites, list);
2010
    }
2011
2012
    return ret;
2013
}
2014
2015
/* Group names include the FFDHE groups, so this is not EC-only. */
2016
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
2017
    !defined(NO_DH)
2018
2019
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
2020
/* Set the supported groups list, by name, on the context.
2021
 *
2022
 * @param [in] ctx   SSL/TLS context object.
2023
 * @param [in] list  Colon-separated list of group names.
2024
 * @return  WOLFSSL_SUCCESS on success.
2025
 * @return  WOLFSSL_FAILURE when ctx or list is NULL or on error.
2026
 */
2027
int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, const char *list)
2028
{
2029
    int ret;
2030
2031
    if ((ctx == NULL) || (list == NULL)) {
2032
        ret = WOLFSSL_FAILURE;
2033
    }
2034
    else {
2035
        ret = set_curves_list(NULL, ctx, list, 0);
2036
    }
2037
2038
    return ret;
2039
}
2040
2041
/* Set the supported groups list, by name, on the object.
2042
 *
2043
 * @param [in] ssl   SSL/TLS object.
2044
 * @param [in] list  Colon-separated list of group names.
2045
 * @return  WOLFSSL_SUCCESS on success.
2046
 * @return  WOLFSSL_FAILURE when ssl or list is NULL or on error.
2047
 */
2048
int wolfSSL_set1_groups_list(WOLFSSL *ssl, const char *list)
2049
{
2050
    int ret;
2051
2052
    if ((ssl == NULL) || (list == NULL)) {
2053
        ret = WOLFSSL_FAILURE;
2054
    }
2055
    else {
2056
        ret = set_curves_list(ssl, NULL, list, 0);
2057
    }
2058
2059
    return ret;
2060
}
2061
#endif /* WOLFSSL_TLS13 */
2062
2063
#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 || !NO_DH */
2064
2065
#endif /* OPENSSL_EXTRA */
2066
2067
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
2068
2069
#ifdef HAVE_SNI
2070
/* Set the SNI host name extension on the object.
2071
 *
2072
 * @param [in] ssl        SSL/TLS object.
2073
 * @param [in] host_name  Host name string.
2074
 * @return  WOLFSSL_SUCCESS on success.
2075
 * @return  BAD_FUNC_ARG when ssl is NULL.
2076
 * @return  Negative value on error.
2077
 */
2078
int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
2079
{
2080
    int ret;
2081
    WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
2082
    ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, host_name,
2083
        (word16)XSTRLEN(host_name));
2084
    WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
2085
    return ret;
2086
}
2087
2088
#ifndef NO_WOLFSSL_SERVER
2089
/* Get the SNI host name requested for the object.
2090
 *
2091
 * May be called by a server to get the accepted name or by a client to get
2092
 * the requested name.
2093
 *
2094
 * @param [in] ssl   SSL/TLS object.
2095
 * @param [in] type  SNI type.
2096
 * @return  Requested server name on success.
2097
 * @return  NULL when ssl is NULL or no name is set.
2098
 */
2099
const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
2100
{
2101
    void * serverName = NULL;
2102
2103
    if (ssl != NULL) {
2104
        TLSX_SNI_GetRequest(ssl->extensions, type, &serverName,
2105
                !wolfSSL_is_server(ssl));
2106
    }
2107
2108
    return (const char *)serverName;
2109
}
2110
#endif
2111
2112
#endif /* HAVE_SNI */
2113
2114
#ifdef HAVE_SNI
2115
/* Set the SNI receive callback on the context.
2116
 *
2117
 * Compatibility function; consider using wolfSSL_CTX_set_servername_callback().
2118
 *
2119
 * @param [in] ctx  SSL/TLS context object.
2120
 * @param [in] cb   SNI receive callback.
2121
 * @return  WOLFSSL_SUCCESS on success.
2122
 * @return  WOLFSSL_FAILURE when ctx is NULL.
2123
 */
2124
int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
2125
                                               CallbackSniRecv cb)
2126
{
2127
    int ret;
2128
2129
    WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
2130
2131
    if (ctx != NULL) {
2132
        ctx->sniRecvCb = cb;
2133
        ret = WOLFSSL_SUCCESS;
2134
    }
2135
    else {
2136
        ret = WOLFSSL_FAILURE;
2137
    }
2138
2139
    return ret;
2140
}
2141
2142
#endif /* HAVE_SNI */
2143
2144
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
2145
2146
#ifdef HAVE_SNI
2147
2148
/* Set the SNI receive callback on the context.
2149
 *
2150
 * @param [in] ctx  SSL/TLS context object.
2151
 * @param [in] cb   SNI receive callback.
2152
 */
2153
void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
2154
0
{
2155
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
2156
2157
0
    if (ctx != NULL) {
2158
0
        ctx->sniRecvCb = cb;
2159
0
    }
2160
0
}
2161
2162
2163
/* Set the user argument passed to the SNI receive callback on the context.
2164
 *
2165
 * @param [in] ctx  SSL/TLS context object.
2166
 * @param [in] arg  User argument for the SNI receive callback.
2167
 * @return  WOLFSSL_SUCCESS on success.
2168
 * @return  WOLFSSL_FAILURE when ctx is NULL.
2169
 */
2170
int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
2171
0
{
2172
0
    int ret;
2173
2174
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
2175
2176
0
    if (ctx != NULL) {
2177
0
        ctx->sniRecvCbArg = arg;
2178
0
        ret = WOLFSSL_SUCCESS;
2179
0
    }
2180
0
    else {
2181
0
        ret = WOLFSSL_FAILURE;
2182
0
    }
2183
2184
0
    return ret;
2185
0
}
2186
2187
#endif /* HAVE_SNI */
2188
2189
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
2190
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
2191
2192
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
2193
/* Expected return values from implementations of OpenSSL ticket key callback.
2194
 */
2195
#define TICKET_KEY_CB_RET_FAILURE    (-1)
2196
#define TICKET_KEY_CB_RET_NOT_FOUND   0
2197
#define TICKET_KEY_CB_RET_OK          1
2198
#define TICKET_KEY_CB_RET_RENEW       2
2199
2200
/* Encrypt the ticket data in place and compute the HMAC over it.
2201
 *
2202
 * @param [in]      evpCtx        Cipher context initialized by the callback.
2203
 * @param [in]      hmacCtx       HMAC context initialized by the callback.
2204
 * @param [in, out] encTicket     Ticket data, encrypted in place.
2205
 * @param [in]      encTicketLen  Length of the plaintext ticket data in bytes.
2206
 * @param [in]      encSz         Capacity of the ticket buffer in bytes.
2207
 * @param [out]     mac           HMAC of the encrypted data.
2208
 * @param [out]     outSz         Length of the encrypted data in bytes.
2209
 * @return  1 on success.
2210
 * @return  0 on error.
2211
 */
2212
static int wolfssl_ticket_key_enc(WOLFSSL_EVP_CIPHER_CTX* evpCtx,
2213
        WOLFSSL_HMAC_CTX* hmacCtx, unsigned char* encTicket, int encTicketLen,
2214
        int encSz, unsigned char* mac, int* outSz)
2215
{
2216
    int ret = 1;
2217
    int len = 0;
2218
    int totalSz = 0;
2219
    unsigned int mdSz = 0;
2220
2221
    /* Encrypt in place. */
2222
    if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len, encTicket,
2223
            encTicketLen)) {
2224
        ret = 0;
2225
    }
2226
    if (ret == 1) {
2227
        totalSz = len;
2228
        /* Encrypted data must fit in the output buffer. */
2229
        if (totalSz > encSz) {
2230
            ret = 0;
2231
        }
2232
    }
2233
    if ((ret == 1) &&
2234
            (!wolfSSL_EVP_EncryptFinal(evpCtx, &encTicket[len], &len))) {
2235
        ret = 0;
2236
    }
2237
    if (ret == 1) {
2238
        /* Total length of encrypted data. */
2239
        totalSz += len;
2240
        if (totalSz > encSz) {
2241
            ret = 0;
2242
        }
2243
    }
2244
    /* HMAC the encrypted data into the parameter 'mac'. */
2245
    if ((ret == 1) && (!wolfSSL_HMAC_Update(hmacCtx, encTicket, totalSz))) {
2246
        ret = 0;
2247
    }
2248
    if ((ret == 1) && (!wolfSSL_HMAC_Final(hmacCtx, mac, &mdSz))) {
2249
        ret = 0;
2250
    }
2251
    if (ret == 1) {
2252
        *outSz = totalSz;
2253
    }
2254
2255
    return ret;
2256
}
2257
2258
/* Verify the ticket HMAC then decrypt the ticket data in place.
2259
 *
2260
 * @param [in]      evpCtx        Cipher context initialized by the callback.
2261
 * @param [in]      hmacCtx       HMAC context initialized by the callback.
2262
 * @param [in, out] encTicket     Ticket data, decrypted in place.
2263
 * @param [in]      encTicketLen  Length of the encrypted ticket data in bytes.
2264
 * @param [in]      mac           Expected HMAC of the encrypted data.
2265
 * @param [out]     outSz         Length of the decrypted data in bytes.
2266
 * @return  1 on success.
2267
 * @return  0 on error or when the HMAC does not match.
2268
 */
2269
static int wolfssl_ticket_key_dec(WOLFSSL_EVP_CIPHER_CTX* evpCtx,
2270
        WOLFSSL_HMAC_CTX* hmacCtx, unsigned char* encTicket, int encTicketLen,
2271
        const unsigned char* mac, int* outSz)
2272
{
2273
    int ret = 1;
2274
    int len = 0;
2275
    int totalSz = 0;
2276
    unsigned int mdSz = 0;
2277
    byte digest[WC_MAX_DIGEST_SIZE];
2278
2279
    /* HMAC the encrypted data and compare it to the passed in data. */
2280
    if (!wolfSSL_HMAC_Update(hmacCtx, encTicket, encTicketLen)) {
2281
        ret = 0;
2282
    }
2283
    if ((ret == 1) && (!wolfSSL_HMAC_Final(hmacCtx, digest, &mdSz))) {
2284
        ret = 0;
2285
    }
2286
    if ((ret == 1) && (ConstantCompare(mac, digest, (int)mdSz) != 0)) {
2287
        ret = 0;
2288
    }
2289
    /* Decrypt the ticket data in place. */
2290
    if ((ret == 1) &&
2291
            (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len, encTicket,
2292
                encTicketLen))) {
2293
        ret = 0;
2294
    }
2295
    if (ret == 1) {
2296
        totalSz = len;
2297
        /* Decrypted data must fit in the buffer. */
2298
        if (totalSz > encTicketLen) {
2299
            ret = 0;
2300
        }
2301
    }
2302
    if ((ret == 1) &&
2303
            (!wolfSSL_EVP_DecryptFinal(evpCtx, &encTicket[len], &len))) {
2304
        ret = 0;
2305
    }
2306
    if (ret == 1) {
2307
        /* Total length of decrypted data. */
2308
        totalSz += len;
2309
        if (totalSz > encTicketLen) {
2310
            ret = 0;
2311
        }
2312
    }
2313
    if (ret == 1) {
2314
        *outSz = totalSz;
2315
    }
2316
2317
    return ret;
2318
}
2319
2320
/* Run the application's ticket key callback and process the ticket.
2321
 *
2322
 * The cipher and HMAC contexts are initialized by the caller. The HMAC context
2323
 * is released here, once the ticket has been encrypted or decrypted.
2324
 *
2325
 * @param [in]      ssl           SSL/TLS object.
2326
 * @param [in]      keyName       Key name identifying the key to use.
2327
 * @param [in]      iv            IV to use.
2328
 * @param [in, out] mac           MAC of the encrypted data.
2329
 * @param [in]      enc           1 to encrypt the ticket, 0 to decrypt.
2330
 * @param [in, out] encTicket     Ticket data, encrypted/decrypted in place.
2331
 * @param [in]      encTicketLen  Length of the ticket data in bytes.
2332
 * @param [in, out] encLen        In: space available. Out: length of ticket.
2333
 * @param [in, out] evpCtx        Initialized cipher context. The callback
2334
 *                                sets the cipher, key and IV on it, and it
2335
 *                                is then run over the ticket data.
2336
 * @param [in, out] hmacCtx       Initialized HMAC context. Released on return.
2337
 * @return  WOLFSSL_TICKET_RET_OK on success.
2338
 * @return  WOLFSSL_TICKET_RET_CREATE when a new ticket is required.
2339
 * @return  WOLFSSL_TICKET_RET_FATAL on error.
2340
 */
2341
static int wolfssl_ticket_key_cb_process(WOLFSSL* ssl,
2342
        unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
2343
        unsigned char iv[WOLFSSL_TICKET_IV_SZ],
2344
        unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
2345
        int enc, unsigned char* encTicket, int encTicketLen, int* encLen,
2346
        WOLFSSL_EVP_CIPHER_CTX* evpCtx, WOLFSSL_HMAC_CTX* hmacCtx)
2347
{
2348
    int ret = WOLFSSL_TICKET_RET_OK;
2349
    int res;
2350
    int totalSz = 0;
2351
2352
    res = ssl->ctx->ticketEncWrapCb(ssl, keyName, iv, evpCtx, hmacCtx, enc);
2353
    if ((res != TICKET_KEY_CB_RET_OK) && (res != TICKET_KEY_CB_RET_RENEW)) {
2354
        WOLFSSL_MSG("Ticket callback error");
2355
        ret = WOLFSSL_TICKET_RET_FATAL;
2356
    }
2357
2358
    if (ret == WOLFSSL_TICKET_RET_OK) {
2359
        if (wolfSSL_HMAC_size(hmacCtx) > WOLFSSL_TICKET_MAC_SZ) {
2360
            WOLFSSL_MSG("Ticket cipher MAC size error");
2361
            ret = WOLFSSL_TICKET_RET_FATAL;
2362
        }
2363
    }
2364
2365
    if (ret == WOLFSSL_TICKET_RET_OK) {
2366
        if (enc) {
2367
            if (!wolfssl_ticket_key_enc(evpCtx, hmacCtx, encTicket,
2368
                    encTicketLen, *encLen, mac, &totalSz)) {
2369
                ret = WOLFSSL_TICKET_RET_FATAL;
2370
            }
2371
        }
2372
        else {
2373
            if (!wolfssl_ticket_key_dec(evpCtx, hmacCtx, encTicket,
2374
                    encTicketLen, mac, &totalSz)) {
2375
                ret = WOLFSSL_TICKET_RET_FATAL;
2376
            }
2377
        }
2378
    }
2379
2380
    if (ret == WOLFSSL_TICKET_RET_OK) {
2381
        *encLen = totalSz;
2382
2383
        /* Below TLS 1.3 a renewed key means the peer needs a new ticket.
2384
         * TLS 1.3 issues tickets separately. */
2385
        if ((res == TICKET_KEY_CB_RET_RENEW) &&
2386
                (!IsAtLeastTLSv1_3(ssl->version)) && (!enc)) {
2387
            ret = WOLFSSL_TICKET_RET_CREATE;
2388
        }
2389
        else {
2390
            ret = WOLFSSL_TICKET_RET_OK;
2391
        }
2392
    }
2393
2394
    wolfSSL_HMAC_CTX_cleanup(hmacCtx);
2395
2396
    return ret;
2397
}
2398
2399
/* Encrypt or decrypt a session ticket using the OpenSSL ticket key callback.
2400
 *
2401
 * Wraps the application's OpenSSL-style callback that initializes the cipher
2402
 * and HMAC.
2403
 *
2404
 * @param [in]      ssl           SSL/TLS object.
2405
 * @param [in]      keyName       Key name identifying the key to use.
2406
 * @param [in]      iv            IV to use.
2407
 * @param [in, out] mac           MAC of the encrypted data.
2408
 * @param [in]      enc           1 to encrypt the ticket, 0 to decrypt.
2409
 * @param [in, out] encTicket     Ticket data, encrypted/decrypted in place.
2410
 * @param [in]      encTicketLen  Length of the ticket data in bytes.
2411
 * @param [out]     encLen        Output length of the ticket data.
2412
 * @param [in]      ctx           Ignored. Application specific data.
2413
 * @return  WOLFSSL_TICKET_RET_OK on success.
2414
 * @return  WOLFSSL_TICKET_RET_CREATE when a new ticket is required.
2415
 * @return  WOLFSSL_TICKET_RET_FATAL on error.
2416
 */
2417
static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
2418
        unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
2419
        unsigned char iv[WOLFSSL_TICKET_IV_SZ],
2420
        unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
2421
        int enc, unsigned char* encTicket,
2422
        int encTicketLen, int* encLen, void* ctx)
2423
{
2424
    WC_DECLARE_VAR(evpCtx, WOLFSSL_EVP_CIPHER_CTX, 1, 0);
2425
    int ret = WOLFSSL_TICKET_RET_OK;
2426
2427
    (void)ctx;
2428
2429
    WOLFSSL_ENTER("wolfSSL_TicketKeyCb");
2430
2431
    if ((ssl == NULL) || (ssl->ctx == NULL) ||
2432
            (ssl->ctx->ticketEncWrapCb == NULL)) {
2433
        WOLFSSL_MSG("Bad parameter");
2434
        ret = WOLFSSL_TICKET_RET_FATAL;
2435
    }
2436
2437
    #ifdef WOLFSSL_SMALL_STACK
2438
    if (ret == WOLFSSL_TICKET_RET_OK) {
2439
        evpCtx = (WOLFSSL_EVP_CIPHER_CTX *)XMALLOC(sizeof(*evpCtx), ssl->heap,
2440
            DYNAMIC_TYPE_TMP_BUFFER);
2441
        if (evpCtx == NULL) {
2442
            WOLFSSL_MSG("out of memory");
2443
            ret = WOLFSSL_TICKET_RET_FATAL;
2444
        }
2445
    }
2446
    #endif
2447
2448
    if (ret == WOLFSSL_TICKET_RET_OK) {
2449
        WOLFSSL_HMAC_CTX hmacCtx;
2450
2451
        /* Initialize the cipher and HMAC. */
2452
        wolfSSL_EVP_CIPHER_CTX_init(evpCtx);
2453
2454
        if (wolfSSL_HMAC_CTX_Init(&hmacCtx) != WOLFSSL_SUCCESS) {
2455
            WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init error");
2456
            ret = WOLFSSL_TICKET_RET_FATAL;
2457
        }
2458
2459
        if (ret == WOLFSSL_TICKET_RET_OK) {
2460
            ret = wolfssl_ticket_key_cb_process(ssl, keyName, iv, mac, enc,
2461
                encTicket, encTicketLen, encLen, evpCtx, &hmacCtx);
2462
        }
2463
        (void)wolfSSL_EVP_CIPHER_CTX_cleanup(evpCtx);
2464
        WC_FREE_VAR_EX(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
2465
    }
2466
2467
    return ret;
2468
}
2469
2470
/* Set the OpenSSL-style session ticket key callback on the context.
2471
 *
2472
 * Installs a wrapper as the ticket encryption callback.
2473
 *
2474
 * @param [in] ctx  SSL/TLS context object.
2475
 * @param [in] cb   OpenSSL session ticket key callback.
2476
 * @return  WOLFSSL_SUCCESS on success.
2477
 */
2478
int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, ticketCompatCb cb)
2479
{
2480
2481
    /* Set the ticket encryption callback to be a wrapper around OpenSSL
2482
     * callback.
2483
     */
2484
    ctx->ticketEncCb = wolfSSL_TicketKeyCb;
2485
    ctx->ticketEncWrapCb = cb;
2486
2487
    return WOLFSSL_SUCCESS;
2488
}
2489
2490
#endif /* HAVE_SESSION_TICKET */
2491
2492
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
2493
    OPENSSL_EXTRA || HAVE_LIGHTY */
2494
2495
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
2496
    !defined(NO_WOLFSSL_SERVER)
2497
/* Serialize the session ticket encryption keys.
2498
 *
2499
 * @param [in]  ctx     SSL/TLS context object.
2500
 * @param [out] keys    Buffer to hold session ticket keys.
2501
 * @param [in]  keylen  Length of buffer.
2502
 * @return  WOLFSSL_SUCCESS on success.
2503
 * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
2504
 *          correct length.
2505
 */
2506
long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
2507
     unsigned char *keys, int keylen)
2508
{
2509
    long ret = WOLFSSL_SUCCESS;
2510
2511
    if ((ctx == NULL) || (keys == NULL) ||
2512
            (keylen != WOLFSSL_TICKET_KEYS_SZ)) {
2513
        ret = WOLFSSL_FAILURE;
2514
    }
2515
    else {
2516
        XMEMCPY(keys, ctx->ticketKeyCtx.name, WOLFSSL_TICKET_NAME_SZ);
2517
        keys += WOLFSSL_TICKET_NAME_SZ;
2518
        XMEMCPY(keys, ctx->ticketKeyCtx.key[0], WOLFSSL_TICKET_KEY_SZ);
2519
        keys += WOLFSSL_TICKET_KEY_SZ;
2520
        XMEMCPY(keys, ctx->ticketKeyCtx.key[1], WOLFSSL_TICKET_KEY_SZ);
2521
        keys += WOLFSSL_TICKET_KEY_SZ;
2522
        c32toa(ctx->ticketKeyCtx.expirary[0], keys);
2523
        keys += OPAQUE32_LEN;
2524
        c32toa(ctx->ticketKeyCtx.expirary[1], keys);
2525
    }
2526
2527
    return ret;
2528
}
2529
2530
/* Deserialize the session ticket encryption keys.
2531
 *
2532
 * @param [in, out] ctx      SSL/TLS context object.
2533
 * @param [in]      keys_vp  Session ticket keys.
2534
 * @param [in]      keylen   Length of data.
2535
 * @return  WOLFSSL_SUCCESS on success.
2536
 * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
2537
 *          correct length.
2538
 */
2539
long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
2540
     const void *keys_vp, int keylen)
2541
{
2542
    const byte* keys = (const byte*)keys_vp;
2543
    long ret = WOLFSSL_SUCCESS;
2544
2545
    if ((ctx == NULL) || (keys == NULL) ||
2546
            (keylen != WOLFSSL_TICKET_KEYS_SZ)) {
2547
        ret = WOLFSSL_FAILURE;
2548
    }
2549
    else {
2550
        XMEMCPY(ctx->ticketKeyCtx.name, keys, WOLFSSL_TICKET_NAME_SZ);
2551
        keys += WOLFSSL_TICKET_NAME_SZ;
2552
        XMEMCPY(ctx->ticketKeyCtx.key[0], keys, WOLFSSL_TICKET_KEY_SZ);
2553
        keys += WOLFSSL_TICKET_KEY_SZ;
2554
        XMEMCPY(ctx->ticketKeyCtx.key[1], keys, WOLFSSL_TICKET_KEY_SZ);
2555
        keys += WOLFSSL_TICKET_KEY_SZ;
2556
        ato32(keys, &ctx->ticketKeyCtx.expirary[0]);
2557
        keys += OPAQUE32_LEN;
2558
        ato32(keys, &ctx->ticketKeyCtx.expirary[1]);
2559
    }
2560
2561
    return ret;
2562
}
2563
#endif
2564
2565
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
2566
    defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY) || \
2567
    defined(WOLFSSL_QUIC)
2568
#ifdef HAVE_ALPN
2569
/* Get the ALPN protocol selected for the object.
2570
 *
2571
 * @param [in]  ssl   SSL/TLS object.
2572
 * @param [out] data  Selected protocol data.
2573
 * @param [out] len   Length of the protocol data in bytes.
2574
 */
2575
void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
2576
                                unsigned int *len)
2577
{
2578
    word16 nameLen = 0;
2579
2580
    if ((ssl != NULL) && (data != NULL) && (len != NULL)) {
2581
        TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
2582
        *len = nameLen;
2583
    }
2584
}
2585
2586
/* Determine whether a protocol appears in the client's protocol list.
2587
 *
2588
 * The client's list is in wire format: each entry is a length byte followed
2589
 * by that many protocol-name bytes.
2590
 *
2591
 * @param [in] proto        Protocol name to look for.
2592
 * @param [in] protoLen     Length of the protocol name in bytes.
2593
 * @param [in] clientNames  Client's protocol list.
2594
 * @param [in] clientLen    Length of the client's list in bytes.
2595
 * @return  1 when the protocol is in the list.
2596
 * @return  0 when the protocol is not in the list.
2597
 */
2598
static int wolfssl_protocol_in_list(const unsigned char* proto, byte protoLen,
2599
    const unsigned char* clientNames, unsigned int clientLen)
2600
{
2601
    unsigned int j;
2602
    byte lenClient;
2603
    int found = 0;
2604
2605
    /* Compare against each of the client's length-prefixed names. */
2606
    for (j = 0; j < clientLen; j += lenClient) {
2607
        lenClient = clientNames[j++];
2608
        if ((lenClient == 0) || (j + lenClient > clientLen)) {
2609
            break;
2610
        }
2611
2612
        if ((protoLen == lenClient) &&
2613
                (XMEMCMP(proto, clientNames + j, protoLen) == 0)) {
2614
            found = 1;
2615
            break;
2616
        }
2617
    }
2618
2619
    return found;
2620
}
2621
2622
/* Select the next protocol from the peer's list that matches the client's.
2623
 *
2624
 * On no overlap, the first client protocol is selected.
2625
 *
2626
 * @param [out] out          Selected protocol data.
2627
 * @param [out] outLen       Length of the selected protocol in bytes.
2628
 * @param [in]  in           Peer's protocol list.
2629
 * @param [in]  inLen        Length of the peer's list in bytes.
2630
 * @param [in]  clientNames  Client's protocol list.
2631
 * @param [in]  clientLen    Length of the client's list in bytes.
2632
 * @return  WOLFSSL_NPN_NEGOTIATED when a match was found.
2633
 * @return  WOLFSSL_NPN_NO_OVERLAP when no match was found.
2634
 * @return  WOLFSSL_NPN_UNSUPPORTED when an argument is NULL.
2635
 */
2636
int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
2637
    const unsigned char *in, unsigned int inLen,
2638
    const unsigned char *clientNames, unsigned int clientLen)
2639
{
2640
    unsigned int i;
2641
    byte lenIn;
2642
    int ret = WOLFSSL_NPN_NO_OVERLAP;
2643
2644
    if ((out == NULL) || (outLen == NULL) || (in == NULL) ||
2645
            (clientNames == NULL)) {
2646
        ret = WOLFSSL_NPN_UNSUPPORTED;
2647
    }
2648
    else {
2649
        /* Walk the peer's list; each entry is a length byte then that many
2650
         * protocol-name bytes. */
2651
        for (i = 0; i < inLen; i += lenIn) {
2652
            lenIn = in[i++];
2653
            /* Stop on an empty entry or one that runs past the buffer. */
2654
            if ((lenIn == 0) || (i + lenIn > inLen)) {
2655
                break;
2656
            }
2657
            /* Select this peer protocol if the client also offered it. */
2658
            if (wolfssl_protocol_in_list(in + i, lenIn, clientNames,
2659
                    clientLen)) {
2660
                *out = (unsigned char *)(in + i);
2661
                *outLen = lenIn;
2662
                ret = WOLFSSL_NPN_NEGOTIATED;
2663
                break;
2664
            }
2665
        }
2666
2667
        if (ret != WOLFSSL_NPN_NEGOTIATED) {
2668
            /* No overlap: fall back to the client's first protocol. */
2669
            if ((clientLen > 0) &&
2670
                    ((unsigned int)clientNames[0] + 1 <= clientLen)) {
2671
                *out = (unsigned char *)clientNames + 1;
2672
                *outLen = clientNames[0];
2673
            }
2674
            else {
2675
                *out = (unsigned char *)clientNames;
2676
                *outLen = 0;
2677
            }
2678
            ret = WOLFSSL_NPN_NO_OVERLAP;
2679
        }
2680
    }
2681
2682
    return ret;
2683
}
2684
2685
/* Set the ALPN selection callback on the object.
2686
 *
2687
 * @param [in] ssl  SSL/TLS object.
2688
 * @param [in] cb   ALPN selection callback.
2689
 * @param [in] arg  User argument passed to the callback.
2690
 */
2691
void wolfSSL_set_alpn_select_cb(WOLFSSL *ssl,
2692
    int (*cb)(WOLFSSL *ssl, const unsigned char **out, unsigned char *outlen,
2693
              const unsigned char *in, unsigned int inlen, void *arg),
2694
    void *arg)
2695
{
2696
    if (ssl != NULL) {
2697
        ssl->alpnSelect = cb;
2698
        ssl->alpnSelectArg = arg;
2699
    }
2700
}
2701
2702
/* Set the ALPN selection callback on the context.
2703
 *
2704
 * @param [in] ctx  SSL/TLS context object.
2705
 * @param [in] cb   ALPN selection callback.
2706
 * @param [in] arg  User argument passed to the callback.
2707
 */
2708
void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
2709
    int (*cb)(WOLFSSL *ssl, const unsigned char **out, unsigned char *outlen,
2710
              const unsigned char *in, unsigned int inlen, void *arg),
2711
    void *arg)
2712
{
2713
    if (ctx != NULL) {
2714
        ctx->alpnSelect = cb;
2715
        ctx->alpnSelectArg = arg;
2716
    }
2717
}
2718
2719
/* Set the NPN advertised-protocols callback on the context.
2720
 *
2721
 * Not implemented - stub for OpenSSL compatibility.
2722
 *
2723
 * @param [in] s    SSL/TLS context object.
2724
 * @param [in] cb   NPN advertised-protocols callback.
2725
 * @param [in] arg  User argument passed to the callback.
2726
 */
2727
void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s,
2728
    int (*cb)(WOLFSSL *ssl, const unsigned char **out, unsigned int *outlen,
2729
              void *arg), void *arg)
2730
{
2731
    (void)s;
2732
    (void)cb;
2733
    (void)arg;
2734
    WOLFSSL_STUB("wolfSSL_CTX_set_next_protos_advertised_cb");
2735
}
2736
2737
/* Set the NPN protocol-selection callback on the context.
2738
 *
2739
 * Not implemented - stub for OpenSSL compatibility.
2740
 *
2741
 * @param [in] s    SSL/TLS context object.
2742
 * @param [in] cb   NPN protocol-selection callback.
2743
 * @param [in] arg  User argument passed to the callback.
2744
 */
2745
void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s,
2746
    int (*cb)(WOLFSSL *ssl, unsigned char **out, unsigned char *outlen,
2747
              const unsigned char *in, unsigned int inlen, void *arg),
2748
    void *arg)
2749
{
2750
    (void)s;
2751
    (void)cb;
2752
    (void)arg;
2753
    WOLFSSL_STUB("wolfSSL_CTX_set_next_proto_select_cb");
2754
}
2755
2756
/* Get the NPN protocol negotiated for the object.
2757
 *
2758
 * Not implemented - stub for OpenSSL compatibility.
2759
 *
2760
 * @param [in]  s     SSL/TLS object.
2761
 * @param [out] data  Negotiated protocol data.
2762
 * @param [out] len   Length of the protocol data in bytes.
2763
 */
2764
void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s,
2765
    const unsigned char **data, unsigned *len)
2766
{
2767
    (void)s;
2768
    (void)data;
2769
    (void)len;
2770
    WOLFSSL_STUB("wolfSSL_get0_next_proto_negotiated");
2771
}
2772
#endif /* HAVE_ALPN */
2773
2774
#endif /* WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
2775
2776
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
2777
2778
/* Determine whether an elliptic curve is disabled for the object.
2779
 *
2780
 * @param [in] ssl       SSL/TLS object.
2781
 * @param [in] curve_id  Curve identifier.
2782
 * @return  1 when the curve is disabled or out of range.
2783
 * @return  0 when the curve is enabled or is an FFDHE group.
2784
 */
2785
int wolfSSL_curve_is_disabled(const WOLFSSL* ssl, word16 curve_id)
2786
{
2787
    int ret = 0;
2788
2789
    WOLFSSL_ENTER("wolfSSL_curve_is_disabled");
2790
    WOLFSSL_MSG_EX("wolfSSL_curve_is_disabled checking for %d", curve_id);
2791
2792
    /* (curve_id >= WOLFSSL_FFDHE_START) - DH parameters are never disabled. */
2793
    if (curve_id < WOLFSSL_FFDHE_START) {
2794
        if (curve_id > WOLFSSL_ECC_MAX_AVAIL) {
2795
            WOLFSSL_MSG("Curve id out of supported range");
2796
            /* Disabled if not in valid range. */
2797
            ret = 1;
2798
        }
2799
        else if (curve_id >= 32) {
2800
            /* 0 is for invalid and 1-14 aren't used otherwise. */
2801
            ret = (ssl->disabledCurves & (1U << (curve_id - 32))) != 0;
2802
        }
2803
        else {
2804
            ret = (ssl->disabledCurves & (1U << curve_id)) != 0;
2805
        }
2806
    }
2807
2808
    WOLFSSL_LEAVE("wolfSSL_curve_is_disabled", ret);
2809
    return ret;
2810
}
2811
2812
#if (defined(HAVE_ECC) || \
2813
    defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))
2814
2815
/* Set the supported curves list, by name, on the context.
2816
 *
2817
 * @param [in] ctx    SSL/TLS context object.
2818
 * @param [in] names  Colon-separated list of curve names.
2819
 * @return  WOLFSSL_SUCCESS on success.
2820
 * @return  WOLFSSL_FAILURE when ctx or names is NULL or on error.
2821
 */
2822
int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
2823
{
2824
    int ret;
2825
2826
    WOLFSSL_ENTER("wolfSSL_CTX_set1_curves_list");
2827
2828
    if ((ctx == NULL) || (names == NULL)) {
2829
        WOLFSSL_MSG("ctx or names was NULL");
2830
        ret = WOLFSSL_FAILURE;
2831
    }
2832
    else {
2833
        ret = set_curves_list(NULL, ctx, names, 1);
2834
    }
2835
2836
    return ret;
2837
}
2838
2839
/* Set the supported curves list, by name, on the object.
2840
 *
2841
 * @param [in] ssl    SSL/TLS object.
2842
 * @param [in] names  Colon-separated list of curve names.
2843
 * @return  WOLFSSL_SUCCESS on success.
2844
 * @return  WOLFSSL_FAILURE when ssl or names is NULL or on error.
2845
 */
2846
int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
2847
{
2848
    int ret;
2849
2850
    WOLFSSL_ENTER("wolfSSL_set1_curves_list");
2851
2852
    if ((ssl == NULL) || (names == NULL)) {
2853
        WOLFSSL_MSG("ssl or names was NULL");
2854
        ret = WOLFSSL_FAILURE;
2855
    }
2856
    else {
2857
        ret = set_curves_list(ssl, NULL, names, 1);
2858
    }
2859
2860
    return ret;
2861
}
2862
2863
#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
2864
#endif /* OPENSSL_EXTRA || HAVE_CURL */
2865
2866
#ifdef OPENSSL_EXTRA
2867
2868
/* Set the ALPN protocol list, in wire format, on the context.
2869
 *
2870
 * @param [in] ctx    SSL/TLS context object.
2871
 * @param [in] p      ALPN protocol list in wire format (length-prefixed).
2872
 * @param [in] p_len  Length of the protocol list in bytes.
2873
 * @return  WOLFSSL_SUCCESS (or 0 with WOLFSSL_ERROR_CODE_OPENSSL) on success.
2874
 * @return  BAD_FUNC_ARG when ctx or p is NULL.
2875
 * @return  WOLFSSL_FAILURE (or 1 with WOLFSSL_ERROR_CODE_OPENSSL) on error.
2876
 */
2877
int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p,
2878
                            unsigned int p_len)
2879
{
2880
    int ret;
2881
2882
    WOLFSSL_ENTER("wolfSSL_CTX_set_alpn_protos");
2883
2884
    if ((ctx == NULL) || (p == NULL)) {
2885
        ret = BAD_FUNC_ARG;
2886
    }
2887
    else {
2888
        if (ctx->alpn_cli_protos != NULL) {
2889
            XFREE((void*)ctx->alpn_cli_protos, ctx->heap, DYNAMIC_TYPE_OPENSSL);
2890
        }
2891
2892
        ctx->alpn_cli_protos = (const unsigned char*)XMALLOC(p_len,
2893
            ctx->heap, DYNAMIC_TYPE_OPENSSL);
2894
        if (ctx->alpn_cli_protos == NULL) {
2895
            /* 0 on success in OpenSSL, non-0 on failure in OpenSSL - the
2896
             * function reverses the return value convention. */
2897
            #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
2898
            ret = 1;
2899
            #else
2900
            ret = WOLFSSL_FAILURE;
2901
            #endif
2902
        }
2903
        else {
2904
            XMEMCPY((void*)ctx->alpn_cli_protos, p, p_len);
2905
            ctx->alpn_cli_protos_len = p_len;
2906
2907
            /* 0 on success in OpenSSL, non-0 on failure in OpenSSL - the
2908
             * function reverses the return value convention. */
2909
            #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
2910
            ret = 0;
2911
            #else
2912
            ret = WOLFSSL_SUCCESS;
2913
            #endif
2914
        }
2915
    }
2916
2917
    return ret;
2918
}
2919
2920
2921
#ifdef HAVE_ALPN
2922
#ifndef NO_BIO
2923
/* Convert a wire-format ALPN protocol list into a comma-separated string.
2924
 *
2925
 * The wire format is a sequence of entries, each a length byte followed by
2926
 * that many protocol-name bytes.
2927
 *
2928
 * @param [in]  p      ALPN protocol list in wire format.
2929
 * @param [in]  p_len  Length of the protocol list in bytes.
2930
 * @param [out] pt     Buffer to hold the comma-separated list. Must hold at
2931
 *                     least p_len bytes.
2932
 * @param [out] ptLen  Length of the comma-separated list written.
2933
 * @return  1 on success.
2934
 * @return  0 when the wire format is invalid.
2935
 */
2936
static int wolfssl_alpn_protos_to_list(const unsigned char* p,
2937
    unsigned int p_len, char* pt, unsigned int* ptLen)
2938
{
2939
    unsigned int idx = 0;
2940
    unsigned int ptIdx = 0;
2941
    unsigned int sz;
2942
    int ret = 1;
2943
2944
    /* Convert into a comma separated list. */
2945
    while (idx < p_len - 1) {
2946
        unsigned int i;
2947
2948
        sz = p[idx++];
2949
        if (idx + sz > p_len) {
2950
            WOLFSSL_MSG("Bad list format");
2951
            ret = 0;
2952
            break;
2953
        }
2954
        if (sz > 0) {
2955
            for (i = 0; i < sz; i++) {
2956
                pt[ptIdx++] = p[idx++];
2957
            }
2958
            if (idx < p_len - 1) {
2959
                pt[ptIdx++] = ',';
2960
            }
2961
        }
2962
    }
2963
2964
    if (ret == 1) {
2965
        *ptLen = ptIdx;
2966
    }
2967
2968
    return ret;
2969
}
2970
2971
/* Set the ALPN protocol list, in wire format, on the object.
2972
 *
2973
 * The list is length-prefixed, e.g.
2974
 *     unsigned char p[] = { 8, 'h','t','t','p','/','1','.','1' };
2975
 *
2976
 * @param [in] ssl    SSL/TLS object.
2977
 * @param [in] p      ALPN protocol list in wire format (length-prefixed).
2978
 * @param [in] p_len  Length of the protocol list in bytes.
2979
 * @return  WOLFSSL_SUCCESS (or 0 with WOLFSSL_ERROR_CODE_OPENSSL) on success.
2980
 * @return  WOLFSSL_FAILURE (or 1 with WOLFSSL_ERROR_CODE_OPENSSL) on error.
2981
 */
2982
int wolfSSL_set_alpn_protos(WOLFSSL* ssl,
2983
        const unsigned char* p, unsigned int p_len)
2984
{
2985
    char* pt = NULL;
2986
    unsigned int ptIdx = 0;
2987
    /* RFC 7301: a server that does not select any of the client's offered
2988
     * protocols MUST send no_application_protocol. Match that contract on
2989
     * the OpenSSL-compat surface rather than silently continuing. */
2990
    int alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
2991
    #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
2992
    int ret = 1;
2993
    #else
2994
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
2995
    #endif
2996
2997
    WOLFSSL_ENTER("wolfSSL_set_alpn_protos");
2998
2999
    if ((ssl != NULL) && (p_len > 1) && (p != NULL)) {
3000
        /* Replacing leading number with trailing ',' and adding '\0'. */
3001
        pt = (char*)XMALLOC(p_len + 1, ssl->heap, DYNAMIC_TYPE_OPENSSL);
3002
        if (pt != NULL) {
3003
            if (wolfssl_alpn_protos_to_list(p, p_len, pt, &ptIdx)) {
3004
                pt[ptIdx++] = '\0';
3005
3006
                /* Clear out all currently set ALPN extensions. */
3007
                TLSX_Remove(&ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL,
3008
                    ssl->heap);
3009
3010
                if (wolfSSL_UseALPN(ssl, pt, ptIdx, (byte)alpn_opt) ==
3011
                        WOLFSSL_SUCCESS) {
3012
                    #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
3013
                    ret = 0;
3014
                    #else
3015
                    ret = WOLFSSL_SUCCESS;
3016
                    #endif
3017
                }
3018
            }
3019
3020
            XFREE(pt, ssl->heap, DYNAMIC_TYPE_OPENSSL);
3021
        }
3022
    }
3023
3024
    return ret;
3025
}
3026
#endif /* !NO_BIO */
3027
#endif /* HAVE_ALPN */
3028
3029
#endif /* OPENSSL_EXTRA */
3030
3031
#endif /* !WOLFCRYPT_ONLY */
3032
3033
#endif /* !WOLFSSL_SSL_API_EXT_INCLUDED */