Coverage Report

Created: 2026-07-16 06:50

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
    if (ssl == NULL)
49
0
        return BAD_FUNC_ARG;
50
51
0
    return TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
52
0
}
53
54
55
/* Set the Server Name Indication extension data on the context.
56
 *
57
 * @param [in] ctx   SSL/TLS context object.
58
 * @param [in] type  SNI type, e.g. WOLFSSL_SNI_HOST_NAME.
59
 * @param [in] data  SNI data.
60
 * @param [in] size  Length of SNI data in bytes.
61
 * @return  WOLFSSL_SUCCESS on success.
62
 * @return  BAD_FUNC_ARG when ctx is NULL.
63
 * @return  Negative value on error.
64
 */
65
WOLFSSL_ABI
66
int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
67
                                                                    word16 size)
68
0
{
69
0
    if (ctx == NULL)
70
0
        return BAD_FUNC_ARG;
71
72
0
    return TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
73
0
}
74
75
#ifndef NO_WOLFSSL_SERVER
76
77
/* Set options for the Server Name Indication extension on the object.
78
 *
79
 * @param [in] ssl      SSL/TLS object.
80
 * @param [in] type     SNI type.
81
 * @param [in] options  Bitmask of SNI options.
82
 */
83
void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
84
0
{
85
0
    if ((ssl != NULL) && (ssl->extensions != NULL)) {
86
0
        TLSX_SNI_SetOptions(ssl->extensions, type, options);
87
0
    }
88
0
}
89
90
91
/* Set options for the Server Name Indication extension on the context.
92
 *
93
 * @param [in] ctx      SSL/TLS context object.
94
 * @param [in] type     SNI type.
95
 * @param [in] options  Bitmask of SNI options.
96
 */
97
void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
98
0
{
99
0
    if ((ctx != NULL) && (ctx->extensions != NULL)) {
100
0
        TLSX_SNI_SetOptions(ctx->extensions, type, options);
101
0
    }
102
0
}
103
104
105
/* Get the status of the Server Name Indication extension on the object.
106
 *
107
 * @param [in] ssl   SSL/TLS object.
108
 * @param [in] type  SNI type.
109
 * @return  SNI status for the type.
110
 */
111
byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
112
0
{
113
0
    return TLSX_SNI_Status((ssl != NULL) ? ssl->extensions : NULL, type);
114
0
}
115
116
117
/* Get the Server Name Indication request data received from the peer.
118
 *
119
 * @param [in]  ssl   SSL/TLS object.
120
 * @param [in]  type  SNI type.
121
 * @param [out] data  Pointer to the SNI request data. May be NULL.
122
 * @return  Length of the SNI request data in bytes, or 0 when none.
123
 */
124
word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
125
0
{
126
0
    if (data)
127
0
        *data = NULL;
128
129
0
    if (ssl && ssl->extensions)
130
0
        return TLSX_SNI_GetRequest(ssl->extensions, type, data, 0);
131
132
0
    return 0;
133
0
}
134
135
136
/* Get the Server Name Indication data from a raw ClientHello buffer.
137
 *
138
 * @param [in]      clientHello  ClientHello message buffer.
139
 * @param [in]      helloSz      Length of the ClientHello in bytes.
140
 * @param [in]      type         SNI type.
141
 * @param [out]     sni          Buffer to hold the SNI data.
142
 * @param [in, out] inOutSz      In: size of buffer. Out: length of SNI data.
143
 * @return  WOLFSSL_SUCCESS on success.
144
 * @return  BAD_FUNC_ARG when an argument is NULL or a size is zero.
145
 */
146
int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
147
                              byte type, byte* sni, word32* inOutSz)
148
0
{
149
0
    if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
150
0
        return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
151
152
0
    return BAD_FUNC_ARG;
153
0
}
154
155
#endif /* !NO_WOLFSSL_SERVER */
156
157
#endif /* HAVE_SNI */
158
159
160
#ifdef HAVE_TRUSTED_CA
161
162
/* Set the Trusted CA Indication extension on the object.
163
 *
164
 * @param [in] ssl       SSL/TLS object.
165
 * @param [in] type      Trusted CA identifier type.
166
 * @param [in] certId    Certificate identifier data.
167
 * @param [in] certIdSz  Length of certificate identifier in bytes.
168
 * @return  WOLFSSL_SUCCESS on success.
169
 * @return  BAD_FUNC_ARG when ssl is NULL or arguments are inconsistent with
170
 *          the type.
171
 */
172
int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type,
173
    const byte* certId, word32 certIdSz)
174
{
175
    if (ssl == NULL)
176
        return BAD_FUNC_ARG;
177
178
    if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED) {
179
        if (certId != NULL || certIdSz != 0)
180
            return BAD_FUNC_ARG;
181
    }
182
    else if (type == WOLFSSL_TRUSTED_CA_X509_NAME) {
183
        if (certId == NULL || certIdSz == 0)
184
            return BAD_FUNC_ARG;
185
    }
186
    #ifndef NO_SHA
187
    else if (type == WOLFSSL_TRUSTED_CA_KEY_SHA1 ||
188
            type == WOLFSSL_TRUSTED_CA_CERT_SHA1) {
189
        if (certId == NULL || certIdSz != WC_SHA_DIGEST_SIZE)
190
            return BAD_FUNC_ARG;
191
    }
192
    #endif
193
    else
194
        return BAD_FUNC_ARG;
195
196
    return TLSX_UseTrustedCA(&ssl->extensions,
197
            type, certId, certIdSz, ssl->heap);
198
}
199
200
#endif /* HAVE_TRUSTED_CA */
201
202
203
#ifdef HAVE_MAX_FRAGMENT
204
#ifndef NO_WOLFSSL_CLIENT
205
206
/* Set the Maximum Fragment Length extension on the object.
207
 *
208
 * @param [in] ssl  SSL/TLS object.
209
 * @param [in] mfl  Maximum fragment length code, e.g. WOLFSSL_MFL_2_9.
210
 * @return  WOLFSSL_SUCCESS on success.
211
 * @return  BAD_FUNC_ARG when ssl is NULL.
212
 * @return  Negative value on error.
213
 */
214
int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
215
{
216
    if (ssl == NULL)
217
        return BAD_FUNC_ARG;
218
219
#ifdef WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST
220
    /* The following is a non-standard way to reconfigure the max packet size
221
        post-handshake for wolfSSL_write/wolfSSL_read */
222
    if (ssl->options.handShakeState == HANDSHAKE_DONE) {
223
        switch (mfl) {
224
            case WOLFSSL_MFL_2_8 : ssl->max_fragment =  256; break;
225
            case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
226
            case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
227
            case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
228
            case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
229
            case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
230
            default: ssl->max_fragment = MAX_RECORD_SIZE; break;
231
        }
232
        return WOLFSSL_SUCCESS;
233
    }
234
#endif /* WOLFSSL_MAX_FRAGMENT_ADJUST */
235
236
    /* This call sets the max fragment TLS extension, which gets sent to server.
237
        The server_hello response is what sets the `ssl->max_fragment` in
238
        TLSX_MFL_Parse */
239
    return TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
240
}
241
242
243
/* Set the Maximum Fragment Length extension on the context.
244
 *
245
 * @param [in] ctx  SSL/TLS context object.
246
 * @param [in] mfl  Maximum fragment length code, e.g. WOLFSSL_MFL_2_9.
247
 * @return  WOLFSSL_SUCCESS on success.
248
 * @return  BAD_FUNC_ARG when ctx is NULL.
249
 * @return  Negative value on error.
250
 */
251
int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
252
{
253
    if (ctx == NULL)
254
        return BAD_FUNC_ARG;
255
256
    return TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
257
}
258
259
#endif /* NO_WOLFSSL_CLIENT */
260
#endif /* HAVE_MAX_FRAGMENT */
261
262
#ifdef HAVE_TRUNCATED_HMAC
263
#ifndef NO_WOLFSSL_CLIENT
264
265
/* Set the Truncated HMAC extension on the object.
266
 *
267
 * @param [in] ssl  SSL/TLS object.
268
 * @return  WOLFSSL_SUCCESS on success.
269
 * @return  BAD_FUNC_ARG when ssl is NULL.
270
 * @return  Negative value on error.
271
 */
272
int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
273
{
274
    if (ssl == NULL)
275
        return BAD_FUNC_ARG;
276
277
    return TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
278
}
279
280
281
/* Set the Truncated HMAC extension on the context.
282
 *
283
 * @param [in] ctx  SSL/TLS context object.
284
 * @return  WOLFSSL_SUCCESS on success.
285
 * @return  BAD_FUNC_ARG when ctx is NULL.
286
 * @return  Negative value on error.
287
 */
288
int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
289
{
290
    if (ctx == NULL)
291
        return BAD_FUNC_ARG;
292
293
    return TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
294
}
295
296
#endif /* NO_WOLFSSL_CLIENT */
297
#endif /* HAVE_TRUNCATED_HMAC */
298
299
/* Elliptic Curves */
300
#if defined(HAVE_SUPPORTED_CURVES)
301
302
/* Determine whether a named group is a supported curve or FFDHE group.
303
 *
304
 * @param [in] name  Named group identifier.
305
 * @return  1 when the named group is valid.
306
 * @return  0 otherwise.
307
 */
308
static int isValidCurveGroup(word16 name)
309
0
{
310
0
    switch (name) {
311
0
        case WOLFSSL_ECC_SECP160K1:
312
0
        case WOLFSSL_ECC_SECP160R1:
313
0
        case WOLFSSL_ECC_SECP160R2:
314
0
        case WOLFSSL_ECC_SECP192K1:
315
0
        case WOLFSSL_ECC_SECP192R1:
316
0
        case WOLFSSL_ECC_SECP224K1:
317
0
        case WOLFSSL_ECC_SECP224R1:
318
0
        case WOLFSSL_ECC_SECP256K1:
319
0
        case WOLFSSL_ECC_SECP256R1:
320
0
        case WOLFSSL_ECC_SECP384R1:
321
0
        case WOLFSSL_ECC_SECP521R1:
322
0
        case WOLFSSL_ECC_BRAINPOOLP256R1:
323
0
        case WOLFSSL_ECC_BRAINPOOLP384R1:
324
0
        case WOLFSSL_ECC_BRAINPOOLP512R1:
325
0
        case WOLFSSL_ECC_SM2P256V1:
326
0
        case WOLFSSL_ECC_X25519:
327
0
        case WOLFSSL_ECC_X448:
328
0
        case WOLFSSL_ECC_BRAINPOOLP256R1TLS13:
329
0
        case WOLFSSL_ECC_BRAINPOOLP384R1TLS13:
330
0
        case WOLFSSL_ECC_BRAINPOOLP512R1TLS13:
331
332
0
        case WOLFSSL_FFDHE_2048:
333
0
        case WOLFSSL_FFDHE_3072:
334
0
        case WOLFSSL_FFDHE_4096:
335
0
        case WOLFSSL_FFDHE_6144:
336
0
        case WOLFSSL_FFDHE_8192:
337
338
0
#ifdef WOLFSSL_HAVE_MLKEM
339
0
#ifndef WOLFSSL_NO_ML_KEM
340
    #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
341
        case WOLFSSL_ML_KEM_512:
342
        case WOLFSSL_ML_KEM_768:
343
        case WOLFSSL_ML_KEM_1024:
344
    #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */
345
0
    #ifdef WOLFSSL_PQC_HYBRIDS
346
0
        case WOLFSSL_SECP384R1MLKEM1024:
347
0
        case WOLFSSL_X25519MLKEM768:
348
0
        case WOLFSSL_SECP256R1MLKEM768:
349
0
    #endif /* WOLFSSL_PQC_HYBRIDS */
350
    #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
351
        case WOLFSSL_SECP256R1MLKEM512:
352
        case WOLFSSL_SECP384R1MLKEM768:
353
        case WOLFSSL_SECP521R1MLKEM1024:
354
        case WOLFSSL_X25519MLKEM512:
355
        case WOLFSSL_X448MLKEM768:
356
    #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
357
0
#endif /* !WOLFSSL_NO_ML_KEM */
358
#ifdef WOLFSSL_MLKEM_KYBER
359
        case WOLFSSL_KYBER_LEVEL1:
360
        case WOLFSSL_KYBER_LEVEL3:
361
        case WOLFSSL_KYBER_LEVEL5:
362
        case WOLFSSL_P256_KYBER_LEVEL1:
363
        case WOLFSSL_P384_KYBER_LEVEL3:
364
        case WOLFSSL_P521_KYBER_LEVEL5:
365
        case WOLFSSL_X25519_KYBER_LEVEL1:
366
        case WOLFSSL_X448_KYBER_LEVEL3:
367
        case WOLFSSL_X25519_KYBER_LEVEL3:
368
        case WOLFSSL_P256_KYBER_LEVEL3:
369
#endif /* WOLFSSL_MLKEM_KYBER */
370
0
#endif
371
0
            return 1;
372
373
0
        default:
374
0
            return 0;
375
0
    }
376
0
}
377
378
/* Set a named group in the Supported Groups extension on the object.
379
 *
380
 * @param [in] ssl   SSL/TLS object.
381
 * @param [in] name  Named group identifier.
382
 * @return  WOLFSSL_SUCCESS on success.
383
 * @return  BAD_FUNC_ARG when ssl is NULL or the group is invalid.
384
 * @return  WOLFSSL_FAILURE when TLS is not compiled in.
385
 */
386
int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
387
0
{
388
0
    if (ssl == NULL || !isValidCurveGroup(name))
389
0
        return BAD_FUNC_ARG;
390
391
0
    ssl->options.userCurves = 1;
392
#if defined(NO_TLS)
393
    return WOLFSSL_FAILURE;
394
#else
395
0
    return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap,
396
0
                                  ssl->options.side);
397
0
#endif /* NO_TLS */
398
0
}
399
400
401
/* Set a named group in the Supported Groups extension on the context.
402
 *
403
 * @param [in] ctx   SSL/TLS context object.
404
 * @param [in] name  Named group identifier.
405
 * @return  WOLFSSL_SUCCESS on success.
406
 * @return  BAD_FUNC_ARG when ctx is NULL or the group is invalid.
407
 * @return  WOLFSSL_FAILURE when TLS is not compiled in.
408
 */
409
int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
410
0
{
411
0
    if (ctx == NULL || !isValidCurveGroup(name))
412
0
        return BAD_FUNC_ARG;
413
414
0
    ctx->userCurves = 1;
415
#if defined(NO_TLS)
416
    return WOLFSSL_FAILURE;
417
#else
418
0
    return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap,
419
0
                                  ctx->method->side);
420
0
#endif /* NO_TLS */
421
0
}
422
423
#if defined(OPENSSL_EXTRA)
424
/* Validate a list of group identifiers and translate them into named groups.
425
 *
426
 * Group values may be wolfSSL named groups or curve NIDs (when ECC is
427
 * available).
428
 *
429
 * @param [in]  groups     Array of group identifiers.
430
 * @param [in]  count      Number of groups in the array.
431
 * @param [out] outGroups  Array to hold the named groups. Must have at least
432
 *                         count entries.
433
 * @return  WOLFSSL_SUCCESS on success.
434
 * @return  WOLFSSL_FAILURE when a group is not recognized.
435
 */
436
static int wolfssl_validate_groups(const int* groups, int count, int* outGroups)
437
{
438
    int i;
439
    int ret = WOLFSSL_SUCCESS;
440
441
    for (i = 0; i < count; i++) {
442
        if (isValidCurveGroup((word16)groups[i])) {
443
            outGroups[i] = groups[i];
444
        }
445
#ifdef HAVE_ECC
446
        else {
447
            /* Groups may be populated with curve NIDs. */
448
            int oid = (int)nid2oid(groups[i], oidCurveType);
449
            int name = (int)GetCurveByOID(oid);
450
            if (name == 0) {
451
                WOLFSSL_MSG("Invalid group name");
452
                ret = WOLFSSL_FAILURE;
453
                break;
454
            }
455
            outGroups[i] = name;
456
        }
457
#else
458
        else {
459
            WOLFSSL_MSG("Invalid group name");
460
            ret = WOLFSSL_FAILURE;
461
            break;
462
        }
463
#endif
464
    }
465
466
    return ret;
467
}
468
469
/* Set the list of supported groups on the context.
470
 *
471
 * Group values may be wolfSSL named groups or curve NIDs.
472
 *
473
 * @param [in] ctx     SSL/TLS context object.
474
 * @param [in] groups  Array of group identifiers.
475
 * @param [in] count   Number of groups in the array.
476
 * @return  WOLFSSL_SUCCESS on success.
477
 * @return  WOLFSSL_FAILURE when count is invalid or a group is not recognized.
478
 */
479
int wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups, int count)
480
{
481
    int _groups[WOLFSSL_MAX_GROUP_COUNT];
482
    int ret = WOLFSSL_SUCCESS;
483
484
    WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
485
    if (groups == NULL || count <= 0) {
486
        WOLFSSL_MSG("Groups NULL or count not positive");
487
        ret = WOLFSSL_FAILURE;
488
    }
489
    else if (count > WOLFSSL_MAX_GROUP_COUNT) {
490
        WOLFSSL_MSG("Group count exceeds maximum");
491
        ret = WOLFSSL_FAILURE;
492
    }
493
    else {
494
        /* Translate the input list into named groups, then apply it. */
495
        ret = wolfssl_validate_groups(groups, count, _groups);
496
        if (ret == WOLFSSL_SUCCESS) {
497
            ret = wolfSSL_CTX_set_groups(ctx, _groups, count);
498
            /* Normalize any non-success result to WOLFSSL_FAILURE. */
499
            if (ret != WOLFSSL_SUCCESS) {
500
                ret = WOLFSSL_FAILURE;
501
            }
502
        }
503
    }
504
505
    return ret;
506
}
507
508
/* Set the list of supported groups on the object.
509
 *
510
 * Group values may be wolfSSL named groups or curve NIDs.
511
 *
512
 * @param [in] ssl     SSL/TLS object.
513
 * @param [in] groups  Array of group identifiers.
514
 * @param [in] count   Number of groups in the array.
515
 * @return  WOLFSSL_SUCCESS on success.
516
 * @return  WOLFSSL_FAILURE when count is invalid or a group is not recognized.
517
 */
518
int wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count)
519
{
520
    int _groups[WOLFSSL_MAX_GROUP_COUNT];
521
    int ret = WOLFSSL_SUCCESS;
522
523
    WOLFSSL_ENTER("wolfSSL_set1_groups");
524
    if (groups == NULL || count <= 0) {
525
        WOLFSSL_MSG("Groups NULL or count not positive");
526
        ret = WOLFSSL_FAILURE;
527
    }
528
    else if (count > WOLFSSL_MAX_GROUP_COUNT) {
529
        WOLFSSL_MSG("Group count exceeds maximum");
530
        ret = WOLFSSL_FAILURE;
531
    }
532
    else {
533
        /* Translate the input list into named groups, then apply it. */
534
        ret = wolfssl_validate_groups(groups, count, _groups);
535
        if (ret == WOLFSSL_SUCCESS) {
536
            ret = wolfSSL_set_groups(ssl, _groups, count);
537
            /* Normalize any non-success result to WOLFSSL_FAILURE. */
538
            if (ret != WOLFSSL_SUCCESS) {
539
                ret = WOLFSSL_FAILURE;
540
            }
541
        }
542
    }
543
544
    return ret;
545
}
546
#endif /* OPENSSL_EXTRA */
547
#endif /* HAVE_SUPPORTED_CURVES */
548
549
/* Application-Layer Protocol Negotiation */
550
#ifdef HAVE_ALPN
551
552
/* Set the Application-Layer Protocol Negotiation extension on the object.
553
 *
554
 * @param [in] ssl                    SSL/TLS object.
555
 * @param [in] protocol_name_list     Comma-separated list of protocol names.
556
 * @param [in] protocol_name_listSz   Length of the list in bytes.
557
 * @param [in] options                Bitmask of ALPN options.
558
 * @return  WOLFSSL_SUCCESS on success.
559
 * @return  BAD_FUNC_ARG when an argument is NULL, the list is too long or
560
 *          options are unsupported.
561
 * @return  MEMORY_ERROR on allocation failure.
562
 */
563
WOLFSSL_ABI
564
int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
565
    word32 protocol_name_listSz, byte options)
566
{
567
    char*  list = NULL;
568
    char*  ptr = NULL;
569
    char** token = NULL;
570
    word16 len;
571
    int    idx = 0;
572
    int    ret = WOLFSSL_SUCCESS;
573
574
    WOLFSSL_ENTER("wolfSSL_UseALPN");
575
576
    if ((ssl == NULL) || (protocol_name_list == NULL)) {
577
        return BAD_FUNC_ARG;
578
    }
579
    else if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
580
             WOLFSSL_MAX_ALPN_PROTO_NAME_LEN + WOLFSSL_MAX_ALPN_NUMBER)) {
581
        WOLFSSL_MSG("Invalid arguments, protocol name list too long");
582
        return BAD_FUNC_ARG;
583
    }
584
    else if ((!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH)) &&
585
             (!(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH))) {
586
        WOLFSSL_MSG("Invalid arguments, options not supported");
587
        return BAD_FUNC_ARG;
588
    }
589
590
    list = (char *)XMALLOC(protocol_name_listSz + 1, ssl->heap,
591
                           DYNAMIC_TYPE_ALPN);
592
    token = (char **)XMALLOC(sizeof(char*) * (WOLFSSL_MAX_ALPN_NUMBER + 1),
593
                             ssl->heap, DYNAMIC_TYPE_ALPN);
594
    if ((list == NULL) || (token == NULL)) {
595
        WOLFSSL_MSG("Memory failure");
596
        ret = MEMORY_ERROR;
597
    }
598
599
    if (ret == WOLFSSL_SUCCESS) {
600
        XMEMSET(token, 0, sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1));
601
602
        XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
603
        list[protocol_name_listSz] = '\0';
604
605
        /* Read all protocol names from the list. */
606
        token[idx] = XSTRTOK(list, ",", &ptr);
607
        while ((idx < WOLFSSL_MAX_ALPN_NUMBER) && (token[idx] != NULL)) {
608
            token[++idx] = XSTRTOK(NULL, ",", &ptr);
609
        }
610
611
        /* Add the protocol name list to the TLS extension in reverse order. */
612
        while ((idx--) > 0) {
613
            len = (word16)XSTRLEN(token[idx]);
614
615
            ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
616
                ssl->heap);
617
            if (ret != WOLFSSL_SUCCESS) {
618
                WOLFSSL_MSG("TLSX_UseALPN failure");
619
                break;
620
            }
621
        }
622
    }
623
624
    XFREE(token, ssl->heap, DYNAMIC_TYPE_ALPN);
625
    XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
626
627
    return ret;
628
}
629
630
/* Get the ALPN protocol negotiated for the object.
631
 *
632
 * @param [in]  ssl            SSL/TLS object.
633
 * @param [out] protocol_name  Negotiated protocol name.
634
 * @param [out] size           Length of the protocol name in bytes.
635
 * @return  WOLFSSL_SUCCESS on success.
636
 * @return  Negative value on error.
637
 */
638
int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
639
{
640
    return TLSX_ALPN_GetRequest((ssl != NULL) ? ssl->extensions : NULL,
641
                                (void **)protocol_name, size);
642
}
643
644
/* Get the ALPN protocol list offered by the peer as a comma-separated string.
645
 *
646
 * The returned list must be freed with wolfSSL_ALPN_FreePeerProtocol().
647
 *
648
 * @param [in]  ssl     SSL/TLS object.
649
 * @param [out] list    Newly allocated comma-separated protocol list.
650
 * @param [out] listSz  Length of the list string.
651
 * @return  WOLFSSL_SUCCESS on success.
652
 * @return  BAD_FUNC_ARG when an argument is NULL.
653
 * @return  BUFFER_ERROR when the peer offered no protocols.
654
 * @return  MEMORY_ERROR on allocation failure.
655
 */
656
int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
657
{
658
    int i, len;
659
    char *p;
660
    byte *s;
661
662
    if (ssl == NULL || list == NULL || listSz == NULL)
663
        return BAD_FUNC_ARG;
664
665
    if (ssl->alpn_peer_requested == NULL
666
        || ssl->alpn_peer_requested_length == 0)
667
        return BUFFER_ERROR;
668
669
    /* ssl->alpn_peer_requested are the original bytes sent in a ClientHello,
670
     * formatted as (len-byte chars+)+. To turn n protocols into a
671
     * comma-separated C string, one needs (n-1) commas and a final 0 byte
672
     * which has the same length as the original.
673
     * The returned length is the strlen() of the C string, so -1 of that. */
674
    *listSz = ssl->alpn_peer_requested_length-1;
675
    *list = p = (char *)XMALLOC(ssl->alpn_peer_requested_length, ssl->heap,
676
                                DYNAMIC_TYPE_TLSX);
677
    if (p == NULL)
678
        return MEMORY_ERROR;
679
680
    for (i = 0, s = ssl->alpn_peer_requested;
681
         i < ssl->alpn_peer_requested_length;
682
         p += len, i += len)
683
    {
684
        if (i)
685
            *p++ = ',';
686
        len = s[i++];
687
        /* guard against bad length bytes. */
688
        if (i + len > ssl->alpn_peer_requested_length) {
689
            XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
690
            *list = NULL;
691
            return WOLFSSL_FAILURE;
692
        }
693
        XMEMCPY(p, s + i, (size_t)len);
694
    }
695
    *p = 0;
696
697
    return WOLFSSL_SUCCESS;
698
}
699
700
701
/* Free a peer protocol list returned by wolfSSL_ALPN_GetPeerProtocol().
702
 *
703
 * @param [in]      ssl   SSL/TLS object.
704
 * @param [in, out] list  Protocol list to free; set to NULL on return.
705
 * @return  WOLFSSL_SUCCESS on success.
706
 * @return  BAD_FUNC_ARG when ssl is NULL.
707
 */
708
int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
709
{
710
    if (ssl == NULL) {
711
        return BAD_FUNC_ARG;
712
    }
713
714
    XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
715
    *list = NULL;
716
717
    return WOLFSSL_SUCCESS;
718
}
719
720
#endif /* HAVE_ALPN */
721
722
/* Secure Renegotiation */
723
#ifdef HAVE_SERVER_RENEGOTIATION_INFO
724
725
/* Enable the Secure Renegotiation extension on the object.
726
 *
727
 * Use of secure renegotiation is discouraged.
728
 *
729
 * @param [in] ssl  SSL/TLS object.
730
 * @return  WOLFSSL_SUCCESS on success.
731
 * @return  BAD_FUNC_ARG when ssl is NULL.
732
 * @return  Negative value on error.
733
 */
734
int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
735
0
{
736
0
    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
737
#if defined(NO_TLS)
738
    (void)ssl;
739
#else
740
0
    if (ssl != NULL) {
741
0
        ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
742
0
    }
743
0
    else {
744
0
        ret = BAD_FUNC_ARG;
745
0
    }
746
747
0
    if (ret == WOLFSSL_SUCCESS) {
748
0
        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
749
0
        if (extension != NULL) {
750
0
            ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
751
0
        }
752
0
    }
753
0
#endif /* !NO_TLS */
754
0
    return ret;
755
0
}
756
757
/* Enable the Secure Renegotiation extension on the context.
758
 *
759
 * Use of secure renegotiation is discouraged.
760
 *
761
 * @param [in] ctx  SSL/TLS context object.
762
 * @return  WOLFSSL_SUCCESS on success.
763
 * @return  BAD_FUNC_ARG when ctx is NULL.
764
 */
765
int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx)
766
0
{
767
0
    if (ctx == NULL)
768
0
        return BAD_FUNC_ARG;
769
770
0
    ctx->useSecureReneg = 1;
771
0
    return WOLFSSL_SUCCESS;
772
0
}
773
774
#ifdef HAVE_SECURE_RENEGOTIATION
775
/* Perform a secure renegotiation handshake on the object.
776
 *
777
 * User forced; use of secure renegotiation is discouraged.
778
 *
779
 * @param [in] ssl  SSL/TLS object.
780
 * @return  WOLFSSL_SUCCESS on success.
781
 * @return  BAD_FUNC_ARG when ssl is NULL.
782
 * @return  SECURE_RENEGOTIATION_E when renegotiation is not allowed.
783
 * @return  WOLFSSL_FATAL_ERROR on error.
784
 */
785
static int _Rehandshake(WOLFSSL* ssl)
786
{
787
    int ret;
788
789
    if (ssl == NULL)
790
        return BAD_FUNC_ARG;
791
792
    if (IsAtLeastTLSv1_3(ssl->version)) {
793
        WOLFSSL_MSG("Secure Renegotiation not supported in TLS 1.3");
794
        return SECURE_RENEGOTIATION_E;
795
    }
796
797
    if (ssl->secure_renegotiation == NULL) {
798
        WOLFSSL_MSG("Secure Renegotiation not forced on by user");
799
        return SECURE_RENEGOTIATION_E;
800
    }
801
802
    if (ssl->secure_renegotiation->enabled == 0) {
803
        WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
804
        return SECURE_RENEGOTIATION_E;
805
    }
806
807
#ifdef WOLFSSL_DTLS
808
    if (ssl->options.dtls && ssl->keys.dtls_epoch == 0xFFFF) {
809
        WOLFSSL_MSG("Secure Renegotiation not allowed. Epoch would wrap");
810
        return SECURE_RENEGOTIATION_E;
811
    }
812
#endif
813
814
    /* If the client started the renegotiation, the server will already
815
     * have processed the client's hello. */
816
    if (ssl->options.side != WOLFSSL_SERVER_END ||
817
        ssl->options.acceptState != ACCEPT_FIRST_REPLY_DONE) {
818
819
        if (ssl->options.handShakeState != HANDSHAKE_DONE) {
820
            if (!ssl->options.handShakeDone) {
821
                WOLFSSL_MSG("Can't renegotiate until initial "
822
                            "handshake complete");
823
                return SECURE_RENEGOTIATION_E;
824
            }
825
            else {
826
                WOLFSSL_MSG("Renegotiation already started. "
827
                            "Moving it forward.");
828
                ret = wolfSSL_negotiate(ssl);
829
                if (ret == WOLFSSL_SUCCESS)
830
                    ssl->secure_rene_count++;
831
                return ret;
832
            }
833
        }
834
835
        /* reset handshake states */
836
        ssl->options.sendVerify = 0;
837
        ssl->options.serverState = NULL_STATE;
838
        ssl->options.clientState = NULL_STATE;
839
        ssl->options.connectState  = CONNECT_BEGIN;
840
        ssl->options.acceptState   = ACCEPT_BEGIN_RENEG;
841
        ssl->options.handShakeState = NULL_STATE;
842
        ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
843
844
        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
845
846
        ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
847
848
#if !defined(NO_WOLFSSL_SERVER) && !defined(WOLFSSL_NO_TLS12)
849
        if (ssl->options.side == WOLFSSL_SERVER_END) {
850
            ret = SendHelloRequest(ssl);
851
            if (ret != 0) {
852
                ssl->error = ret;
853
                return WOLFSSL_FATAL_ERROR;
854
            }
855
        }
856
#endif /* !NO_WOLFSSL_SERVER && !WOLFSSL_NO_TLS12 */
857
858
        ret = InitHandshakeHashes(ssl);
859
        if (ret != 0) {
860
            ssl->error = ret;
861
            return WOLFSSL_FATAL_ERROR;
862
        }
863
    }
864
    ret = wolfSSL_negotiate(ssl);
865
    if (ret == WOLFSSL_SUCCESS)
866
        ssl->secure_rene_count++;
867
    return ret;
868
}
869
870
871
/* Perform a secure renegotiation handshake on the object.
872
 *
873
 * User forced; use of secure renegotiation is discouraged.
874
 *
875
 * @param [in] ssl  SSL/TLS object.
876
 * @return  WOLFSSL_SUCCESS on success.
877
 * @return  WOLFSSL_FAILURE when ssl is NULL.
878
 * @return  Negative value on error.
879
 */
880
int wolfSSL_Rehandshake(WOLFSSL* ssl)
881
{
882
    int ret;
883
    WOLFSSL_ENTER("wolfSSL_Rehandshake");
884
885
    if (ssl == NULL)
886
        return WOLFSSL_FAILURE;
887
888
#ifdef HAVE_SESSION_TICKET
889
    ret = WOLFSSL_SUCCESS;
890
#endif
891
892
    if (ssl->options.side == WOLFSSL_SERVER_END) {
893
        /* Reset option to send certificate verify. */
894
        ssl->options.sendVerify = 0;
895
        /* Reset resuming flag to do full secure handshake. */
896
        ssl->options.resuming = 0;
897
    }
898
    else {
899
        /* Reset resuming flag to do full secure handshake. */
900
        ssl->options.resuming = 0;
901
        #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_CLIENT)
902
            /* Clearing the ticket. */
903
            ret = wolfSSL_UseSessionTicket(ssl);
904
        #endif
905
    }
906
    /* CLIENT/SERVER: Reset peer authentication for full secure handshake. */
907
    ssl->options.peerAuthGood = 0;
908
909
#ifdef HAVE_SESSION_TICKET
910
    if (ret == WOLFSSL_SUCCESS)
911
#endif
912
        ret = _Rehandshake(ssl);
913
914
    return ret;
915
}
916
917
918
#ifndef NO_WOLFSSL_CLIENT
919
920
/* Perform a secure resumption handshake on the object.
921
 *
922
 * Client side only. User forced; use of secure renegotiation is discouraged.
923
 *
924
 * @param [in] ssl  SSL/TLS object.
925
 * @return  WOLFSSL_SUCCESS on success.
926
 * @return  BAD_FUNC_ARG when ssl is NULL.
927
 * @return  WOLFSSL_FATAL_ERROR when called on a server.
928
 */
929
int wolfSSL_SecureResume(WOLFSSL* ssl)
930
{
931
    WOLFSSL_ENTER("wolfSSL_SecureResume");
932
933
    if (ssl == NULL)
934
        return BAD_FUNC_ARG;
935
936
    if (ssl->options.side == WOLFSSL_SERVER_END) {
937
        ssl->error = SIDE_ERROR;
938
        return WOLFSSL_FATAL_ERROR;
939
    }
940
941
    return _Rehandshake(ssl);
942
}
943
944
#endif /* NO_WOLFSSL_CLIENT */
945
946
#endif /* HAVE_SECURE_RENEGOTIATION */
947
948
/* Get whether secure renegotiation is enabled for the object.
949
 *
950
 * @param [in] ssl  SSL/TLS object.
951
 * @return  1 when secure renegotiation is enabled.
952
 * @return  0 when ssl is NULL or it is not enabled.
953
 */
954
long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
955
0
{
956
0
    WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
957
958
0
    return (ssl != NULL) && (ssl->secure_renegotiation != NULL) &&
959
0
           ssl->secure_renegotiation->enabled;
960
0
}
961
962
#endif /* HAVE_SECURE_RENEGOTIATION_INFO */
963
964
#if !defined(NO_WOLFSSL_CLIENT) && !defined(WOLFSSL_NO_TLS12) && \
965
    defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_HARDEN_TLS_NO_SCR_CHECK)
966
/* Get whether the secure renegotiation check is enabled for the object.
967
 *
968
 * @param [in] ssl  SSL/TLS object.
969
 * @return  Non-zero when the check is enabled, 0 otherwise.
970
 * @return  BAD_FUNC_ARG when ssl is NULL.
971
 */
972
WOLFSSL_API int wolfSSL_get_scr_check_enabled(const WOLFSSL* ssl)
973
{
974
    WOLFSSL_ENTER("wolfSSL_get_scr_check_enabled");
975
976
    if (ssl == NULL)
977
        return BAD_FUNC_ARG;
978
979
    return ssl->scr_check_enabled;
980
}
981
982
/* Set whether the secure renegotiation check is enabled for the object.
983
 *
984
 * @param [in] ssl      SSL/TLS object.
985
 * @param [in] enabled  Non-zero to enable the check, 0 to disable it.
986
 * @return  WOLFSSL_SUCCESS on success.
987
 * @return  BAD_FUNC_ARG when ssl is NULL.
988
 */
989
WOLFSSL_API int wolfSSL_set_scr_check_enabled(WOLFSSL* ssl, byte enabled)
990
{
991
    WOLFSSL_ENTER("wolfSSL_set_scr_check_enabled");
992
993
    if (ssl == NULL)
994
        return BAD_FUNC_ARG;
995
996
    ssl->scr_check_enabled = !!enabled;
997
    return WOLFSSL_SUCCESS;
998
}
999
#endif
1000
1001
#if defined(HAVE_SESSION_TICKET)
1002
/* Session Ticket */
1003
1004
#if !defined(NO_WOLFSSL_SERVER)
1005
/* Disable use of session tickets with TLS 1.2 on the context.
1006
 *
1007
 * @param [in] ctx  SSL/TLS context object.
1008
 * @return  WOLFSSL_SUCCESS on success.
1009
 * @return  BAD_FUNC_ARG when ctx is NULL.
1010
 */
1011
int wolfSSL_CTX_NoTicketTLSv12(WOLFSSL_CTX* ctx)
1012
{
1013
    if (ctx == NULL)
1014
        return BAD_FUNC_ARG;
1015
1016
    ctx->noTicketTls12 = 1;
1017
1018
    return WOLFSSL_SUCCESS;
1019
}
1020
1021
/* Disable use of session tickets with TLS 1.2 on the object.
1022
 *
1023
 * @param [in] ssl  SSL/TLS object.
1024
 * @return  WOLFSSL_SUCCESS on success.
1025
 * @return  BAD_FUNC_ARG when ssl is NULL.
1026
 */
1027
int wolfSSL_NoTicketTLSv12(WOLFSSL* ssl)
1028
{
1029
    if (ssl == NULL)
1030
        return BAD_FUNC_ARG;
1031
1032
    ssl->options.noTicketTls12 = 1;
1033
1034
    return WOLFSSL_SUCCESS;
1035
}
1036
1037
/* Set the session ticket encryption callback on the context.
1038
 *
1039
 * @param [in] ctx  SSL/TLS context object.
1040
 * @param [in] cb   Session ticket encryption callback.
1041
 * @return  WOLFSSL_SUCCESS on success.
1042
 * @return  BAD_FUNC_ARG when ctx is NULL.
1043
 */
1044
int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
1045
{
1046
    if (ctx == NULL)
1047
        return BAD_FUNC_ARG;
1048
1049
    ctx->ticketEncCb = cb;
1050
1051
    return WOLFSSL_SUCCESS;
1052
}
1053
1054
/* Set the session ticket lifetime hint, in seconds, on the context.
1055
 *
1056
 * @param [in] ctx   SSL/TLS context object.
1057
 * @param [in] hint  Lifetime hint in seconds. No more than 604800 (7 days).
1058
 * @return  WOLFSSL_SUCCESS on success.
1059
 * @return  BAD_FUNC_ARG when ctx is NULL or hint is out of range.
1060
 */
1061
int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
1062
{
1063
    if (ctx == NULL)
1064
        return BAD_FUNC_ARG;
1065
1066
    /* RFC8446 Section 4.6.1: Servers MUST NOT use any value greater than
1067
     * 604800 seconds (7 days). */
1068
    if (hint < 0 || hint > 604800)
1069
        return BAD_FUNC_ARG;
1070
1071
    ctx->ticketHint = hint;
1072
1073
    return WOLFSSL_SUCCESS;
1074
}
1075
1076
/* Set the user context passed to the session ticket encryption callback.
1077
 *
1078
 * @param [in] ctx      SSL/TLS context object.
1079
 * @param [in] userCtx  User context for the ticket encryption callback.
1080
 * @return  WOLFSSL_SUCCESS on success.
1081
 * @return  BAD_FUNC_ARG when ctx is NULL.
1082
 */
1083
int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
1084
{
1085
    if (ctx == NULL)
1086
        return BAD_FUNC_ARG;
1087
1088
    ctx->ticketEncCtx = userCtx;
1089
1090
    return WOLFSSL_SUCCESS;
1091
}
1092
1093
/* Get the user context passed to the session ticket encryption callback.
1094
 *
1095
 * @param [in] ctx  SSL/TLS context object.
1096
 * @return  User context on success.
1097
 * @return  NULL when ctx is NULL.
1098
 */
1099
void* wolfSSL_CTX_get_TicketEncCtx(WOLFSSL_CTX* ctx)
1100
{
1101
    if (ctx == NULL)
1102
        return NULL;
1103
1104
    return ctx->ticketEncCtx;
1105
}
1106
1107
#ifdef WOLFSSL_TLS13
1108
/* Set the maximum number of TLS 1.3 session tickets to send.
1109
 *
1110
 * @param [in] ctx        SSL/TLS context object.
1111
 * @param [in] mxTickets  Maximum number of tickets to send.
1112
 * @return  WOLFSSL_SUCCESS on success.
1113
 * @return  WOLFSSL_FAILURE when ctx is NULL.
1114
 */
1115
int wolfSSL_CTX_set_num_tickets(WOLFSSL_CTX* ctx, size_t mxTickets)
1116
{
1117
    if (ctx == NULL)
1118
        return WOLFSSL_FAILURE;
1119
1120
    ctx->maxTicketTls13 = (unsigned int)mxTickets;
1121
    return WOLFSSL_SUCCESS;
1122
}
1123
1124
/* Get the maximum number of TLS 1.3 session tickets to send.
1125
 *
1126
 * @param [in] ctx  SSL/TLS context object.
1127
 * @return  Maximum number of tickets to send, or 0 when ctx is NULL.
1128
 */
1129
size_t wolfSSL_CTX_get_num_tickets(WOLFSSL_CTX* ctx)
1130
{
1131
    if (ctx == NULL)
1132
        return 0;
1133
1134
    return (size_t)ctx->maxTicketTls13;
1135
}
1136
#endif /* WOLFSSL_TLS13 */
1137
#endif /* !NO_WOLFSSL_SERVER */
1138
1139
#if !defined(NO_WOLFSSL_CLIENT)
1140
/* Enable use of the session ticket extension on the object.
1141
 *
1142
 * @param [in] ssl  SSL/TLS object.
1143
 * @return  WOLFSSL_SUCCESS on success.
1144
 * @return  BAD_FUNC_ARG when ssl is NULL.
1145
 * @return  Negative value on error.
1146
 */
1147
int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
1148
{
1149
    if (ssl == NULL)
1150
        return BAD_FUNC_ARG;
1151
1152
    return TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
1153
}
1154
1155
/* Enable use of the session ticket extension on the context.
1156
 *
1157
 * @param [in] ctx  SSL/TLS context object.
1158
 * @return  WOLFSSL_SUCCESS on success.
1159
 * @return  BAD_FUNC_ARG when ctx is NULL.
1160
 * @return  Negative value on error.
1161
 */
1162
int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
1163
{
1164
    if (ctx == NULL)
1165
        return BAD_FUNC_ARG;
1166
1167
    return TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
1168
}
1169
1170
/* Get the session ticket stored on the object.
1171
 *
1172
 * When buf is NULL and *bufSz is 0, the length required is returned in bufSz.
1173
 *
1174
 * @param [in]      ssl    SSL/TLS object.
1175
 * @param [out]     buf    Buffer to hold the ticket. May be NULL for length.
1176
 * @param [in, out] bufSz  In: size of buffer. Out: length of ticket.
1177
 * @return  WOLFSSL_SUCCESS on success.
1178
 * @return  LENGTH_ONLY_E when buf is NULL and bufSz has been set.
1179
 * @return  BAD_FUNC_ARG when ssl or bufSz is NULL.
1180
 */
1181
int wolfSSL_get_SessionTicket(WOLFSSL* ssl, byte* buf, word32* bufSz)
1182
{
1183
    if (ssl == NULL || bufSz == NULL)
1184
        return BAD_FUNC_ARG;
1185
1186
    if (*bufSz == 0 && buf == NULL) {
1187
        *bufSz = ssl->session->ticketLen;
1188
        return LENGTH_ONLY_E;
1189
    }
1190
1191
    if (buf == NULL)
1192
        return BAD_FUNC_ARG;
1193
1194
    if (ssl->session->ticketLen <= *bufSz) {
1195
        XMEMCPY(buf, ssl->session->ticket, ssl->session->ticketLen);
1196
        *bufSz = ssl->session->ticketLen;
1197
    }
1198
    else
1199
        *bufSz = 0;
1200
1201
    return WOLFSSL_SUCCESS;
1202
}
1203
1204
/* Set the session ticket to use on the object.
1205
 *
1206
 * @param [in] ssl    SSL/TLS object.
1207
 * @param [in] buf    Ticket data, may be NULL when bufSz is 0.
1208
 * @param [in] bufSz  Length of ticket data in bytes.
1209
 * @return  WOLFSSL_SUCCESS on success.
1210
 * @return  BAD_FUNC_ARG when ssl is NULL or buf is NULL with bufSz > 0.
1211
 * @return  MEMORY_ERROR on allocation failure.
1212
 */
1213
int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
1214
                                          word32 bufSz)
1215
{
1216
    if (ssl == NULL || (buf == NULL && bufSz > 0))
1217
        return BAD_FUNC_ARG;
1218
1219
    if (bufSz > 0) {
1220
        /* Ticket will fit into static ticket */
1221
        if (bufSz <= SESSION_TICKET_LEN) {
1222
            if (ssl->session->ticketLenAlloc > 0) {
1223
                XFREE(ssl->session->ticket, ssl->session->heap,
1224
                      DYNAMIC_TYPE_SESSION_TICK);
1225
                ssl->session->ticketLenAlloc = 0;
1226
                ssl->session->ticket = ssl->session->staticTicket;
1227
            }
1228
        }
1229
        else { /* Ticket requires dynamic ticket storage */
1230
            /* is dyn buffer big enough */
1231
            if (ssl->session->ticketLen < bufSz) {
1232
                if (ssl->session->ticketLenAlloc > 0) {
1233
                    XFREE(ssl->session->ticket, ssl->session->heap,
1234
                          DYNAMIC_TYPE_SESSION_TICK);
1235
                }
1236
                ssl->session->ticket = (byte*)XMALLOC(bufSz, ssl->session->heap,
1237
                        DYNAMIC_TYPE_SESSION_TICK);
1238
                if(ssl->session->ticket == NULL) {
1239
                    ssl->session->ticket = ssl->session->staticTicket;
1240
                    ssl->session->ticketLenAlloc = 0;
1241
                    return MEMORY_ERROR;
1242
                }
1243
                ssl->session->ticketLenAlloc = (word16)bufSz;
1244
            }
1245
        }
1246
        XMEMCPY(ssl->session->ticket, buf, bufSz);
1247
    }
1248
    ssl->session->ticketLen = (word16)bufSz;
1249
1250
    return WOLFSSL_SUCCESS;
1251
}
1252
1253
1254
/* Set the session ticket callback and user context on the object.
1255
 *
1256
 * @param [in] ssl  SSL/TLS object.
1257
 * @param [in] cb   Session ticket callback.
1258
 * @param [in] ctx  User context passed to the callback.
1259
 * @return  WOLFSSL_SUCCESS on success.
1260
 * @return  BAD_FUNC_ARG when ssl is NULL.
1261
 */
1262
int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
1263
                                 CallbackSessionTicket cb, void* ctx)
1264
{
1265
    if (ssl == NULL)
1266
        return BAD_FUNC_ARG;
1267
1268
    ssl->session_ticket_cb = cb;
1269
    ssl->session_ticket_ctx = ctx;
1270
1271
    return WOLFSSL_SUCCESS;
1272
}
1273
#endif /* !NO_WOLFSSL_CLIENT */
1274
1275
#endif /* HAVE_SESSION_TICKET */
1276
1277
1278
#ifdef HAVE_EXTENDED_MASTER
1279
#ifndef NO_WOLFSSL_CLIENT
1280
1281
/* Disable the Extended Master Secret extension on the context.
1282
 *
1283
 * @param [in] ctx  SSL/TLS context object.
1284
 * @return  WOLFSSL_SUCCESS on success.
1285
 * @return  BAD_FUNC_ARG when ctx is NULL.
1286
 */
1287
int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
1288
0
{
1289
0
    if (ctx == NULL)
1290
0
        return BAD_FUNC_ARG;
1291
1292
0
    ctx->haveEMS = 0;
1293
1294
0
    return WOLFSSL_SUCCESS;
1295
0
}
1296
1297
1298
/* Disable the Extended Master Secret extension on the object.
1299
 *
1300
 * @param [in] ssl  SSL/TLS object.
1301
 * @return  WOLFSSL_SUCCESS on success.
1302
 * @return  BAD_FUNC_ARG when ssl is NULL.
1303
 */
1304
int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
1305
0
{
1306
0
    if (ssl == NULL)
1307
0
        return BAD_FUNC_ARG;
1308
1309
0
    ssl->options.haveEMS = 0;
1310
1311
0
    return WOLFSSL_SUCCESS;
1312
0
}
1313
1314
#endif
1315
#endif
1316
1317
#endif /* !NO_TLS */
1318
/* ---- OpenSSL-compatibility TLS extension APIs (moved from ssl.c) ---- */
1319
1320
#ifdef OPENSSL_EXTRA
1321
1322
#ifdef HAVE_PK_CALLBACKS
1323
/* Set the debug argument passed to the logging callback on the object.
1324
 *
1325
 * @param [in] ssl  SSL/TLS object.
1326
 * @param [in] arg  Debug argument.
1327
 * @return  WOLFSSL_SUCCESS on success.
1328
 * @return  WOLFSSL_FAILURE when ssl is NULL.
1329
 */
1330
long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
1331
{
1332
    if (ssl == NULL) {
1333
        return WOLFSSL_FAILURE;
1334
    }
1335
1336
    ssl->loggingCtx = arg;
1337
    return WOLFSSL_SUCCESS;
1338
}
1339
#endif /* HAVE_PK_CALLBACKS */
1340
1341
#ifndef NO_WOLFSSL_STUB
1342
/* Get the certificate status request extensions on the object.
1343
 *
1344
 * Not implemented - stub for OpenSSL compatibility.
1345
 *
1346
 * @param [in] s    SSL/TLS object.
1347
 * @param [in] arg  Ignored.
1348
 * @return  WOLFSSL_FAILURE always.
1349
 */
1350
long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg)
1351
{
1352
    (void)s;
1353
    (void)arg;
1354
    WOLFSSL_STUB("wolfSSL_get_tlsext_status_exts");
1355
    return WOLFSSL_FAILURE;
1356
}
1357
#endif
1358
1359
/* Set the certificate status request extensions on the object.
1360
 *
1361
 * Not implemented - stub for OpenSSL compatibility.
1362
 *
1363
 * @param [in] s    SSL/TLS object.
1364
 * @param [in] arg  Ignored.
1365
 * @return  WOLFSSL_FAILURE always.
1366
 */
1367
#ifndef NO_WOLFSSL_STUB
1368
long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg)
1369
{
1370
    (void)s;
1371
    (void)arg;
1372
    WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts");
1373
    return WOLFSSL_FAILURE;
1374
}
1375
#endif
1376
1377
/* Get the certificate status request responder ids on the object.
1378
 *
1379
 * Not implemented - stub for OpenSSL compatibility.
1380
 *
1381
 * @param [in] s    SSL/TLS object.
1382
 * @param [in] arg  Ignored.
1383
 * @return  WOLFSSL_FAILURE always.
1384
 */
1385
#ifndef NO_WOLFSSL_STUB
1386
long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg)
1387
{
1388
    (void)s;
1389
    (void)arg;
1390
    WOLFSSL_STUB("wolfSSL_get_tlsext_status_ids");
1391
    return WOLFSSL_FAILURE;
1392
}
1393
#endif
1394
1395
/* Set the certificate status request responder ids on the object.
1396
 *
1397
 * Not implemented - stub for OpenSSL compatibility.
1398
 *
1399
 * @param [in] s    SSL/TLS object.
1400
 * @param [in] arg  Ignored.
1401
 * @return  WOLFSSL_FAILURE always.
1402
 */
1403
#ifndef NO_WOLFSSL_STUB
1404
long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg)
1405
{
1406
    (void)s;
1407
    (void)arg;
1408
    WOLFSSL_STUB("wolfSSL_set_tlsext_status_ids");
1409
    return WOLFSSL_FAILURE;
1410
}
1411
#endif
1412
1413
#ifdef HAVE_MAX_FRAGMENT
1414
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
1415
/* Set the Maximum Fragment Length extension on the context.
1416
 *
1417
 * @param [in] c     SSL/TLS context object.
1418
 * @param [in] mode  Maximum fragment length mode, e.g. WOLFSSL_MFL_2_9.
1419
 * @return  WOLFSSL_SUCCESS on success.
1420
 * @return  BAD_FUNC_ARG when c is NULL or mode is out of range.
1421
 */
1422
int wolfSSL_CTX_set_tlsext_max_fragment_length(WOLFSSL_CTX *c,
1423
                                               unsigned char mode)
1424
{
1425
    if (c == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
1426
        return BAD_FUNC_ARG;
1427
1428
    return wolfSSL_CTX_UseMaxFragment(c, mode);
1429
}
1430
/* Set the Maximum Fragment Length extension on the object.
1431
 *
1432
 * @param [in] s     SSL/TLS object.
1433
 * @param [in] mode  Maximum fragment length mode, e.g. WOLFSSL_MFL_2_9.
1434
 * @return  WOLFSSL_SUCCESS on success.
1435
 * @return  BAD_FUNC_ARG when s is NULL or mode is out of range.
1436
 */
1437
int wolfSSL_set_tlsext_max_fragment_length(WOLFSSL *s, unsigned char mode)
1438
{
1439
    if (s == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
1440
        return BAD_FUNC_ARG;
1441
1442
    return wolfSSL_UseMaxFragment(s, mode);
1443
}
1444
#endif /* !NO_WOLFSSL_CLIENT && !NO_TLS */
1445
#endif /* HAVE_MAX_FRAGMENT */
1446
1447
/* Set the signature algorithms list on the context.
1448
 *
1449
 * @param [in] ctx   SSL/TLS context object.
1450
 * @param [in] list  Colon-separated list of <public key>+<digest> algorithms.
1451
 * @return  WOLFSSL_SUCCESS on success.
1452
 * @return  WOLFSSL_FAILURE when ctx or list is NULL or on error.
1453
 */
1454
int wolfSSL_CTX_set1_sigalgs_list(WOLFSSL_CTX* ctx, const char* list)
1455
{
1456
    WOLFSSL_MSG("wolfSSL_CTX_set1_sigalg_list");
1457
1458
    if (ctx == NULL || list == NULL) {
1459
        WOLFSSL_MSG("Bad function arguments");
1460
        return WOLFSSL_FAILURE;
1461
    }
1462
1463
    if (AllocateCtxSuites(ctx) != 0)
1464
        return WOLFSSL_FAILURE;
1465
1466
    return SetSuitesHashSigAlgo(ctx->suites, list);
1467
}
1468
1469
/* Set the signature algorithms list on the object.
1470
 *
1471
 * @param [in] ssl   SSL/TLS object.
1472
 * @param [in] list  Colon-separated list of <public key>+<digest> algorithms.
1473
 * @return  WOLFSSL_SUCCESS on success.
1474
 * @return  WOLFSSL_FAILURE when ssl or list is NULL or on error.
1475
 */
1476
int wolfSSL_set1_sigalgs_list(WOLFSSL* ssl, const char* list)
1477
{
1478
    WOLFSSL_MSG("wolfSSL_set1_sigalg_list");
1479
1480
    if (ssl == NULL || list == NULL) {
1481
        WOLFSSL_MSG("Bad function arguments");
1482
        return WOLFSSL_FAILURE;
1483
    }
1484
1485
    if (AllocateSuites(ssl) != 0)
1486
        return WOLFSSL_FAILURE;
1487
1488
    return SetSuitesHashSigAlgo(ssl->suites, list);
1489
}
1490
1491
#ifdef HAVE_ECC
1492
1493
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
1494
/* Set the supported groups list, by name, on the context.
1495
 *
1496
 * @param [in] ctx   SSL/TLS context object.
1497
 * @param [in] list  Colon-separated list of group names.
1498
 * @return  WOLFSSL_SUCCESS on success.
1499
 * @return  WOLFSSL_FAILURE when ctx or list is NULL or on error.
1500
 */
1501
int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, const char *list)
1502
{
1503
    if (!ctx || !list) {
1504
        return WOLFSSL_FAILURE;
1505
    }
1506
1507
    return set_curves_list(NULL, ctx, list, 0);
1508
}
1509
1510
/* Set the supported groups list, by name, on the object.
1511
 *
1512
 * @param [in] ssl   SSL/TLS object.
1513
 * @param [in] list  Colon-separated list of group names.
1514
 * @return  WOLFSSL_SUCCESS on success.
1515
 * @return  WOLFSSL_FAILURE when ssl or list is NULL or on error.
1516
 */
1517
int wolfSSL_set1_groups_list(WOLFSSL *ssl, const char *list)
1518
{
1519
    if (!ssl || !list) {
1520
        return WOLFSSL_FAILURE;
1521
    }
1522
1523
    return set_curves_list(ssl, NULL, list, 0);
1524
}
1525
#endif /* WOLFSSL_TLS13 */
1526
1527
#endif /* HAVE_ECC */
1528
1529
#endif /* OPENSSL_EXTRA */
1530
1531
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
1532
1533
#ifdef HAVE_SNI
1534
/* Set the SNI host name extension on the object.
1535
 *
1536
 * @param [in] ssl        SSL/TLS object.
1537
 * @param [in] host_name  Host name string.
1538
 * @return  WOLFSSL_SUCCESS on success.
1539
 * @return  BAD_FUNC_ARG when ssl is NULL.
1540
 * @return  Negative value on error.
1541
 */
1542
int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
1543
{
1544
    int ret;
1545
    WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
1546
    ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, host_name,
1547
        (word16)XSTRLEN(host_name));
1548
    WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
1549
    return ret;
1550
}
1551
1552
#ifndef NO_WOLFSSL_SERVER
1553
/* Get the SNI host name requested for the object.
1554
 *
1555
 * May be called by a server to get the accepted name or by a client to get
1556
 * the requested name.
1557
 *
1558
 * @param [in] ssl   SSL/TLS object.
1559
 * @param [in] type  SNI type.
1560
 * @return  Requested server name on success.
1561
 * @return  NULL when ssl is NULL or no name is set.
1562
 */
1563
const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
1564
{
1565
    void * serverName = NULL;
1566
    if (ssl == NULL)
1567
        return NULL;
1568
    TLSX_SNI_GetRequest(ssl->extensions, type, &serverName,
1569
            !wolfSSL_is_server(ssl));
1570
    return (const char *)serverName;
1571
}
1572
#endif
1573
1574
#endif /* HAVE_SNI */
1575
1576
#ifdef HAVE_SNI
1577
/* Set the SNI receive callback on the context.
1578
 *
1579
 * Compatibility function; consider using wolfSSL_CTX_set_servername_callback().
1580
 *
1581
 * @param [in] ctx  SSL/TLS context object.
1582
 * @param [in] cb   SNI receive callback.
1583
 * @return  WOLFSSL_SUCCESS on success.
1584
 * @return  WOLFSSL_FAILURE when ctx is NULL.
1585
 */
1586
int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
1587
                                               CallbackSniRecv cb)
1588
{
1589
    WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
1590
    if (ctx) {
1591
        ctx->sniRecvCb = cb;
1592
        return WOLFSSL_SUCCESS;
1593
    }
1594
    return WOLFSSL_FAILURE;
1595
}
1596
1597
#endif /* HAVE_SNI */
1598
1599
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
1600
1601
#ifdef HAVE_SNI
1602
1603
/* Set the SNI receive callback on the context.
1604
 *
1605
 * @param [in] ctx  SSL/TLS context object.
1606
 * @param [in] cb   SNI receive callback.
1607
 */
1608
void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
1609
0
{
1610
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
1611
1612
0
    if (ctx != NULL) {
1613
0
        ctx->sniRecvCb = cb;
1614
0
    }
1615
0
}
1616
1617
1618
/* Set the user argument passed to the SNI receive callback on the context.
1619
 *
1620
 * @param [in] ctx  SSL/TLS context object.
1621
 * @param [in] arg  User argument for the SNI receive callback.
1622
 * @return  WOLFSSL_SUCCESS on success.
1623
 * @return  WOLFSSL_FAILURE when ctx is NULL.
1624
 */
1625
int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
1626
0
{
1627
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
1628
0
    if (ctx) {
1629
0
        ctx->sniRecvCbArg = arg;
1630
0
        return WOLFSSL_SUCCESS;
1631
0
    }
1632
0
    return WOLFSSL_FAILURE;
1633
0
}
1634
1635
#endif /* HAVE_SNI */
1636
1637
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
1638
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
1639
1640
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
1641
/* Expected return values from implementations of OpenSSL ticket key callback.
1642
 */
1643
#define TICKET_KEY_CB_RET_FAILURE    (-1)
1644
#define TICKET_KEY_CB_RET_NOT_FOUND   0
1645
#define TICKET_KEY_CB_RET_OK          1
1646
#define TICKET_KEY_CB_RET_RENEW       2
1647
1648
/* Encrypt the ticket data in place and compute the HMAC over it.
1649
 *
1650
 * @param [in]      evpCtx        Cipher context initialized by the callback.
1651
 * @param [in]      hmacCtx       HMAC context initialized by the callback.
1652
 * @param [in, out] encTicket     Ticket data, encrypted in place.
1653
 * @param [in]      encTicketLen  Length of the plaintext ticket data in bytes.
1654
 * @param [in]      encSz         Capacity of the ticket buffer in bytes.
1655
 * @param [out]     mac           HMAC of the encrypted data.
1656
 * @param [out]     outSz         Length of the encrypted data in bytes.
1657
 * @return  1 on success.
1658
 * @return  0 on error.
1659
 */
1660
static int wolfssl_ticket_key_enc(WOLFSSL_EVP_CIPHER_CTX* evpCtx,
1661
        WOLFSSL_HMAC_CTX* hmacCtx, unsigned char* encTicket, int encTicketLen,
1662
        int encSz, unsigned char* mac, int* outSz)
1663
{
1664
    int ret = 1;
1665
    int len = 0;
1666
    int totalSz = 0;
1667
    unsigned int mdSz = 0;
1668
1669
    /* Encrypt in place. */
1670
    if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len, encTicket,
1671
            encTicketLen)) {
1672
        ret = 0;
1673
    }
1674
    if (ret == 1) {
1675
        totalSz = len;
1676
        /* Encrypted data must fit in the output buffer. */
1677
        if (totalSz > encSz) {
1678
            ret = 0;
1679
        }
1680
    }
1681
    if ((ret == 1) &&
1682
            (!wolfSSL_EVP_EncryptFinal(evpCtx, &encTicket[len], &len))) {
1683
        ret = 0;
1684
    }
1685
    if (ret == 1) {
1686
        /* Total length of encrypted data. */
1687
        totalSz += len;
1688
        if (totalSz > encSz) {
1689
            ret = 0;
1690
        }
1691
    }
1692
    /* HMAC the encrypted data into the parameter 'mac'. */
1693
    if ((ret == 1) && (!wolfSSL_HMAC_Update(hmacCtx, encTicket, totalSz))) {
1694
        ret = 0;
1695
    }
1696
    if ((ret == 1) && (!wolfSSL_HMAC_Final(hmacCtx, mac, &mdSz))) {
1697
        ret = 0;
1698
    }
1699
    if (ret == 1) {
1700
        *outSz = totalSz;
1701
    }
1702
1703
    return ret;
1704
}
1705
1706
/* Verify the ticket HMAC then decrypt the ticket data in place.
1707
 *
1708
 * @param [in]      evpCtx        Cipher context initialized by the callback.
1709
 * @param [in]      hmacCtx       HMAC context initialized by the callback.
1710
 * @param [in, out] encTicket     Ticket data, decrypted in place.
1711
 * @param [in]      encTicketLen  Length of the encrypted ticket data in bytes.
1712
 * @param [in]      mac           Expected HMAC of the encrypted data.
1713
 * @param [out]     outSz         Length of the decrypted data in bytes.
1714
 * @return  1 on success.
1715
 * @return  0 on error or when the HMAC does not match.
1716
 */
1717
static int wolfssl_ticket_key_dec(WOLFSSL_EVP_CIPHER_CTX* evpCtx,
1718
        WOLFSSL_HMAC_CTX* hmacCtx, unsigned char* encTicket, int encTicketLen,
1719
        const unsigned char* mac, int* outSz)
1720
{
1721
    int ret = 1;
1722
    int len = 0;
1723
    int totalSz = 0;
1724
    unsigned int mdSz = 0;
1725
    byte digest[WC_MAX_DIGEST_SIZE];
1726
1727
    /* HMAC the encrypted data and compare it to the passed in data. */
1728
    if (!wolfSSL_HMAC_Update(hmacCtx, encTicket, encTicketLen)) {
1729
        ret = 0;
1730
    }
1731
    if ((ret == 1) && (!wolfSSL_HMAC_Final(hmacCtx, digest, &mdSz))) {
1732
        ret = 0;
1733
    }
1734
    if ((ret == 1) && (ConstantCompare(mac, digest, (int)mdSz) != 0)) {
1735
        ret = 0;
1736
    }
1737
    /* Decrypt the ticket data in place. */
1738
    if ((ret == 1) &&
1739
            (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len, encTicket,
1740
                encTicketLen))) {
1741
        ret = 0;
1742
    }
1743
    if (ret == 1) {
1744
        totalSz = len;
1745
        /* Decrypted data must fit in the buffer. */
1746
        if (totalSz > encTicketLen) {
1747
            ret = 0;
1748
        }
1749
    }
1750
    if ((ret == 1) &&
1751
            (!wolfSSL_EVP_DecryptFinal(evpCtx, &encTicket[len], &len))) {
1752
        ret = 0;
1753
    }
1754
    if (ret == 1) {
1755
        /* Total length of decrypted data. */
1756
        totalSz += len;
1757
        if (totalSz > encTicketLen) {
1758
            ret = 0;
1759
        }
1760
    }
1761
    if (ret == 1) {
1762
        *outSz = totalSz;
1763
    }
1764
1765
    return ret;
1766
}
1767
1768
/* Encrypt or decrypt a session ticket using the OpenSSL ticket key callback.
1769
 *
1770
 * Wraps the application's OpenSSL-style callback that initializes the cipher
1771
 * and HMAC.
1772
 *
1773
 * @param [in]      ssl           SSL/TLS object.
1774
 * @param [in]      keyName       Key name identifying the key to use.
1775
 * @param [in]      iv            IV to use.
1776
 * @param [in, out] mac          MAC of the encrypted data.
1777
 * @param [in]      enc           1 to encrypt the ticket, 0 to decrypt.
1778
 * @param [in, out] encTicket     Ticket data, encrypted/decrypted in place.
1779
 * @param [in]      encTicketLen  Length of the ticket data in bytes.
1780
 * @param [out]     encLen        Output length of the ticket data.
1781
 * @param [in]      ctx           Ignored. Application specific data.
1782
 * @return  WOLFSSL_TICKET_RET_OK on success.
1783
 * @return  WOLFSSL_TICKET_RET_CREATE when a new ticket is required.
1784
 * @return  WOLFSSL_TICKET_RET_FATAL on error.
1785
 */
1786
static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
1787
        unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
1788
        unsigned char iv[WOLFSSL_TICKET_IV_SZ],
1789
        unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
1790
        int enc, unsigned char* encTicket,
1791
        int encTicketLen, int* encLen, void* ctx)
1792
{
1793
    WC_DECLARE_VAR(evpCtx, WOLFSSL_EVP_CIPHER_CTX, 1, 0);
1794
    int ret = WOLFSSL_TICKET_RET_OK;
1795
1796
    (void)ctx;
1797
1798
    WOLFSSL_ENTER("wolfSSL_TicketKeyCb");
1799
1800
    if ((ssl == NULL) || (ssl->ctx == NULL) ||
1801
            (ssl->ctx->ticketEncWrapCb == NULL)) {
1802
        WOLFSSL_MSG("Bad parameter");
1803
        ret = WOLFSSL_TICKET_RET_FATAL;
1804
    }
1805
1806
#ifdef WOLFSSL_SMALL_STACK
1807
    if (ret == WOLFSSL_TICKET_RET_OK) {
1808
        evpCtx = (WOLFSSL_EVP_CIPHER_CTX *)XMALLOC(sizeof(*evpCtx), ssl->heap,
1809
            DYNAMIC_TYPE_TMP_BUFFER);
1810
        if (evpCtx == NULL) {
1811
            WOLFSSL_MSG("out of memory");
1812
            ret = WOLFSSL_TICKET_RET_FATAL;
1813
        }
1814
    }
1815
#endif
1816
1817
    if (ret == WOLFSSL_TICKET_RET_OK) {
1818
        WOLFSSL_HMAC_CTX hmacCtx;
1819
1820
        /* Initialize the cipher and HMAC. */
1821
        wolfSSL_EVP_CIPHER_CTX_init(evpCtx);
1822
1823
        if (wolfSSL_HMAC_CTX_Init(&hmacCtx) != WOLFSSL_SUCCESS) {
1824
            WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init error");
1825
            ret = WOLFSSL_TICKET_RET_FATAL;
1826
        }
1827
1828
        if (ret == WOLFSSL_TICKET_RET_OK) {
1829
            int res;
1830
            int totalSz = 0;
1831
1832
            res = ssl->ctx->ticketEncWrapCb(ssl, keyName, iv, evpCtx, &hmacCtx,
1833
                    enc);
1834
            if ((res != TICKET_KEY_CB_RET_OK) &&
1835
                    (res != TICKET_KEY_CB_RET_RENEW)) {
1836
                WOLFSSL_MSG("Ticket callback error");
1837
                ret = WOLFSSL_TICKET_RET_FATAL;
1838
            }
1839
1840
            if (ret == WOLFSSL_TICKET_RET_OK) {
1841
                if (wolfSSL_HMAC_size(&hmacCtx) > WOLFSSL_TICKET_MAC_SZ) {
1842
                    WOLFSSL_MSG("Ticket cipher MAC size error");
1843
                    ret = WOLFSSL_TICKET_RET_FATAL;
1844
                }
1845
            }
1846
1847
            if (ret == WOLFSSL_TICKET_RET_OK) {
1848
                if (enc) {
1849
                    if (!wolfssl_ticket_key_enc(evpCtx, &hmacCtx, encTicket,
1850
                            encTicketLen, *encLen, mac, &totalSz)) {
1851
                        ret = WOLFSSL_TICKET_RET_FATAL;
1852
                    }
1853
                }
1854
                else {
1855
                    if (!wolfssl_ticket_key_dec(evpCtx, &hmacCtx, encTicket,
1856
                            encTicketLen, mac, &totalSz)) {
1857
                        ret = WOLFSSL_TICKET_RET_FATAL;
1858
                    }
1859
                }
1860
            }
1861
1862
            if (ret == WOLFSSL_TICKET_RET_OK) {
1863
                *encLen = totalSz;
1864
1865
                if ((res == TICKET_KEY_CB_RET_RENEW) &&
1866
                        (!IsAtLeastTLSv1_3(ssl->version)) && (!enc)) {
1867
                    ret = WOLFSSL_TICKET_RET_CREATE;
1868
                }
1869
                else {
1870
                    ret = WOLFSSL_TICKET_RET_OK;
1871
                }
1872
            }
1873
1874
            (void)wc_HmacFree(&hmacCtx.hmac);
1875
        }
1876
        (void)wolfSSL_EVP_CIPHER_CTX_cleanup(evpCtx);
1877
        WC_FREE_VAR_EX(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1878
    }
1879
1880
    return ret;
1881
}
1882
1883
/* Set the OpenSSL-style session ticket key callback on the context.
1884
 *
1885
 * Installs a wrapper as the ticket encryption callback.
1886
 *
1887
 * @param [in] ctx  SSL/TLS context object.
1888
 * @param [in] cb   OpenSSL session ticket key callback.
1889
 * @return  WOLFSSL_SUCCESS on success.
1890
 */
1891
int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, ticketCompatCb cb)
1892
{
1893
1894
    /* Set the ticket encryption callback to be a wrapper around OpenSSL
1895
     * callback.
1896
     */
1897
    ctx->ticketEncCb = wolfSSL_TicketKeyCb;
1898
    ctx->ticketEncWrapCb = cb;
1899
1900
    return WOLFSSL_SUCCESS;
1901
}
1902
1903
#endif /* HAVE_SESSION_TICKET */
1904
1905
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
1906
    OPENSSL_EXTRA || HAVE_LIGHTY */
1907
1908
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
1909
    !defined(NO_WOLFSSL_SERVER)
1910
/* Serialize the session ticket encryption keys.
1911
 *
1912
 * @param [in]  ctx     SSL/TLS context object.
1913
 * @param [in]  keys    Buffer to hold session ticket keys.
1914
 * @param [in]  keylen  Length of buffer.
1915
 * @return  WOLFSSL_SUCCESS on success.
1916
 * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
1917
 *          correct length.
1918
 */
1919
long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
1920
     unsigned char *keys, int keylen)
1921
{
1922
    if (ctx == NULL || keys == NULL) {
1923
        return WOLFSSL_FAILURE;
1924
    }
1925
    if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
1926
        return WOLFSSL_FAILURE;
1927
    }
1928
1929
    XMEMCPY(keys, ctx->ticketKeyCtx.name, WOLFSSL_TICKET_NAME_SZ);
1930
    keys += WOLFSSL_TICKET_NAME_SZ;
1931
    XMEMCPY(keys, ctx->ticketKeyCtx.key[0], WOLFSSL_TICKET_KEY_SZ);
1932
    keys += WOLFSSL_TICKET_KEY_SZ;
1933
    XMEMCPY(keys, ctx->ticketKeyCtx.key[1], WOLFSSL_TICKET_KEY_SZ);
1934
    keys += WOLFSSL_TICKET_KEY_SZ;
1935
    c32toa(ctx->ticketKeyCtx.expirary[0], keys);
1936
    keys += OPAQUE32_LEN;
1937
    c32toa(ctx->ticketKeyCtx.expirary[1], keys);
1938
1939
    return WOLFSSL_SUCCESS;
1940
}
1941
1942
/* Deserialize the session ticket encryption keys.
1943
 *
1944
 * @param [in]  ctx     SSL/TLS context object.
1945
 * @param [in]  keys    Session ticket keys.
1946
 * @param [in]  keylen  Length of data.
1947
 * @return  WOLFSSL_SUCCESS on success.
1948
 * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
1949
 *          correct length.
1950
 */
1951
long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
1952
     const void *keys_vp, int keylen)
1953
{
1954
    const byte* keys = (const byte*)keys_vp;
1955
    if (ctx == NULL || keys == NULL) {
1956
        return WOLFSSL_FAILURE;
1957
    }
1958
    if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
1959
        return WOLFSSL_FAILURE;
1960
    }
1961
1962
    XMEMCPY(ctx->ticketKeyCtx.name, keys, WOLFSSL_TICKET_NAME_SZ);
1963
    keys += WOLFSSL_TICKET_NAME_SZ;
1964
    XMEMCPY(ctx->ticketKeyCtx.key[0], keys, WOLFSSL_TICKET_KEY_SZ);
1965
    keys += WOLFSSL_TICKET_KEY_SZ;
1966
    XMEMCPY(ctx->ticketKeyCtx.key[1], keys, WOLFSSL_TICKET_KEY_SZ);
1967
    keys += WOLFSSL_TICKET_KEY_SZ;
1968
    ato32(keys, &ctx->ticketKeyCtx.expirary[0]);
1969
    keys += OPAQUE32_LEN;
1970
    ato32(keys, &ctx->ticketKeyCtx.expirary[1]);
1971
1972
    return WOLFSSL_SUCCESS;
1973
}
1974
#endif
1975
1976
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
1977
    defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY) || \
1978
    defined(WOLFSSL_QUIC)
1979
#ifdef HAVE_ALPN
1980
/* Get the ALPN protocol selected for the object.
1981
 *
1982
 * @param [in]  ssl   SSL/TLS object.
1983
 * @param [out] data  Selected protocol data.
1984
 * @param [out] len   Length of the protocol data in bytes.
1985
 */
1986
void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
1987
                                unsigned int *len)
1988
{
1989
    word16 nameLen = 0;
1990
1991
    if ((ssl != NULL) && (data != NULL) && (len != NULL)) {
1992
        TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
1993
        *len = nameLen;
1994
    }
1995
}
1996
1997
/* Determine whether a protocol appears in the client's protocol list.
1998
 *
1999
 * The client's list is in wire format: each entry is a length byte followed
2000
 * by that many protocol-name bytes.
2001
 *
2002
 * @param [in]  proto        Protocol name to look for.
2003
 * @param [in]  protoLen     Length of the protocol name in bytes.
2004
 * @param [in]  clientNames  Client's protocol list.
2005
 * @param [in]  clientLen    Length of the client's list in bytes.
2006
 * @return  1 when the protocol is in the list.
2007
 * @return  0 when the protocol is not in the list.
2008
 */
2009
static int wolfssl_protocol_in_list(const unsigned char* proto, byte protoLen,
2010
    const unsigned char* clientNames, unsigned int clientLen)
2011
{
2012
    unsigned int j;
2013
    byte lenClient;
2014
    int found = 0;
2015
2016
    /* Compare against each of the client's length-prefixed names. */
2017
    for (j = 0; j < clientLen; j += lenClient) {
2018
        lenClient = clientNames[j++];
2019
        if ((lenClient == 0) || (j + lenClient > clientLen)) {
2020
            break;
2021
        }
2022
2023
        if ((protoLen == lenClient) &&
2024
                (XMEMCMP(proto, clientNames + j, protoLen) == 0)) {
2025
            found = 1;
2026
            break;
2027
        }
2028
    }
2029
2030
    return found;
2031
}
2032
2033
/* Select the next protocol from the peer's list that matches the client's.
2034
 *
2035
 * On no overlap, the first client protocol is selected.
2036
 *
2037
 * @param [out] out          Selected protocol data.
2038
 * @param [out] outLen        Length of the selected protocol in bytes.
2039
 * @param [in]  in            Peer's protocol list.
2040
 * @param [in]  inLen         Length of the peer's list in bytes.
2041
 * @param [in]  clientNames   Client's protocol list.
2042
 * @param [in]  clientLen     Length of the client's list in bytes.
2043
 * @return  WOLFSSL_NPN_NEGOTIATED when a match was found.
2044
 * @return  WOLFSSL_NPN_NO_OVERLAP when no match was found.
2045
 * @return  WOLFSSL_NPN_UNSUPPORTED when an argument is NULL.
2046
 */
2047
int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
2048
    const unsigned char *in, unsigned int inLen,
2049
    const unsigned char *clientNames, unsigned int clientLen)
2050
{
2051
    unsigned int i;
2052
    byte lenIn;
2053
    int ret = WOLFSSL_NPN_NO_OVERLAP;
2054
2055
    if ((out == NULL) || (outLen == NULL) || (in == NULL) ||
2056
            (clientNames == NULL)) {
2057
        ret = WOLFSSL_NPN_UNSUPPORTED;
2058
    }
2059
    else {
2060
        /* Walk the peer's list; each entry is a length byte then that many
2061
         * protocol-name bytes. */
2062
        for (i = 0; i < inLen; i += lenIn) {
2063
            lenIn = in[i++];
2064
            /* Stop on an empty entry or one that runs past the buffer. */
2065
            if ((lenIn == 0) || (i + lenIn > inLen)) {
2066
                break;
2067
            }
2068
            /* Select this peer protocol if the client also offered it. */
2069
            if (wolfssl_protocol_in_list(in + i, lenIn, clientNames,
2070
                    clientLen)) {
2071
                *out = (unsigned char *)(in + i);
2072
                *outLen = lenIn;
2073
                ret = WOLFSSL_NPN_NEGOTIATED;
2074
                break;
2075
            }
2076
        }
2077
2078
        if (ret != WOLFSSL_NPN_NEGOTIATED) {
2079
            /* No overlap: fall back to the client's first protocol. */
2080
            if ((clientLen > 0) &&
2081
                    ((unsigned int)clientNames[0] + 1 <= clientLen)) {
2082
                *out = (unsigned char *)clientNames + 1;
2083
                *outLen = clientNames[0];
2084
            }
2085
            else {
2086
                *out = (unsigned char *)clientNames;
2087
                *outLen = 0;
2088
            }
2089
            ret = WOLFSSL_NPN_NO_OVERLAP;
2090
        }
2091
    }
2092
2093
    return ret;
2094
}
2095
2096
/* Set the ALPN selection callback on the object.
2097
 *
2098
 * @param [in] ssl  SSL/TLS object.
2099
 * @param [in] cb   ALPN selection callback.
2100
 * @param [in] arg  User argument passed to the callback.
2101
 */
2102
void wolfSSL_set_alpn_select_cb(WOLFSSL *ssl,
2103
    int (*cb)(WOLFSSL *ssl, const unsigned char **out, unsigned char *outlen,
2104
              const unsigned char *in, unsigned int inlen, void *arg),
2105
    void *arg)
2106
{
2107
    if (ssl != NULL) {
2108
        ssl->alpnSelect = cb;
2109
        ssl->alpnSelectArg = arg;
2110
    }
2111
}
2112
2113
/* Set the ALPN selection callback on the context.
2114
 *
2115
 * @param [in] ctx  SSL/TLS context object.
2116
 * @param [in] cb   ALPN selection callback.
2117
 * @param [in] arg  User argument passed to the callback.
2118
 */
2119
void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
2120
    int (*cb)(WOLFSSL *ssl, const unsigned char **out, unsigned char *outlen,
2121
              const unsigned char *in, unsigned int inlen, void *arg),
2122
    void *arg)
2123
{
2124
    if (ctx != NULL) {
2125
        ctx->alpnSelect = cb;
2126
        ctx->alpnSelectArg = arg;
2127
    }
2128
}
2129
2130
/* Set the NPN advertised-protocols callback on the context.
2131
 *
2132
 * Not implemented - stub for OpenSSL compatibility.
2133
 *
2134
 * @param [in] s    SSL/TLS context object.
2135
 * @param [in] cb   NPN advertised-protocols callback.
2136
 * @param [in] arg  User argument passed to the callback.
2137
 */
2138
void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s,
2139
    int (*cb)(WOLFSSL *ssl, const unsigned char **out, unsigned int *outlen,
2140
              void *arg), void *arg)
2141
{
2142
    (void)s;
2143
    (void)cb;
2144
    (void)arg;
2145
    WOLFSSL_STUB("wolfSSL_CTX_set_next_protos_advertised_cb");
2146
}
2147
2148
/* Set the NPN protocol-selection callback on the context.
2149
 *
2150
 * Not implemented - stub for OpenSSL compatibility.
2151
 *
2152
 * @param [in] s    SSL/TLS context object.
2153
 * @param [in] cb   NPN protocol-selection callback.
2154
 * @param [in] arg  User argument passed to the callback.
2155
 */
2156
void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s,
2157
    int (*cb)(WOLFSSL *ssl, unsigned char **out, unsigned char *outlen,
2158
              const unsigned char *in, unsigned int inlen, void *arg),
2159
    void *arg)
2160
{
2161
    (void)s;
2162
    (void)cb;
2163
    (void)arg;
2164
    WOLFSSL_STUB("wolfSSL_CTX_set_next_proto_select_cb");
2165
}
2166
2167
/* Get the NPN protocol negotiated for the object.
2168
 *
2169
 * Not implemented - stub for OpenSSL compatibility.
2170
 *
2171
 * @param [in]  s     SSL/TLS object.
2172
 * @param [out] data  Negotiated protocol data.
2173
 * @param [out] len   Length of the protocol data in bytes.
2174
 */
2175
void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s,
2176
    const unsigned char **data, unsigned *len)
2177
{
2178
    (void)s;
2179
    (void)data;
2180
    (void)len;
2181
    WOLFSSL_STUB("wolfSSL_get0_next_proto_negotiated");
2182
}
2183
#endif /* HAVE_ALPN */
2184
2185
#endif /* WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
2186
2187
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
2188
2189
/* Determine whether an elliptic curve is disabled for the object.
2190
 *
2191
 * @param [in] ssl       SSL/TLS object.
2192
 * @param [in] curve_id  Curve identifier.
2193
 * @return  1 when the curve is disabled or out of range.
2194
 * @return  0 when the curve is enabled or is an FFDHE group.
2195
 */
2196
int wolfSSL_curve_is_disabled(const WOLFSSL* ssl, word16 curve_id)
2197
{
2198
    int ret = 0;
2199
2200
    WOLFSSL_ENTER("wolfSSL_curve_is_disabled");
2201
    WOLFSSL_MSG_EX("wolfSSL_curve_is_disabled checking for %d", curve_id);
2202
2203
    /* (curve_id >= WOLFSSL_FFDHE_START) - DH parameters are never disabled. */
2204
    if (curve_id < WOLFSSL_FFDHE_START) {
2205
        if (curve_id > WOLFSSL_ECC_MAX_AVAIL) {
2206
            WOLFSSL_MSG("Curve id out of supported range");
2207
            /* Disabled if not in valid range. */
2208
            ret = 1;
2209
        }
2210
        else if (curve_id >= 32) {
2211
            /* 0 is for invalid and 1-14 aren't used otherwise. */
2212
            ret = (ssl->disabledCurves & (1U << (curve_id - 32))) != 0;
2213
        }
2214
        else {
2215
            ret = (ssl->disabledCurves & (1U << curve_id)) != 0;
2216
        }
2217
    }
2218
2219
    WOLFSSL_LEAVE("wolfSSL_curve_is_disabled", ret);
2220
    return ret;
2221
}
2222
2223
#if (defined(HAVE_ECC) || \
2224
    defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))
2225
2226
/* Set the supported curves list, by name, on the context.
2227
 *
2228
 * @param [in] ctx    SSL/TLS context object.
2229
 * @param [in] names  Colon-separated list of curve names.
2230
 * @return  WOLFSSL_SUCCESS on success.
2231
 * @return  WOLFSSL_FAILURE when ctx or names is NULL or on error.
2232
 */
2233
int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
2234
{
2235
    WOLFSSL_ENTER("wolfSSL_CTX_set1_curves_list");
2236
    if (ctx == NULL || names == NULL) {
2237
        WOLFSSL_MSG("ctx or names was NULL");
2238
        return WOLFSSL_FAILURE;
2239
    }
2240
    return set_curves_list(NULL, ctx, names, 1);
2241
}
2242
2243
/* Set the supported curves list, by name, on the object.
2244
 *
2245
 * @param [in] ssl    SSL/TLS object.
2246
 * @param [in] names  Colon-separated list of curve names.
2247
 * @return  WOLFSSL_SUCCESS on success.
2248
 * @return  WOLFSSL_FAILURE when ssl or names is NULL or on error.
2249
 */
2250
int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
2251
{
2252
    WOLFSSL_ENTER("wolfSSL_set1_curves_list");
2253
    if (ssl == NULL || names == NULL) {
2254
        WOLFSSL_MSG("ssl or names was NULL");
2255
        return WOLFSSL_FAILURE;
2256
    }
2257
    return set_curves_list(ssl, NULL, names, 1);
2258
}
2259
2260
#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
2261
#endif /* OPENSSL_EXTRA || HAVE_CURL */
2262
2263
#ifdef OPENSSL_EXTRA
2264
2265
/* Set the ALPN protocol list, in wire format, on the context.
2266
 *
2267
 * @param [in] ctx    SSL/TLS context object.
2268
 * @param [in] p      ALPN protocol list in wire format (length-prefixed).
2269
 * @param [in] p_len  Length of the protocol list in bytes.
2270
 * @return  WOLFSSL_SUCCESS (or 0 with WOLFSSL_ERROR_CODE_OPENSSL) on success.
2271
 * @return  BAD_FUNC_ARG when ctx or p is NULL.
2272
 * @return  WOLFSSL_FAILURE (or 1 with WOLFSSL_ERROR_CODE_OPENSSL) on error.
2273
 */
2274
int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p,
2275
                            unsigned int p_len)
2276
{
2277
    WOLFSSL_ENTER("wolfSSL_CTX_set_alpn_protos");
2278
    if (ctx == NULL || p == NULL)
2279
        return BAD_FUNC_ARG;
2280
    if (ctx->alpn_cli_protos != NULL) {
2281
        XFREE((void*)ctx->alpn_cli_protos, ctx->heap, DYNAMIC_TYPE_OPENSSL);
2282
    }
2283
2284
    ctx->alpn_cli_protos = (const unsigned char*)XMALLOC(p_len,
2285
        ctx->heap, DYNAMIC_TYPE_OPENSSL);
2286
    if (ctx->alpn_cli_protos == NULL) {
2287
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
2288
        /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
2289
         * the function reverses the return value convention.
2290
         */
2291
        return 1;
2292
#else
2293
        return WOLFSSL_FAILURE;
2294
#endif
2295
    }
2296
    XMEMCPY((void*)ctx->alpn_cli_protos, p, p_len);
2297
    ctx->alpn_cli_protos_len = p_len;
2298
2299
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
2300
    /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
2301
     * the function reverses the return value convention.
2302
     */
2303
    return 0;
2304
#else
2305
    return WOLFSSL_SUCCESS;
2306
#endif
2307
}
2308
2309
2310
#ifdef HAVE_ALPN
2311
#ifndef NO_BIO
2312
/* Convert a wire-format ALPN protocol list into a comma-separated string.
2313
 *
2314
 * The wire format is a sequence of entries, each a length byte followed by
2315
 * that many protocol-name bytes.
2316
 *
2317
 * @param [in]  p      ALPN protocol list in wire format.
2318
 * @param [in]  p_len  Length of the protocol list in bytes.
2319
 * @param [out] pt     Buffer to hold the comma-separated list. Must hold at
2320
 *                     least p_len bytes.
2321
 * @param [out] ptLen  Length of the comma-separated list written.
2322
 * @return  1 on success.
2323
 * @return  0 when the wire format is invalid.
2324
 */
2325
static int wolfssl_alpn_protos_to_list(const unsigned char* p,
2326
    unsigned int p_len, char* pt, unsigned int* ptLen)
2327
{
2328
    unsigned int idx = 0;
2329
    unsigned int ptIdx = 0;
2330
    unsigned int sz;
2331
    int ret = 1;
2332
2333
    /* Convert into a comma separated list. */
2334
    while (idx < p_len - 1) {
2335
        unsigned int i;
2336
2337
        sz = p[idx++];
2338
        if (idx + sz > p_len) {
2339
            WOLFSSL_MSG("Bad list format");
2340
            ret = 0;
2341
            break;
2342
        }
2343
        if (sz > 0) {
2344
            for (i = 0; i < sz; i++) {
2345
                pt[ptIdx++] = p[idx++];
2346
            }
2347
            if (idx < p_len - 1) {
2348
                pt[ptIdx++] = ',';
2349
            }
2350
        }
2351
    }
2352
2353
    if (ret == 1) {
2354
        *ptLen = ptIdx;
2355
    }
2356
2357
    return ret;
2358
}
2359
2360
/* Set the ALPN protocol list, in wire format, on the object.
2361
 *
2362
 * The list is length-prefixed, e.g.
2363
 *     unsigned char p[] = { 8, 'h','t','t','p','/','1','.','1' };
2364
 *
2365
 * @param [in] ssl    SSL/TLS object.
2366
 * @param [in] p      ALPN protocol list in wire format (length-prefixed).
2367
 * @param [in] p_len  Length of the protocol list in bytes.
2368
 * @return  WOLFSSL_SUCCESS (or 0 with WOLFSSL_ERROR_CODE_OPENSSL) on success.
2369
 * @return  WOLFSSL_FAILURE (or 1 with WOLFSSL_ERROR_CODE_OPENSSL) on error.
2370
 */
2371
int wolfSSL_set_alpn_protos(WOLFSSL* ssl,
2372
        const unsigned char* p, unsigned int p_len)
2373
{
2374
    char* pt = NULL;
2375
    unsigned int ptIdx = 0;
2376
    /* RFC 7301: a server that does not select any of the client's offered
2377
     * protocols MUST send no_application_protocol. Match that contract on
2378
     * the OpenSSL-compat surface rather than silently continuing. */
2379
    int alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
2380
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
2381
    int ret = 1;
2382
#else
2383
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
2384
#endif
2385
2386
    WOLFSSL_ENTER("wolfSSL_set_alpn_protos");
2387
2388
    if ((ssl != NULL) && (p_len > 1) && (p != NULL)) {
2389
        /* Replacing leading number with trailing ',' and adding '\0'. */
2390
        pt = (char*)XMALLOC(p_len + 1, ssl->heap, DYNAMIC_TYPE_OPENSSL);
2391
        if (pt != NULL) {
2392
            if (wolfssl_alpn_protos_to_list(p, p_len, pt, &ptIdx)) {
2393
                pt[ptIdx++] = '\0';
2394
2395
                /* Clear out all currently set ALPN extensions. */
2396
                TLSX_Remove(&ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL,
2397
                    ssl->heap);
2398
2399
                if (wolfSSL_UseALPN(ssl, pt, ptIdx, (byte)alpn_opt) ==
2400
                        WOLFSSL_SUCCESS) {
2401
                #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
2402
                    ret = 0;
2403
                #else
2404
                    ret = WOLFSSL_SUCCESS;
2405
                #endif
2406
                }
2407
            }
2408
2409
            XFREE(pt, ssl->heap, DYNAMIC_TYPE_OPENSSL);
2410
        }
2411
    }
2412
2413
    return ret;
2414
}
2415
#endif /* !NO_BIO */
2416
#endif /* HAVE_ALPN */
2417
2418
#endif /* OPENSSL_EXTRA */
2419
2420
#endif /* !WOLFCRYPT_ONLY */
2421
2422
#endif /* !WOLFSSL_SSL_API_EXT_INCLUDED */