Coverage Report

Created: 2026-11-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-heapmath/src/ssl_api_pk.c
Line
Count
Source
1
/* ssl_api_pk.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_PK_INCLUDED)
25
    #ifndef WOLFSSL_IGNORE_FILE_WARN
26
        #warning ssl_api_pk.c is not compiled separately from ssl.c
27
    #endif
28
#else
29
30
#ifndef NO_CERTS
31
32
#ifndef NO_CHECK_PRIVATE_KEY
33
34
#ifdef WOLF_PRIVATE_KEY_ID
35
/* Check priv against pub for match using external device with given devId
36
 *
37
 * @param [in] keyOID   Public key OID.
38
 * @param [in] privKey  Private key data.
39
 * @param [in] privSz   Length of private key data in bytes.
40
 * @param [in] pubKey   Public key data.
41
 * @param [in] pubSz    Length of public key data in bytes.
42
 * @param [in] label    Key data is a hardware label.
43
 * @param [in] id       Key data is a hardware id.
44
 * @param [in] heap     Heap hint for dynamic memory allocation.
45
 * @param [in] devId    Device Id.
46
 * @return  0 on success.
47
 * @return  MISSING_KEY when privKey is NULL.
48
 * @return  Other negative value on error.
49
 */
50
static int check_cert_key_dev(word32 keyOID, byte* privKey, word32 privSz,
51
    const byte* pubKey, word32 pubSz, int label, int id, void* heap, int devId)
52
0
{
53
0
    int ret = 0;
54
0
    int type = 0;
55
0
    int slhParam = -1;
56
0
    void *pkey = NULL;
57
58
0
    if (privKey == NULL) {
59
0
        ret = MISSING_KEY;
60
0
    }
61
0
    else {
62
0
        switch (keyOID) {
63
0
    #ifndef NO_RSA
64
0
            case RSAk:
65
0
        #ifdef WC_RSA_PSS
66
0
            case RSAPSSk:
67
0
        #endif
68
0
                type = DYNAMIC_TYPE_RSA;
69
0
                break;
70
0
    #endif
71
0
        #ifdef HAVE_ECC
72
0
            case ECDSAk:
73
0
                type = DYNAMIC_TYPE_ECC;
74
0
                break;
75
0
        #endif
76
0
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && \
77
0
        defined(ED25519_MAX_ID_LEN)
78
0
            case ED25519k:
79
0
                type = DYNAMIC_TYPE_ED25519;
80
0
                break;
81
0
    #endif
82
0
    #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && \
83
0
        defined(ED448_MAX_ID_LEN)
84
0
            case ED448k:
85
0
                type = DYNAMIC_TYPE_ED448;
86
0
                break;
87
0
    #endif
88
    #if defined(WOLFSSL_HAVE_MLDSA)
89
            case ML_DSA_44k:
90
            case ML_DSA_65k:
91
            case ML_DSA_87k:
92
        #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
93
            case DILITHIUM_LEVEL2k:
94
            case DILITHIUM_LEVEL3k:
95
            case DILITHIUM_LEVEL5k:
96
        #endif
97
                type = DYNAMIC_TYPE_MLDSA;
98
                break;
99
    #endif
100
    #if defined(HAVE_FALCON)
101
            case FALCON_LEVEL1k:
102
            case FALCON_LEVEL5k:
103
                type = DYNAMIC_TYPE_FALCON;
104
                break;
105
    #endif
106
    #if defined(WOLFSSL_HAVE_SLHDSA)
107
            case SLH_DSA_SHA2_128Sk:
108
            case SLH_DSA_SHA2_128Fk:
109
            case SLH_DSA_SHA2_192Sk:
110
            case SLH_DSA_SHA2_192Fk:
111
            case SLH_DSA_SHA2_256Sk:
112
            case SLH_DSA_SHA2_256Fk:
113
            case SLH_DSA_SHAKE_128Sk:
114
            case SLH_DSA_SHAKE_128Fk:
115
            case SLH_DSA_SHAKE_192Sk:
116
            case SLH_DSA_SHAKE_192Fk:
117
            case SLH_DSA_SHAKE_256Sk:
118
            case SLH_DSA_SHAKE_256Fk:
119
                type = DYNAMIC_TYPE_SLHDSA;
120
                slhParam = wc_SlhDsaOidToParam((int)keyOID);
121
                if (slhParam < 0) {
122
                    ret = ALGO_ID_E;
123
                }
124
                break;
125
    #endif
126
0
        }
127
128
0
        if (ret == 0) {
129
0
            ret = CreateDevPrivateKey(&pkey, privKey, privSz, type, label, id,
130
0
                heap, devId, slhParam);
131
0
        }
132
0
    }
133
0
#ifdef WOLF_CRYPTO_CB
134
0
    if (ret == 0) {
135
0
        switch (keyOID) {
136
0
    #ifndef NO_RSA
137
0
            case RSAk:
138
0
        #ifdef WC_RSA_PSS
139
0
            case RSAPSSk:
140
0
        #endif
141
0
                ret = wc_CryptoCb_RsaCheckPrivKey((RsaKey*)pkey, pubKey, pubSz);
142
0
                break;
143
0
    #endif
144
0
    #ifdef HAVE_ECC
145
0
            case ECDSAk:
146
0
                ret = wc_CryptoCb_EccCheckPrivKey((ecc_key*)pkey, pubKey,
147
0
                    pubSz);
148
0
                break;
149
0
    #endif
150
0
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && \
151
0
        defined(ED25519_MAX_ID_LEN)
152
            /* Not wc_ed*_check_key: its software fallback skips the device
153
             * private key. */
154
0
            case ED25519k:
155
0
                ret = wc_ed25519_import_public_ex(pubKey, pubSz,
156
0
                    (ed25519_key*)pkey, 1);
157
0
                if (ret == 0) {
158
0
                    ret = wc_CryptoCb_Ed25519CheckKey((ed25519_key*)pkey);
159
0
                }
160
0
                break;
161
0
    #endif
162
0
    #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && \
163
0
        defined(ED448_MAX_ID_LEN)
164
0
            case ED448k:
165
0
                ret = wc_ed448_import_public_ex(pubKey, pubSz,
166
0
                    (ed448_key*)pkey, 1);
167
0
                if (ret == 0) {
168
0
                    ret = wc_CryptoCb_Ed448CheckKey((ed448_key*)pkey);
169
0
                }
170
0
                break;
171
0
    #endif
172
    #if defined(WOLFSSL_HAVE_MLDSA)
173
            case ML_DSA_44k:
174
            case ML_DSA_65k:
175
            case ML_DSA_87k:
176
        #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
177
            case DILITHIUM_LEVEL2k:
178
            case DILITHIUM_LEVEL3k:
179
            case DILITHIUM_LEVEL5k:
180
        #endif
181
                ret = wc_CryptoCb_PqcSignatureCheckPrivKey(pkey,
182
                    WC_PQC_SIG_TYPE_MLDSA, pubKey, pubSz);
183
                break;
184
    #endif
185
    #if defined(HAVE_FALCON)
186
            case FALCON_LEVEL1k:
187
            case FALCON_LEVEL5k:
188
                ret = wc_CryptoCb_PqcSignatureCheckPrivKey(pkey,
189
                    WC_PQC_SIG_TYPE_FALCON, pubKey, pubSz);
190
                break;
191
    #endif
192
    #if defined(WOLFSSL_HAVE_SLHDSA)
193
            case SLH_DSA_SHA2_128Sk:
194
            case SLH_DSA_SHA2_128Fk:
195
            case SLH_DSA_SHA2_192Sk:
196
            case SLH_DSA_SHA2_192Fk:
197
            case SLH_DSA_SHA2_256Sk:
198
            case SLH_DSA_SHA2_256Fk:
199
            case SLH_DSA_SHAKE_128Sk:
200
            case SLH_DSA_SHAKE_128Fk:
201
            case SLH_DSA_SHAKE_192Sk:
202
            case SLH_DSA_SHAKE_192Fk:
203
            case SLH_DSA_SHAKE_256Sk:
204
            case SLH_DSA_SHAKE_256Fk:
205
                ret = wc_CryptoCb_PqcSignatureCheckPrivKey(pkey,
206
                    WC_PQC_SIG_TYPE_SLHDSA, pubKey, pubSz);
207
                break;
208
    #endif
209
0
            default:
210
0
                ret = 0;
211
0
        }
212
0
    }
213
#else
214
    /* devId was set, so don't check for now. */
215
    /* TODO: Add callback for private key check? */
216
    (void) pubKey;
217
    (void) pubSz;
218
#endif
219
220
0
    switch (keyOID) {
221
0
    #ifndef NO_RSA
222
0
        case RSAk:
223
0
        #ifdef WC_RSA_PSS
224
0
        case RSAPSSk:
225
0
        #endif
226
0
            wc_FreeRsaKey((RsaKey*)pkey);
227
0
            break;
228
0
    #endif
229
0
    #ifdef HAVE_ECC
230
0
        case ECDSAk:
231
0
            wc_ecc_free((ecc_key*)pkey);
232
0
            break;
233
0
    #endif
234
0
    #ifdef HAVE_ED25519
235
0
        case ED25519k:
236
0
            wc_ed25519_free((ed25519_key*)pkey);
237
0
            break;
238
0
    #endif
239
0
    #ifdef HAVE_ED448
240
0
        case ED448k:
241
0
            wc_ed448_free((ed448_key*)pkey);
242
0
            break;
243
0
    #endif
244
    #if defined(WOLFSSL_HAVE_MLDSA)
245
        case ML_DSA_44k:
246
        case ML_DSA_65k:
247
        case ML_DSA_87k:
248
        #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
249
        case DILITHIUM_LEVEL2k:
250
        case DILITHIUM_LEVEL3k:
251
        case DILITHIUM_LEVEL5k:
252
        #endif
253
            wc_MlDsaKey_Free((wc_MlDsaKey*)pkey);
254
            break;
255
    #endif
256
    #if defined(HAVE_FALCON)
257
        case FALCON_LEVEL1k:
258
        case FALCON_LEVEL5k:
259
            wc_falcon_free((falcon_key*)pkey);
260
            break;
261
    #endif
262
    #if defined(WOLFSSL_HAVE_SLHDSA)
263
        case SLH_DSA_SHA2_128Sk:
264
        case SLH_DSA_SHA2_128Fk:
265
        case SLH_DSA_SHA2_192Sk:
266
        case SLH_DSA_SHA2_192Fk:
267
        case SLH_DSA_SHA2_256Sk:
268
        case SLH_DSA_SHA2_256Fk:
269
        case SLH_DSA_SHAKE_128Sk:
270
        case SLH_DSA_SHAKE_128Fk:
271
        case SLH_DSA_SHAKE_192Sk:
272
        case SLH_DSA_SHAKE_192Fk:
273
        case SLH_DSA_SHAKE_256Sk:
274
        case SLH_DSA_SHAKE_256Fk:
275
            wc_SlhDsaKey_Free((SlhDsaKey*)pkey);
276
            break;
277
    #endif
278
0
        default:
279
0
            WC_DO_NOTHING;
280
0
    }
281
0
    XFREE(pkey, heap, type);
282
283
0
    return ret;
284
0
}
285
#endif /* WOLF_PRIVATE_KEY_ID */
286
287
/* Check private against public in certificate for match.
288
 *
289
 * @param [in] cert           DER encoded certificate.
290
 * @param [in] key            DER encoded private key.
291
 * @param [in] altKey         Alternative DER encoded key.
292
 * @param [in] heap           Heap hint for dynamic memory allocation.
293
 * @param [in] devId          Device Id.
294
 * @param [in] isKeyLabel     Whether key is label.
295
 * @param [in] isKeyId        Whether key is an id.
296
 * @param [in] altDevId       Alternative key's device id.
297
 * @param [in] isAltKeyLabel  Is alternative key a label.
298
 * @param [in] isAltKeyId     Is alternative key an id.
299
 * @return  1 on success.
300
 * @return  0 on failure.
301
 * @return  MEMORY_E when memory allocation fails.
302
 */
303
static int check_cert_key(const DerBuffer* cert, const DerBuffer* key,
304
    const DerBuffer* altKey, void* heap, int devId, int isKeyLabel, int isKeyId,
305
    int altDevId, int isAltKeyLabel, int isAltKeyId)
306
0
{
307
0
    WC_DECLARE_VAR(der, DecodedCert, 1, 0);
308
0
    word32 size;
309
0
    byte*  buff;
310
0
    int    ret = 1;
311
312
0
    WOLFSSL_ENTER("check_cert_key");
313
314
    /* Validate parameters. */
315
0
    if ((cert == NULL) || (key == NULL)) {
316
0
        return 0;
317
0
    }
318
0
    if (ret == 1) {
319
        /* Make a decoded certificate object available. */
320
0
        WC_ALLOC_VAR_EX(der, DecodedCert, 1, heap, DYNAMIC_TYPE_DCERT,
321
0
            return MEMORY_E);
322
0
    }
323
324
0
    if (ret == 1) {
325
        /* Decode certificate. */
326
0
        InitDecodedCert_ex(der, cert->buffer, cert->length, heap, devId);
327
        /* Parse certificate. */
328
0
        if (ParseCertRelative(der, CERT_TYPE, NO_VERIFY, NULL, NULL) != 0) {
329
0
            ret = 0;
330
0
        }
331
0
     }
332
333
0
     if (ret == 1) {
334
0
        buff = key->buffer;
335
0
        size = key->length;
336
0
    #ifdef WOLF_PRIVATE_KEY_ID
337
0
        if (devId != INVALID_DEVID) {
338
0
            ret = check_cert_key_dev(der->keyOID, buff, size, der->publicKey,
339
0
                der->pubKeySize, isKeyLabel, isKeyId, heap, devId);
340
0
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
341
0
                ret = (ret == 0) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE;
342
0
            }
343
0
        }
344
0
        else {
345
            /* Fall through if unavailable. */
346
0
            ret = CRYPTOCB_UNAVAILABLE;
347
0
        }
348
349
0
        if (ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
350
0
    #endif /* WOLF_PRIVATE_KEY_ID */
351
0
        {
352
0
            ret = wc_CheckPrivateKeyCert(buff, size, der, 0, heap);
353
0
            if (ret != 1) {
354
0
                ret = 0;
355
0
            }
356
0
        }
357
358
    #ifdef WOLFSSL_DUAL_ALG_CERTS
359
        if ((ret == 1) && der->extSapkiSet && (der->sapkiDer != NULL)) {
360
            /* Certificate contains an alternative public key. Hence, we also
361
             * need an alternative private key. */
362
            if (altKey == NULL) {
363
                ret = MISSING_KEY;
364
                buff = NULL;
365
                size = 0;
366
            }
367
            else {
368
                size = altKey->length;
369
                buff = altKey->buffer;
370
            }
371
        #ifdef WOLF_PRIVATE_KEY_ID
372
            if (altDevId != INVALID_DEVID) {
373
                /* We have to decode the public key first. */
374
                /* Default to max pub key size. */
375
                word32 pubKeyLen = MAX_PUBLIC_KEY_SZ;
376
                byte* decodedPubKey = (byte*)XMALLOC(pubKeyLen, heap,
377
                    DYNAMIC_TYPE_PUBLIC_KEY);
378
                if (decodedPubKey == NULL) {
379
                    ret = MEMORY_E;
380
                }
381
                if (ret == WOLFSSL_SUCCESS) {
382
                    if ((der->sapkiOID == RSAk) || (der->sapkiOID == ECDSAk)) {
383
                        /* Simply copy the data. */
384
                        XMEMCPY(decodedPubKey, der->sapkiDer, der->sapkiLen);
385
                        pubKeyLen = der->sapkiLen;
386
                        ret = 0;
387
                    }
388
                    else {
389
                    #if defined(WC_ENABLE_ASYM_KEY_IMPORT)
390
                        word32 idx = 0;
391
                        ret = DecodeAsymKeyPublic(der->sapkiDer, &idx,
392
                                                  der->sapkiLen, decodedPubKey,
393
                                                  &pubKeyLen, der->sapkiOID);
394
                    #else
395
                        ret = NOT_COMPILED_IN;
396
                    #endif /* WC_ENABLE_ASYM_KEY_IMPORT */
397
                    }
398
                }
399
                if (ret == 0) {
400
                    ret = check_cert_key_dev(der->sapkiOID, buff, size,
401
                        decodedPubKey, pubKeyLen, isAltKeyLabel, isAltKeyId,
402
                        heap, altDevId);
403
                }
404
                XFREE(decodedPubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
405
                if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
406
                    ret = (ret == 0) ? 1: 0;
407
                }
408
            }
409
            else {
410
                /* Fall through if unavailable. */
411
                ret = CRYPTOCB_UNAVAILABLE;
412
            }
413
414
            if (ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
415
        #else
416
            if (ret == 1)
417
        #endif /* WOLF_PRIVATE_KEY_ID */
418
            {
419
                ret = wc_CheckPrivateKeyCert(buff, size, der, 1, heap);
420
                if (ret != 1) {
421
                    ret = 0;
422
                }
423
            }
424
        }
425
    #endif /* WOLFSSL_DUAL_ALG_CERTS */
426
0
    }
427
428
0
    FreeDecodedCert(der);
429
0
    WC_FREE_VAR_EX(der, heap, DYNAMIC_TYPE_DCERT);
430
431
0
    (void)devId;
432
0
    (void)isKeyLabel;
433
0
    (void)isKeyId;
434
0
    (void)altKey;
435
0
    (void)altDevId;
436
0
    (void)isAltKeyLabel;
437
0
    (void)isAltKeyId;
438
439
0
    return ret;
440
0
}
441
442
/* Check private against public in certificate for match
443
 *
444
 * @param [in] ctx  SSL/TLS context with a private key and certificate.
445
 *
446
 * @return  1 on good private key
447
 * @return  0 if mismatched.
448
 */
449
int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
450
0
{
451
0
    int res = 1;
452
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
453
    DerBuffer *privateKey;
454
#ifdef WOLFSSL_DUAL_ALG_CERTS
455
    DerBuffer *altPrivateKey;
456
#endif
457
#else
458
0
    const DerBuffer *privateKey;
459
#ifdef WOLFSSL_DUAL_ALG_CERTS
460
    const DerBuffer *altPrivateKey;
461
#endif
462
0
#endif
463
464
    /* Validate parameter. */
465
0
    if (ctx == NULL) {
466
0
        res = 0;
467
0
    }
468
0
    else {
469
#ifdef WOLFSSL_DUAL_ALG_CERTS
470
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
471
        /* Unblind private keys. */
472
        privateKey = wolfssl_priv_der_unblind(ctx->privateKey,
473
            ctx->privateKeyMask);
474
        if (privateKey == NULL) {
475
            res = 0;
476
        }
477
        if (ctx->altPrivateKey != NULL) {
478
            altPrivateKey = wolfssl_priv_der_unblind(ctx->altPrivateKey,
479
                ctx->altPrivateKeyMask);
480
            if (altPrivateKey == NULL) {
481
                res = 0;
482
            }
483
        }
484
        else {
485
            altPrivateKey = NULL;
486
        }
487
    #else
488
        privateKey = ctx->privateKey;
489
        altPrivateKey = ctx->altPrivateKey;
490
    #endif
491
        if (res == 1) {
492
            /* Check certificate and private keys. */
493
            res = check_cert_key(ctx->certificate, privateKey, altPrivateKey,
494
                ctx->heap, ctx->privateKeyDevId, ctx->privateKeyLabel,
495
                ctx->privateKeyId, ctx->altPrivateKeyDevId,
496
                ctx->altPrivateKeyLabel, ctx->altPrivateKeyId) == 1;
497
        }
498
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
499
        /* Dispose of the unblinded buffers. */
500
        wolfssl_priv_der_unblind_free(privateKey);
501
        wolfssl_priv_der_unblind_free(altPrivateKey);
502
    #endif
503
#else
504
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
505
        /* Unblind private key. */
506
        privateKey = wolfssl_priv_der_unblind(ctx->privateKey,
507
            ctx->privateKeyMask);
508
        if (privateKey == NULL) {
509
            res = 0;
510
        }
511
    #else
512
0
        privateKey = ctx->privateKey;
513
0
    #endif
514
0
        if (res == WOLFSSL_SUCCESS) {
515
            /* Check certificate and private key. */
516
0
            res = check_cert_key(ctx->certificate, privateKey, NULL, ctx->heap,
517
0
                ctx->privateKeyDevId, ctx->privateKeyLabel, ctx->privateKeyId,
518
0
                INVALID_DEVID, 0, 0);
519
0
        }
520
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
521
        /* Dispose of the unblinded buffer. */
522
        wolfssl_priv_der_unblind_free(privateKey);
523
    #endif
524
0
#endif
525
0
    }
526
527
    /* Place error into queue for Python port. */
528
0
    if (res != 1) {
529
0
        WOLFSSL_ERROR(WC_KEY_MISMATCH_E);
530
0
    }
531
532
0
    return res;
533
0
}
534
535
#ifdef OPENSSL_EXTRA
536
/* Check private against public in certificate for match.
537
 *
538
 * @param [in] ssl  SSL/TLS object with a private key and certificate.
539
 *
540
 * @return  1 on good private key
541
 * @return  0 if mismatched.
542
 */
543
int wolfSSL_check_private_key(const WOLFSSL* ssl)
544
{
545
    int res = 1;
546
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
547
    DerBuffer *privateKey;
548
#ifdef WOLFSSL_DUAL_ALG_CERTS
549
    DerBuffer *altPrivateKey;
550
#endif
551
#else
552
    const DerBuffer *privateKey;
553
#ifdef WOLFSSL_DUAL_ALG_CERTS
554
    const DerBuffer *altPrivateKey;
555
#endif
556
#endif
557
558
    /* Validate parameter. */
559
    if (ssl == NULL) {
560
        res = 0;
561
    }
562
    else {
563
#ifdef WOLFSSL_DUAL_ALG_CERTS
564
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
565
        /* Unblind private keys. */
566
        privateKey = wolfssl_priv_der_unblind(ssl->buffers.key,
567
            ssl->buffers.keyMask);
568
        if (privateKey == NULL) {
569
            res = 0;
570
        }
571
        if (ssl->buffers.altKey != NULL) {
572
            altPrivateKey = wolfssl_priv_der_unblind(ssl->buffers.altKey,
573
                ssl->buffers.altKeyMask);
574
            if (altPrivateKey == NULL) {
575
                res = 0;
576
            }
577
        }
578
        else {
579
            altPrivateKey = NULL;
580
        }
581
    #else
582
        privateKey = ssl->buffers.key;
583
        altPrivateKey = ssl->buffers.altKey;
584
    #endif
585
        if (res == 1) {
586
            /* Check certificate and private keys. */
587
            res = check_cert_key(ssl->buffers.certificate, privateKey,
588
                altPrivateKey, ssl->heap, ssl->buffers.keyDevId,
589
                ssl->buffers.keyLabel, ssl->buffers.keyId,
590
                ssl->buffers.altKeyDevId, ssl->buffers.altKeyLabel,
591
                ssl->buffers.altKeyId);
592
        }
593
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
594
        /* Dispose of the unblinded buffers. */
595
        wolfssl_priv_der_unblind_free(privateKey);
596
        wolfssl_priv_der_unblind_free(altPrivateKey);
597
    #endif
598
#else
599
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
600
        /* Unblind private key. */
601
        privateKey = wolfssl_priv_der_unblind(ssl->buffers.key,
602
            ssl->buffers.keyMask);
603
        if (privateKey == NULL) {
604
            res = 0;
605
        }
606
    #else
607
        privateKey = ssl->buffers.key;
608
    #endif
609
        if (res == 1) {
610
            /* Check certificate and private key. */
611
            res = check_cert_key(ssl->buffers.certificate, privateKey, NULL,
612
                ssl->heap, ssl->buffers.keyDevId, ssl->buffers.keyLabel,
613
                ssl->buffers.keyId, INVALID_DEVID, 0, 0);
614
        }
615
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
616
        /* Dispose of the unblinded buffer. */
617
        wolfssl_priv_der_unblind_free(privateKey);
618
    #endif
619
#endif
620
    }
621
622
    return res;
623
}
624
#endif /* OPENSSL_EXTRA */
625
#endif /* !NO_CHECK_PRIVATE_KEY */
626
627
#ifdef OPENSSL_ALL
628
/**
629
 * Return the private key of the SSL/TLS context.
630
 *
631
 * The caller doesn *NOT*` free the returned object.
632
 *
633
 * Note, even though the supplied ctx pointer is designated const, on success
634
 * ctx->privateKeyPKey is changed by this call.  The change is done safely using
635
 * a hardware-synchronized store.
636
 *
637
 * @param [in] ctx  SSL/TLS context.
638
 * @return  A WOFLSSL_EVP_PKEY on success.
639
 * @return  NULL on error.
640
 */
641
WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx)
642
{
643
    WOLFSSL_EVP_PKEY* res = NULL;
644
    const unsigned char *key;
645
    int type = WC_EVP_PKEY_NONE;
646
647
    WOLFSSL_ENTER("wolfSSL_CTX_get0_privatekey");
648
649
    if ((ctx == NULL) || (ctx->privateKey == NULL) ||
650
            (ctx->privateKey->buffer == NULL)) {
651
        WOLFSSL_MSG("Bad parameter or key not set");
652
    }
653
    else {
654
        switch (ctx->privateKeyType) {
655
    #ifndef NO_RSA
656
            case rsa_sa_algo:
657
                type = WC_EVP_PKEY_RSA;
658
                break;
659
    #endif
660
    #ifdef HAVE_ECC
661
            case ecc_dsa_sa_algo:
662
                type = WC_EVP_PKEY_EC;
663
                break;
664
    #endif
665
    #ifdef WOLFSSL_SM2
666
            case sm2_sa_algo:
667
                type = WC_EVP_PKEY_EC;
668
                break;
669
    #endif
670
            default:
671
                /* Other key types not supported either as ssl private keys
672
                 * or in the EVP layer */
673
                WOLFSSL_MSG("Unsupported key type");
674
        }
675
    }
676
677
    if (type != WC_EVP_PKEY_NONE) {
678
        if (ctx->privateKeyPKey != NULL) {
679
            res = ctx->privateKeyPKey;
680
        }
681
        else {
682
        #ifdef WOLFSSL_BLIND_PRIVATE_KEY
683
            DerBuffer* unblinded_privateKey = wolfssl_priv_der_unblind(
684
                ctx->privateKey, ctx->privateKeyMask);
685
            if (unblinded_privateKey != NULL) {
686
                key = unblinded_privateKey->buffer;
687
            }
688
            else {
689
                key = NULL;
690
            }
691
        #else
692
            key = ctx->privateKey->buffer;
693
        #endif
694
            if (key != NULL) {
695
                res = wolfSSL_d2i_PrivateKey(type, NULL, &key,
696
                    (long)ctx->privateKey->length);
697
            #ifdef WOLFSSL_BLIND_PRIVATE_KEY
698
                wolfssl_priv_der_unblind_free(unblinded_privateKey);
699
            #endif
700
            }
701
            if (res != NULL) {
702
            #ifdef WOLFSSL_ATOMIC_OPS
703
                WOLFSSL_EVP_PKEY *current_pkey = NULL;
704
                if (!wolfSSL_Atomic_Ptr_CompareExchange(
705
                        (void * volatile *)&ctx->privateKeyPKey,
706
                        (void **)&current_pkey, res)) {
707
                    wolfSSL_EVP_PKEY_free(res);
708
                    res = current_pkey;
709
                }
710
            #else
711
                ((WOLFSSL_CTX *)ctx)->privateKeyPKey = res;
712
            #endif
713
            }
714
        }
715
    }
716
717
    return res;
718
}
719
#endif /* OPENSSL_ALL */
720
721
#ifdef HAVE_ECC
722
723
/* Set size, in bytes, of temporary ECDHE key into SSL/TLS context.
724
 *
725
 * Values can be: 14 - 66 (112 - 521 bit)
726
 * Uses the private key length if sz is 0.
727
 *
728
 * @param [in] ctx  SSL/TLS context.
729
 * @param [in] sz   Size of EC key in bytes.
730
 * @return  1 on success.
731
 * @return  BAD_FUNC_ARG when ctx is NULL or sz is invalid.
732
 */
733
int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
734
0
{
735
0
    int ret = 0;
736
737
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetTmpEC_DHE_Sz");
738
739
    /* Validate parameters. */
740
0
    if (ctx == NULL) {
741
0
        ret = BAD_FUNC_ARG;
742
0
    }
743
    /* If size is 0 then get value from loaded private key. */
744
0
    else if (sz == 0) {
745
        /* Applies only to ECDSA. */
746
0
        if (ctx->privateKeyType != ecc_dsa_sa_algo) {
747
0
            ret = 1;
748
0
        }
749
        /* Must have a key set. */
750
0
        else if (ctx->privateKeySz == 0) {
751
0
            WOLFSSL_MSG("Must set private key/cert first");
752
0
            ret = BAD_FUNC_ARG;
753
0
        }
754
0
        else {
755
0
            sz = (word16)ctx->privateKeySz;
756
0
        }
757
0
    }
758
0
    if (ret == 0) {
759
        /* Check size against bounds. */
760
    #if ECC_MIN_KEY_SZ > 0
761
        if (sz < ECC_MINSIZE) {
762
            ret = BAD_FUNC_ARG;
763
        }
764
        else
765
    #endif
766
0
        if (sz > ECC_MAXSIZE) {
767
0
            ret = BAD_FUNC_ARG;
768
0
        }
769
0
        else {
770
            /* Store the size requested. */
771
0
            ctx->eccTempKeySz = sz;
772
0
            ret = 1;
773
0
        }
774
0
    }
775
776
0
    return ret;
777
0
}
778
779
/* Set size, in bytes, of temporary ECDHE key into SSL/TLS object.
780
 *
781
 * Values can be: 14 - 66 (112 - 521 bit)
782
 * Uses the private key length if sz is 0.
783
 *
784
 * @param [in] ssl  SSL/TLS object.
785
 * @param [in] sz   Size of EC key in bytes.
786
 * @return  1 on success.
787
 * @return  BAD_FUNC_ARG when ssl is NULL or sz is invalid.
788
 */
789
int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
790
0
{
791
0
    int ret = 1;
792
793
0
    WOLFSSL_ENTER("wolfSSL_SetTmpEC_DHE_Sz");
794
795
    /* Validate parameters. */
796
0
    if (ssl == NULL) {
797
0
        ret = BAD_FUNC_ARG;
798
0
    }
799
    /* Check size against bounds. */
800
#if ECC_MIN_KEY_SZ > 0
801
    else if (sz < ECC_MINSIZE) {
802
        ret = BAD_FUNC_ARG;
803
    }
804
#endif
805
0
    else if (sz > ECC_MAXSIZE) {
806
0
        ret = BAD_FUNC_ARG;
807
0
    }
808
0
    else {
809
        /* Store the size requested. */
810
0
        ssl->eccTempKeySz = sz;
811
0
    }
812
813
0
    return ret;
814
0
}
815
816
#endif /* HAVE_ECC */
817
818
#ifdef  HAVE_PK_CALLBACKS
819
820
#ifdef HAVE_ECC
821
/* Set the ECC key generation callback into the SSL/TLS context.
822
 *
823
 * @param [in] ctx  SSL/TLS context.
824
 * @param [in] cb   ECC key generation callback.
825
 */
826
void  wolfSSL_CTX_SetEccKeyGenCb(WOLFSSL_CTX* ctx, CallbackEccKeyGen cb)
827
{
828
    if (ctx != NULL) {
829
        ctx->EccKeyGenCb = cb;
830
    }
831
}
832
/* Set the context for ECC key generation callback into the SSL/TLS object.
833
 *
834
 * @param [in] ssl  SSL/TLS object.
835
 * @param [in] ctx  Context for ECC key generation callback.
836
 */
837
void  wolfSSL_SetEccKeyGenCtx(WOLFSSL* ssl, void *ctx)
838
{
839
    if (ssl != NULL) {
840
        ssl->EccKeyGenCtx = ctx;
841
    }
842
}
843
/* Get the context for ECC key generation callback from the SSL/TLS object.
844
 *
845
 * @param [in] ssl  SSL/TLS object.
846
 * @return  Context for ECC key generation callback.
847
 * @return  NULL when ssl is NULL.
848
 */
849
void* wolfSSL_GetEccKeyGenCtx(WOLFSSL* ssl)
850
{
851
    void* ret;
852
853
    if (ssl == NULL) {
854
        ret = NULL;
855
    }
856
    else {
857
        ret = ssl->EccKeyGenCtx;
858
    }
859
860
    return ret;
861
}
862
/* Set the context for ECC sign callback into the SSL/TLS context.
863
 *
864
 * @param [in] ctx  SSL/TLS context.
865
 * @param [in] userCtx  Context for ECC sign callback.
866
 */
867
void  wolfSSL_CTX_SetEccSignCtx(WOLFSSL_CTX* ctx, void *userCtx)
868
{
869
    if (ctx != NULL) {
870
        ctx->EccSignCtx = userCtx;
871
    }
872
}
873
/* Get the context for ECC sign callback from the SSL/TLS context.
874
 *
875
 * @param [in] ctx  SSL/TLS context.
876
 * @return  Context for ECC sign for callback.
877
 * @return  NULL when ctx is NULL.
878
 */
879
void* wolfSSL_CTX_GetEccSignCtx(WOLFSSL_CTX* ctx)
880
{
881
    void* ret;
882
883
    if (ctx == NULL) {
884
        ret = NULL;
885
    }
886
    else {
887
        ret = ctx->EccSignCtx;
888
    }
889
890
    return ret;
891
}
892
893
/* Set the ECC sign callback into the SSL/TLS context.
894
 *
895
 * @param [in] ctx  SSL/TLS context.
896
 * @param [in] cb   ECC sign callback.
897
 */
898
WOLFSSL_ABI
899
void wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
900
{
901
    if (ctx != NULL) {
902
        ctx->EccSignCb = cb;
903
    }
904
}
905
/* Set the context for ECC sign callback into the SSL/TLS object.
906
 *
907
 * @param [in] ssl  SSL/TLS object.
908
 * @param [in] ctx  Context for ECC sign callback.
909
 */
910
void wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
911
{
912
    if (ssl != NULL) {
913
        ssl->EccSignCtx = ctx;
914
    }
915
}
916
/* Get the context for ECC sign callback from the SSL/TLS object.
917
 *
918
 * @param [in] ssl  SSL/TLS object.
919
 * @return  Context for ECC sign for callback.
920
 * @return  NULL when ssl is NULL.
921
 */
922
void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
923
{
924
    void* ret;
925
926
    if (ssl == NULL) {
927
        ret = NULL;
928
    }
929
    else {
930
        ret = ssl->EccSignCtx;
931
    }
932
933
    return ret;
934
}
935
936
/* Set the ECC verify callback into the SSL/TLS context.
937
 *
938
 * @param [in] ctx  SSL/TLS context.
939
 * @param [in] cb   ECC verify callback.
940
 */
941
void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
942
{
943
    if (ctx != NULL) {
944
        ctx->EccVerifyCb = cb;
945
    }
946
}
947
/* Set the context for ECC verify callback into the SSL/TLS object.
948
 *
949
 * @param [in] ssl  SSL/TLS object.
950
 * @param [in] ctx  Context for ECC verify callback.
951
 */
952
void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
953
{
954
    if (ssl != NULL) {
955
        ssl->EccVerifyCtx = ctx;
956
    }
957
}
958
/* Get the context for ECC verify callback from the SSL/TLS object.
959
 *
960
 * @param [in] ssl  SSL/TLS object.
961
 * @return  Context for ECC verify for callback.
962
 * @return  NULL when ssl is NULL.
963
 */
964
void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
965
{
966
    void* ret;
967
968
    if (ssl == NULL) {
969
        ret = NULL;
970
    }
971
    else {
972
        ret = ssl->EccVerifyCtx;
973
    }
974
975
    return ret;
976
}
977
978
/* Set the ECC shared secret callback into the SSL/TLS context.
979
 *
980
 * @param [in] ctx  SSL/TLS context.
981
 * @param [in] cb   ECC shared secret callback.
982
 */
983
void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX* ctx,
984
    CallbackEccSharedSecret cb)
985
{
986
    if (ctx != NULL) {
987
        ctx->EccSharedSecretCb = cb;
988
    }
989
}
990
/* Set the context for ECC shared secret callback into the SSL/TLS object.
991
 *
992
 * @param [in] ssl  SSL/TLS object.
993
 * @param [in] ctx  Context for ECC shared secret callback.
994
 */
995
void  wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx)
996
{
997
    if (ssl != NULL) {
998
        ssl->EccSharedSecretCtx = ctx;
999
    }
1000
}
1001
/* Get the context for ECC shared secret callback from the SSL/TLS object.
1002
 *
1003
 * @param [in] ssl  SSL/TLS object.
1004
 * @return  Context for ECC shared secret callback.
1005
 * @return  NULL when ssl is NULL.
1006
 */
1007
void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl)
1008
{
1009
    void* ret;
1010
1011
    if (ssl == NULL) {
1012
        ret = NULL;
1013
    }
1014
    else {
1015
        ret = ssl->EccSharedSecretCtx;
1016
    }
1017
1018
    return ret;
1019
}
1020
#endif /* HAVE_ECC */
1021
1022
#ifdef HAVE_ED25519
1023
/* Set the Ed25519 sign callback into the SSL/TLS context.
1024
 *
1025
 * @param [in] ctx  SSL/TLS context.
1026
 * @param [in] cb   Ed25519 sign callback.
1027
 */
1028
void  wolfSSL_CTX_SetEd25519SignCb(WOLFSSL_CTX* ctx, CallbackEd25519Sign cb)
1029
{
1030
    if (ctx != NULL) {
1031
        ctx->Ed25519SignCb = cb;
1032
    }
1033
}
1034
/* Set the context for Ed25519 sign callback into the SSL/TLS object.
1035
 *
1036
 * @param [in] ssl  SSL/TLS object.
1037
 * @param [in] ctx  Context for Ed25519 sign callback.
1038
 */
1039
void  wolfSSL_SetEd25519SignCtx(WOLFSSL* ssl, void *ctx)
1040
{
1041
    if (ssl != NULL) {
1042
        ssl->Ed25519SignCtx = ctx;
1043
    }
1044
}
1045
/* Get the context for Ed25519 sign callback from the SSL/TLS object.
1046
 *
1047
 * @param [in] ssl  SSL/TLS object.
1048
 * @return  Context for Ed25519 sign callback.
1049
 * @return  NULL when ssl is NULL.
1050
 */
1051
void* wolfSSL_GetEd25519SignCtx(WOLFSSL* ssl)
1052
{
1053
    void* ret;
1054
1055
    if (ssl == NULL) {
1056
        ret = NULL;
1057
    }
1058
    else {
1059
        ret = ssl->Ed25519SignCtx;
1060
    }
1061
1062
    return ret;
1063
}
1064
1065
/* Set the Ed25519 verify callback into the SSL/TLS context.
1066
 *
1067
 * @param [in] ctx  SSL/TLS context.
1068
 * @param [in] cb   Ed25519 verify callback.
1069
 */
1070
void  wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX* ctx, CallbackEd25519Verify cb)
1071
{
1072
    if (ctx != NULL) {
1073
        ctx->Ed25519VerifyCb = cb;
1074
    }
1075
}
1076
/* Set the context for Ed25519 verify callback into the SSL/TLS object.
1077
 *
1078
 * @param [in] ssl  SSL/TLS object.
1079
 * @param [in] ctx  Context for Ed25519 verify callback.
1080
 */
1081
void  wolfSSL_SetEd25519VerifyCtx(WOLFSSL* ssl, void *ctx)
1082
{
1083
    if (ssl != NULL) {
1084
        ssl->Ed25519VerifyCtx = ctx;
1085
    }
1086
}
1087
/* Get the context for Ed25519 verify callback from the SSL/TLS object.
1088
 *
1089
 * @param [in] ssl  SSL/TLS object.
1090
 * @return  Context for Ed25519 verify callback.
1091
 * @return  NULL when ssl is NULL.
1092
 */
1093
void* wolfSSL_GetEd25519VerifyCtx(WOLFSSL* ssl)
1094
{
1095
    void* ret;
1096
1097
    if (ssl == NULL) {
1098
        ret = NULL;
1099
    }
1100
    else {
1101
        ret = ssl->Ed25519VerifyCtx;
1102
    }
1103
1104
    return ret;
1105
}
1106
#endif /* HAVE_ED25519 */
1107
1108
#ifdef HAVE_CURVE25519
1109
/* Set the X25519 key generation callback into the SSL/TLS context.
1110
 *
1111
 * @param [in] ctx  SSL/TLS context.
1112
 * @param [in] cb   X25519 key generation callback.
1113
 */
1114
void wolfSSL_CTX_SetX25519KeyGenCb(WOLFSSL_CTX* ctx, CallbackX25519KeyGen cb)
1115
{
1116
    if (ctx != NULL) {
1117
        ctx->X25519KeyGenCb = cb;
1118
    }
1119
}
1120
/* Set the context for X25519 key generation callback into the SSL/TLS object.
1121
 *
1122
 * @param [in] ssl  SSL/TLS object.
1123
 * @param [in] ctx  Context for X25519 key generation callback.
1124
 */
1125
void  wolfSSL_SetX25519KeyGenCtx(WOLFSSL* ssl, void *ctx)
1126
{
1127
    if (ssl != NULL) {
1128
        ssl->X25519KeyGenCtx = ctx;
1129
    }
1130
}
1131
/* Get the context for X25519 key generation callback from the SSL/TLS object.
1132
 *
1133
 * @param [in] ssl  SSL/TLS object.
1134
 * @return  Context for X25519 key generation callback.
1135
 * @return  NULL when ssl is NULL.
1136
 */
1137
void* wolfSSL_GetX25519KeyGenCtx(WOLFSSL* ssl)
1138
{
1139
    void* ret;
1140
1141
    if (ssl == NULL) {
1142
        ret = NULL;
1143
    }
1144
    else {
1145
        ret = ssl->X25519KeyGenCtx;
1146
    }
1147
1148
    return ret;
1149
}
1150
1151
/* Set the X25519 shared secret callback into the SSL/TLS context.
1152
 *
1153
 * @param [in] ctx  SSL/TLS context.
1154
 * @param [in] cb   X25519 shared secret callback.
1155
 */
1156
void wolfSSL_CTX_SetX25519SharedSecretCb(WOLFSSL_CTX* ctx,
1157
    CallbackX25519SharedSecret cb)
1158
{
1159
    if (ctx != NULL) {
1160
        ctx->X25519SharedSecretCb = cb;
1161
    }
1162
}
1163
/* Set the context for X25519 shared secret callback into the SSL/TLS object.
1164
 *
1165
 * @param [in] ssl  SSL/TLS object.
1166
 * @param [in] ctx  Context for X25519 shared secret callback.
1167
 */
1168
void  wolfSSL_SetX25519SharedSecretCtx(WOLFSSL* ssl, void *ctx)
1169
{
1170
    if (ssl != NULL) {
1171
        ssl->X25519SharedSecretCtx = ctx;
1172
    }
1173
}
1174
/* Get the context for X25519 shared secret callback from the SSL/TLS object.
1175
 *
1176
 * @param [in] ssl  SSL/TLS object.
1177
 * @return  Context for X25519 shared secret callback.
1178
 * @return  NULL when ssl is NULL.
1179
 */
1180
void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl)
1181
{
1182
    void* ret;
1183
1184
    if (ssl == NULL) {
1185
        ret = NULL;
1186
    }
1187
    else {
1188
        ret = ssl->X25519SharedSecretCtx;
1189
    }
1190
1191
    return ret;
1192
}
1193
#endif /* HAVE_CURVE25519 */
1194
1195
#ifdef HAVE_ED448
1196
/* Set the Ed448 sign callback into the SSL/TLS context.
1197
 *
1198
 * @param [in] ctx  SSL/TLS context.
1199
 * @param [in] cb   Ed448 sign callback.
1200
 */
1201
void wolfSSL_CTX_SetEd448SignCb(WOLFSSL_CTX* ctx, CallbackEd448Sign cb)
1202
{
1203
    if (ctx != NULL) {
1204
        ctx->Ed448SignCb = cb;
1205
    }
1206
}
1207
/* Set the context for Ed448 sign callback into the SSL/TLS object.
1208
 *
1209
 * @param [in] ssl  SSL/TLS object.
1210
 * @param [in] ctx  Context for Ed448 sign callback.
1211
 */
1212
void wolfSSL_SetEd448SignCtx(WOLFSSL* ssl, void *ctx)
1213
{
1214
    if (ssl != NULL) {
1215
        ssl->Ed448SignCtx = ctx;
1216
    }
1217
}
1218
/* Get the context for Ed448 sign callback from the SSL/TLS object.
1219
 *
1220
 * @param [in] ssl  SSL/TLS object.
1221
 * @return  Context for Ed448 sign callback.
1222
 * @return  NULL when ssl is NULL.
1223
 */
1224
void* wolfSSL_GetEd448SignCtx(WOLFSSL* ssl)
1225
{
1226
    void* ret;
1227
1228
    if (ssl == NULL) {
1229
        ret = NULL;
1230
    }
1231
    else {
1232
        ret = ssl->Ed448SignCtx;
1233
    }
1234
1235
    return ret;
1236
}
1237
1238
/* Set the Ed448 verify callback into the SSL/TLS context.
1239
 *
1240
 * @param [in] ctx  SSL/TLS context.
1241
 * @param [in] cb   Ed448 verify callback.
1242
 */
1243
void  wolfSSL_CTX_SetEd448VerifyCb(WOLFSSL_CTX* ctx, CallbackEd448Verify cb)
1244
{
1245
    if (ctx != NULL) {
1246
        ctx->Ed448VerifyCb = cb;
1247
    }
1248
}
1249
/* Set the context for Ed448 verify callback into the SSL/TLS object.
1250
 *
1251
 * @param [in] ssl  SSL/TLS object.
1252
 * @param [in] ctx  Context for Ed448 verify callback.
1253
 */
1254
void  wolfSSL_SetEd448VerifyCtx(WOLFSSL* ssl, void *ctx)
1255
{
1256
    if (ssl != NULL) {
1257
        ssl->Ed448VerifyCtx = ctx;
1258
    }
1259
}
1260
/* Get the context for Ed448 verify callback from the SSL/TLS object.
1261
 *
1262
 * @param [in] ssl  SSL/TLS object.
1263
 * @return  Context for Ed448 verify callback.
1264
 * @return  NULL when ssl is NULL.
1265
 */
1266
void* wolfSSL_GetEd448VerifyCtx(WOLFSSL* ssl)
1267
{
1268
    void* ret;
1269
1270
    if (ssl == NULL) {
1271
        ret = NULL;
1272
    }
1273
    else {
1274
        ret = ssl->Ed448VerifyCtx;
1275
    }
1276
1277
    return ret;
1278
}
1279
#endif /* HAVE_ED448 */
1280
1281
#ifdef HAVE_CURVE448
1282
/* Set the X448 key generation callback into the SSL/TLS context.
1283
 *
1284
 * @param [in] ctx  SSL/TLS context.
1285
 * @param [in] cb   X448 key generation callback.
1286
 */
1287
void wolfSSL_CTX_SetX448KeyGenCb(WOLFSSL_CTX* ctx,
1288
        CallbackX448KeyGen cb)
1289
{
1290
    if (ctx != NULL) {
1291
        ctx->X448KeyGenCb = cb;
1292
    }
1293
}
1294
/* Set the context for X448 key generation callback into the SSL/TLS object.
1295
 *
1296
 * @param [in] ssl  SSL/TLS object.
1297
 * @param [in] ctx  Context for X448 key generation callback.
1298
 */
1299
void  wolfSSL_SetX448KeyGenCtx(WOLFSSL* ssl, void *ctx)
1300
{
1301
    if (ssl != NULL) {
1302
        ssl->X448KeyGenCtx = ctx;
1303
    }
1304
}
1305
/* Get the context for X448 key generation callback from the SSL/TLS object.
1306
 *
1307
 * @param [in] ssl  SSL/TLS object.
1308
 * @return  Context for X448 key generation callback.
1309
 * @return  NULL when ssl is NULL.
1310
 */
1311
void* wolfSSL_GetX448KeyGenCtx(WOLFSSL* ssl)
1312
{
1313
    void* ret;
1314
1315
    if (ssl == NULL) {
1316
        ret = NULL;
1317
    }
1318
    else {
1319
        ret = ssl->X448KeyGenCtx;
1320
    }
1321
1322
    return ret;
1323
}
1324
1325
/* Set the X448 shared secret callback into the SSL/TLS context.
1326
 *
1327
 * @param [in] ctx  SSL/TLS context.
1328
 * @param [in] cb   X448 shared secret callback.
1329
 */
1330
void wolfSSL_CTX_SetX448SharedSecretCb(WOLFSSL_CTX* ctx,
1331
        CallbackX448SharedSecret cb)
1332
{
1333
    if (ctx != NULL) {
1334
        ctx->X448SharedSecretCb = cb;
1335
    }
1336
}
1337
/* Set the context for X448 shared secret callback into the SSL/TLS object.
1338
 *
1339
 * @param [in] ssl  SSL/TLS object.
1340
 * @param [in] ctx  Context for X448 shared secret callback.
1341
 */
1342
void  wolfSSL_SetX448SharedSecretCtx(WOLFSSL* ssl, void *ctx)
1343
{
1344
    if (ssl != NULL) {
1345
        ssl->X448SharedSecretCtx = ctx;
1346
    }
1347
}
1348
/* Get the context for X448 shared secret callback from the SSL/TLS object.
1349
 *
1350
 * @param [in] ssl  SSL/TLS object.
1351
 * @return  Context for X448 shared secret callback.
1352
 * @return  NULL when ssl is NULL.
1353
 */
1354
void* wolfSSL_GetX448SharedSecretCtx(WOLFSSL* ssl)
1355
{
1356
    void* ret;
1357
1358
    if (ssl == NULL) {
1359
        ret = NULL;
1360
    }
1361
    else {
1362
        ret = ssl->X448SharedSecretCtx;
1363
    }
1364
1365
    return ret;
1366
}
1367
#endif /* HAVE_CURVE448 */
1368
1369
#ifndef NO_RSA
1370
/* Set the RSA sign callback into the SSL/TLS context.
1371
 *
1372
 * @param [in] ctx  SSL/TLS context.
1373
 * @param [in] cb   RSA sign callback.
1374
 */
1375
void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
1376
{
1377
    if (ctx != NULL) {
1378
        ctx->RsaSignCb = cb;
1379
    }
1380
}
1381
/* Set the RSA sign check callback into the SSL/TLS context.
1382
 *
1383
 * @param [in] ctx  SSL/TLS context.
1384
 * @param [in] cb   RSA sign check callback.
1385
 */
1386
void  wolfSSL_CTX_SetRsaSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
1387
{
1388
    if (ctx != NULL) {
1389
        ctx->RsaSignCheckCb = cb;
1390
    }
1391
}
1392
/* Set the context for RSA sign callback into the SSL/TLS object.
1393
 *
1394
 * @param [in] ssl  SSL/TLS object.
1395
 * @param [in] ctx  Context for RSA sign callback.
1396
 */
1397
void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
1398
{
1399
    if (ssl != NULL) {
1400
        ssl->RsaSignCtx = ctx;
1401
    }
1402
}
1403
/* Get the context for RSA sign callback from the SSL/TLS object.
1404
 *
1405
 * @param [in] ssl  SSL/TLS object.
1406
 * @return  Context for RSA sign callback.
1407
 * @return  NULL when ssl is NULL.
1408
 */
1409
void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
1410
{
1411
    void* ret;
1412
1413
    if (ssl == NULL) {
1414
        ret = NULL;
1415
    }
1416
    else {
1417
        ret = ssl->RsaSignCtx;
1418
    }
1419
1420
    return ret;
1421
}
1422
1423
/* Set the RSA verify callback into the SSL/TLS context.
1424
 *
1425
 * @param [in] ctx  SSL/TLS context.
1426
 * @param [in] cb   RSA verify callback.
1427
 */
1428
void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
1429
{
1430
    if (ctx != NULL) {
1431
        ctx->RsaVerifyCb = cb;
1432
    }
1433
}
1434
/* Set the context for RSA verify callback into the SSL/TLS object.
1435
 *
1436
 * @param [in] ssl  SSL/TLS object.
1437
 * @param [in] ctx  Context for RSA verify callback.
1438
 */
1439
void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
1440
{
1441
    if (ssl != NULL) {
1442
        ssl->RsaVerifyCtx = ctx;
1443
    }
1444
}
1445
/* Get the context for RSA verify callback from the SSL/TLS object.
1446
 *
1447
 * @param [in] ssl  SSL/TLS object.
1448
 * @return  Context for RSA verify callback.
1449
 * @return  NULL when ssl is NULL.
1450
 */
1451
void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
1452
{
1453
    void* ret;
1454
1455
    if (ssl == NULL) {
1456
        ret = NULL;
1457
    }
1458
    else {
1459
        ret = ssl->RsaVerifyCtx;
1460
    }
1461
1462
    return ret;
1463
}
1464
1465
#ifdef WC_RSA_PSS
1466
/* Set the RSA PSS sign callback into the SSL/TLS context.
1467
 *
1468
 * @param [in] ctx  SSL/TLS context.
1469
 * @param [in] cb   RSA PSS sign callback.
1470
 */
1471
void  wolfSSL_CTX_SetRsaPssSignCb(WOLFSSL_CTX* ctx, CallbackRsaPssSign cb)
1472
{
1473
    if (ctx != NULL) {
1474
        ctx->RsaPssSignCb = cb;
1475
    }
1476
}
1477
/* Set the RSA PSS sign check callback into the SSL/TLS context.
1478
 *
1479
 * @param [in] ctx  SSL/TLS context.
1480
 * @param [in] cb   RSA PSS sign check callback.
1481
 */
1482
void  wolfSSL_CTX_SetRsaPssSignCheckCb(WOLFSSL_CTX* ctx,
1483
    CallbackRsaPssVerify cb)
1484
{
1485
    if (ctx != NULL) {
1486
        ctx->RsaPssSignCheckCb = cb;
1487
    }
1488
}
1489
/* Set the context for RSA PSS sign callback into the SSL/TLS object.
1490
 *
1491
 * @param [in] ssl  SSL/TLS object.
1492
 * @param [in] ctx  Context for RSA PSS sign callback.
1493
 */
1494
void  wolfSSL_SetRsaPssSignCtx(WOLFSSL* ssl, void *ctx)
1495
{
1496
    if (ssl != NULL) {
1497
        ssl->RsaPssSignCtx = ctx;
1498
    }
1499
}
1500
/* Get the context for RSA PSS sign callback from the SSL/TLS object.
1501
 *
1502
 * @param [in] ssl  SSL/TLS object.
1503
 * @return  Context for RSA PSS sign callback.
1504
 * @return  NULL when ssl is NULL.
1505
 */
1506
void* wolfSSL_GetRsaPssSignCtx(WOLFSSL* ssl)
1507
{
1508
    void* ret;
1509
1510
    if (ssl == NULL) {
1511
        ret = NULL;
1512
    }
1513
    else {
1514
        ret = ssl->RsaPssSignCtx;
1515
    }
1516
1517
    return ret;
1518
}
1519
1520
/* Set the RSA PSS verify callback into the SSL/TLS context.
1521
 *
1522
 * @param [in] ctx  SSL/TLS context.
1523
 * @param [in] cb   RSA PSS verify callback.
1524
 */
1525
void  wolfSSL_CTX_SetRsaPssVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
1526
{
1527
    if (ctx != NULL) {
1528
        ctx->RsaPssVerifyCb = cb;
1529
    }
1530
}
1531
/* Set the context for RSA PSS verify callback into the SSL/TLS object.
1532
 *
1533
 * @param [in] ssl  SSL/TLS object.
1534
 * @param [in] ctx  Context for RSA PSS verify callback.
1535
 */
1536
void  wolfSSL_SetRsaPssVerifyCtx(WOLFSSL* ssl, void *ctx)
1537
{
1538
    if (ssl != NULL) {
1539
        ssl->RsaPssVerifyCtx = ctx;
1540
    }
1541
}
1542
/* Get the context for RSA PSS verify callback from the SSL/TLS object.
1543
 *
1544
 * @param [in] ssl  SSL/TLS object.
1545
 * @return  Context for RSA PSS verify callback.
1546
 * @return  NULL when ssl is NULL.
1547
 */
1548
void* wolfSSL_GetRsaPssVerifyCtx(WOLFSSL* ssl)
1549
{
1550
    void* ret;
1551
1552
    if (ssl == NULL) {
1553
        ret = NULL;
1554
    }
1555
    else {
1556
        ret = ssl->RsaPssVerifyCtx;
1557
    }
1558
1559
    return ret;
1560
}
1561
#endif /* WC_RSA_PSS */
1562
1563
/* Set the RSA encrypt callback into the SSL/TLS context.
1564
 *
1565
 * @param [in] ctx  SSL/TLS context.
1566
 * @param [in] cb   RSA encrypt callback.
1567
 */
1568
void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
1569
{
1570
    if (ctx != NULL) {
1571
        ctx->RsaEncCb = cb;
1572
    }
1573
}
1574
/* Set the context for RSA encrypt callback into the SSL/TLS object.
1575
 *
1576
 * @param [in] ssl  SSL/TLS object.
1577
 * @param [in] ctx  Context for RSA encrypt callback.
1578
 */
1579
void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
1580
{
1581
    if (ssl != NULL) {
1582
        ssl->RsaEncCtx = ctx;
1583
    }
1584
}
1585
/* Get the context for RSA encrypt callback from the SSL/TLS object.
1586
 *
1587
 * @param [in] ssl  SSL/TLS object.
1588
 * @return  Context for RSA encrypt callback.
1589
 * @return  NULL when ssl is NULL.
1590
 */
1591
void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
1592
{
1593
    void* ret;
1594
1595
    if (ssl == NULL) {
1596
        ret = NULL;
1597
    }
1598
    else {
1599
        ret = ssl->RsaEncCtx;
1600
    }
1601
1602
    return ret;
1603
}
1604
1605
/* Set the RSA decrypt callback into the SSL/TLS context.
1606
 *
1607
 * @param [in] ctx  SSL/TLS context.
1608
 * @param [in] cb   RSA decrypt callback.
1609
 */
1610
void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
1611
{
1612
    if (ctx != NULL) {
1613
        ctx->RsaDecCb = cb;
1614
    }
1615
}
1616
/* Set the context for RSA decrypt callback into the SSL/TLS object.
1617
 *
1618
 * @param [in] ssl  SSL/TLS object.
1619
 * @param [in] ctx  Context for RSA decrypt callback.
1620
 */
1621
void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
1622
{
1623
    if (ssl != NULL) {
1624
        ssl->RsaDecCtx = ctx;
1625
    }
1626
}
1627
/* Get the context for RSA decrypt callback from the SSL/TLS object.
1628
 *
1629
 * @param [in] ssl  SSL/TLS object.
1630
 * @return  Context for RSA decrypt callback.
1631
 * @return  NULL when ssl is NULL.
1632
 */
1633
void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
1634
{
1635
    void* ret;
1636
1637
    if (ssl == NULL) {
1638
        ret = NULL;
1639
    }
1640
    else {
1641
        ret = ssl->RsaDecCtx;
1642
    }
1643
1644
    return ret;
1645
}
1646
#endif /* NO_RSA */
1647
1648
#endif /* HAVE_PK_CALLBACKS */
1649
1650
#endif /* !NO_CERTS */
1651
1652
#if defined(HAVE_PK_CALLBACKS) && !defined(NO_DH)
1653
/* Set the DH key pair generation callback into the SSL/TLS context.
1654
 *
1655
 * @param [in] ctx  SSL/TLS context.
1656
 * @param [in] cb   DH key pair generation callback.
1657
 */
1658
void wolfSSL_CTX_SetDhGenerateKeyPair(WOLFSSL_CTX* ctx,
1659
    CallbackDhGenerateKeyPair cb)
1660
{
1661
    if (ctx != NULL) {
1662
        ctx->DhGenerateKeyPairCb = cb;
1663
    }
1664
}
1665
/* Set the DH key agree callback into the SSL/TLS context.
1666
 *
1667
 * @param [in] ctx  SSL/TLS context.
1668
 * @param [in] cb   DH key agree callback.
1669
 */
1670
void wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX* ctx, CallbackDhAgree cb)
1671
{
1672
    if (ctx != NULL) {
1673
        ctx->DhAgreeCb = cb;
1674
    }
1675
}
1676
/* Set the context for DH key agree callback into the SSL/TLS object.
1677
 *
1678
 * @param [in] ssl  SSL/TLS object.
1679
 * @param [in] ctx  Context for DH key agree callback.
1680
 */
1681
void wolfSSL_SetDhAgreeCtx(WOLFSSL* ssl, void *ctx)
1682
{
1683
    if (ssl != NULL) {
1684
        ssl->DhAgreeCtx = ctx;
1685
    }
1686
}
1687
/* Get the context for DH key ageww callback from the SSL/TLS object.
1688
 *
1689
 * @param [in] ssl  SSL/TLS object.
1690
 * @return  Context for DH key agree callback.
1691
 * @return  NULL when ssl is NULL.
1692
 */
1693
void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
1694
{
1695
    void* ret;
1696
1697
    if (ssl == NULL) {
1698
        ret = NULL;
1699
    }
1700
    else {
1701
        ret = ssl->DhAgreeCtx;
1702
    }
1703
1704
    return ret;
1705
}
1706
#endif /* HAVE_PK_CALLBACKS && !NO_DH */
1707
1708
#ifndef WOLFCRYPT_ONLY
1709
1710
#ifndef NO_TLS
1711
#ifdef HAVE_ECC
1712
/* Set the minimum ECC key size, in bits, allowed with the context.
1713
 *
1714
 * @param [in] ctx    SSL/TLS context object.
1715
 * @param [in] keySz  Minimum ECC key size in bits.
1716
 * @return  WOLFSSL_SUCCESS on success.
1717
 * @return  BAD_FUNC_ARG when ctx is NULL or keySz is negative.
1718
 * @return  CRYPTO_POLICY_FORBIDDEN when below the active crypto-policy minimum.
1719
 */
1720
int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
1721
0
{
1722
0
    short keySzBytes;
1723
1724
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetMinEccKey_Sz");
1725
0
    if (ctx == NULL || keySz < 0) {
1726
0
        WOLFSSL_MSG("Key size must be positive value or ctx was null");
1727
0
        return BAD_FUNC_ARG;
1728
0
    }
1729
1730
0
    if (keySz % 8 == 0) {
1731
0
        keySzBytes = keySz / 8;
1732
0
    }
1733
0
    else {
1734
0
        keySzBytes = (keySz / 8) + 1;
1735
0
    }
1736
1737
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
1738
    if (crypto_policy.enabled) {
1739
        if (ctx->minEccKeySz > (keySzBytes)) {
1740
            return CRYPTO_POLICY_FORBIDDEN;
1741
        }
1742
    }
1743
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
1744
1745
0
    ctx->minEccKeySz     = keySzBytes;
1746
0
#ifndef NO_CERTS
1747
0
    ctx->cm->minEccKeySz = keySzBytes;
1748
0
#endif
1749
0
    return WOLFSSL_SUCCESS;
1750
0
}
1751
1752
/* Set the minimum ECC key size, in bits, allowed with the object.
1753
 *
1754
 * @param [in] ssl    SSL/TLS object.
1755
 * @param [in] keySz  Minimum ECC key size in bits.
1756
 * @return  WOLFSSL_SUCCESS on success.
1757
 * @return  BAD_FUNC_ARG when ssl is NULL or keySz is negative.
1758
 * @return  CRYPTO_POLICY_FORBIDDEN when below the active crypto-policy minimum.
1759
 */
1760
int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
1761
0
{
1762
0
    short keySzBytes;
1763
1764
0
    WOLFSSL_ENTER("wolfSSL_SetMinEccKey_Sz");
1765
0
    if (ssl == NULL || keySz < 0) {
1766
0
        WOLFSSL_MSG("Key size must be positive value or ctx was null");
1767
0
        return BAD_FUNC_ARG;
1768
0
    }
1769
1770
0
    if (keySz % 8 == 0) {
1771
0
        keySzBytes = keySz / 8;
1772
0
    }
1773
0
    else {
1774
0
        keySzBytes = (keySz / 8) + 1;
1775
0
    }
1776
1777
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
1778
    if (crypto_policy.enabled) {
1779
        if (ssl->options.minEccKeySz > (keySzBytes)) {
1780
            return CRYPTO_POLICY_FORBIDDEN;
1781
        }
1782
    }
1783
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
1784
1785
0
    ssl->options.minEccKeySz = keySzBytes;
1786
0
    return WOLFSSL_SUCCESS;
1787
0
}
1788
1789
#endif /* HAVE_ECC */
1790
1791
#ifndef NO_RSA
1792
/* Set the minimum RSA key size, in bits, allowed with the context.
1793
 *
1794
 * @param [in] ctx    SSL/TLS context object.
1795
 * @param [in] keySz  Minimum RSA key size in bits. Must be a multiple of 8.
1796
 * @return  WOLFSSL_SUCCESS on success.
1797
 * @return  BAD_FUNC_ARG when ctx is NULL or keySz is negative or not a
1798
 *          multiple of 8.
1799
 * @return  CRYPTO_POLICY_FORBIDDEN when below the active crypto-policy minimum.
1800
 */
1801
int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz)
1802
0
{
1803
0
    if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
1804
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
1805
0
        return BAD_FUNC_ARG;
1806
0
    }
1807
1808
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
1809
    if (crypto_policy.enabled) {
1810
        if (ctx->minRsaKeySz > (keySz / 8)) {
1811
            return CRYPTO_POLICY_FORBIDDEN;
1812
        }
1813
    }
1814
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
1815
1816
0
    ctx->minRsaKeySz     = keySz / 8;
1817
0
    ctx->cm->minRsaKeySz = keySz / 8;
1818
0
    return WOLFSSL_SUCCESS;
1819
0
}
1820
1821
/* Set the minimum RSA key size, in bits, allowed with the object.
1822
 *
1823
 * @param [in] ssl    SSL/TLS object.
1824
 * @param [in] keySz  Minimum RSA key size in bits. Must be a multiple of 8.
1825
 * @return  WOLFSSL_SUCCESS on success.
1826
 * @return  BAD_FUNC_ARG when ssl is NULL or keySz is negative or not a
1827
 *          multiple of 8.
1828
 * @return  CRYPTO_POLICY_FORBIDDEN when below the active crypto-policy minimum.
1829
 */
1830
int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
1831
0
{
1832
0
    if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
1833
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
1834
0
        return BAD_FUNC_ARG;
1835
0
    }
1836
1837
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
1838
    if (crypto_policy.enabled) {
1839
        if (ssl->options.minRsaKeySz > (keySz / 8)) {
1840
            return CRYPTO_POLICY_FORBIDDEN;
1841
        }
1842
    }
1843
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
1844
1845
0
    ssl->options.minRsaKeySz = keySz / 8;
1846
0
    return WOLFSSL_SUCCESS;
1847
0
}
1848
#endif /* !NO_RSA */
1849
1850
#ifndef NO_DH
1851
1852
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
1853
    !defined(HAVE_SELFTEST)
1854
/* Enable or disable the DH key prime test on the object.
1855
 *
1856
 * @param [in] ssl     SSL/TLS object.
1857
 * @param [in] enable  1 to enable the prime test and 0 to disable it.
1858
 * @return  WOLFSSL_SUCCESS on success.
1859
 * @return  BAD_FUNC_ARG when ssl is NULL.
1860
 */
1861
int wolfSSL_SetEnableDhKeyTest(WOLFSSL* ssl, int enable)
1862
0
{
1863
0
    WOLFSSL_ENTER("wolfSSL_SetEnableDhKeyTest");
1864
1865
0
    if (ssl == NULL)
1866
0
        return BAD_FUNC_ARG;
1867
1868
0
    if (!enable)
1869
0
        ssl->options.dhDoKeyTest = 0;
1870
0
    else
1871
0
        ssl->options.dhDoKeyTest = 1;
1872
1873
0
    WOLFSSL_LEAVE("wolfSSL_SetEnableDhKeyTest", WOLFSSL_SUCCESS);
1874
0
    return WOLFSSL_SUCCESS;
1875
0
}
1876
#endif
1877
1878
/* Set the minimum DH key size, in bits, allowed with the context.
1879
 *
1880
 * @param [in] ctx         SSL/TLS context object.
1881
 * @param [in] keySz_bits  Minimum DH key size in bits. No more than 16000 and
1882
 *                         a multiple of 8. A floor above what the build's
1883
 *                         math supports is accepted: it simply refuses every
1884
 *                         DH key a peer can offer, which is what a caller
1885
 *                         tightening its policy asked for.
1886
 * @return  WOLFSSL_SUCCESS on success.
1887
 * @return  BAD_FUNC_ARG when ctx is NULL or keySz_bits is invalid.
1888
 * @return  CRYPTO_POLICY_FORBIDDEN when below the active crypto-policy minimum.
1889
 */
1890
int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
1891
0
{
1892
0
    if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
1893
0
        return BAD_FUNC_ARG;
1894
1895
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
1896
    if (crypto_policy.enabled) {
1897
        if (ctx->minDhKeySz > (keySz_bits / 8)) {
1898
            return CRYPTO_POLICY_FORBIDDEN;
1899
        }
1900
    }
1901
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
1902
1903
0
    ctx->minDhKeySz = keySz_bits / 8;
1904
0
    return WOLFSSL_SUCCESS;
1905
0
}
1906
1907
/* Set the minimum DH key size, in bits, allowed with the object.
1908
 *
1909
 * @param [in] ssl         SSL/TLS object.
1910
 * @param [in] keySz_bits  Minimum DH key size in bits. No more than 16000 and
1911
 *                         a multiple of 8. A floor above what the build's
1912
 *                         math supports is accepted: it simply refuses every
1913
 *                         DH key a peer can offer, which is what a caller
1914
 *                         tightening its policy asked for.
1915
 * @return  WOLFSSL_SUCCESS on success.
1916
 * @return  BAD_FUNC_ARG when ssl is NULL or keySz_bits is invalid.
1917
 * @return  CRYPTO_POLICY_FORBIDDEN when below the active crypto-policy minimum.
1918
 */
1919
int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
1920
0
{
1921
0
    if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
1922
0
        return BAD_FUNC_ARG;
1923
1924
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
1925
    if (crypto_policy.enabled) {
1926
        if (ssl->options.minDhKeySz > (keySz_bits / 8)) {
1927
            return CRYPTO_POLICY_FORBIDDEN;
1928
        }
1929
    }
1930
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
1931
1932
0
    ssl->options.minDhKeySz = keySz_bits / 8;
1933
0
    return WOLFSSL_SUCCESS;
1934
0
}
1935
1936
/* Set the maximum DH key size, in bits, allowed with the context.
1937
 *
1938
 * @param [in] ctx         SSL/TLS context object.
1939
 * @param [in] keySz_bits  Maximum DH key size in bits. No more than 16000 and
1940
 *                         a multiple of 8, and no more than what the build's
1941
 *                         math supports.
1942
 * @return  WOLFSSL_SUCCESS on success.
1943
 * @return  BAD_FUNC_ARG when ctx is NULL or keySz_bits is invalid.
1944
 */
1945
int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
1946
0
{
1947
0
    if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
1948
0
        return BAD_FUNC_ARG;
1949
1950
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
1951
    if (crypto_policy.enabled) {
1952
        if (ctx->minDhKeySz > (keySz_bits / 8)) {
1953
            return CRYPTO_POLICY_FORBIDDEN;
1954
        }
1955
    }
1956
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
1957
1958
    /* The pre-master secret buffer is sized for the largest prime the build's
1959
     * math supports, so a ceiling above that cannot be honoured. Checked
1960
     * after the crypto policy so a request that breaks both is still reported
1961
     * as the policy violation it is. */
1962
0
    if ((keySz_bits / 8) > MAX_DHKEY_SZ) {
1963
0
        WOLFSSL_MSG("Requested maximum DH key size exceeds MAX_DHKEY_SZ");
1964
0
        return BAD_FUNC_ARG;
1965
0
    }
1966
1967
0
    ctx->maxDhKeySz = keySz_bits / 8;
1968
0
    return WOLFSSL_SUCCESS;
1969
0
}
1970
1971
/* Set the maximum DH key size, in bits, allowed with the object.
1972
 *
1973
 * @param [in] ssl         SSL/TLS object.
1974
 * @param [in] keySz_bits  Maximum DH key size in bits. No more than 16000 and
1975
 *                         a multiple of 8, and no more than what the build's
1976
 *                         math supports.
1977
 * @return  WOLFSSL_SUCCESS on success.
1978
 * @return  BAD_FUNC_ARG when ssl is NULL or keySz_bits is invalid.
1979
 */
1980
int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
1981
0
{
1982
0
    if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
1983
0
        return BAD_FUNC_ARG;
1984
1985
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
1986
    if (crypto_policy.enabled) {
1987
        if (ssl->options.minDhKeySz > (keySz_bits / 8)) {
1988
            return CRYPTO_POLICY_FORBIDDEN;
1989
        }
1990
    }
1991
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
1992
1993
    /* The pre-master secret buffer is sized for the largest prime the build's
1994
     * math supports, so a ceiling above that cannot be honoured. Checked
1995
     * after the crypto policy so a request that breaks both is still reported
1996
     * as the policy violation it is. */
1997
0
    if ((keySz_bits / 8) > MAX_DHKEY_SZ) {
1998
0
        WOLFSSL_MSG("Requested maximum DH key size exceeds MAX_DHKEY_SZ");
1999
0
        return BAD_FUNC_ARG;
2000
0
    }
2001
2002
0
    ssl->options.maxDhKeySz = keySz_bits / 8;
2003
0
    return WOLFSSL_SUCCESS;
2004
0
}
2005
2006
/* Get the size, in bits, of the DH key being used by the object.
2007
 *
2008
 * @param [in] ssl  SSL/TLS object.
2009
 * @return  DH key size in bits on success.
2010
 * @return  BAD_FUNC_ARG when ssl is NULL.
2011
 */
2012
int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
2013
0
{
2014
0
    if (ssl == NULL)
2015
0
        return BAD_FUNC_ARG;
2016
2017
0
    return (ssl->options.dhKeySz * 8);
2018
0
}
2019
2020
#endif /* !NO_DH */
2021
2022
#endif /* !NO_TLS */
2023
2024
#ifdef OPENSSL_EXTRA
2025
#ifndef NO_WOLFSSL_STUB
2026
/* Get the private key of the object.
2027
 *
2028
 * Not implemented - stub for OpenSSL compatibility.
2029
 *
2030
 * @param [in] ssl  SSL/TLS object.
2031
 * @return  NULL always.
2032
 */
2033
WOLFSSL_EVP_PKEY *wolfSSL_get_privatekey(const WOLFSSL *ssl)
2034
{
2035
    (void)ssl;
2036
    WOLFSSL_STUB("SSL_get_privatekey");
2037
    return NULL;
2038
}
2039
#endif
2040
2041
/* Map a wolfSSL MAC/hash algorithm identifier to a NID.
2042
 *
2043
 * @param [in]  hashAlgo  MAC/hash algorithm identifier.
2044
 * @param [out] nid       NID corresponding to the hash algorithm.
2045
 * @return  WOLFSSL_SUCCESS on success.
2046
 * @return  WOLFSSL_FAILURE when the algorithm is not recognized.
2047
 */
2048
static int HashToNid(byte hashAlgo, int* nid)
2049
{
2050
    int ret = WOLFSSL_SUCCESS;
2051
2052
    /* Cast for compiler to check everything is implemented. */
2053
    switch ((enum wc_MACAlgorithm)hashAlgo) {
2054
        case no_mac:
2055
        case rmd_mac:
2056
            *nid = WC_NID_undef;
2057
            break;
2058
        case md5_mac:
2059
            *nid = WC_NID_md5;
2060
            break;
2061
        case sha_mac:
2062
            *nid = WC_NID_sha1;
2063
            break;
2064
        case sha224_mac:
2065
            *nid = WC_NID_sha224;
2066
            break;
2067
        case sha256_mac:
2068
            *nid = WC_NID_sha256;
2069
            break;
2070
        case sha384_mac:
2071
            *nid = WC_NID_sha384;
2072
            break;
2073
        case sha512_mac:
2074
            *nid = WC_NID_sha512;
2075
            break;
2076
        case blake2b_mac:
2077
            *nid = WC_NID_blake2b512;
2078
            break;
2079
        case sm3_mac:
2080
            *nid = WC_NID_sm3;
2081
            break;
2082
        default:
2083
            ret = WOLFSSL_FAILURE;
2084
            break;
2085
    }
2086
2087
    return ret;
2088
}
2089
2090
/* Map a wolfSSL signature algorithm identifier to a NID.
2091
 *
2092
 * @param [in]  sa   Signature algorithm identifier.
2093
 * @param [out] nid  NID corresponding to the signature algorithm.
2094
 * @return  WOLFSSL_SUCCESS on success.
2095
 * @return  WOLFSSL_FAILURE when the algorithm is not recognized or not
2096
 *          compiled in.
2097
 */
2098
static int SaToNid(byte sa, int* nid)
2099
{
2100
    int ret = WOLFSSL_SUCCESS;
2101
2102
    /* Cast for compiler to check everything is implemented. */
2103
    switch ((enum SignatureAlgorithm)sa) {
2104
        case anonymous_sa_algo:
2105
            *nid = WC_NID_undef;
2106
            break;
2107
        case rsa_sa_algo:
2108
            *nid = WC_NID_rsaEncryption;
2109
            break;
2110
        case dsa_sa_algo:
2111
            *nid = WC_NID_dsa;
2112
            break;
2113
        case ecc_dsa_sa_algo:
2114
        case ecc_brainpool_sa_algo:
2115
            *nid = WC_NID_X9_62_id_ecPublicKey;
2116
            break;
2117
        case rsa_pss_sa_algo:
2118
            *nid = WC_NID_rsassaPss;
2119
            break;
2120
        case ed25519_sa_algo:
2121
#ifdef HAVE_ED25519
2122
            *nid = WC_NID_ED25519;
2123
#else
2124
            ret = WOLFSSL_FAILURE;
2125
#endif
2126
            break;
2127
        case rsa_pss_pss_algo:
2128
            *nid = WC_NID_rsassaPss;
2129
            break;
2130
        case ed448_sa_algo:
2131
#ifdef HAVE_ED448
2132
            *nid = WC_NID_ED448;
2133
#else
2134
            ret = WOLFSSL_FAILURE;
2135
#endif
2136
            break;
2137
        case falcon_level1_sa_algo:
2138
            *nid = CTC_FALCON_LEVEL1;
2139
            break;
2140
        case falcon_level5_sa_algo:
2141
            *nid = CTC_FALCON_LEVEL5;
2142
            break;
2143
        case mldsa_44_sa_algo:
2144
            *nid = CTC_ML_DSA_44;
2145
            break;
2146
        case mldsa_65_sa_algo:
2147
            *nid = CTC_ML_DSA_65;
2148
            break;
2149
        case mldsa_87_sa_algo:
2150
            *nid = CTC_ML_DSA_87;
2151
            break;
2152
        case slhdsa_sha2_128s_sa_algo:
2153
            *nid = CTC_SLH_DSA_SHA2_128S;
2154
            break;
2155
        case slhdsa_sha2_128f_sa_algo:
2156
            *nid = CTC_SLH_DSA_SHA2_128F;
2157
            break;
2158
        case slhdsa_sha2_192s_sa_algo:
2159
            *nid = CTC_SLH_DSA_SHA2_192S;
2160
            break;
2161
        case slhdsa_sha2_192f_sa_algo:
2162
            *nid = CTC_SLH_DSA_SHA2_192F;
2163
            break;
2164
        case slhdsa_sha2_256s_sa_algo:
2165
            *nid = CTC_SLH_DSA_SHA2_256S;
2166
            break;
2167
        case slhdsa_sha2_256f_sa_algo:
2168
            *nid = CTC_SLH_DSA_SHA2_256F;
2169
            break;
2170
        case slhdsa_shake_128s_sa_algo:
2171
            *nid = CTC_SLH_DSA_SHAKE_128S;
2172
            break;
2173
        case slhdsa_shake_128f_sa_algo:
2174
            *nid = CTC_SLH_DSA_SHAKE_128F;
2175
            break;
2176
        case slhdsa_shake_192s_sa_algo:
2177
            *nid = CTC_SLH_DSA_SHAKE_192S;
2178
            break;
2179
        case slhdsa_shake_192f_sa_algo:
2180
            *nid = CTC_SLH_DSA_SHAKE_192F;
2181
            break;
2182
        case slhdsa_shake_256s_sa_algo:
2183
            *nid = CTC_SLH_DSA_SHAKE_256S;
2184
            break;
2185
        case slhdsa_shake_256f_sa_algo:
2186
            *nid = CTC_SLH_DSA_SHAKE_256F;
2187
            break;
2188
        case sm2_sa_algo:
2189
            *nid = WC_NID_sm2;
2190
            break;
2191
        case invalid_sa_algo:
2192
        case any_sa_algo:
2193
        default:
2194
            ret = WOLFSSL_FAILURE;
2195
            break;
2196
    }
2197
    return ret;
2198
}
2199
2200
/* Get the NID of the hash algorithm used for signing by this side.
2201
 *
2202
 * @param [in]  ssl  SSL/TLS object.
2203
 * @param [out] nid  NID of the hash algorithm.
2204
 * @return  WOLFSSL_SUCCESS on success.
2205
 * @return  WOLFSSL_FAILURE when ssl or nid is NULL or the algorithm is not
2206
 *          recognized.
2207
 */
2208
int wolfSSL_get_signature_nid(WOLFSSL *ssl, int* nid)
2209
{
2210
    WOLFSSL_MSG("wolfSSL_get_signature_nid");
2211
2212
    if (ssl == NULL || nid == NULL) {
2213
        WOLFSSL_MSG("Bad function arguments");
2214
        return WOLFSSL_FAILURE;
2215
    }
2216
2217
    return HashToNid(ssl->options.hashAlgo, nid);
2218
}
2219
2220
/* Get the NID of the signature algorithm used for signing by this side.
2221
 *
2222
 * @param [in]  ssl  SSL/TLS object.
2223
 * @param [out] nid  NID of the signature algorithm.
2224
 * @return  WOLFSSL_SUCCESS on success.
2225
 * @return  WOLFSSL_FAILURE when ssl or nid is NULL or the algorithm is not
2226
 *          recognized.
2227
 */
2228
int wolfSSL_get_signature_type_nid(const WOLFSSL* ssl, int* nid)
2229
{
2230
    WOLFSSL_MSG("wolfSSL_get_signature_type_nid");
2231
2232
    if (ssl == NULL || nid == NULL) {
2233
        WOLFSSL_MSG("Bad function arguments");
2234
        return WOLFSSL_FAILURE;
2235
    }
2236
2237
    return SaToNid(ssl->options.sigAlgo, nid);
2238
}
2239
2240
/* Get the NID of the hash algorithm used for signing by the peer.
2241
 *
2242
 * @param [in]  ssl  SSL/TLS object.
2243
 * @param [out] nid  NID of the hash algorithm.
2244
 * @return  WOLFSSL_SUCCESS on success.
2245
 * @return  WOLFSSL_FAILURE when ssl or nid is NULL or the algorithm is not
2246
 *          recognized.
2247
 */
2248
int wolfSSL_get_peer_signature_nid(WOLFSSL* ssl, int* nid)
2249
{
2250
    WOLFSSL_MSG("wolfSSL_get_peer_signature_nid");
2251
2252
    if (ssl == NULL || nid == NULL) {
2253
        WOLFSSL_MSG("Bad function arguments");
2254
        return WOLFSSL_FAILURE;
2255
    }
2256
2257
    return HashToNid(ssl->options.peerHashAlgo, nid);
2258
}
2259
2260
/* Get the NID of the signature algorithm used for signing by the peer.
2261
 *
2262
 * @param [in]  ssl  SSL/TLS object.
2263
 * @param [out] nid  NID of the signature algorithm.
2264
 * @return  WOLFSSL_SUCCESS on success.
2265
 * @return  WOLFSSL_FAILURE when ssl or nid is NULL or the algorithm is not
2266
 *          recognized.
2267
 */
2268
int wolfSSL_get_peer_signature_type_nid(const WOLFSSL* ssl, int* nid)
2269
{
2270
    WOLFSSL_MSG("wolfSSL_get_peer_signature_type_nid");
2271
2272
    if (ssl == NULL || nid == NULL) {
2273
        WOLFSSL_MSG("Bad function arguments");
2274
        return WOLFSSL_FAILURE;
2275
    }
2276
2277
    return SaToNid(ssl->options.peerSigAlgo, nid);
2278
}
2279
2280
#endif /* OPENSSL_EXTRA */
2281
2282
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
2283
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
2284
#ifdef HAVE_ECC
2285
/* Set the temporary ECDH key's curve on the context.
2286
 *
2287
 * @param [in] ctx   SSL/TLS context object.
2288
 * @param [in] ecdh  EC key whose curve is to be used.
2289
 * @return  WOLFSSL_SUCCESS on success.
2290
 * @return  BAD_FUNC_ARG when ctx or ecdh is NULL.
2291
 */
2292
int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
2293
{
2294
    WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_tmp_ecdh");
2295
2296
    if (ctx == NULL || ecdh == NULL)
2297
        return BAD_FUNC_ARG;
2298
2299
    ctx->ecdhCurveOID = (word32)ecdh->group->curve_oid;
2300
2301
    return WOLFSSL_SUCCESS;
2302
}
2303
#endif
2304
2305
#endif
2306
2307
#ifdef WOLFSSL_STATIC_EPHEMERAL
2308
/* Decode the loaded static ephemeral key into the given key object.
2309
 *
2310
 * @param [in]  ssl      SSL/TLS object.
2311
 * @param [in]  keyAlgo  Key algorithm: WC_PK_TYPE_DH, WC_PK_TYPE_ECDH,
2312
 *                       WC_PK_TYPE_CURVE25519 or WC_PK_TYPE_CURVE448.
2313
 * @param [out] keyPtr   Key object to decode into.
2314
 * @return  0 on success.
2315
 * @return  BAD_FUNC_ARG when ssl, its context or keyPtr is NULL.
2316
 * @return  BUFFER_E when no static key has been set.
2317
 * @return  NOT_COMPILED_IN when the key algorithm is not supported.
2318
 * @return  Other negative value on error.
2319
 */
2320
int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr)
2321
{
2322
    int ret;
2323
    word32 idx = 0;
2324
    DerBuffer* der = NULL;
2325
2326
    if (ssl == NULL || ssl->ctx == NULL || keyPtr == NULL) {
2327
        return BAD_FUNC_ARG;
2328
    }
2329
2330
#ifndef SINGLE_THREADED
2331
    if (!ssl->ctx->staticKELockInit) {
2332
        return BUFFER_E; /* no keys set */
2333
    }
2334
    ret = wc_LockMutex(&ssl->ctx->staticKELock);
2335
    if (ret != 0) {
2336
        return ret;
2337
    }
2338
#endif
2339
2340
    ret = BUFFER_E; /* set default error */
2341
    switch (keyAlgo) {
2342
    #ifndef NO_DH
2343
        case WC_PK_TYPE_DH:
2344
            if (ssl != NULL)
2345
                der = ssl->staticKE.dhKey;
2346
            if (der == NULL)
2347
                der = ssl->ctx->staticKE.dhKey;
2348
            if (der != NULL) {
2349
                DhKey* key = (DhKey*)keyPtr;
2350
                WOLFSSL_MSG("Using static DH key");
2351
                ret = wc_DhKeyDecode(der->buffer, &idx, key, der->length);
2352
            }
2353
            break;
2354
    #endif
2355
    #ifdef HAVE_ECC
2356
        case WC_PK_TYPE_ECDH:
2357
            if (ssl != NULL)
2358
                der = ssl->staticKE.ecKey;
2359
            if (der == NULL)
2360
                der = ssl->ctx->staticKE.ecKey;
2361
            if (der != NULL) {
2362
                ecc_key* key = (ecc_key*)keyPtr;
2363
                WOLFSSL_MSG("Using static ECDH key");
2364
                ret = wc_EccPrivateKeyDecode(der->buffer, &idx, key,
2365
                    der->length);
2366
            }
2367
            break;
2368
    #endif
2369
    #ifdef HAVE_CURVE25519
2370
        case WC_PK_TYPE_CURVE25519:
2371
            if (ssl != NULL)
2372
                der = ssl->staticKE.x25519Key;
2373
            if (der == NULL)
2374
                der = ssl->ctx->staticKE.x25519Key;
2375
            if (der != NULL) {
2376
                curve25519_key* key = (curve25519_key*)keyPtr;
2377
                WOLFSSL_MSG("Using static X25519 key");
2378
2379
            #ifdef WOLFSSL_CURVE25519_BLINDING
2380
                ret = wc_curve25519_set_rng(key, ssl->rng);
2381
                if (ret == 0)
2382
            #endif
2383
                    ret = wc_Curve25519PrivateKeyDecode(der->buffer, &idx, key,
2384
                        der->length);
2385
            }
2386
            break;
2387
    #endif
2388
    #ifdef HAVE_CURVE448
2389
        case WC_PK_TYPE_CURVE448:
2390
            if (ssl != NULL)
2391
                der = ssl->staticKE.x448Key;
2392
            if (der == NULL)
2393
                der = ssl->ctx->staticKE.x448Key;
2394
            if (der != NULL) {
2395
                curve448_key* key = (curve448_key*)keyPtr;
2396
                WOLFSSL_MSG("Using static X448 key");
2397
                ret = wc_Curve448PrivateKeyDecode(der->buffer, &idx, key,
2398
                    der->length);
2399
            }
2400
            break;
2401
    #endif
2402
        default:
2403
            /* not supported */
2404
            ret = NOT_COMPILED_IN;
2405
            break;
2406
    }
2407
2408
#ifndef SINGLE_THREADED
2409
    wc_UnLockMutex(&ssl->ctx->staticKELock);
2410
#endif
2411
    return ret;
2412
}
2413
2414
/* Detect the algorithm of an ASN.1 DER encoded private key.
2415
 *
2416
 * Attempts to decode the key as each supported algorithm in turn, setting
2417
 * keyAlgo to the first type that decodes successfully. Detection is only
2418
 * performed when keyAlgo is WC_PK_TYPE_NONE on entry.
2419
 *
2420
 * @param [in]      keyBuf   ASN.1 DER encoded private key data.
2421
 * @param [in]      keySz    Length of key data in bytes.
2422
 * @param [in]      heap     Heap hint for dynamic memory allocation.
2423
 * @param [in, out] keyAlgo  Key algorithm. Detected when WC_PK_TYPE_NONE on
2424
 *                           entry; left unchanged otherwise.
2425
 * @return  0 on success.
2426
 * @return  MEMORY_E when dynamic memory allocation fails.
2427
 * @return  Other negative value on key initialization error.
2428
 */
2429
static int DetectStaticEphemeralKeyType(const byte* keyBuf, unsigned int keySz,
2430
    void* heap, int* keyAlgo)
2431
{
2432
    int ret = 0;
2433
2434
#ifdef HAVE_ECC
2435
    {
2436
        word32 idx = 0;
2437
        WC_DECLARE_VAR(eccKey, ecc_key, 1, heap);
2438
        WC_ALLOC_VAR_EX(eccKey, ecc_key, 1, heap, DYNAMIC_TYPE_ECC,
2439
                        ret = MEMORY_E);
2440
        if (ret == 0) {
2441
            ret = wc_ecc_init_ex(eccKey, heap, INVALID_DEVID);
2442
        }
2443
        if (ret == 0) {
2444
            ret = wc_EccPrivateKeyDecode(keyBuf, &idx, eccKey, keySz);
2445
            if (ret == 0) {
2446
                *keyAlgo = WC_PK_TYPE_ECDH;
2447
            }
2448
            wc_ecc_free(eccKey);
2449
            ret = 0; /* clear error to enable key-type detect cascade */
2450
        }
2451
        WC_FREE_VAR_EX(eccKey, heap, DYNAMIC_TYPE_ECC);
2452
    }
2453
#endif
2454
#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
2455
    if (*keyAlgo == WC_PK_TYPE_NONE) {
2456
        word32 idx = 0;
2457
        WC_DECLARE_VAR(dhKey, DhKey, 1, heap);
2458
        WC_ALLOC_VAR_EX(dhKey, DhKey, 1, heap, DYNAMIC_TYPE_DH,
2459
                        ret = MEMORY_E);
2460
        if (ret == 0) {
2461
            ret = wc_InitDhKey_ex(dhKey, heap, INVALID_DEVID);
2462
        }
2463
        if (ret == 0) {
2464
            ret = wc_DhKeyDecode(keyBuf, &idx, dhKey, keySz);
2465
            if (ret == 0) {
2466
                *keyAlgo = WC_PK_TYPE_DH;
2467
            }
2468
            wc_FreeDhKey(dhKey);
2469
            ret = 0; /* clear error to enable key-type detect cascade */
2470
        }
2471
        WC_FREE_VAR_EX(dhKey, heap, DYNAMIC_TYPE_DH);
2472
    }
2473
#endif
2474
#ifdef HAVE_CURVE25519
2475
    if (*keyAlgo == WC_PK_TYPE_NONE) {
2476
        word32 idx = 0;
2477
        WC_DECLARE_VAR(x25519Key, curve25519_key, 1, heap);
2478
        WC_ALLOC_VAR_EX(x25519Key, curve25519_key, 1, heap,
2479
                        DYNAMIC_TYPE_CURVE25519, ret = MEMORY_E);
2480
        if (ret == 0) {
2481
            ret = wc_curve25519_init_ex(x25519Key, heap, INVALID_DEVID);
2482
        }
2483
        if (ret == 0) {
2484
            ret = wc_Curve25519PrivateKeyDecode(keyBuf, &idx,
2485
                x25519Key, keySz);
2486
            if (ret == 0) {
2487
                *keyAlgo = WC_PK_TYPE_CURVE25519;
2488
            }
2489
            wc_curve25519_free(x25519Key);
2490
            ret = 0; /* clear error to enable key-type detect cascade */
2491
        }
2492
        WC_FREE_VAR_EX(x25519Key, heap, DYNAMIC_TYPE_CURVE25519);
2493
    }
2494
#endif
2495
#ifdef HAVE_CURVE448
2496
    if (*keyAlgo == WC_PK_TYPE_NONE) {
2497
        word32 idx = 0;
2498
        WC_DECLARE_VAR(x448Key, curve448_key, 1, heap);
2499
        WC_ALLOC_VAR_EX(x448Key, curve448_key, 1, heap,
2500
                        DYNAMIC_TYPE_CURVE448, ret = MEMORY_E);
2501
        if (ret == 0) {
2502
            ret = wc_curve448_init_ex(x448Key, heap, INVALID_DEVID);
2503
        }
2504
        if (ret == 0) {
2505
            ret = wc_Curve448PrivateKeyDecode(keyBuf, &idx, x448Key,
2506
                keySz);
2507
            if (ret == 0) {
2508
                *keyAlgo = WC_PK_TYPE_CURVE448;
2509
            }
2510
            wc_curve448_free(x448Key);
2511
            ret = 0; /* clear error to enable key-type detect cascade */
2512
        }
2513
        WC_FREE_VAR_EX(x448Key, heap, DYNAMIC_TYPE_CURVE448);
2514
    }
2515
#endif
2516
2517
    (void)keyBuf;
2518
    (void)keySz;
2519
    (void)heap;
2520
    (void)keyAlgo;
2521
2522
    return ret;
2523
}
2524
2525
/* Load and store a static ephemeral key into the static key exchange info.
2526
 *
2527
 * An empty key (key NULL) frees the stored buffer. A file is loaded when key
2528
 * is a path and keySz is 0. The key algorithm is auto-detected when keyAlgo
2529
 * is WC_PK_TYPE_NONE.
2530
 *
2531
 * @param [in]      ctx       SSL/TLS context object (used for the mutex).
2532
 * @param [in, out] staticKE  Static key exchange info to store the key in.
2533
 * @param [in]      keyAlgo   Key algorithm or WC_PK_TYPE_NONE to detect.
2534
 * @param [in]      key       Key data or file path, may be NULL to free.
2535
 * @param [in]      keySz     Length of key data in bytes, 0 to load a file.
2536
 * @param [in]      format    WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
2537
 * @param [in]      heap      Heap hint for dynamic memory allocation.
2538
 * @return  0 on success.
2539
 * @return  BAD_FUNC_ARG when staticKE is NULL or key is NULL with keySz > 0.
2540
 * @return  NOT_COMPILED_IN when the key algorithm is not supported.
2541
 * @return  Other negative value on error.
2542
 */
2543
static int SetStaticEphemeralKey(WOLFSSL_CTX* ctx,
2544
    StaticKeyExchangeInfo_t* staticKE, int keyAlgo, const char* key,
2545
    unsigned int keySz, int format, void* heap)
2546
{
2547
    int ret = 0;
2548
    DerBuffer* der = NULL;
2549
    byte* keyBuf = NULL;
2550
#ifndef NO_FILESYSTEM
2551
    const char* keyFile = NULL;
2552
#endif
2553
2554
    WOLFSSL_ENTER("SetStaticEphemeralKey");
2555
2556
    /* Allow an empty key to free the buffer. */
2557
    if ((staticKE == NULL) || ((key == NULL) && (keySz > 0))) {
2558
        ret = BAD_FUNC_ARG;
2559
    }
2560
2561
    /* If just freeing the key then skip loading. */
2562
    if ((ret == 0) && (key != NULL)) {
2563
    #ifndef NO_FILESYSTEM
2564
        /* Load the file from the filesystem. */
2565
        if ((key != NULL) && (keySz == 0)) {
2566
            size_t keyBufSz = 0;
2567
            keyFile = (const char*)key;
2568
            ret = wc_FileLoad(keyFile, &keyBuf, &keyBufSz, heap);
2569
            if (ret == 0) {
2570
                keySz = (unsigned int)keyBufSz;
2571
            }
2572
        }
2573
        else
2574
    #endif
2575
        {
2576
            /* Use as the key buffer directly. */
2577
            keyBuf = (byte*)key;
2578
        }
2579
2580
        if (ret != 0) {
2581
            /* File load failed - nothing more to process. */
2582
        }
2583
        else if (format == WOLFSSL_FILETYPE_PEM) {
2584
        #ifdef WOLFSSL_PEM_TO_DER
2585
            int keyFormat = 0;
2586
            ret = PemToDer(keyBuf, keySz, PRIVATEKEY_TYPE, &der,
2587
                heap, NULL, &keyFormat);
2588
            /* Auto-detect the key type. */
2589
            if ((ret == 0) && (keyAlgo == WC_PK_TYPE_NONE)) {
2590
                if (keyFormat == ECDSAk) {
2591
                    keyAlgo = WC_PK_TYPE_ECDH;
2592
                }
2593
                else if (keyFormat == X25519k) {
2594
                    keyAlgo = WC_PK_TYPE_CURVE25519;
2595
                }
2596
                else {
2597
                    keyAlgo = WC_PK_TYPE_DH;
2598
                }
2599
            }
2600
        #else
2601
            ret = NOT_COMPILED_IN;
2602
        #endif
2603
        }
2604
        else {
2605
            /* Detect the key type if not specified. */
2606
            if (keyAlgo == WC_PK_TYPE_NONE) {
2607
                ret = DetectStaticEphemeralKeyType(keyBuf, keySz, heap,
2608
                    &keyAlgo);
2609
            }
2610
            if ((ret == 0) && (keyAlgo != WC_PK_TYPE_NONE)) {
2611
                ret = AllocDer(&der, keySz, PRIVATEKEY_TYPE, heap);
2612
                if (ret == 0) {
2613
                    XMEMCPY(der->buffer, keyBuf, keySz);
2614
                }
2615
            }
2616
        }
2617
    }
2618
2619
#ifndef NO_FILESYSTEM
2620
    /* Done with the keyFile buffer. */
2621
    if ((keyFile != NULL) && (keyBuf != NULL)) {
2622
        ForceZero(keyBuf, keySz);
2623
        XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
2624
    }
2625
#endif
2626
2627
#ifndef SINGLE_THREADED
2628
    if ((ret == 0) && (!ctx->staticKELockInit)) {
2629
        ret = wc_InitMutex(&ctx->staticKELock);
2630
        if (ret == 0) {
2631
            ctx->staticKELockInit = 1;
2632
        }
2633
    }
2634
#endif
2635
    if ((ret == 0)
2636
    #ifndef SINGLE_THREADED
2637
        && ((ret = wc_LockMutex(&ctx->staticKELock)) == 0)
2638
    #endif
2639
    ) {
2640
        switch (keyAlgo) {
2641
        #ifndef NO_DH
2642
            case WC_PK_TYPE_DH:
2643
                FreeDer(&staticKE->dhKey);
2644
                staticKE->dhKey = der;
2645
                der = NULL;
2646
                break;
2647
        #endif
2648
        #ifdef HAVE_ECC
2649
            case WC_PK_TYPE_ECDH:
2650
                FreeDer(&staticKE->ecKey);
2651
                staticKE->ecKey = der;
2652
                der = NULL;
2653
                break;
2654
        #endif
2655
        #ifdef HAVE_CURVE25519
2656
            case WC_PK_TYPE_CURVE25519:
2657
                FreeDer(&staticKE->x25519Key);
2658
                staticKE->x25519Key = der;
2659
                der = NULL;
2660
                break;
2661
        #endif
2662
        #ifdef HAVE_CURVE448
2663
            case WC_PK_TYPE_CURVE448:
2664
                FreeDer(&staticKE->x448Key);
2665
                staticKE->x448Key = der;
2666
                der = NULL;
2667
                break;
2668
        #endif
2669
            default:
2670
                /* Not supported. */
2671
                ret = NOT_COMPILED_IN;
2672
                break;
2673
        }
2674
2675
    #ifndef SINGLE_THREADED
2676
        wc_UnLockMutex(&ctx->staticKELock);
2677
    #endif
2678
    }
2679
2680
    if (ret != 0) {
2681
        FreeDer(&der);
2682
    }
2683
2684
    (void)ctx; /* not used for single threaded */
2685
2686
    WOLFSSL_LEAVE("SetStaticEphemeralKey", ret);
2687
2688
    return ret;
2689
}
2690
2691
/* Set the static ephemeral key on the context.
2692
 *
2693
 * @param [in] ctx      SSL/TLS context object.
2694
 * @param [in] keyAlgo  Key algorithm or WC_PK_TYPE_NONE to detect.
2695
 * @param [in] key      Key data or file path.
2696
 * @param [in] keySz    Length of key data in bytes, 0 to load a file.
2697
 * @param [in] format   WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
2698
 * @return  0 on success.
2699
 * @return  BAD_FUNC_ARG when ctx is NULL.
2700
 * @return  Other negative value on error.
2701
 */
2702
int wolfSSL_CTX_set_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
2703
    const char* key, unsigned int keySz, int format)
2704
{
2705
    if (ctx == NULL) {
2706
        return BAD_FUNC_ARG;
2707
    }
2708
    return SetStaticEphemeralKey(ctx, &ctx->staticKE, keyAlgo,
2709
        key, keySz, format, ctx->heap);
2710
}
2711
/* Set the static ephemeral key on the object.
2712
 *
2713
 * @param [in] ssl      SSL/TLS object.
2714
 * @param [in] keyAlgo  Key algorithm or WC_PK_TYPE_NONE to detect.
2715
 * @param [in] key      Key data or file path.
2716
 * @param [in] keySz    Length of key data in bytes, 0 to load a file.
2717
 * @param [in] format   WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
2718
 * @return  0 on success.
2719
 * @return  BAD_FUNC_ARG when ssl or its context is NULL.
2720
 * @return  Other negative value on error.
2721
 */
2722
int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
2723
    const char* key, unsigned int keySz, int format)
2724
{
2725
    if (ssl == NULL || ssl->ctx == NULL) {
2726
        return BAD_FUNC_ARG;
2727
    }
2728
    return SetStaticEphemeralKey(ssl->ctx, &ssl->staticKE, keyAlgo,
2729
        key, keySz, format, ssl->heap);
2730
}
2731
2732
/* Get the loaded static ephemeral key as ASN.1 DER data.
2733
 *
2734
 * @param [in]  ctx      SSL/TLS context object.
2735
 * @param [in]  ssl      SSL/TLS object, may be NULL to use only the context.
2736
 * @param [in]  keyAlgo  Key algorithm to retrieve.
2737
 * @param [out] key      Pointer to the key's DER data. May be NULL.
2738
 * @param [out] keySz    Length of the key's DER data. May be NULL.
2739
 * @return  0 on success.
2740
 * @return  NOT_COMPILED_IN when the key algorithm is not supported.
2741
 * @return  Other negative value on error.
2742
 */
2743
static int GetStaticEphemeralKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
2744
    int keyAlgo, const unsigned char** key, unsigned int* keySz)
2745
{
2746
    int ret = 0;
2747
    DerBuffer* der = NULL;
2748
2749
    if (key)   *key = NULL;
2750
    if (keySz) *keySz = 0;
2751
2752
#ifndef SINGLE_THREADED
2753
    if (ctx->staticKELockInit &&
2754
        (ret = wc_LockMutex(&ctx->staticKELock)) != 0) {
2755
        return ret;
2756
    }
2757
#endif
2758
2759
    switch (keyAlgo) {
2760
    #ifndef NO_DH
2761
        case WC_PK_TYPE_DH:
2762
            if (ssl != NULL)
2763
                der = ssl->staticKE.dhKey;
2764
            if (der == NULL)
2765
                der = ctx->staticKE.dhKey;
2766
            break;
2767
    #endif
2768
    #ifdef HAVE_ECC
2769
        case WC_PK_TYPE_ECDH:
2770
            if (ssl != NULL)
2771
                der = ssl->staticKE.ecKey;
2772
            if (der == NULL)
2773
                der = ctx->staticKE.ecKey;
2774
            break;
2775
    #endif
2776
    #ifdef HAVE_CURVE25519
2777
        case WC_PK_TYPE_CURVE25519:
2778
            if (ssl != NULL)
2779
                der = ssl->staticKE.x25519Key;
2780
            if (der == NULL)
2781
                der = ctx->staticKE.x25519Key;
2782
            break;
2783
    #endif
2784
    #ifdef HAVE_CURVE448
2785
        case WC_PK_TYPE_CURVE448:
2786
            if (ssl != NULL)
2787
                der = ssl->staticKE.x448Key;
2788
            if (der == NULL)
2789
                der = ctx->staticKE.x448Key;
2790
            break;
2791
    #endif
2792
        default:
2793
            /* not supported */
2794
            ret = NOT_COMPILED_IN;
2795
            break;
2796
    }
2797
2798
    if (der) {
2799
        if (key)
2800
            *key = der->buffer;
2801
        if (keySz)
2802
            *keySz = der->length;
2803
    }
2804
2805
#ifndef SINGLE_THREADED
2806
    wc_UnLockMutex(&ctx->staticKELock);
2807
#endif
2808
2809
    return ret;
2810
}
2811
2812
/* Get the static ephemeral key set on the context as ASN.1 DER data.
2813
 *
2814
 * The returned data can be converted to PEM using wc_DerToPem().
2815
 *
2816
 * @param [in]  ctx      SSL/TLS context object.
2817
 * @param [in]  keyAlgo  Key algorithm to retrieve.
2818
 * @param [out] key      Pointer to the key's DER data. May be NULL.
2819
 * @param [out] keySz    Length of the key's DER data. May be NULL.
2820
 * @return  0 on success.
2821
 * @return  BAD_FUNC_ARG when ctx is NULL.
2822
 * @return  Other negative value on error.
2823
 */
2824
int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
2825
    const unsigned char** key, unsigned int* keySz)
2826
{
2827
    if (ctx == NULL) {
2828
        return BAD_FUNC_ARG;
2829
    }
2830
2831
    return GetStaticEphemeralKey(ctx, NULL, keyAlgo, key, keySz);
2832
}
2833
/* Get the static ephemeral key in use by the object as ASN.1 DER data.
2834
 *
2835
 * @param [in]  ssl      SSL/TLS object.
2836
 * @param [in]  keyAlgo  Key algorithm to retrieve.
2837
 * @param [out] key      Pointer to the key's DER data. May be NULL.
2838
 * @param [out] keySz    Length of the key's DER data. May be NULL.
2839
 * @return  0 on success.
2840
 * @return  BAD_FUNC_ARG when ssl or its context is NULL.
2841
 * @return  Other negative value on error.
2842
 */
2843
int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
2844
    const unsigned char** key, unsigned int* keySz)
2845
{
2846
    if (ssl == NULL || ssl->ctx == NULL) {
2847
        return BAD_FUNC_ARG;
2848
    }
2849
2850
    return GetStaticEphemeralKey(ssl->ctx, ssl, keyAlgo, key, keySz);
2851
}
2852
2853
#endif /* WOLFSSL_STATIC_EPHEMERAL */
2854
2855
#ifdef OPENSSL_EXTRA
2856
/* Enable or disable automatic ECDH curve selection on the object.
2857
 *
2858
 * Provided for compatibility with SSL_set_ecdh_auto(). Automatic selection is
2859
 * always enabled in wolfSSL so this is a stub.
2860
 *
2861
 * @param [in] ssl    SSL/TLS object.
2862
 * @param [in] onoff  Ignored.
2863
 * @return  WOLFSSL_SUCCESS always.
2864
 */
2865
int wolfSSL_set_ecdh_auto(WOLFSSL* ssl, int onoff)
2866
{
2867
    (void)ssl;
2868
    (void)onoff;
2869
    return WOLFSSL_SUCCESS;
2870
}
2871
/* Enable or disable automatic ECDH curve selection on the context.
2872
 *
2873
 * Provided for compatibility with SSL_CTX_set_ecdh_auto(). Automatic selection
2874
 * is always enabled in wolfSSL so this is a stub.
2875
 *
2876
 * @param [in] ctx    SSL/TLS context object.
2877
 * @param [in] onoff  Ignored.
2878
 * @return  WOLFSSL_SUCCESS always.
2879
 */
2880
int wolfSSL_CTX_set_ecdh_auto(WOLFSSL_CTX* ctx, int onoff)
2881
{
2882
    (void)ctx;
2883
    (void)onoff;
2884
    return WOLFSSL_SUCCESS;
2885
}
2886
2887
/* Enable or disable automatic DH parameter selection on the context.
2888
 *
2889
 * Provided for compatibility with SSL_CTX_set_dh_auto(). Automatic selection
2890
 * is always enabled in wolfSSL so this is a stub.
2891
 *
2892
 * @param [in] ctx    SSL/TLS context object.
2893
 * @param [in] onoff  Ignored.
2894
 * @return  WOLFSSL_SUCCESS always.
2895
 */
2896
int wolfSSL_CTX_set_dh_auto(WOLFSSL_CTX* ctx, int onoff)
2897
{
2898
    (void)ctx;
2899
    (void)onoff;
2900
    return WOLFSSL_SUCCESS;
2901
}
2902
2903
    #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
2904
        && !defined(WC_NO_RNG)
2905
    static const byte srp_N[] = {
2906
        0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6, 0x9C, 0x33, 0xF8,
2907
        0x0A, 0xFA, 0x8F, 0xC5, 0xE8, 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF,
2908
        0x3C, 0x0B, 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76, 0xD6,
2909
        0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3, 0x38, 0x3B, 0x48, 0x13,
2910
        0xD6, 0x92, 0xC6, 0xE0, 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B,
2911
        0xE4, 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1, 0x5D, 0xC7,
2912
        0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6, 0xCE, 0x8E, 0xF4, 0xAD, 0x69,
2913
        0xB1, 0x5D, 0x49, 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
2914
        0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC, 0x68, 0xED, 0xBC,
2915
        0x3C, 0x05, 0x72, 0x6C, 0xC0, 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E,
2916
        0xAA, 0x9A, 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B, 0x9F,
2917
        0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
2918
    };
2919
    static const byte srp_g[] = {
2920
        0x02
2921
    };
2922
2923
    /* Set the SRP username on the SSL/TLS CTX object.
2924
     *
2925
     * The SRP side is taken from the method of the CTX object. When a password
2926
     * has already been set with wolfSSL_CTX_set_srp_password() then the saved
2927
     * password is applied here.
2928
     *
2929
     * @param [in, out] ctx       SSL/TLS CTX object.
2930
     * @param [in]      username  SRP username.
2931
     * @return  WOLFSSL_SUCCESS on success.
2932
     * @return  WOLFSSL_FAILURE when ctx, its SRP object or username is NULL,
2933
     *          the side is not set, or a wolfCrypt SRP operation fails.
2934
     */
2935
    int wolfSSL_CTX_set_srp_username(WOLFSSL_CTX* ctx, char* username)
2936
    {
2937
        int r = 0;
2938
        SrpSide srp_side = SRP_CLIENT_SIDE;
2939
2940
        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_username");
2941
        if (ctx == NULL || ctx->srp == NULL || username==NULL)
2942
            return WOLFSSL_FAILURE;
2943
2944
        if (ctx->method->side == WOLFSSL_SERVER_END){
2945
            srp_side = SRP_SERVER_SIDE;
2946
        } else if (ctx->method->side == WOLFSSL_CLIENT_END){
2947
            srp_side = SRP_CLIENT_SIDE;
2948
        } else {
2949
            WOLFSSL_MSG("Init CTX failed");
2950
            return WOLFSSL_FAILURE;
2951
        }
2952
2953
        if (wc_SrpInit(ctx->srp, SRP_TYPE_SHA256, srp_side) < 0) {
2954
            WOLFSSL_MSG("Init SRP CTX failed");
2955
            XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
2956
            ctx->srp = NULL;
2957
            return WOLFSSL_FAILURE;
2958
        }
2959
        r = wc_SrpSetUsername(ctx->srp, (const byte*)username,
2960
                              (word32)XSTRLEN(username));
2961
        if (r < 0) {
2962
            WOLFSSL_MSG("fail to set srp username.");
2963
            return WOLFSSL_FAILURE;
2964
        }
2965
2966
        /* if wolfSSL_CTX_set_srp_password has already been called, */
2967
        /* use saved password here */
2968
        if (ctx->srp_password != NULL) {
2969
            if (ctx->srp->user == NULL)
2970
                return WOLFSSL_FAILURE;
2971
            return wolfSSL_CTX_set_srp_password(ctx, (char*)ctx->srp_password);
2972
        }
2973
2974
        return WOLFSSL_SUCCESS;
2975
    }
2976
2977
    /* Set the SRP password on the SSL/TLS CTX object.
2978
     *
2979
     * When the username has been set, the SRP parameters and a random salt are
2980
     * set on the SRP object with the password. Otherwise the password is saved
2981
     * for wolfSSL_CTX_set_srp_username() to apply.
2982
     *
2983
     * @param [in, out] ctx       SSL/TLS CTX object.
2984
     * @param [in]      password  SRP password.
2985
     * @return  WOLFSSL_SUCCESS on success.
2986
     * @return  WOLFSSL_FAILURE when ctx, its SRP object or password is NULL, a
2987
     *          wolfCrypt SRP operation fails or dynamic memory allocation
2988
     *          fails.
2989
     */
2990
    int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX* ctx, char* password)
2991
    {
2992
        int r;
2993
        byte salt[SRP_SALT_SIZE];
2994
2995
        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_password");
2996
        if (ctx == NULL || ctx->srp == NULL || password == NULL)
2997
            return WOLFSSL_FAILURE;
2998
2999
        if (ctx->srp->user != NULL) {
3000
            WC_RNG rng;
3001
            if (wc_InitRng(&rng) < 0) {
3002
                WOLFSSL_MSG("wc_InitRng failed");
3003
                return WOLFSSL_FAILURE;
3004
            }
3005
            XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
3006
            r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0]));
3007
            wc_FreeRng(&rng);
3008
            if (r <  0) {
3009
                WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
3010
                return WOLFSSL_FAILURE;
3011
            }
3012
            if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
3013
                                srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
3014
                                salt, sizeof(salt)/sizeof(salt[0])) < 0){
3015
                WOLFSSL_MSG("wc_SrpSetParam failed");
3016
                return WOLFSSL_FAILURE;
3017
            }
3018
            r = wc_SrpSetPassword(ctx->srp, (const byte*)password,
3019
                                  (word32)XSTRLEN(password));
3020
            if (r < 0) {
3021
                WOLFSSL_MSG("wc_SrpSetPassword failed.");
3022
                return WOLFSSL_FAILURE;
3023
            }
3024
            if (ctx->srp_password != NULL) {
3025
                ForceZero(ctx->srp_password,
3026
                          (word32)XSTRLEN((char*)ctx->srp_password));
3027
            }
3028
            XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
3029
            ctx->srp_password = NULL;
3030
        } else {
3031
            /* save password for wolfSSL_set_srp_username */
3032
            if (ctx->srp_password != NULL) {
3033
                ForceZero(ctx->srp_password,
3034
                          (word32)XSTRLEN((char*)ctx->srp_password));
3035
            }
3036
            XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
3037
3038
            ctx->srp_password = (byte*)XMALLOC(XSTRLEN(password) + 1, ctx->heap,
3039
                                               DYNAMIC_TYPE_SRP);
3040
            if (ctx->srp_password == NULL){
3041
                WOLFSSL_MSG("memory allocation error");
3042
                return WOLFSSL_FAILURE;
3043
            }
3044
            XMEMCPY(ctx->srp_password, password, XSTRLEN(password) + 1);
3045
        }
3046
        return WOLFSSL_SUCCESS;
3047
    }
3048
3049
    /**
3050
     * The modulus passed to wc_SrpSetParams in ssl_api_pk.c is constant so
3051
     * check that the requested strength is less than or equal to the size of
3052
     * the static modulus size.
3053
     * @param ctx Not used
3054
     * @param strength Minimum number of bits for the modulus
3055
     * @return 1 if strength is less than or equal to static modulus
3056
     *         0 if strength is greater than static modulus
3057
     */
3058
    int  wolfSSL_CTX_set_srp_strength(WOLFSSL_CTX *ctx, int strength)
3059
    {
3060
        (void)ctx;
3061
        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_strength");
3062
        if (strength > (int)(sizeof(srp_N)*8)) {
3063
            WOLFSSL_MSG("Bad Parameter");
3064
            return WOLFSSL_FAILURE;
3065
        }
3066
        return WOLFSSL_SUCCESS;
3067
    }
3068
3069
    /* Get the SRP username set on the CTX object of an SSL/TLS object.
3070
     *
3071
     * @param [in] ssl  SSL/TLS object.
3072
     * @return  SRP username on success.
3073
     * @return  NULL when ssl, its CTX object or the SRP object is NULL.
3074
     */
3075
    char* wolfSSL_get_srp_username(WOLFSSL *ssl)
3076
    {
3077
        if (ssl && ssl->ctx && ssl->ctx->srp) {
3078
            return (char*) ssl->ctx->srp->user;
3079
        }
3080
        return NULL;
3081
    }
3082
    #endif /* WOLFCRYPT_HAVE_SRP && !NO_SHA256 && !WC_NO_RNG */
3083
3084
#endif /* OPENSSL_EXTRA */
3085
3086
#endif /* !WOLFCRYPT_ONLY */
3087
3088
#endif /* !WOLFSSL_SSL_API_PK_INCLUDED */