Coverage Report

Created: 2026-09-04 06:41

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