Coverage Report

Created: 2026-07-16 06:50

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