Coverage Report

Created: 2025-06-23 06:10

/src/wolfssl/src/ssl_load.c
Line
Count
Source (jump to first uncovered line)
1
/* ssl_load.c
2
 *
3
 * Copyright (C) 2006-2025 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 2 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
/*
25
 * WOLFSSL_SYS_CA_CERTS
26
 *     Enables ability to load system CA certs from the OS via
27
 *     wolfSSL_CTX_load_system_CA_certs.
28
 */
29
30
#ifdef WOLFSSL_SYS_CA_CERTS
31
32
#ifdef _WIN32
33
    #define _WINSOCKAPI_ /* block inclusion of winsock.h header file */
34
    #include <windows.h>
35
    #include <wincrypt.h>
36
    #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header file */
37
38
    /* mingw gcc does not support pragma comment, and the
39
     * linking with crypt32 is handled in configure.ac */
40
    #if !defined(__MINGW32__) && !defined(__MINGW64__)
41
        #pragma comment(lib, "crypt32")
42
    #endif
43
#endif
44
45
#if defined(__APPLE__) && defined(HAVE_SECURITY_SECTRUSTSETTINGS_H)
46
#include <Security/SecTrustSettings.h>
47
#endif
48
49
#endif /* WOLFSSL_SYS_CA_CERTS */
50
51
#if !defined(WOLFSSL_SSL_LOAD_INCLUDED)
52
    #ifndef WOLFSSL_IGNORE_FILE_WARN
53
        #warning ssl_load.c does not need to be compiled separately from ssl.c
54
    #endif
55
#else
56
57
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
58
    /* PSK field of context when it exists. */
59
    #define CTX_HAVE_PSK(ctx)   (ctx)->havePSK
60
    /* PSK field of ssl when it exists. */
61
    #define SSL_HAVE_PSK(ssl)   (ssl)->options.havePSK
62
#else
63
    /* Have PSK value when no field. */
64
0
    #define CTX_HAVE_PSK(ctx)   0
65
    /* Have PSK value when no field. */
66
0
    #define SSL_HAVE_PSK(ssl)   0
67
#endif
68
#ifdef NO_RSA
69
    /* Boolean for RSA available. */
70
    #define WOLFSSL_HAVE_RSA    0
71
#else
72
    /* Boolean for RSA available. */
73
0
    #define WOLFSSL_HAVE_RSA    1
74
#endif
75
#ifndef NO_CERTS
76
    /* Private key size from ssl. */
77
0
    #define SSL_KEY_SZ(ssl)     (ssl)->buffers.keySz
78
#else
79
    /* Private key size not available. */
80
    #define SSL_KEY_SZ(ssl)     0
81
#endif
82
#ifdef HAVE_ANON
83
    /* Anonymous ciphersuite allowed field in context. */
84
    #define CTX_USE_ANON(ctx)   (ctx)->useAnon
85
#else
86
    /* Anonymous ciphersuite allowed field not in context. */
87
0
    #define CTX_USE_ANON(ctx)   0
88
#endif
89
90
#ifdef HAVE_PK_CALLBACKS
91
    #define WOLFSSL_IS_PRIV_PK_SET(ctx, ssl)                            \
92
        wolfSSL_CTX_IsPrivatePkSet(((ssl) == NULL) ? (ctx) : (ssl)->ctx)
93
#else
94
    #define WOLFSSL_IS_PRIV_PK_SET(ctx, ssl)    0
95
#endif
96
97
/* Get the heap from the context or the ssl depending on which is available. */
98
#define WOLFSSL_HEAP(ctx, ssl)                                              \
99
0
    (((ctx) != NULL) ? (ctx)->heap : (((ssl) != NULL) ? (ssl)->heap : NULL))
100
101
102
#ifndef NO_CERTS
103
104
/* Get DER encoding from data in a buffer as a DerBuffer.
105
 *
106
 * @param [in]      buff    Buffer containing data.
107
 * @param [in]      len     Length of data in buffer.
108
 * @param [in]      format  Format of data:
109
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
110
 * @param [in]      type    Type of data:
111
 *                            CERT_TYPE, CA_TYPE, TRUSTED_PEER_TYPE,
112
 *                            PRIVATEKEY_TYPE or ALT_PRIVATEKEY_TYPE.
113
 * @param [in, out] info    Info for encryption.
114
 * @param [in]      heap    Dynamic memory allocation hint.
115
 * @param [out]     der     Holds DER encoded data.
116
 * @param [out]     algId   Algorithm identifier for private keys.
117
 * @return  0 on success.
118
 * @return  NOT_COMPILED_IN when format is PEM and PEM not supported.
119
 * @return  ASN_PARSE_E when format is ASN.1 and invalid DER encoding.
120
 * @return  MEMORY_E when dynamic memory allocation fails.
121
 */
122
static int DataToDerBuffer(const unsigned char* buff, word32 len, int format,
123
    int type, EncryptedInfo* info, void* heap, DerBuffer** der, int* algId)
124
0
{
125
0
    int ret;
126
127
0
    info->consumed = 0;
128
129
    /* Data in buffer has PEM format - extract DER data. */
130
0
    if (format == WOLFSSL_FILETYPE_PEM) {
131
0
    #ifdef WOLFSSL_PEM_TO_DER
132
0
        ret = PemToDer(buff, (long)(len), type, der, heap, info, algId);
133
0
        if (ret != 0) {
134
0
            FreeDer(der);
135
0
        }
136
    #else
137
        (void)algId;
138
        ret = NOT_COMPILED_IN;
139
    #endif
140
0
    }
141
    /* Data in buffer is ASN.1 format - get first SEQ or OCT into der. */
142
0
    else {
143
        /* Get length of SEQ including header. */
144
0
        if ((info->consumed = wolfssl_der_length(buff, (int)len)) > 0) {
145
0
            ret = 0;
146
0
        }
147
0
        else {
148
0
            ret = ASN_PARSE_E;
149
0
        }
150
151
0
        if (info->consumed > (int)len) {
152
0
            ret = ASN_PARSE_E;
153
0
        }
154
0
        if (ret == 0) {
155
0
            ret = AllocCopyDer(der, buff, (word32)info->consumed, type, heap);
156
0
        }
157
0
    }
158
159
0
    return ret;
160
0
}
161
162
/* Process a user's certificate.
163
 *
164
 * Puts the 3-byte length before certificate data as required for TLS.
165
 * CA certificates are added to the certificate manager.
166
 *
167
 * @param [in]      cm           Certificate manager.
168
 * @param [in, out] pDer         DER encoded data.
169
 * @param [in]      type         Type of data. Valid values:
170
 *                                 CERT_TYPE, CA_TYPE or TRUSTED_PEER_TYPE.
171
 * @param [in]      verify       How to verify certificate.
172
 * @param [out]     chainBuffer  Buffer to hold chain of certificates.
173
 * @param [in, out] pIdx         On in, current index into chainBuffer.
174
 *                               On out, index after certificate added.
175
 * @param [in]      bufferSz     Size of buffer in bytes.
176
 * @return  0 on success.
177
 * @return  BUFFER_E if chain buffer not big enough to hold certificate.
178
 */
179
static int ProcessUserCert(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer,
180
    int type, int verify, byte* chainBuffer, word32* pIdx, word32 bufferSz)
181
0
{
182
0
    int ret = 0;
183
0
    word32 idx = *pIdx;
184
0
    DerBuffer* der = *pDer;
185
186
    /* Check there is space for certificate in chainBuffer. */
187
0
    if ((ret == 0) && ((idx + der->length + CERT_HEADER_SZ) > bufferSz)) {
188
0
        WOLFSSL_MSG("   Cert Chain bigger than buffer. "
189
0
                    "Consider increasing MAX_CHAIN_DEPTH");
190
0
        ret = BUFFER_E;
191
0
    }
192
0
    if (ret == 0) {
193
        /* 3-byte length. */
194
0
        c32to24(der->length, &chainBuffer[idx]);
195
0
        idx += CERT_HEADER_SZ;
196
        /* Add complete DER encoded certificate. */
197
0
        XMEMCPY(&chainBuffer[idx], der->buffer, der->length);
198
0
        idx += der->length;
199
200
0
        if (type == CA_TYPE) {
201
            /* Add CA to certificate manager */
202
0
            ret = AddCA(cm, pDer, WOLFSSL_USER_CA, verify);
203
0
            if (ret == 1) {
204
0
                ret = 0;
205
0
            }
206
0
        }
207
0
    }
208
209
    /* Update the index into chainBuffer. */
210
0
    *pIdx = idx;
211
0
    return ret;
212
0
}
213
214
/* Store the certificate chain buffer aganst WOLFSSL_CTX or WOLFSSL object.
215
 *
216
 * @param [in, out] ctx          SSL context object.
217
 * @param [in, out] ssl          SSL object.
218
 * @param [in]      chainBuffer  Buffer containing chain of certificates.
219
 * @param [in]      len          Length, in bytes, of data in buffer.
220
 * @param [in]      cnt          Number of certificates in chain.
221
 * @param [in]      type         Type of data. Valid values:
222
 *                                 CERT_TYPE, CA_TYPE or CHAIN_CERT_TYPE.
223
 * @param [in]      heap         Dynamic memory allocation hint.
224
 * @return  0 on success.
225
 * @return  MEMORY_E when dynamic memory allocation fails.
226
 */
227
static int ProcessUserChainRetain(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
228
    const byte* chainBuffer, word32 len, int cnt, int type, void* heap)
229
0
{
230
0
    int ret = 0;
231
232
0
    (void)cnt;
233
234
    /* Store in SSL object if available. */
235
0
    if (ssl != NULL) {
236
        /* Dispose of old chain if not reference to context's. */
237
0
        if (ssl->buffers.weOwnCertChain) {
238
0
            FreeDer(&ssl->buffers.certChain);
239
0
        }
240
        /* Allocate and copy the buffer into SSL object. */
241
0
        ret = AllocCopyDer(&ssl->buffers.certChain, chainBuffer, len, type,
242
0
            heap);
243
0
        ssl->buffers.weOwnCertChain = (ret == 0);
244
0
    #ifdef WOLFSSL_TLS13
245
        /* Update count of certificates in chain. */
246
0
        ssl->buffers.certChainCnt = cnt;
247
0
    #endif
248
0
    }
249
    /* Store in SSL context object if available. */
250
0
    else if (ctx != NULL) {
251
        /* Dispose of old chain and allocate and copy in new chain. */
252
0
        FreeDer(&ctx->certChain);
253
        /* Allocate and copy the buffer into SSL context object. */
254
0
        ret = AllocCopyDer(&ctx->certChain, chainBuffer, len, type, heap);
255
0
    #ifdef WOLFSSL_TLS13
256
        /* Update count of certificates in chain. */
257
0
        ctx->certChainCnt = cnt;
258
0
    #endif
259
0
    }
260
261
0
    return ret;
262
0
}
263
264
/* Process user cert chain to pass during the TLS handshake.
265
 *
266
 * If not a certificate type then data is ignored.
267
 *
268
 * @param [in, out] ctx     SSL context object.
269
 * @param [in, out] ssl     SSL object.
270
 * @param [in]      buff    Buffer holding certificates.
271
 * @param [in]      sz      Length of data in buffer.
272
 * @param [in]      format  Format of the certificate:
273
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1
274
 * @param [in]      type    Type of certificate:
275
 *                            CA_TYPE, CERT_TYPE or CHAIN_CERT_TYPE
276
 * @param [out]     used    Number of bytes from buff used.
277
 * @param [in, out] info    Encryption information.
278
 * @param [in]      verify  How to verify certificate.
279
 * @return  0 on success.
280
 * @return  BAD_FUNC_ARG when type is CA_TYPE and ctx is NULL.
281
 * @return  MEMORY_E when dynamic memory allocation fails.
282
 */
283
static int ProcessUserChain(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
284
    const unsigned char* buff, long sz, int format, int type, long* used,
285
    EncryptedInfo* info, int verify)
286
0
{
287
0
    int ret = 0;
288
0
    void* heap = WOLFSSL_HEAP(ctx, ssl);
289
290
0
    WOLFSSL_ENTER("ProcessUserChain");
291
292
    /* Check we haven't consumed all the data. */
293
0
    if (info->consumed >= sz) {
294
0
        WOLFSSL_MSG("Already consumed data");
295
0
    }
296
0
    else {
297
0
    #ifndef WOLFSSL_SMALL_STACK
298
0
        byte stackBuffer[FILE_BUFFER_SIZE];
299
0
    #endif
300
0
        StaticBuffer chain;
301
0
        long   consumed = info->consumed;
302
0
        word32 idx = 0;
303
0
        int    gotOne = 0;
304
0
        int    cnt = 0;
305
        /* Calculate max possible size, including max headers */
306
0
        long   maxSz = (sz - consumed) + (CERT_HEADER_SZ * MAX_CHAIN_DEPTH);
307
308
        /* Setup buffer to hold chain. */
309
    #ifdef WOLFSSL_SMALL_STACK
310
        static_buffer_init(&chain);
311
    #else
312
0
        static_buffer_init(&chain, stackBuffer, FILE_BUFFER_SIZE);
313
0
    #endif
314
        /* Make buffer big enough to support maximum size. */
315
0
        ret = static_buffer_set_size(&chain, (word32)maxSz, heap,
316
0
            DYNAMIC_TYPE_FILE);
317
318
0
        WOLFSSL_MSG("Processing Cert Chain");
319
        /* Keep parsing certificates will data available. */
320
0
        while ((ret == 0) && (consumed < sz)) {
321
0
            DerBuffer* part = NULL;
322
323
            /* Get a certificate as DER. */
324
0
            ret = DataToDerBuffer(buff + consumed, (word32)(sz - consumed),
325
0
                format, type, info, heap, &part, NULL);
326
0
            if (ret == 0) {
327
                /* Process the user certificate. */
328
0
                ret = ProcessUserCert(ctx->cm, &part, type, verify,
329
0
                   chain.buffer, &idx, (word32)maxSz);
330
0
            }
331
            /* PEM may have trailing data that can be ignored. */
332
0
            if ((ret == WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER)) && gotOne) {
333
0
                WOLFSSL_MSG("We got one good cert, so stuff at end ok");
334
0
                ret = 0;
335
0
                break;
336
0
            }
337
            /* Certificate data handled. */
338
0
            FreeDer(&part);
339
340
0
            if (ret == 0) {
341
                /* Update consumed length. */
342
0
                consumed += info->consumed;
343
0
                WOLFSSL_MSG("   Consumed another Cert in Chain");
344
                /* Update whether we got a user certificate. */
345
0
                gotOne |= (type != CA_TYPE);
346
                /* Update count of certificates added to chain. */
347
0
                cnt++;
348
0
            }
349
0
        }
350
0
        if (used != NULL) {
351
            /* Return the total consumed length. */
352
0
            *used = consumed;
353
0
        }
354
355
        /* Check whether there is data in the chain buffer. */
356
0
        if ((ret == 0) && (idx > 0)) {
357
            /* Put the chain buffer against the SSL or SSL context object. */
358
0
            ret = ProcessUserChainRetain(ctx, ssl, chain.buffer, idx, cnt, type,
359
0
                heap);
360
0
        }
361
362
        /* Dispose of chain buffer. */
363
0
        static_buffer_free(&chain, heap, DYNAMIC_TYPE_FILE);
364
0
    }
365
366
0
    WOLFSSL_LEAVE("ProcessUserChain", ret);
367
0
    return ret;
368
0
}
369
370
#ifndef NO_RSA
371
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
372
    (HAVE_FIPS_VERSION > 2))
373
/* See if DER data is an RSA private key.
374
 *
375
 * Checks size meets minimum RSA key size.
376
 * This implementation uses less dynamic memory.
377
 *
378
 * @param [in, out] ctx        SSL context object.
379
 * @param [in, out] ssl        SSL object.
380
 * @param [in]      der        DER encoding.
381
 * @param [in, out] keyFormat  On in, expected format. 0 means unknown.
382
 * @param [in]      devId      Device identifier.
383
 * @param [out]     keyType    Type of key.
384
 * @param [out]     keySize    Size of key.
385
 * @return  0 on success or not an RSA key and format unknown.
386
 * @return  RSA_KEY_SIZE_E when key size doesn't meet minimum required.
387
 */
388
static int ProcessBufferTryDecodeRsa(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
389
    DerBuffer* der, int* keyFormat, int devId, byte* keyType, int* keySize)
390
0
{
391
0
    int ret;
392
0
    word32 idx;
393
0
    int keySz = 0;
394
395
0
    (void)devId;
396
397
    /* Validate we have an RSA private key and get key size. */
398
0
    idx = 0;
399
0
    ret = wc_RsaPrivateKeyValidate(der->buffer, &idx, &keySz, der->length);
400
#ifdef WOLF_PRIVATE_KEY_ID
401
    /* If that didn't work then maybe a public key if device ID or callback. */
402
    if ((ret != 0) && ((devId != INVALID_DEVID) ||
403
            WOLFSSL_IS_PRIV_PK_SET(ctx, ssl))) {
404
        word32 nSz;
405
406
        /* Decode as an RSA public key. */
407
        idx = 0;
408
        ret = wc_RsaPublicKeyDecode_ex(der->buffer, &idx, der->length, NULL,
409
            &nSz, NULL, NULL);
410
        if (ret == 0) {
411
            keySz = (int)nSz;
412
        }
413
    }
414
#endif
415
0
    if (ret == 0) {
416
        /* Get the minimum RSA key size from SSL or SSL context object. */
417
0
        int minRsaSz = ssl ? ssl->options.minRsaKeySz : ctx->minRsaKeySz;
418
419
        /* Format, type and size are known. */
420
0
        *keyFormat = RSAk;
421
0
        *keyType = rsa_sa_algo;
422
0
        *keySize = keySz;
423
424
        /* Check that the size of the RSA key is enough. */
425
0
        if (keySz < minRsaSz) {
426
0
            WOLFSSL_MSG("Private Key size too small");
427
0
            ret = RSA_KEY_SIZE_E;
428
0
        }
429
         /* No static ECC key possible. */
430
0
        if ((ssl != NULL) && (ssl->options.side == WOLFSSL_SERVER_END)) {
431
0
             ssl->options.haveStaticECC = 0;
432
0
        }
433
0
    }
434
    /* Not an RSA key but check whether we know what it is. */
435
0
    else if (*keyFormat == 0) {
436
0
        WOLFSSL_MSG("Not an RSA key");
437
        /* Format unknown so keep trying. */
438
0
        ret = 0;
439
0
    }
440
441
0
    return ret;
442
0
}
443
#else
444
/* See if DER data is an RSA private key.
445
 *
446
 * Checks size meets minimum RSA key size.
447
 * This implementation uses more dynamic memory but supports older FIPS.
448
 *
449
 * @param [in, out] ctx        SSL context object.
450
 * @param [in, out] ssl        SSL object.
451
 * @param [in]      der        DER encoding.
452
 * @param [in, out] keyFormat  On in, expected format. 0 means unknown.
453
 * @param [in]      heap       Dynamic memory allocation hint.
454
 * @param [in]      devId      Device identifier.
455
 * @param [out]     keyType    Type of key.
456
 * @param [out]     keySize    Size of key.
457
 * @return  0 on success or not an RSA key and format unknown.
458
 * @return  RSA_KEY_SIZE_E when key size doesn't meet minimum required.
459
 */
460
static int ProcessBufferTryDecodeRsa(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
461
    DerBuffer* der, int* keyFormat, void* heap, int devId, byte* keyType,
462
    int* keySize)
463
{
464
    int ret;
465
    word32 idx;
466
    /* make sure RSA key can be used */
467
#ifdef WOLFSSL_SMALL_STACK
468
    RsaKey* key;
469
#else
470
    RsaKey  key[1];
471
#endif
472
473
#ifdef WOLFSSL_SMALL_STACK
474
    /* Allocate an RSA key to parse into so we can get size. */
475
    key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA);
476
    if (key == NULL)
477
        return MEMORY_E;
478
#endif
479
480
    /* Initialize the RSA key. */
481
    ret = wc_InitRsaKey_ex(key, heap, devId);
482
    if (ret == 0) {
483
        /* Check we have an RSA private key. */
484
        idx = 0;
485
        ret = wc_RsaPrivateKeyDecode(der->buffer, &idx, key, der->length);
486
    #ifdef WOLF_PRIVATE_KEY_ID
487
        /* If that didn't work then maybe a public key if device ID or callback.
488
         */
489
        if ((ret != 0) && ((devId != INVALID_DEVID) ||
490
                WOLFSSL_IS_PRIV_PK_SET(ctx, ssl))) {
491
            /* If that didn't work then maybe a public key if device ID or
492
             * callback. */
493
            idx = 0;
494
            ret = wc_RsaPublicKeyDecode(der->buffer, &idx, key, der->length);
495
        }
496
    #endif
497
        if (ret == 0) {
498
            /* Get the minimum RSA key size from SSL or SSL context object. */
499
            int minRsaSz = ssl ? ssl->options.minRsaKeySz : ctx->minRsaKeySz;
500
            int keySz = wc_RsaEncryptSize((RsaKey*)key);
501
502
            /* Format is known. */
503
            *keyFormat = RSAk;
504
            *keyType = rsa_sa_algo;
505
            *keySize = keySz;
506
507
            /* Check that the size of the RSA key is enough. */
508
            if (keySz < minRsaSz) {
509
                WOLFSSL_MSG("Private Key size too small");
510
                ret = RSA_KEY_SIZE_E;
511
            }
512
            /* No static ECC key possible. */
513
            if ((ssl != NULL) && (ssl->options.side == WOLFSSL_SERVER_END)) {
514
                 ssl->options.haveStaticECC = 0;
515
            }
516
        }
517
        /* Not an RSA key but check whether we know what it is. */
518
        else if (*keyFormat == 0) {
519
            WOLFSSL_MSG("Not an RSA key");
520
            /* Format unknown so keep trying. */
521
            ret = 0;
522
        }
523
524
        /* Free dynamically allocated data in key. */
525
        wc_FreeRsaKey(key);
526
    }
527
528
#ifdef WOLFSSL_SMALL_STACK
529
    /* Dispose of allocated key. */
530
    XFREE(key, heap, DYNAMIC_TYPE_RSA);
531
#endif
532
533
    return ret;
534
}
535
#endif
536
#endif /* !NO_RSA */
537
538
#ifdef HAVE_ECC
539
/* See if DER data is an ECC private key.
540
 *
541
 * Checks size meets minimum ECC key size.
542
 *
543
 * @param [in, out] ctx        SSL context object.
544
 * @param [in, out] ssl        SSL object.
545
 * @param [in]      der        DER encoding.
546
 * @param [in, out] keyFormat  On in, expected format. 0 means unknown.
547
 * @param [in]      heap       Dynamic memory allocation hint.
548
 * @param [in]      devId      Device identifier.
549
 * @param [out]     keyType    Type of key.
550
 * @param [out]     keySize    Size of key.
551
 * @return  0 on success or not an ECC key and format unknown.
552
 * @return  ECC_KEY_SIZE_E when ECC key size doesn't meet minimum required.
553
 */
554
static int ProcessBufferTryDecodeEcc(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
555
    DerBuffer* der, int* keyFormat, void* heap, int devId, byte* keyType,
556
    int* keySize)
557
0
{
558
0
    int ret = 0;
559
0
    word32 idx;
560
    /* make sure ECC key can be used */
561
#ifdef WOLFSSL_SMALL_STACK
562
    ecc_key* key;
563
#else
564
0
    ecc_key  key[1];
565
0
#endif
566
567
#ifdef WOLFSSL_SMALL_STACK
568
    /* Allocate an ECC key to parse into. */
569
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
570
    if (key == NULL)
571
        return MEMORY_E;
572
#endif
573
574
    /* Initialize ECC key. */
575
0
    if (wc_ecc_init_ex(key, heap, devId) == 0) {
576
        /* Decode as an ECC private key. */
577
0
        idx = 0;
578
0
        ret = wc_EccPrivateKeyDecode(der->buffer, &idx, key, der->length);
579
    #ifdef WOLF_PRIVATE_KEY_ID
580
        /* If that didn't work then maybe a public key if device ID or callback.
581
         */
582
        if ((ret != 0) && ((devId != INVALID_DEVID) ||
583
                WOLFSSL_IS_PRIV_PK_SET(ctx, ssl))) {
584
            /* Decode as an ECC public key. */
585
            idx = 0;
586
            ret = wc_EccPublicKeyDecode(der->buffer, &idx, key, der->length);
587
        }
588
    #endif
589
    #ifdef WOLFSSL_SM2
590
        if (*keyFormat == SM2k) {
591
            ret = wc_ecc_set_curve(key, WOLFSSL_SM2_KEY_BITS / 8,
592
                ECC_SM2P256V1);
593
        }
594
    #endif
595
0
        if (ret == 0) {
596
            /* Get the minimum ECC key size from SSL or SSL context object. */
597
0
            int minKeySz = ssl ? ssl->options.minEccKeySz : ctx->minEccKeySz;
598
0
            int keySz = wc_ecc_size(key);
599
600
            /* Format is known. */
601
0
            *keyFormat = ECDSAk;
602
        #ifdef WOLFSSL_SM2
603
            if (key->dp->id == ECC_SM2P256V1) {
604
                *keyType = sm2_sa_algo;
605
            }
606
            else
607
        #endif
608
0
            {
609
0
                *keyType = ecc_dsa_sa_algo;
610
0
            }
611
0
            *keySize = keySz;
612
613
            /* Check that the size of the ECC key is enough. */
614
0
            if (keySz < minKeySz) {
615
0
                WOLFSSL_MSG("ECC private key too small");
616
0
                ret = ECC_KEY_SIZE_E;
617
0
            }
618
            /* Static ECC key possible. */
619
0
            if (ssl) {
620
0
                ssl->options.haveStaticECC = 1;
621
0
            }
622
0
            else {
623
0
                ctx->haveStaticECC = 1;
624
0
            }
625
0
        }
626
        /* Not an ECC key but check whether we know what it is. */
627
0
        else if (*keyFormat == 0) {
628
0
            WOLFSSL_MSG("Not an ECC key");
629
            /* Format unknown so keep trying. */
630
0
            ret = 0;
631
0
        }
632
633
        /* Free dynamically allocated data in key. */
634
0
        wc_ecc_free(key);
635
0
    }
636
637
#ifdef WOLFSSL_SMALL_STACK
638
    /* Dispose of allocated key. */
639
    XFREE(key, heap, DYNAMIC_TYPE_ECC);
640
#endif
641
0
    return ret;
642
0
}
643
#endif /* HAVE_ECC */
644
645
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
646
/* See if DER data is an Ed25519 private key.
647
 *
648
 * Checks size meets minimum ECC key size.
649
 *
650
 * @param [in, out] ctx        SSL context object.
651
 * @param [in, out] ssl        SSL object.
652
 * @param [in]      der        DER encoding.
653
 * @param [in, out] keyFormat  On in, expected format. 0 means unknown.
654
 * @param [in]      heap       Dynamic memory allocation hint.
655
 * @param [in]      devId      Device identifier.
656
 * @param [out]     keyType    Type of key.
657
 * @param [out]     keySize    Size of key.
658
 * @return  0 on success or not an Ed25519 key and format unknown.
659
 * @return  ECC_KEY_SIZE_E when key size doesn't meet minimum required.
660
 */
661
static int ProcessBufferTryDecodeEd25519(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
662
    DerBuffer* der, int* keyFormat, void* heap, int devId, byte* keyType,
663
    int* keySize)
664
{
665
    int ret;
666
    word32 idx;
667
    /* make sure Ed25519 key can be used */
668
#ifdef WOLFSSL_SMALL_STACK
669
    ed25519_key* key;
670
#else
671
    ed25519_key  key[1];
672
#endif
673
674
#ifdef WOLFSSL_SMALL_STACK
675
    /* Allocate an Ed25519 key to parse into. */
676
    key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
677
        DYNAMIC_TYPE_ED25519);
678
    if (key == NULL)
679
        return MEMORY_E;
680
#endif
681
682
    /* Initialize Ed25519 key. */
683
    ret = wc_ed25519_init_ex(key, heap, devId);
684
    if (ret == 0) {
685
        /* Decode as an Ed25519 private key. */
686
        idx = 0;
687
        ret = wc_Ed25519PrivateKeyDecode(der->buffer, &idx, key, der->length);
688
    #ifdef WOLF_PRIVATE_KEY_ID
689
        /* If that didn't work then maybe a public key if device ID or callback.
690
         */
691
        if ((ret != 0) && ((devId != INVALID_DEVID) ||
692
                WOLFSSL_IS_PRIV_PK_SET(ctx, ssl))) {
693
            /* Decode as an Ed25519 public key. */
694
            idx = 0;
695
            ret = wc_Ed25519PublicKeyDecode(der->buffer, &idx, key,
696
                der->length);
697
        }
698
    #endif
699
        if (ret == 0) {
700
            /* Get the minimum ECC key size from SSL or SSL context object. */
701
            int minKeySz = ssl ? ssl->options.minEccKeySz : ctx->minEccKeySz;
702
703
            /* Format is known. */
704
            *keyFormat = ED25519k;
705
            *keyType = ed25519_sa_algo;
706
            *keySize = ED25519_KEY_SIZE;
707
708
            /* Check that the size of the ECC key is enough. */
709
            if (ED25519_KEY_SIZE < minKeySz) {
710
                WOLFSSL_MSG("ED25519 private key too small");
711
                ret = ECC_KEY_SIZE_E;
712
            }
713
            if (ssl != NULL) {
714
#if !defined(WOLFSSL_NO_CLIENT_AUTH) && !defined(NO_ED25519_CLIENT_AUTH)
715
                /* Ed25519 requires caching enabled for tracking message
716
                 * hash used in EdDSA_Update for signing */
717
                ssl->options.cacheMessages = 1;
718
#endif
719
            }
720
        }
721
        /* Not an Ed25519 key but check whether we know what it is. */
722
        else if (*keyFormat == 0) {
723
            WOLFSSL_MSG("Not an Ed25519 key");
724
            /* Format unknown so keep trying. */
725
            ret = 0;
726
        }
727
728
        /* Free dynamically allocated data in key. */
729
        wc_ed25519_free(key);
730
    }
731
732
#ifdef WOLFSSL_SMALL_STACK
733
    /* Dispose of allocated key. */
734
    XFREE(key, heap, DYNAMIC_TYPE_ED25519);
735
#endif
736
    return ret;
737
}
738
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
739
740
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
741
/* See if DER data is an Ed448 private key.
742
 *
743
 * Checks size meets minimum ECC key size.
744
 *
745
 * @param [in, out] ctx        SSL context object.
746
 * @param [in, out] ssl        SSL object.
747
 * @param [in]      der        DER encoding.
748
 * @param [in, out] keyFormat  On in, expected format. 0 means unknown.
749
 * @param [in]      heap       Dynamic memory allocation hint.
750
 * @param [in]      devId      Device identifier.
751
 * @param [out]     keyType    Type of key.
752
 * @param [out]     keySize    Size of key.
753
 * @return  0 on success or not an Ed448 key and format unknown.
754
 * @return  ECC_KEY_SIZE_E when key size doesn't meet minimum required.
755
 */
756
static int ProcessBufferTryDecodeEd448(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
757
    DerBuffer* der, int* keyFormat, void* heap, int devId, byte* keyType,
758
    int* keySize)
759
{
760
    int ret;
761
    word32 idx;
762
    /* make sure Ed448 key can be used */
763
#ifdef WOLFSSL_SMALL_STACK
764
    ed448_key* key = NULL;
765
#else
766
    ed448_key  key[1];
767
#endif
768
769
#ifdef WOLFSSL_SMALL_STACK
770
    /* Allocate an Ed448 key to parse into. */
771
    key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
772
    if (key == NULL)
773
        return MEMORY_E;
774
#endif
775
776
    /* Initialize Ed448 key. */
777
    ret = wc_ed448_init_ex(key, heap, devId);
778
    if (ret == 0) {
779
        /* Decode as an Ed448 private key. */
780
        idx = 0;
781
        ret = wc_Ed448PrivateKeyDecode(der->buffer, &idx, key, der->length);
782
    #ifdef WOLF_PRIVATE_KEY_ID
783
        /* If that didn't work then maybe a public key if device ID or callback.
784
         */
785
        if ((ret != 0) && ((devId != INVALID_DEVID) ||
786
                WOLFSSL_IS_PRIV_PK_SET(ctx, ssl))) {
787
            /* Decode as an Ed448 public key. */
788
            idx = 0;
789
            ret = wc_Ed448PublicKeyDecode(der->buffer, &idx, key, der->length);
790
        }
791
    #endif
792
        if (ret == 0) {
793
            /* Get the minimum ECC key size from SSL or SSL context object. */
794
            int minKeySz = ssl ? ssl->options.minEccKeySz : ctx->minEccKeySz;
795
796
            /* Format is known. */
797
            *keyFormat = ED448k;
798
            *keyType = ed448_sa_algo;
799
            *keySize = ED448_KEY_SIZE;
800
801
            /* Check that the size of the ECC key is enough. */
802
            if (ED448_KEY_SIZE < minKeySz) {
803
                WOLFSSL_MSG("ED448 private key too small");
804
                ret = ECC_KEY_SIZE_E;
805
            }
806
            if (ssl != NULL) {
807
                /* Ed448 requires caching enabled for tracking message
808
                 * hash used in EdDSA_Update for signing */
809
                ssl->options.cacheMessages = 1;
810
            }
811
        }
812
        /* Not an Ed448 key but check whether we know what it is. */
813
        else if (*keyFormat == 0) {
814
            WOLFSSL_MSG("Not an Ed448 key");
815
            /* Format unknown so keep trying. */
816
            ret = 0;
817
        }
818
819
        /* Free dynamically allocated data in key. */
820
        wc_ed448_free(key);
821
    }
822
823
#ifdef WOLFSSL_SMALL_STACK
824
    /* Dispose of allocated key. */
825
    XFREE(key, heap, DYNAMIC_TYPE_ED448);
826
#endif
827
    return ret;
828
}
829
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
830
831
#if defined(HAVE_FALCON)
832
/* See if DER data is an Falcon private key.
833
 *
834
 * Checks size meets minimum Falcon key size.
835
 *
836
 * @param [in, out] ctx        SSL context object.
837
 * @param [in, out] ssl        SSL object.
838
 * @param [in]      der        DER encoding.
839
 * @param [in, out] keyFormat  On in, expected format. 0 means unknown.
840
 * @param [in]      heap       Dynamic memory allocation hint.
841
 * @param [in]      devId      Device identifier.
842
 * @param [out]     keyType    Type of key.
843
 * @param [out]     keySize    Size of key.
844
 * @return  0 on success or not an Falcon key and format unknown.
845
 * @return  FALCON_KEY_SIZE_E when key size doesn't meet minimum required.
846
 */
847
static int ProcessBufferTryDecodeFalcon(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
848
    DerBuffer* der, int* keyFormat, void* heap, byte* keyType, int* keySize)
849
{
850
    int ret;
851
    falcon_key* key;
852
853
    /* Allocate a Falcon key to parse into. */
854
    key = (falcon_key*)XMALLOC(sizeof(falcon_key), heap, DYNAMIC_TYPE_FALCON);
855
    if (key == NULL) {
856
        return MEMORY_E;
857
    }
858
859
    /* Initialize Falcon key. */
860
    ret = wc_falcon_init(key);
861
    if (ret == 0) {
862
        /* Set up key to parse the format specified. */
863
        if ((*keyFormat == FALCON_LEVEL1k) || ((*keyFormat == 0) &&
864
                ((der->length == FALCON_LEVEL1_KEY_SIZE) ||
865
                 (der->length == FALCON_LEVEL1_PRV_KEY_SIZE)))) {
866
            ret = wc_falcon_set_level(key, 1);
867
        }
868
        else if ((*keyFormat == FALCON_LEVEL5k) || ((*keyFormat == 0) &&
869
                 ((der->length == FALCON_LEVEL5_KEY_SIZE) ||
870
                  (der->length == FALCON_LEVEL5_PRV_KEY_SIZE)))) {
871
            ret = wc_falcon_set_level(key, 5);
872
        }
873
        else {
874
            wc_falcon_free(key);
875
            ret = ALGO_ID_E;
876
        }
877
    }
878
879
    if (ret == 0) {
880
        /* Decode as a Falcon private key. */
881
        ret = wc_falcon_import_private_only(der->buffer, der->length, key);
882
        if (ret == 0) {
883
            /* Get the minimum Falcon key size from SSL or SSL context object.
884
             */
885
            int minKeySz = ssl ? ssl->options.minFalconKeySz :
886
                                 ctx->minFalconKeySz;
887
888
            /* Format is known. */
889
            if (*keyFormat == FALCON_LEVEL1k) {
890
                *keyType = falcon_level1_sa_algo;
891
                *keySize = FALCON_LEVEL1_KEY_SIZE;
892
            }
893
            else {
894
                *keyType = falcon_level5_sa_algo;
895
                *keySize = FALCON_LEVEL5_KEY_SIZE;
896
            }
897
898
            /* Check that the size of the Falcon key is enough. */
899
            if (*keySize < minKeySz) {
900
                WOLFSSL_MSG("Falcon private key too small");
901
                ret = FALCON_KEY_SIZE_E;
902
            }
903
        }
904
        /* Not a Falcon key but check whether we know what it is. */
905
        else if (*keyFormat == 0) {
906
            WOLFSSL_MSG("Not a Falcon key");
907
            /* Format unknown so keep trying. */
908
            ret = 0;
909
        }
910
911
        /* Free dynamically allocated data in key. */
912
        wc_falcon_free(key);
913
    }
914
    else if ((ret == WC_NO_ERR_TRACE(ALGO_ID_E)) && (*keyFormat == 0)) {
915
        WOLFSSL_MSG("Not a Falcon key");
916
        /* Format unknown so keep trying. */
917
        ret = 0;
918
    }
919
920
    /* Dispose of allocated key. */
921
    XFREE(key, heap, DYNAMIC_TYPE_FALCON);
922
    return ret;
923
}
924
#endif
925
926
#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_SIGN) && \
927
    !defined(WOLFSSL_DILITHIUM_NO_ASN1)
928
/* See if DER data is an Dilithium private key.
929
 *
930
 * Checks size meets minimum Falcon key size.
931
 *
932
 * @param [in, out] ctx        SSL context object.
933
 * @param [in, out] ssl        SSL object.
934
 * @param [in]      der        DER encoding.
935
 * @param [in, out] keyFormat  On in, expected format. 0 means unknown.
936
 * @param [in]      heap       Dynamic memory allocation hint.
937
 * @param [in]      devId      Device identifier.
938
 * @param [out]     keyType    Type of key.
939
 * @param [out]     keySize    Size of key.
940
 * @return  0 on success or not a Dilithium key and format unknown.
941
 * @return  DILITHIUM_KEY_SIZE_E when key size doesn't meet minimum required.
942
 */
943
static int ProcessBufferTryDecodeDilithium(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
944
    DerBuffer* der, int* keyFormat, void* heap, byte* keyType, int* keySize)
945
{
946
    int ret;
947
    word32 idx;
948
    dilithium_key* key;
949
    int keyFormatTemp = 0;
950
    int keyTypeTemp;
951
    int keySizeTemp;
952
953
    /* Allocate a Dilithium key to parse into. */
954
    key = (dilithium_key*)XMALLOC(sizeof(dilithium_key), heap,
955
        DYNAMIC_TYPE_DILITHIUM);
956
    if (key == NULL) {
957
        return MEMORY_E;
958
    }
959
960
    /* Initialize Dilithium key. */
961
    ret = wc_dilithium_init(key);
962
    if (ret == 0) {
963
        /* Decode as a Dilithium private key. */
964
        idx = 0;
965
        ret = wc_Dilithium_PrivateKeyDecode(der->buffer, &idx, key, der->length);
966
        if (ret == 0) {
967
            ret = dilithium_get_oid_sum(key, &keyFormatTemp);
968
            if (ret == 0) {
969
                /* Format is known. */
970
                #if defined(WOLFSSL_DILITHIUM_FIPS204_DRAFT)
971
                if (keyFormatTemp == DILITHIUM_LEVEL2k) {
972
                    keyTypeTemp = dilithium_level2_sa_algo;
973
                    keySizeTemp = DILITHIUM_LEVEL2_KEY_SIZE;
974
                }
975
                else if (keyFormatTemp == DILITHIUM_LEVEL3k) {
976
                    keyTypeTemp = dilithium_level3_sa_algo;
977
                    keySizeTemp = DILITHIUM_LEVEL3_KEY_SIZE;
978
                }
979
                else if (keyFormatTemp == DILITHIUM_LEVEL5k) {
980
                    keyTypeTemp = dilithium_level5_sa_algo;
981
                    keySizeTemp = DILITHIUM_LEVEL5_KEY_SIZE;
982
                }
983
                else
984
                #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
985
                if (keyFormatTemp == ML_DSA_LEVEL2k) {
986
                    keyTypeTemp = dilithium_level2_sa_algo;
987
                    keySizeTemp = ML_DSA_LEVEL2_KEY_SIZE;
988
                }
989
                else if (keyFormatTemp == ML_DSA_LEVEL3k) {
990
                    keyTypeTemp = dilithium_level3_sa_algo;
991
                    keySizeTemp = ML_DSA_LEVEL3_KEY_SIZE;
992
                }
993
                else if (keyFormatTemp == ML_DSA_LEVEL5k) {
994
                    keyTypeTemp = dilithium_level5_sa_algo;
995
                    keySizeTemp = ML_DSA_LEVEL5_KEY_SIZE;
996
                }
997
                else {
998
                    ret = ALGO_ID_E;
999
                }
1000
            }
1001
1002
            if (ret == 0) {
1003
                /* Get the minimum Dilithium key size from SSL or SSL context
1004
                 * object. */
1005
                int minKeySz = ssl ? ssl->options.minDilithiumKeySz :
1006
                                     ctx->minDilithiumKeySz;
1007
1008
                /* Check that the size of the Dilithium key is enough. */
1009
                if (keySizeTemp < minKeySz) {
1010
                    WOLFSSL_MSG("Dilithium private key too small");
1011
                    ret = DILITHIUM_KEY_SIZE_E;
1012
                }
1013
            }
1014
1015
            if (ret == 0) {
1016
                *keyFormat = keyFormatTemp;
1017
                *keyType = keyTypeTemp;
1018
                *keySize = keySizeTemp;
1019
            }
1020
        }
1021
        else if (*keyFormat == 0) {
1022
            WOLFSSL_MSG("Not a Dilithium key");
1023
            /* Unknown format wasn't dilithium, so keep trying other formats. */
1024
            ret = 0;
1025
        }
1026
1027
        /* Free dynamically allocated data in key. */
1028
        wc_dilithium_free(key);
1029
    }
1030
1031
    /* Dispose of allocated key. */
1032
    XFREE(key, heap, DYNAMIC_TYPE_DILITHIUM);
1033
    return ret;
1034
}
1035
#endif /* HAVE_DILITHIUM */
1036
1037
/* Try to decode DER data is a known private key.
1038
 *
1039
 * Checks size meets minimum for key type.
1040
 *
1041
 * @param [in, out] ctx        SSL context object.
1042
 * @param [in, out] ssl        SSL object.
1043
 * @param [in]      der        DER encoding.
1044
 * @param [in, out] keyFormat  On in, expected format. 0 means unknown.
1045
 * @param [in]      heap       Dynamic memory allocation hint.
1046
 * @param [out]     type       Type of key:
1047
 *                               PRIVATEKEY_TYPE or ALT_PRIVATEKEY_TYPE.
1048
 * @return  0 on success.
1049
 * @return  BAD_FUNC_ARG when der or keyFormat is NULL.
1050
 * @return  BAD_FUNC_ARG when ctx and ssl are NULL.
1051
 * @return  WOLFSSL_BAD_FILE when unable to identify the key format.
1052
 */
1053
static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
1054
    DerBuffer* der, int* keyFormat, void* heap, int type)
1055
0
{
1056
0
    int ret = 0;
1057
0
    int devId = wolfSSL_CTX_GetDevId(ctx, ssl);
1058
0
    byte* keyType = NULL;
1059
0
    int* keySz = NULL;
1060
0
    int matchAnyKey = 0;
1061
1062
0
    (void)heap;
1063
0
    (void)devId;
1064
0
    (void)type;
1065
1066
    /* Validate parameters. */
1067
0
    if ((der == NULL) || (keyFormat == NULL)) {
1068
0
        ret = BAD_FUNC_ARG;
1069
0
    }
1070
    /* Must have an SSL context or SSL object to use. */
1071
0
    if ((ret == 0) && (ctx == NULL) && (ssl == NULL)) {
1072
0
        ret = BAD_FUNC_ARG;
1073
0
    }
1074
1075
0
    if (ret == 0) {
1076
        /* Determine where to put key type and size in SSL or context object. */
1077
    #ifdef WOLFSSL_DUAL_ALG_CERTS
1078
        if (type == ALT_PRIVATEKEY_TYPE) {
1079
            if (ssl != NULL) {
1080
                keyType = &ssl->buffers.altKeyType;
1081
                keySz = &ssl->buffers.altKeySz;
1082
            }
1083
            else {
1084
                keyType = &ctx->altPrivateKeyType;
1085
                keySz = &ctx->altPrivateKeySz;
1086
            }
1087
        }
1088
        else
1089
    #endif
1090
        /* Type is PRIVATEKEY_TYPE. */
1091
0
        if (ssl != NULL) {
1092
0
            keyType = &ssl->buffers.keyType;
1093
0
            keySz = &ssl->buffers.keySz;
1094
0
        }
1095
0
        else {
1096
0
            keyType = &ctx->privateKeyType;
1097
0
            keySz = &ctx->privateKeySz;
1098
0
        }
1099
0
    }
1100
1101
0
#ifndef NO_RSA
1102
    /* Try RSA if key format is RSA or yet unknown. */
1103
0
    if ((ret == 0) && ((*keyFormat == 0) || (*keyFormat == RSAk))) {
1104
0
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
1105
0
    (HAVE_FIPS_VERSION > 2))
1106
0
        ret = ProcessBufferTryDecodeRsa(ctx, ssl, der, keyFormat, devId,
1107
0
            keyType, keySz);
1108
#else
1109
        ret = ProcessBufferTryDecodeRsa(ctx, ssl, der, keyFormat, heap, devId,
1110
            keyType, keySz);
1111
#endif
1112
0
        matchAnyKey = 1;
1113
0
    }
1114
0
#ifdef WC_RSA_PSS
1115
0
    if((ret == 0) && (*keyFormat == RSAPSSk)) {
1116
        /*
1117
            Require logic to verify that the der is RSAPSSk (when *keyFormat == RSAPSSK),
1118
            and to detect that the der is RSAPSSk (when *keyFormat == 0).
1119
        */
1120
1121
0
        matchAnyKey = 1;
1122
0
    }
1123
0
#endif /* WC_RSA_PSS */
1124
0
#endif /* NO_RSA */
1125
0
#ifdef HAVE_ECC
1126
    /* Try ECC if key format is ECDSA or SM2, or yet unknown. */
1127
0
    if ((ret == 0) && ((*keyFormat == 0) || (*keyFormat == ECDSAk)
1128
    #ifdef WOLFSSL_SM2
1129
        || (*keyFormat == SM2k)
1130
    #endif
1131
0
        )) {
1132
0
        ret = ProcessBufferTryDecodeEcc(ctx, ssl, der, keyFormat, heap, devId,
1133
0
            keyType, keySz);
1134
0
        matchAnyKey = 1;
1135
0
    }
1136
0
#endif /* HAVE_ECC */
1137
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
1138
    /* Try Ed25519 if key format is Ed25519 or yet unknown. */
1139
    if ((ret == 0) && ((*keyFormat == 0 || *keyFormat == ED25519k))) {
1140
        ret = ProcessBufferTryDecodeEd25519(ctx, ssl, der, keyFormat, heap,
1141
            devId, keyType, keySz);
1142
        matchAnyKey = 1;
1143
    }
1144
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
1145
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
1146
    /* Try Ed448 if key format is Ed448 or yet unknown. */
1147
    if ((ret == 0) && ((*keyFormat == 0 || *keyFormat == ED448k))) {
1148
        ret = ProcessBufferTryDecodeEd448(ctx, ssl, der, keyFormat, heap, devId,
1149
            keyType, keySz);
1150
        matchAnyKey = 1;
1151
    }
1152
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
1153
#if defined(HAVE_FALCON)
1154
    /* Try Falcon if key format is Falcon level 1k or 5k or yet unknown. */
1155
    if ((ret == 0) && ((*keyFormat == 0) || (*keyFormat == FALCON_LEVEL1k) ||
1156
            (*keyFormat == FALCON_LEVEL5k))) {
1157
        ret = ProcessBufferTryDecodeFalcon(ctx, ssl, der, keyFormat, heap,
1158
            keyType, keySz);
1159
        matchAnyKey = 1;
1160
    }
1161
#endif /* HAVE_FALCON */
1162
#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_SIGN) && \
1163
    !defined(WOLFSSL_DILITHIUM_NO_ASN1)
1164
    /* Try Falcon if key format is Dilithium level 2k, 3k or 5k or yet unknown.
1165
     */
1166
    if ((ret == 0) &&
1167
        ((*keyFormat == 0) ||
1168
        (*keyFormat == ML_DSA_LEVEL2k) ||
1169
        (*keyFormat == ML_DSA_LEVEL3k) ||
1170
        (*keyFormat == ML_DSA_LEVEL5k)
1171
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
1172
     || (*keyFormat == DILITHIUM_LEVEL2k)
1173
     || (*keyFormat == DILITHIUM_LEVEL3k)
1174
     || (*keyFormat == DILITHIUM_LEVEL5k)
1175
    #endif
1176
        )) {
1177
        ret = ProcessBufferTryDecodeDilithium(ctx, ssl, der, keyFormat, heap,
1178
            keyType, keySz);
1179
        matchAnyKey = 1;
1180
    }
1181
#endif /* HAVE_DILITHIUM */
1182
1183
    /* Check we know the format. */
1184
0
    if ((ret == 0) &&
1185
0
        ((*keyFormat == 0) || ((*keyFormat != 0) && (matchAnyKey == 0)))) {
1186
0
        WOLFSSL_MSG("Not a supported key type");
1187
        /* Not supported key format. */
1188
0
        ret = WOLFSSL_BAD_FILE;
1189
0
    }
1190
1191
0
    return ret;
1192
0
}
1193
1194
#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
1195
/* Decrypt PKCS#8 private key.
1196
 *
1197
 * @param [in] info   Encryption information.
1198
 * @param [in] der    DER encoded data.
1199
 * @param [in] heap   Dynamic memory allocation hint.
1200
 * @return  0 on success.
1201
 * @return  MEMORY_E when dynamic memory allocation fails.
1202
 */
1203
static int ProcessBufferPrivPkcs8Dec(EncryptedInfo* info, DerBuffer* der,
1204
    void* heap)
1205
{
1206
    int ret = 0;
1207
    word32 algId;
1208
    int   passwordSz = NAME_SZ;
1209
#ifndef WOLFSSL_SMALL_STACK
1210
    char  password[NAME_SZ];
1211
#else
1212
    char* password;
1213
#endif
1214
1215
    (void)heap;
1216
#ifdef WOLFSSL_SMALL_STACK
1217
    /* Allocate memory for password. */
1218
    password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
1219
    if (password == NULL) {
1220
        ret = MEMORY_E;
1221
    }
1222
#endif
1223
1224
    if (ret == 0) {
1225
        /* Get password. */
1226
        ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
1227
            info->passwd_userdata);
1228
    }
1229
    if (ret >= 0) {
1230
        /* Returned value is password size. */
1231
        passwordSz = ret;
1232
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1233
        wc_MemZero_Add("ProcessBuffer password", password, passwordSz);
1234
    #endif
1235
1236
        /* Decrypt PKCS#8 private key inline and get algorithm id. */
1237
        ret = ToTraditionalEnc(der->buffer, der->length, password, passwordSz,
1238
            &algId);
1239
    }
1240
    if (ret >= 0) {
1241
        /* Zero out encrypted data not overwritten. */
1242
        ForceZero(der->buffer + ret, der->length - (word32)ret);
1243
        /* Set decrypted data length. */
1244
        der->length = (word32)ret;
1245
    }
1246
1247
#ifdef WOLFSSL_SMALL_STACK
1248
    if (password != NULL)
1249
#endif
1250
    {
1251
        /* Ensure password is zeroized. */
1252
        ForceZero(password, (word32)passwordSz);
1253
    }
1254
#ifdef WOLFSSL_SMALL_STACK
1255
    /* Dispose of password memory. */
1256
    XFREE(password, heap, DYNAMIC_TYPE_STRING);
1257
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1258
    wc_MemZero_Check(password, NAME_SZ);
1259
#endif
1260
    return ret;
1261
}
1262
#endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */
1263
1264
/* Put the DER into the SSL or SSL context object.
1265
 *
1266
 * Precondition: ctx or ssl is not NULL.
1267
 * Precondition: Must be a private key type.
1268
 *
1269
 * @param [in, out] ctx  SSL context object.
1270
 * @param [in, out] ssl  SSL object.
1271
 * @param [in]      der  DER encoding.
1272
 * @return  0 on success.
1273
 */
1274
static int ProcessBufferPrivKeyHandleDer(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
1275
    DerBuffer** der, int type)
1276
0
{
1277
0
    int ret = 0;
1278
1279
0
    (void)type;
1280
1281
#ifdef WOLFSSL_DUAL_ALG_CERTS
1282
    if (type == ALT_PRIVATEKEY_TYPE) {
1283
        /* Put in alternate private key fields of objects. */
1284
        if (ssl != NULL) {
1285
            /* Dispose of previous key if not context's. */
1286
            if (ssl->buffers.weOwnAltKey) {
1287
                FreeDer(&ssl->buffers.altKey);
1288
            #ifdef WOLFSSL_BLIND_PRIVATE_KEY
1289
                FreeDer(&ssl->buffers.altKeyMask);
1290
            #endif
1291
            }
1292
            ssl->buffers.altKeyId = 0;
1293
            ssl->buffers.altKeyLabel = 0;
1294
            ssl->buffers.altKeyDevId = INVALID_DEVID;
1295
            /* Store key by reference and own it. */
1296
            ssl->buffers.altKey = *der;
1297
        #ifdef WOLFSSL_CHECK_MEM_ZERO
1298
            wc_MemZero_Add("SSL Buffers key", (*der)->buffer, (*der)->length);
1299
        #endif
1300
            ssl->buffers.weOwnAltKey = 1;
1301
        }
1302
        else if (ctx != NULL) {
1303
            /* Dispose of previous key. */
1304
            FreeDer(&ctx->altPrivateKey);
1305
            ctx->altPrivateKeyId = 0;
1306
            ctx->altPrivateKeyLabel = 0;
1307
            ctx->altPrivateKeyDevId = INVALID_DEVID;
1308
            /* Store key by reference. */
1309
            ctx->altPrivateKey = *der;
1310
        #ifdef WOLFSSL_CHECK_MEM_ZERO
1311
            wc_MemZero_Add("CTX private key", (*der)->buffer, (*der)->length);
1312
        #endif
1313
        }
1314
    }
1315
    else
1316
#endif /* WOLFSSL_DUAL_ALG_CERTS */
1317
0
    if (ssl != NULL) {
1318
        /* Dispose of previous key if not context's. */
1319
0
        if (ssl->buffers.weOwnKey) {
1320
0
            FreeDer(&ssl->buffers.key);
1321
        #ifdef WOLFSSL_BLIND_PRIVATE_KEY
1322
            FreeDer(&ssl->buffers.keyMask);
1323
        #endif
1324
0
        }
1325
0
        ssl->buffers.keyId = 0;
1326
0
        ssl->buffers.keyLabel = 0;
1327
0
        ssl->buffers.keyDevId = INVALID_DEVID;
1328
        /* Store key by reference and own it. */
1329
0
        ssl->buffers.key = *der;
1330
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1331
        wc_MemZero_Add("SSL Buffers key", (*der)->buffer, (*der)->length);
1332
    #endif
1333
0
        ssl->buffers.weOwnKey = 1;
1334
0
    }
1335
0
    else if (ctx != NULL) {
1336
        /* Dispose of previous key. */
1337
0
        FreeDer(&ctx->privateKey);
1338
0
        ctx->privateKeyId = 0;
1339
0
        ctx->privateKeyLabel = 0;
1340
0
        ctx->privateKeyDevId = INVALID_DEVID;
1341
        /* Store key by reference. */
1342
0
        ctx->privateKey = *der;
1343
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1344
        wc_MemZero_Add("CTX private key", (*der)->buffer, (*der)->length);
1345
    #endif
1346
0
    }
1347
1348
0
    return ret;
1349
0
}
1350
1351
/* Decode private key.
1352
 *
1353
 * Precondition: ctx or ssl is not NULL.
1354
 * Precondition: Must be a private key type.
1355
 *
1356
 * @param [in, out] ctx     SSL context object.
1357
 * @param [in, out] ssl     SSL object.
1358
 * @param [in]      der     DER encoding.
1359
 * @param [in]      format  Original format of data.
1360
 * @param [in]      info    Encryption information.
1361
 * @param [in]      heap    Dynamic memory allocation hint.
1362
 * @param [in]      type    Type of data:
1363
 *                            PRIVATEKEY_TYPE or ALT_PRIVATEKEY_TYPE.
1364
 * @param [in]      algId   Algorithm id of key.
1365
 * @return  0 on success.
1366
 * @return  WOLFSSL_BAD_FILE when not able to decode.
1367
 */
1368
static int ProcessBufferPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
1369
    DerBuffer* der, int format, EncryptedInfo* info, void* heap, int type,
1370
    int algId)
1371
0
{
1372
0
    int ret;
1373
1374
0
    (void)info;
1375
0
    (void)format;
1376
1377
    /* Put the data into the SSL or SSL context object. */
1378
0
    ret = ProcessBufferPrivKeyHandleDer(ctx, ssl, &der, type);
1379
0
    if (ret == 0) {
1380
        /* Try to decode the DER data. */
1381
0
        ret = ProcessBufferTryDecode(ctx, ssl, der, &algId, heap, type);
1382
0
    }
1383
1384
#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
1385
    /* If private key type PKCS8 header wasn't already removed (algId == 0). */
1386
    if (((ret != 0) || (algId == 0)) && (format != WOLFSSL_FILETYPE_PEM) &&
1387
            (info->passwd_cb != NULL) && (algId == 0)) {
1388
        /* Try to decrypt DER data as a PKCS#8 private key. */
1389
        ret = ProcessBufferPrivPkcs8Dec(info, der, heap);
1390
        if (ret >= 0) {
1391
            /* Try to decode decrypted data.  */
1392
            ret = ProcessBufferTryDecode(ctx, ssl, der, &algId, heap, type);
1393
        }
1394
    }
1395
#endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */
1396
1397
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
1398
#ifdef WOLFSSL_DUAL_ALG_CERTS
1399
    if (type == ALT_PRIVATEKEY_TYPE) {
1400
        if (ssl != NULL) {
1401
            ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey,
1402
                &ssl->buffers.altKeyMask);
1403
        }
1404
        else {
1405
            ret = wolfssl_priv_der_blind(NULL, ctx->altPrivateKey,
1406
                &ctx->altPrivateKeyMask);
1407
        }
1408
    }
1409
    else
1410
#endif
1411
    if (ssl != NULL) {
1412
        ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
1413
            &ssl->buffers.keyMask);
1414
    }
1415
    else {
1416
        ret = wolfssl_priv_der_blind(NULL, ctx->privateKey,
1417
            &ctx->privateKeyMask);
1418
    }
1419
#endif
1420
1421
    /* Check if we were able to determine algorithm id. */
1422
0
    if ((ret == 0) && (algId == 0)) {
1423
    #ifdef OPENSSL_EXTRA
1424
        /* Decryption password is probably wrong. */
1425
        if (info->passwd_cb) {
1426
            WOLFSSL_EVPerr(0, -WOLFSSL_EVP_R_BAD_DECRYPT_E);
1427
        }
1428
    #endif
1429
0
        WOLFSSL_ERROR(WOLFSSL_BAD_FILE);
1430
        /* Unable to decode DER data. */
1431
0
        ret = WOLFSSL_BAD_FILE;
1432
0
    }
1433
1434
0
    return ret;
1435
0
}
1436
1437
/* Use the key OID to determine have options.
1438
 *
1439
 * @param [in, out] ctx     SSL context object.
1440
 * @param [in, out] ssl     SSL object.
1441
 * @param [in]      keyOID  OID for public/private key.
1442
 */
1443
static void wolfssl_set_have_from_key_oid(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
1444
    int keyOID)
1445
0
{
1446
    /* Set which private key algorithm available based on key OID. */
1447
0
    switch (keyOID) {
1448
0
        case ECDSAk:
1449
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
1450
        case SM2k:
1451
    #endif
1452
    #ifdef HAVE_ED25519
1453
        case ED25519k:
1454
    #endif
1455
    #ifdef HAVE_ED448
1456
        case ED448k:
1457
    #endif
1458
0
            if (ssl != NULL) {
1459
0
                ssl->options.haveECC = 1;
1460
0
            }
1461
0
            else {
1462
0
                ctx->haveECC = 1;
1463
0
            }
1464
0
            break;
1465
0
    #ifndef NO_RSA
1466
0
        case RSAk:
1467
0
        #ifdef WC_RSA_PSS
1468
0
        case RSAPSSk:
1469
0
        #endif
1470
0
            if (ssl != NULL) {
1471
0
                ssl->options.haveRSA = 1;
1472
0
            }
1473
0
            else {
1474
0
                ctx->haveRSA = 1;
1475
0
            }
1476
0
            break;
1477
0
    #endif
1478
    #ifdef HAVE_FALCON
1479
        case FALCON_LEVEL1k:
1480
        case FALCON_LEVEL5k:
1481
            if (ssl != NULL) {
1482
                ssl->options.haveFalconSig = 1;
1483
            }
1484
            else {
1485
                ctx->haveFalconSig = 1;
1486
            }
1487
            break;
1488
    #endif /* HAVE_FALCON */
1489
    #ifdef HAVE_DILITHIUM
1490
        case ML_DSA_LEVEL2k:
1491
        case ML_DSA_LEVEL3k:
1492
        case ML_DSA_LEVEL5k:
1493
        #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
1494
        case DILITHIUM_LEVEL2k:
1495
        case DILITHIUM_LEVEL3k:
1496
        case DILITHIUM_LEVEL5k:
1497
        #endif
1498
            if (ssl != NULL) {
1499
                ssl->options.haveDilithiumSig = 1;
1500
            }
1501
            else {
1502
                ctx->haveDilithiumSig = 1;
1503
            }
1504
            break;
1505
    #endif /* HAVE_DILITHIUM */
1506
0
        default:
1507
0
            WOLFSSL_MSG("Cert key not supported");
1508
0
            break;
1509
0
        }
1510
0
}
1511
1512
/* Set which private key algorithm we have against SSL or SSL context object.
1513
 *
1514
 * Precondition: ctx or ssl is not NULL.
1515
 *
1516
 * @param [in, out] ctx     SSL context object.
1517
 * @param [in, out] ssl     SSL object.
1518
 * @param [in]      cert    Decode certificate.
1519
 */
1520
static void ProcessBufferCertSetHave(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
1521
    DecodedCert* cert)
1522
0
{
1523
0
    if (ssl != NULL) {
1524
        /* Reset signatures we have in SSL. */
1525
0
        ssl->options.haveECDSAsig = 0;
1526
0
        ssl->options.haveFalconSig = 0;
1527
0
        ssl->options.haveDilithiumSig = 0;
1528
0
    }
1529
1530
    /* Set which signature we have based on the type in the cert. */
1531
0
    switch (cert->signatureOID) {
1532
0
        case CTC_SHAwECDSA:
1533
0
        case CTC_SHA256wECDSA:
1534
0
        case CTC_SHA384wECDSA:
1535
0
        case CTC_SHA512wECDSA:
1536
    #ifdef HAVE_ED25519
1537
        case CTC_ED25519:
1538
    #endif
1539
    #ifdef HAVE_ED448
1540
        case CTC_ED448:
1541
    #endif
1542
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
1543
        case CTC_SM3wSM2:
1544
    #endif
1545
0
            WOLFSSL_MSG("ECDSA/ED25519/ED448 cert signature");
1546
0
            if (ssl) {
1547
0
                ssl->options.haveECDSAsig = 1;
1548
0
            }
1549
0
            else if (ctx) {
1550
0
                ctx->haveECDSAsig = 1;
1551
0
            }
1552
0
            break;
1553
    #ifdef HAVE_FALCON
1554
        case CTC_FALCON_LEVEL1:
1555
        case CTC_FALCON_LEVEL5:
1556
            WOLFSSL_MSG("Falcon cert signature");
1557
            if (ssl) {
1558
                ssl->options.haveFalconSig = 1;
1559
            }
1560
            else if (ctx) {
1561
                ctx->haveFalconSig = 1;
1562
            }
1563
            break;
1564
    #endif
1565
    #ifdef HAVE_DILITHIUM
1566
        case CTC_ML_DSA_LEVEL2:
1567
        case CTC_ML_DSA_LEVEL3:
1568
        case CTC_ML_DSA_LEVEL5:
1569
        #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
1570
        case CTC_DILITHIUM_LEVEL2:
1571
        case CTC_DILITHIUM_LEVEL3:
1572
        case CTC_DILITHIUM_LEVEL5:
1573
        #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
1574
            WOLFSSL_MSG("Dilithium cert signature");
1575
            if (ssl) {
1576
                ssl->options.haveDilithiumSig = 1;
1577
            }
1578
            else if (ctx) {
1579
                ctx->haveDilithiumSig = 1;
1580
            }
1581
            break;
1582
    #endif
1583
0
        default:
1584
0
            WOLFSSL_MSG("Cert signature not supported");
1585
0
            break;
1586
0
    }
1587
1588
0
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
1589
0
    defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || !defined(NO_RSA)
1590
0
    #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
1591
    /* Set the private key curve OID. */
1592
0
    if (ssl != NULL) {
1593
0
        ssl->pkCurveOID = cert->pkCurveOID;
1594
0
    }
1595
0
    else if (ctx) {
1596
0
        ctx->pkCurveOID = cert->pkCurveOID;
1597
0
    }
1598
0
    #endif
1599
0
#ifndef WC_STRICT_SIG
1600
0
    if ((ctx != NULL) || (ssl != NULL)) {
1601
0
        wolfssl_set_have_from_key_oid(ctx, ssl, (int)cert->keyOID);
1602
0
    }
1603
#else
1604
    /* Set whether ECC is available based on signature available. */
1605
    if (ssl != NULL) {
1606
        ssl->options.haveECC = ssl->options.haveECDSAsig;
1607
    }
1608
    else if (ctx) {
1609
        ctx->haveECC = ctx->haveECDSAsig;
1610
    }
1611
#endif /* !WC_STRICT_SIG */
1612
0
#endif
1613
0
}
1614
1615
/* Check key size is valid.
1616
 *
1617
 * Precondition: ctx or ssl is not NULL.
1618
 *
1619
 * @param [in] min    Minimum key size.
1620
 * @param [in] max    Maximum key size.
1621
 * @param [in] keySz  Key size.
1622
 * @param [in] err    Error value to return when key size is invalid.
1623
 * @return  0 on success.
1624
 * @return  err when verifying and min is less than 0 or key size is invalid.
1625
 */
1626
#define CHECK_KEY_SZ(min, max, keySz, err)                                     \
1627
0
    (((min) < 0) || ((keySz) < (min)) || ((keySz) > (max))) ? (err) : 0
1628
1629
/* Check public key in certificate.
1630
 *
1631
 * @param [in, out] ctx   SSL context object.
1632
 * @param [in, out] ssl   SSL object.
1633
 * @param [in]      cert  Certificate object.
1634
 * @return  0 on success.
1635
 * @return  Non-zero when an error occurred.
1636
 */
1637
static int ProcessBufferCertPublicKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
1638
    DecodedCert* cert, int checkKeySz)
1639
0
{
1640
0
    int ret = 0;
1641
0
    byte keyType = 0;
1642
0
    int keySz = 0;
1643
0
#ifndef NO_RSA
1644
0
    word32 idx;
1645
0
#endif
1646
1647
    /* Get key size and check unless not verifying. */
1648
0
    switch (cert->keyOID) {
1649
0
#ifndef NO_RSA
1650
0
    #ifdef WC_RSA_PSS
1651
0
        case RSAPSSk:
1652
0
    #endif
1653
0
        case RSAk:
1654
0
            keyType = rsa_sa_algo;
1655
            /* Determine RSA key size by parsing public key */
1656
0
            idx = 0;
1657
0
            ret = wc_RsaPublicKeyDecode_ex(cert->publicKey, &idx,
1658
0
                cert->pubKeySize, NULL, (word32*)&keySz, NULL, NULL);
1659
0
            if ((ret == 0) && checkKeySz) {
1660
0
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minRsaKeySz :
1661
0
                    ctx->minRsaKeySz, RSA_MAX_SIZE / 8, keySz, RSA_KEY_SIZE_E);
1662
0
            }
1663
0
            break;
1664
0
#endif /* !NO_RSA */
1665
0
    #ifdef HAVE_ECC
1666
0
        case ECDSAk:
1667
0
            keyType = ecc_dsa_sa_algo;
1668
            /* Determine ECC key size based on curve */
1669
        #ifdef WOLFSSL_CUSTOM_CURVES
1670
            if ((cert->pkCurveOID == 0) && (cert->pkCurveSize != 0)) {
1671
                keySz = cert->pkCurveSize;
1672
            }
1673
            else
1674
        #endif
1675
0
            {
1676
0
                keySz = wc_ecc_get_curve_size_from_id(wc_ecc_get_oid(
1677
0
                    cert->pkCurveOID, NULL, NULL));
1678
0
            }
1679
1680
0
            if (checkKeySz) {
1681
0
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minEccKeySz :
1682
0
                     ctx->minEccKeySz, (MAX_ECC_BITS + 7) / 8, keySz,
1683
0
                     ECC_KEY_SIZE_E);
1684
0
            }
1685
0
            break;
1686
0
    #endif /* HAVE_ECC */
1687
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
1688
        case SM2k:
1689
            keyType = sm2_sa_algo;
1690
            /* Determine ECC key size based on curve */
1691
            keySz = WOLFSSL_SM2_KEY_BITS / 8;
1692
            if (checkKeySz) {
1693
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minEccKeySz :
1694
                    ctx->minEccKeySz, (MAX_ECC_BITS + 7) / 8, keySz,
1695
                    ECC_KEY_SIZE_E);
1696
            }
1697
            break;
1698
    #endif /* HAVE_ED25519 */
1699
    #ifdef HAVE_ED25519
1700
        case ED25519k:
1701
            keyType = ed25519_sa_algo;
1702
            /* ED25519 is fixed key size */
1703
            keySz = ED25519_KEY_SIZE;
1704
            if (checkKeySz) {
1705
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minEccKeySz :
1706
                    ctx->minEccKeySz, ED25519_KEY_SIZE, keySz, ECC_KEY_SIZE_E);
1707
            }
1708
            break;
1709
    #endif /* HAVE_ED25519 */
1710
    #ifdef HAVE_ED448
1711
        case ED448k:
1712
            keyType = ed448_sa_algo;
1713
            /* ED448 is fixed key size */
1714
            keySz = ED448_KEY_SIZE;
1715
            if (checkKeySz) {
1716
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minEccKeySz :
1717
                    ctx->minEccKeySz, ED448_KEY_SIZE, keySz, ECC_KEY_SIZE_E);
1718
            }
1719
            break;
1720
    #endif /* HAVE_ED448 */
1721
    #if defined(HAVE_FALCON)
1722
        case FALCON_LEVEL1k:
1723
            keyType = falcon_level1_sa_algo;
1724
            /* Falcon is fixed key size */
1725
            keySz = FALCON_LEVEL1_KEY_SIZE;
1726
            if (checkKeySz) {
1727
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minFalconKeySz :
1728
                    ctx->minFalconKeySz, FALCON_MAX_KEY_SIZE, keySz,
1729
                    FALCON_KEY_SIZE_E);
1730
            }
1731
            break;
1732
        case FALCON_LEVEL5k:
1733
            keyType = falcon_level5_sa_algo;
1734
            /* Falcon is fixed key size */
1735
            keySz = FALCON_LEVEL5_KEY_SIZE;
1736
            if (checkKeySz) {
1737
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minFalconKeySz :
1738
                    ctx->minFalconKeySz, FALCON_MAX_KEY_SIZE, keySz,
1739
                    FALCON_KEY_SIZE_E);
1740
            }
1741
            break;
1742
    #endif /* HAVE_FALCON */
1743
    #if defined(HAVE_DILITHIUM)
1744
        #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
1745
        case DILITHIUM_LEVEL2k:
1746
            keyType = dilithium_level2_sa_algo;
1747
            /* Dilithium is fixed key size */
1748
            keySz = DILITHIUM_LEVEL2_KEY_SIZE;
1749
            if (checkKeySz) {
1750
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
1751
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
1752
                    DILITHIUM_KEY_SIZE_E);
1753
            }
1754
            break;
1755
        case DILITHIUM_LEVEL3k:
1756
            keyType = dilithium_level3_sa_algo;
1757
            /* Dilithium is fixed key size */
1758
            keySz = DILITHIUM_LEVEL3_KEY_SIZE;
1759
            if (checkKeySz) {
1760
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
1761
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
1762
                    DILITHIUM_KEY_SIZE_E);
1763
            }
1764
            break;
1765
        case DILITHIUM_LEVEL5k:
1766
            keyType = dilithium_level5_sa_algo;
1767
            /* Dilithium is fixed key size */
1768
            keySz = DILITHIUM_LEVEL5_KEY_SIZE;
1769
            if (checkKeySz) {
1770
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
1771
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
1772
                    DILITHIUM_KEY_SIZE_E);
1773
            }
1774
            break;
1775
        #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
1776
        case ML_DSA_LEVEL2k:
1777
            keyType = dilithium_level2_sa_algo;
1778
            /* Dilithium is fixed key size */
1779
            keySz = ML_DSA_LEVEL2_KEY_SIZE;
1780
            if (checkKeySz) {
1781
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
1782
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
1783
                    DILITHIUM_KEY_SIZE_E);
1784
            }
1785
            break;
1786
        case ML_DSA_LEVEL3k:
1787
            keyType = dilithium_level3_sa_algo;
1788
            /* Dilithium is fixed key size */
1789
            keySz = ML_DSA_LEVEL3_KEY_SIZE;
1790
            if (checkKeySz) {
1791
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
1792
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
1793
                    DILITHIUM_KEY_SIZE_E);
1794
            }
1795
            break;
1796
        case ML_DSA_LEVEL5k:
1797
            keyType = dilithium_level5_sa_algo;
1798
            /* Dilithium is fixed key size */
1799
            keySz = ML_DSA_LEVEL5_KEY_SIZE;
1800
            if (checkKeySz) {
1801
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
1802
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
1803
                    DILITHIUM_KEY_SIZE_E);
1804
            }
1805
            break;
1806
    #endif /* HAVE_DILITHIUM */
1807
1808
0
        default:
1809
0
            WOLFSSL_MSG("No key size check done on public key in certificate");
1810
0
            break;
1811
0
    }
1812
1813
    /* Store the type and key size as there may not be a private key set. */
1814
0
    if (ssl != NULL) {
1815
0
        ssl->buffers.keyType = keyType;
1816
0
        ssl->buffers.keySz = keySz;
1817
0
    }
1818
0
    else {
1819
0
        ctx->privateKeyType = keyType;
1820
0
        ctx->privateKeySz = keySz;
1821
0
    }
1822
1823
0
    return ret;
1824
0
}
1825
1826
#ifdef WOLFSSL_DUAL_ALG_CERTS
1827
static int ProcessBufferCertAltPublicKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
1828
    DecodedCert* cert, int checkKeySz)
1829
{
1830
    int ret = 0;
1831
    void* heap = WOLFSSL_HEAP(ctx, ssl);
1832
    byte keyType = 0;
1833
    int keySz = 0;
1834
#ifndef NO_RSA
1835
    word32 idx;
1836
#endif
1837
1838
    /* Check alternative key size of cert. */
1839
    switch (cert->sapkiOID) {
1840
        /* No OID set. */
1841
        case 0:
1842
            if (cert->sapkiLen != 0) {
1843
                /* Have the alternative key data but no OID. */
1844
                ret = NOT_COMPILED_IN;
1845
            }
1846
            break;
1847
1848
#ifndef NO_RSA
1849
    #ifdef WC_RSA_PSS
1850
        case RSAPSSk:
1851
    #endif
1852
        case RSAk:
1853
            keyType = rsa_sa_algo;
1854
            /* Determine RSA key size by parsing public key */
1855
            idx = 0;
1856
            ret = wc_RsaPublicKeyDecode_ex(cert->sapkiDer, &idx,
1857
                cert->sapkiLen, NULL, (word32*)&keySz, NULL, NULL);
1858
            if ((ret == 0) && checkKeySz) {
1859
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minRsaKeySz :
1860
                    ctx->minRsaKeySz, RSA_MAX_SIZE / 8, keySz, RSA_KEY_SIZE_E);
1861
            }
1862
            break;
1863
#endif /* !NO_RSA */
1864
    #ifdef HAVE_ECC
1865
        case ECDSAk:
1866
        {
1867
        #ifdef WOLFSSL_SMALL_STACK
1868
            ecc_key* temp_key = NULL;
1869
        #else
1870
            ecc_key temp_key[1];
1871
        #endif
1872
            keyType = ecc_dsa_sa_algo;
1873
1874
        #ifdef WOLFSSL_SMALL_STACK
1875
            temp_key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap,
1876
                DYNAMIC_TYPE_ECC);
1877
            if (temp_key == NULL) {
1878
                ret = MEMORY_E;
1879
            }
1880
        #endif
1881
1882
            /* Determine ECC key size. We have to decode the sapki for
1883
             * that. */
1884
            if (ret == 0) {
1885
                ret = wc_ecc_init_ex(temp_key, heap, INVALID_DEVID);
1886
                if (ret == 0) {
1887
                    idx = 0;
1888
                    ret = wc_EccPublicKeyDecode(cert->sapkiDer, &idx, temp_key,
1889
                        cert->sapkiLen);
1890
                    if (ret == 0) {
1891
                        keySz = wc_ecc_size(temp_key);
1892
                    }
1893
                    wc_ecc_free(temp_key);
1894
                }
1895
            }
1896
        #ifdef WOLFSSL_SMALL_STACK
1897
            XFREE(temp_key, heap, DYNAMIC_TYPE_ECC);
1898
        #endif
1899
1900
            if ((ret == 0) && checkKeySz) {
1901
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minEccKeySz :
1902
                     ctx->minEccKeySz, (MAX_ECC_BITS + 7) / 8, keySz,
1903
                     ECC_KEY_SIZE_E);
1904
            }
1905
            break;
1906
        }
1907
    #endif /* HAVE_ECC */
1908
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
1909
        case SM2k:
1910
            keyType = sm2_sa_algo;
1911
            /* Determine ECC key size based on curve */
1912
            keySz = WOLFSSL_SM2_KEY_BITS / 8;
1913
            if (checkKeySz) {
1914
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minEccKeySz :
1915
                    ctx->minEccKeySz, (MAX_ECC_BITS + 7) / 8, keySz,
1916
                    ECC_KEY_SIZE_E);
1917
            }
1918
            break;
1919
    #endif /* HAVE_ED25519 */
1920
    #ifdef HAVE_ED25519
1921
        case ED25519k:
1922
            keyType = ed25519_sa_algo;
1923
            /* ED25519 is fixed key size */
1924
            keySz = ED25519_KEY_SIZE;
1925
            if (checkKeySz) {
1926
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minEccKeySz :
1927
                    ctx->minEccKeySz, ED25519_KEY_SIZE, keySz, ECC_KEY_SIZE_E);
1928
            }
1929
            break;
1930
    #endif /* HAVE_ED25519 */
1931
    #ifdef HAVE_ED448
1932
        case ED448k:
1933
            keyType = ed448_sa_algo;
1934
            /* ED448 is fixed key size */
1935
            keySz = ED448_KEY_SIZE;
1936
            if (checkKeySz) {
1937
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minEccKeySz :
1938
                    ctx->minEccKeySz, ED448_KEY_SIZE, keySz, ECC_KEY_SIZE_E);
1939
            }
1940
            break;
1941
    #endif /* HAVE_ED448 */
1942
    #if defined(HAVE_FALCON)
1943
        case FALCON_LEVEL1k:
1944
            keyType = falcon_level1_sa_algo;
1945
            /* Falcon is fixed key size */
1946
            keySz = FALCON_LEVEL1_KEY_SIZE;
1947
            if (checkKeySz) {
1948
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minFalconKeySz :
1949
                    ctx->minFalconKeySz, FALCON_MAX_KEY_SIZE, keySz,
1950
                    FALCON_KEY_SIZE_E);
1951
            }
1952
            break;
1953
        case FALCON_LEVEL5k:
1954
            keyType = falcon_level5_sa_algo;
1955
            /* Falcon is fixed key size */
1956
            keySz = FALCON_LEVEL5_KEY_SIZE;
1957
            if (checkKeySz) {
1958
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minFalconKeySz :
1959
                    ctx->minFalconKeySz, FALCON_MAX_KEY_SIZE, keySz,
1960
                    FALCON_KEY_SIZE_E);
1961
            }
1962
            break;
1963
    #endif /* HAVE_FALCON */
1964
    #if defined(HAVE_DILITHIUM)
1965
        #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
1966
        case DILITHIUM_LEVEL2k:
1967
            keyType = dilithium_level2_sa_algo;
1968
            /* Dilithium is fixed key size */
1969
            keySz = DILITHIUM_LEVEL2_KEY_SIZE;
1970
            if (checkKeySz) {
1971
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
1972
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
1973
                    DILITHIUM_KEY_SIZE_E);
1974
            }
1975
            break;
1976
        case DILITHIUM_LEVEL3k:
1977
            keyType = dilithium_level3_sa_algo;
1978
            /* Dilithium is fixed key size */
1979
            keySz = DILITHIUM_LEVEL3_KEY_SIZE;
1980
            if (checkKeySz) {
1981
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
1982
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
1983
                    DILITHIUM_KEY_SIZE_E);
1984
            }
1985
            break;
1986
        case DILITHIUM_LEVEL5k:
1987
            keyType = dilithium_level5_sa_algo;
1988
            /* Dilithium is fixed key size */
1989
            keySz = DILITHIUM_LEVEL5_KEY_SIZE;
1990
            if (checkKeySz) {
1991
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
1992
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
1993
                    DILITHIUM_KEY_SIZE_E);
1994
            }
1995
            break;
1996
        #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
1997
        case ML_DSA_LEVEL2k:
1998
            keyType = dilithium_level2_sa_algo;
1999
            /* Dilithium is fixed key size */
2000
            keySz = ML_DSA_LEVEL2_KEY_SIZE;
2001
            if (checkKeySz) {
2002
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
2003
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
2004
                    DILITHIUM_KEY_SIZE_E);
2005
            }
2006
            break;
2007
        case ML_DSA_LEVEL3k:
2008
            keyType = dilithium_level3_sa_algo;
2009
            /* Dilithium is fixed key size */
2010
            keySz = ML_DSA_LEVEL3_KEY_SIZE;
2011
            if (checkKeySz) {
2012
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
2013
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
2014
                    DILITHIUM_KEY_SIZE_E);
2015
            }
2016
            break;
2017
        case ML_DSA_LEVEL5k:
2018
            keyType = dilithium_level5_sa_algo;
2019
            /* Dilithium is fixed key size */
2020
            keySz = ML_DSA_LEVEL5_KEY_SIZE;
2021
            if (checkKeySz) {
2022
                ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz :
2023
                    ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz,
2024
                    DILITHIUM_KEY_SIZE_E);
2025
            }
2026
            break;
2027
    #endif /* HAVE_DILITHIUM */
2028
2029
        default:
2030
            /* In this case, there was an OID that we didn't recognize.
2031
             * This is an error. Use not compiled in because likely the
2032
             * given algorithm was not enabled. */
2033
            ret = NOT_COMPILED_IN;
2034
            WOLFSSL_MSG("No alt key size check done on certificate");
2035
            break;
2036
    }
2037
2038
    if (ssl != NULL) {
2039
        ssl->buffers.altKeyType = (byte)keyType;
2040
        ssl->buffers.altKeySz = keySz;
2041
    }
2042
    else if (ctx != NULL) {
2043
        ctx->altPrivateKeyType = (byte)keyType;
2044
        ctx->altPrivateKeySz = keySz;
2045
    }
2046
2047
    return ret;
2048
}
2049
#endif /* WOLFSSL_DUAL_ALG_CERTS */
2050
2051
/* Parse the certificate and pull out information for TLS handshake.
2052
 *
2053
 * @param [in, out] ctx   SSL context object.
2054
 * @param [in, out] ssl   SSL object.
2055
 * @param [in]      der   DER encoded X509 certificate.
2056
 * @return  0 on success.
2057
 * @return  MEMORY_E when dynamic memory allocation fails.
2058
 * @return  WOLFSSL_BAD_FILE when decoding certificate fails.
2059
 */
2060
static int ProcessBufferCert(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der)
2061
0
{
2062
0
    int ret = 0;
2063
0
    void* heap = WOLFSSL_HEAP(ctx, ssl);
2064
#if defined(HAVE_RPK)
2065
    RpkState* rpkState = ssl ? &ssl->options.rpkState : &ctx->rpkState;
2066
#endif
2067
#ifdef WOLFSSL_SMALL_STACK
2068
    DecodedCert* cert;
2069
#else
2070
0
    DecodedCert  cert[1];
2071
0
#endif
2072
2073
#ifdef WOLFSSL_SMALL_STACK
2074
    /* Allocate memory for certificate to be decoded into. */
2075
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap, DYNAMIC_TYPE_DCERT);
2076
    if (cert == NULL) {
2077
        ret = MEMORY_E;
2078
    }
2079
2080
    if (ret == 0)
2081
#endif
2082
0
    {
2083
        /* Get device id from SSL context or SSL object. */
2084
0
        int devId = wolfSSL_CTX_GetDevId(ctx, ssl);
2085
2086
0
        WOLFSSL_MSG("Checking cert signature type");
2087
        /* Initialize certificate object. */
2088
0
        InitDecodedCert_ex(cert, der->buffer, der->length, heap, devId);
2089
2090
        /* Decode up to and including public key. */
2091
0
        if (DecodeToKey(cert, 0) < 0) {
2092
0
            WOLFSSL_MSG("Decode to key failed");
2093
0
            ret = WOLFSSL_BAD_FILE;
2094
0
        }
2095
0
        if (ret == 0) {
2096
0
            int checkKeySz = 1;
2097
2098
        #if defined(HAVE_RPK)
2099
            /* Store whether the crtificate is a raw public key. */
2100
            rpkState->isRPKLoaded = cert->isRPK;
2101
        #endif /* HAVE_RPK */
2102
2103
            /* Set which private key algorithm we have. */
2104
0
            ProcessBufferCertSetHave(ctx, ssl, cert);
2105
2106
            /* Don't check if verification is disabled for SSL. */
2107
0
            if ((ssl != NULL) && ssl->options.verifyNone) {
2108
0
                checkKeySz = 0;
2109
0
            }
2110
            /* Don't check if no SSL object verification is disabled for SSL
2111
             * context. */
2112
0
            else if ((ssl == NULL) && ctx->verifyNone) {
2113
0
                checkKeySz = 0;
2114
0
            }
2115
2116
            /* Check public key size. */
2117
0
            ret = ProcessBufferCertPublicKey(ctx, ssl, cert, checkKeySz);
2118
        #ifdef WOLFSSL_DUAL_ALG_CERTS
2119
            if (ret == 0) {
2120
                ret = ProcessBufferCertAltPublicKey(ctx, ssl, cert, checkKeySz);
2121
            }
2122
        #endif
2123
0
        }
2124
0
    }
2125
2126
    /* Dispose of dynamic memory in certificate object. */
2127
0
    FreeDecodedCert(cert);
2128
#ifdef WOLFSSL_SMALL_STACK
2129
    /* Dispose of certificate object. */
2130
    XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
2131
#endif
2132
0
    return ret;
2133
0
}
2134
2135
/* Handle storing the DER encoding of the certificate.
2136
 *
2137
 * Do not free der outside of this function.
2138
 *
2139
 * @param [in, out] ctx     SSL context object.
2140
 * @param [in, out] ssl     SSL object.
2141
 * @param [in]      der     DER encoded certificate.
2142
 * @param [in]      type    Type of data:
2143
 *                            CERT_TYPE, CA_TYPE or TRUSTED_PEER_TYPE.
2144
 * @param [in]      verify  What verification to do.
2145
 * @return  0 on success.
2146
 * @return  BAD_FUNC_ARG when type is CA_TYPE and ctx is NULL.
2147
 * @return  WOLFSSL_BAD_CERTTYPE when data type is not supported.
2148
 */
2149
static int ProcessBufferCertHandleDer(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
2150
    DerBuffer* der, int type, int verify)
2151
0
{
2152
0
    int ret = 0;
2153
2154
    /* CA certificate to verify with. */
2155
0
    if (type == CA_TYPE) {
2156
        /* verify CA unless user set to no verify */
2157
0
        ret = AddCA(ctx->cm, &der, WOLFSSL_USER_CA, verify);
2158
0
        if (ret == 1) {
2159
0
            ret = 0;
2160
0
        }
2161
0
    }
2162
#ifdef WOLFSSL_TRUST_PEER_CERT
2163
    /* Trusted certificate to verify peer with. */
2164
    else if (type == TRUSTED_PEER_TYPE) {
2165
        WOLFSSL_CERT_MANAGER* cm;
2166
2167
        /* Get certificate manager to add certificate to. */
2168
        if (ctx != NULL) {
2169
            cm = ctx->cm;
2170
        }
2171
        else {
2172
            SSL_CM_WARNING(ssl);
2173
            cm = SSL_CM(ssl);
2174
        }
2175
        /* Add certificate as a trusted peer. */
2176
        ret = AddTrustedPeer(cm, &der, verify);
2177
        if (ret != 1) {
2178
            WOLFSSL_MSG("Error adding trusted peer");
2179
        }
2180
    }
2181
#endif /* WOLFSSL_TRUST_PEER_CERT */
2182
    /* Leaf certificate - our certificate. */
2183
0
    else if (type == CERT_TYPE) {
2184
0
        if (ssl != NULL) {
2185
            /* Free previous certificate if we own it. */
2186
0
            if (ssl->buffers.weOwnCert) {
2187
0
                FreeDer(&ssl->buffers.certificate);
2188
            #ifdef KEEP_OUR_CERT
2189
                /* Dispose of X509 version of certificate. */
2190
                wolfSSL_X509_free(ssl->ourCert);
2191
                ssl->ourCert = NULL;
2192
            #endif
2193
0
            }
2194
            /* Store certificate as ours. */
2195
0
            ssl->buffers.certificate = der;
2196
        #ifdef KEEP_OUR_CERT
2197
            ssl->keepCert = 1; /* hold cert for ssl lifetime */
2198
        #endif
2199
            /* We have to free the certificate buffer. */
2200
0
            ssl->buffers.weOwnCert = 1;
2201
            /* ourCert is created on demand. */
2202
0
        }
2203
0
        else if (ctx != NULL) {
2204
            /* Free previous certificate. */
2205
0
            FreeDer(&ctx->certificate); /* Make sure previous is free'd */
2206
        #ifdef KEEP_OUR_CERT
2207
            /* Dispose of X509 version of certificate if we own it. */
2208
            if (ctx->ownOurCert) {
2209
                wolfSSL_X509_free(ctx->ourCert);
2210
            }
2211
            ctx->ourCert = NULL;
2212
        #endif
2213
            /* Store certificate as ours. */
2214
0
            ctx->certificate = der;
2215
            /* ourCert is created on demand. */
2216
0
        }
2217
0
    }
2218
0
    else {
2219
        /* Dispose of DER buffer. */
2220
0
        FreeDer(&der);
2221
        /* Not a certificate type supported. */
2222
0
        ret = WOLFSSL_BAD_CERTTYPE;
2223
0
    }
2224
2225
0
    return ret;
2226
0
}
2227
2228
/* Process certificate based on type.
2229
 *
2230
 * @param [in, out] ctx     SSL context object.
2231
 * @param [in, out] ssl     SSL object.
2232
 * @param [in]      buff    Buffer holding original data.
2233
 * @param [in]      sz      Size of data in buffer.
2234
 * @param [in]      der     DER encoding of certificate.
2235
 * @param [in]      format  Format of data.
2236
 * @param [in]      type    Type of data:
2237
 *                            CERT_TYPE, CA_TYPE or TRUSTED_PEER_TYPE.
2238
 * @param [in]      verify  What verification to do.
2239
 * @return  0 on success.
2240
 * @return  WOLFSSL_FATAL_ERROR on failure.
2241
 */
2242
static int ProcessBufferCertTypes(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
2243
    const unsigned char* buff, long sz, DerBuffer* der, int format, int type,
2244
    int verify)
2245
0
{
2246
0
    int ret;
2247
2248
0
    (void)buff;
2249
0
    (void)sz;
2250
0
    (void)format;
2251
2252
0
    ret = ProcessBufferCertHandleDer(ctx, ssl, der, type, verify);
2253
0
    if ((ret == 0) && (type == CERT_TYPE)) {
2254
        /* Process leaf certificate. */
2255
0
        ret = ProcessBufferCert(ctx, ssl, der);
2256
0
    }
2257
0
#if !defined(NO_WOLFSSL_CM_VERIFY) && (!defined(NO_WOLFSSL_CLIENT) || \
2258
0
    !defined(WOLFSSL_NO_CLIENT_AUTH))
2259
    /* Hand bad CA or user certificate to callback. */
2260
0
    if ((ret < 0) && ((type == CA_TYPE) || (type == CERT_TYPE))) {
2261
        /* Check for verification callback that may override error. */
2262
0
        if ((ctx != NULL) && (ctx->cm != NULL) &&
2263
0
                (ctx->cm->verifyCallback != NULL)) {
2264
            /* Verify and use callback. */
2265
0
            ret = CM_VerifyBuffer_ex(ctx->cm, buff, sz, format, ret);
2266
            /* Convert error. */
2267
0
            if (ret == 0) {
2268
0
                ret = WOLFSSL_FATAL_ERROR;
2269
0
            }
2270
0
            if (ret == 1) {
2271
0
                ret = 0;
2272
0
            }
2273
0
        }
2274
0
    }
2275
0
#endif /* NO_WOLFSSL_CM_VERIFY */
2276
2277
0
    return ret;
2278
0
}
2279
2280
/* Reset the cipher suites based on updated private key or certificate.
2281
 *
2282
 * @param [in, out] ctx     SSL context object.
2283
 * @param [in, out] ssl     SSL object.
2284
 * @param [in]      type    Type of certificate.
2285
 * @return  0 on success.
2286
 * @return  WOLFSSL_FATAL_ERROR when allocation fails.
2287
 */
2288
static int ProcessBufferResetSuites(WOLFSSL_CTX* ctx, WOLFSSL* ssl, int type)
2289
0
{
2290
0
    int ret = 0;
2291
2292
    /* Reset suites of SSL object. */
2293
0
    if (ssl != NULL) {
2294
0
        if (ssl->options.side == WOLFSSL_SERVER_END) {
2295
            /* Allocate memory for suites. */
2296
0
            if (AllocateSuites(ssl) != 0) {
2297
0
                ret = WOLFSSL_FATAL_ERROR;
2298
0
            }
2299
0
            else {
2300
                /* Determine cipher suites based on what we have. */
2301
0
                InitSuites(ssl->suites, ssl->version, ssl->buffers.keySz,
2302
0
                    WOLFSSL_HAVE_RSA, SSL_HAVE_PSK(ssl), ssl->options.haveDH,
2303
0
                    ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE,
2304
0
                    ssl->options.haveStaticECC,
2305
0
                    ssl->options.useAnon, TRUE,
2306
0
                    TRUE, TRUE, TRUE, ssl->options.side);
2307
0
            }
2308
0
        }
2309
0
    }
2310
    /* Reset suites of SSL context object. */
2311
0
    else if ((type == CERT_TYPE) && (ctx->method->side == WOLFSSL_SERVER_END)) {
2312
        /* Allocate memory for suites. */
2313
0
        if (AllocateCtxSuites(ctx) != 0) {
2314
0
            ret = WOLFSSL_FATAL_ERROR;
2315
0
        }
2316
0
        else {
2317
            /* Determine cipher suites based on what we have. */
2318
0
            InitSuites(ctx->suites, ctx->method->version, ctx->privateKeySz,
2319
0
                WOLFSSL_HAVE_RSA, CTX_HAVE_PSK(ctx), ctx->haveDH,
2320
0
                ctx->haveECDSAsig, ctx->haveECC, TRUE, ctx->haveStaticECC,
2321
0
                CTX_USE_ANON(ctx),
2322
0
                TRUE, TRUE, TRUE, TRUE, ctx->method->side);
2323
0
        }
2324
0
    }
2325
2326
0
    return ret;
2327
0
}
2328
2329
#ifndef WOLFSSL_DUAL_ALG_CERTS
2330
    /* Determine whether the type is for a private key. */
2331
0
    #define IS_PRIVKEY_TYPE(type) ((type) == PRIVATEKEY_TYPE)
2332
#else
2333
    /* Determine whether the type is for a private key. */
2334
    #define IS_PRIVKEY_TYPE(type) (((type) == PRIVATEKEY_TYPE) ||   \
2335
                                   ((type) == ALT_PRIVATEKEY_TYPE))
2336
#endif
2337
2338
/* Process a buffer of data.
2339
 *
2340
 * Data type is a private key or a certificate.
2341
 * The format can be ASN.1 (DER) or PEM.
2342
 *
2343
 * @param [in, out] ctx        SSL context object.
2344
 * @param [in]      buff       Buffer holding data.
2345
 * @param [in]      sz         Size of data in buffer.
2346
 * @param [in]      format     Format of data:
2347
 *                               WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
2348
 * @param [in]      type       Type of data:
2349
 *                               CERT_TYPE, CA_TYPE, TRUSTED_PEER_TYPE,
2350
 *                               PRIVATEKEY_TYPE or ALT_PRIVATEKEY_TYPE.
2351
 * @param [in, out] ssl        SSL object.
2352
 * @param [out]     used       Number of bytes consumed.
2353
 * @param [in[      userChain  Whether this certificate is for user's chain.
2354
 * @param [in]      verify     How to verify certificate.
2355
 * @param [in]      source_name Associated filename or other source ID.
2356
 * @return  1 on success.
2357
 * @return  Less than 1 on failure.
2358
 */
2359
int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, long sz,
2360
    int format, int type, WOLFSSL* ssl, long* used, int userChain, int verify,
2361
    const char *source_name)
2362
0
{
2363
0
    DerBuffer*    der = NULL;
2364
0
    int           ret = 0;
2365
0
    void*         heap = WOLFSSL_HEAP(ctx, ssl);
2366
#ifdef WOLFSSL_SMALL_STACK
2367
    EncryptedInfo* info = NULL;
2368
#else
2369
0
    EncryptedInfo  info[1];
2370
0
#endif
2371
0
    int           algId = 0;
2372
#ifdef WOLFSSL_DEBUG_CERTIFICATE_LOADS
2373
    long usedAtStart = used ? *used : 0L;
2374
#else
2375
0
    (void)source_name;
2376
0
#endif
2377
2378
0
    WOLFSSL_ENTER("ProcessBuffer");
2379
2380
    /* Check data format is supported. */
2381
0
    if ((format != WOLFSSL_FILETYPE_ASN1) && (format != WOLFSSL_FILETYPE_PEM)) {
2382
0
        ret = WOLFSSL_BAD_FILETYPE;
2383
0
    }
2384
    /* Need an object to store certificate into. */
2385
0
    if ((ret == 0) && (ctx == NULL) && (ssl == NULL)) {
2386
0
        ret = BAD_FUNC_ARG;
2387
0
    }
2388
    /* CA certificates go into the SSL context object. */
2389
0
    if ((ret == 0) && (ctx == NULL) && (type == CA_TYPE)) {
2390
0
        ret = BAD_FUNC_ARG;
2391
0
    }
2392
    /* This API does not handle CHAIN_CERT_TYPE */
2393
0
    if ((ret == 0) && (type == CHAIN_CERT_TYPE)) {
2394
0
        ret = BAD_FUNC_ARG;
2395
0
    }
2396
2397
#ifdef WOLFSSL_SMALL_STACK
2398
    if (ret == 0) {
2399
        /* Allocate memory for encryption information. */
2400
        info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
2401
            DYNAMIC_TYPE_ENCRYPTEDINFO);
2402
        if (info == NULL) {
2403
            ret = MEMORY_E;
2404
        }
2405
    }
2406
#endif
2407
0
    if (ret == 0) {
2408
        /* Initialize encryption information. */
2409
0
        XMEMSET(info, 0, sizeof(EncryptedInfo));
2410
    #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
2411
        if (ctx != NULL) {
2412
            info->passwd_cb       = ctx->passwd_cb;
2413
            info->passwd_userdata = ctx->passwd_userdata;
2414
        }
2415
    #endif
2416
2417
        /* Get the DER data for a private key or certificate. */
2418
0
        ret = DataToDerBuffer(buff, (word32)sz, format, type, info, heap, &der,
2419
0
            &algId);
2420
0
        if (used != NULL) {
2421
            /* Update to amount used/consumed. */
2422
0
            *used = info->consumed;
2423
0
        }
2424
    #ifdef WOLFSSL_SMALL_STACK
2425
        if (ret != 0) {
2426
             /* Info no longer needed as loading failed. */
2427
             XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
2428
        }
2429
    #endif
2430
0
    }
2431
2432
0
    if ((ret == 0) && IS_PRIVKEY_TYPE(type)) {
2433
        /* Process the private key. */
2434
0
        ret = ProcessBufferPrivateKey(ctx, ssl, der, format, info, heap, type,
2435
0
            algId);
2436
    #ifdef WOLFSSL_SMALL_STACK
2437
        /* Info no longer needed - keep max memory usage down. */
2438
        XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
2439
    #endif
2440
0
    }
2441
0
    else if (ret == 0) {
2442
        /* Processing a certificate. */
2443
0
        if (userChain) {
2444
            /* Take original buffer and add to user chain to send in TLS
2445
             * handshake. */
2446
0
            ret = ProcessUserChain(ctx, ssl, buff, sz, format, type, used, info,
2447
0
                verify);
2448
            /* Additional chain is optional */
2449
0
            if (ret == WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER)) {
2450
0
                unsigned long pemErr = 0;
2451
0
                CLEAR_ASN_NO_PEM_HEADER_ERROR(pemErr);
2452
0
                ret = 0;
2453
0
            }
2454
#ifdef WOLFSSL_DEBUG_CERTIFICATE_LOADS
2455
            if (ret < 0) {
2456
#ifdef NO_ERROR_STRINGS
2457
                WOLFSSL_DEBUG_PRINTF(
2458
                    "ERROR: ProcessUserChain: certificate from %s at offset %ld"
2459
                    " rejected with code %d\n",
2460
                    source_name, usedAtStart, ret);
2461
#else
2462
                WOLFSSL_DEBUG_PRINTF(
2463
                    "ERROR: ProcessUserChain: certificate from %s at offset %ld"
2464
                    " rejected with code %d: %s\n",
2465
                    source_name, usedAtStart, ret,
2466
                    wolfSSL_ERR_reason_error_string(ret));
2467
#endif
2468
            }
2469
#endif /* WOLFSSL_DEBUG_CERTIFICATE_LOADS */
2470
0
        }
2471
2472
    #ifdef WOLFSSL_SMALL_STACK
2473
        /* Info no longer needed - keep max memory usage down. */
2474
        XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
2475
    #endif
2476
2477
0
        if (ret == 0) {
2478
            /* Process the different types of certificates. */
2479
0
            ret = ProcessBufferCertTypes(ctx, ssl, buff, sz, der, format, type,
2480
0
                verify);
2481
#ifdef WOLFSSL_DEBUG_CERTIFICATE_LOADS
2482
            if (ret < 0) {
2483
#ifdef NO_ERROR_STRINGS
2484
                WOLFSSL_DEBUG_PRINTF(
2485
                    "ERROR: ProcessBufferCertTypes: certificate from %s at"
2486
                    " offset %ld rejected with code %d\n",
2487
                    source_name, usedAtStart, ret);
2488
#else
2489
                WOLFSSL_DEBUG_PRINTF(
2490
                    "ERROR: ProcessBufferCertTypes: certificate from %s at"
2491
                    " offset %ld rejected with code %d: %s\n",
2492
                    source_name, usedAtStart, ret,
2493
                    wolfSSL_ERR_reason_error_string(ret));
2494
#endif
2495
            }
2496
#endif /* WOLFSSL_DEBUG_CERTIFICATE_LOADS */
2497
0
        }
2498
0
        else {
2499
0
            FreeDer(&der);
2500
0
        }
2501
0
    }
2502
2503
    /* Reset suites if this is a private key or user certificate. */
2504
0
    if ((ret == 0) && ((type == PRIVATEKEY_TYPE) || (type == CERT_TYPE))) {
2505
0
        ret = ProcessBufferResetSuites(ctx, ssl, type);
2506
0
    }
2507
2508
    /* Convert return code. */
2509
0
    if (ret == 0) {
2510
0
        ret = 1;
2511
0
    }
2512
0
    else if (ret == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) {
2513
0
        ret = 0;
2514
0
    }
2515
0
    WOLFSSL_LEAVE("ProcessBuffer", ret);
2516
0
    return ret;
2517
0
}
2518
2519
#if defined(WOLFSSL_WPAS) && defined(HAVE_CRL)
2520
/* Try to parse data as a PEM CRL.
2521
 *
2522
 * @param [in]  ctx       SSL context object.
2523
 * @param [in]  buff      Buffer containing potential CRL in PEM format.
2524
 * @param [in]  sz        Amount of data in buffer remaining.
2525
 * @param [out] consumed  Number of bytes in buffer was the CRL.
2526
 * @return  0 on success.
2527
 */
2528
static int ProcessChainBufferCRL(WOLFSSL_CTX* ctx, const unsigned char* buff,
2529
    long sz, long* consumed)
2530
{
2531
    int           ret;
2532
    DerBuffer*    der = NULL;
2533
    EncryptedInfo info;
2534
2535
    WOLFSSL_MSG("Trying a CRL");
2536
    ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, NULL);
2537
    if (ret == 0) {
2538
        WOLFSSL_MSG("   Processed a CRL");
2539
        wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, der->buffer, der->length,
2540
            WOLFSSL_FILETYPE_ASN1);
2541
        FreeDer(&der);
2542
        *consumed = info.consumed;
2543
    }
2544
2545
    return ret;
2546
}
2547
#endif
2548
2549
/* Process all chain certificates (and CRLs) in the PEM data.
2550
 *
2551
 * @param [in, out] ctx     SSL context object.
2552
 * @param [in, out] ssl     SSL object.
2553
 * @param [in]      buff    Buffer containing PEM data.
2554
 * @param [in]      sz      Size of data in buffer.
2555
 * @param [in]      type    Type of data.
2556
 * @param [in]      verify  How to verify certificate.
2557
 * @param [in]      source_name   Associated filename or other source ID.
2558
 * @return  1 on success.
2559
 * @return  0 on failure.
2560
 * @return  MEMORY_E when dynamic memory allocation fails.
2561
 */
2562
static int ProcessChainBuffer(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
2563
    const unsigned char* buff, long sz, int type, int verify,
2564
    const char *source_name)
2565
0
{
2566
0
    int  ret    = 0;
2567
0
    long used   = 0;
2568
0
    int  gotOne = 0;
2569
2570
0
    WOLFSSL_MSG("Processing CA PEM file");
2571
    /* Keep processing file while no errors and data to parse. */
2572
0
    while ((ret >= 0) && (used < sz)) {
2573
0
        long consumed = used;
2574
2575
        /* Process the buffer. */
2576
0
        ret = ProcessBuffer(ctx, buff + used, sz - used, WOLFSSL_FILETYPE_PEM,
2577
0
            type, ssl, &consumed, 0, verify, source_name);
2578
        /* Memory allocation failure is fatal. */
2579
0
        if (ret == WC_NO_ERR_TRACE(MEMORY_E)) {
2580
0
            gotOne = 0;
2581
0
        }
2582
        /* Other error parsing. */
2583
0
        else if (ret < 0) {
2584
#if defined(WOLFSSL_WPAS) && defined(HAVE_CRL)
2585
            /* Try parsing a CRL. */
2586
            if (ProcessChainBufferCRL(ctx, buff + used, sz - used,
2587
                    &consumed) == 0) {
2588
                ret = 0;
2589
            }
2590
            else
2591
#endif
2592
            /* Check whether we made progress. */
2593
0
            if (consumed > 0) {
2594
0
                WOLFSSL_ERROR(ret);
2595
0
                WOLFSSL_MSG("CA Parse failed, with progress in file.");
2596
0
                WOLFSSL_MSG("Search for other certs in file");
2597
                /* Check if we have more data to parse to recover. */
2598
0
                if (used + consumed < sz) {
2599
0
                    ret = 0;
2600
0
                }
2601
0
            }
2602
0
            else {
2603
                /* No progress in parsing being made - stop here. */
2604
0
                WOLFSSL_MSG("CA Parse failed, no progress in file.");
2605
0
                WOLFSSL_MSG("Do not continue search for other certs in file");
2606
0
            }
2607
0
        }
2608
0
        else {
2609
            /* Got a certificate out. */
2610
0
            WOLFSSL_MSG("   Processed a CA");
2611
0
            gotOne = 1;
2612
0
        }
2613
        /* Update used count. */
2614
0
        used += consumed;
2615
0
    }
2616
2617
    /* May have other unparsable data but did we get a certificate? */
2618
0
    if (gotOne) {
2619
0
        WOLFSSL_MSG("Processed at least one valid CA. Other stuff OK");
2620
0
        ret = 1;
2621
0
    }
2622
0
    return ret;
2623
0
}
2624
2625
2626
/* Get verify settings for AddCA from SSL context. */
2627
#define GET_VERIFY_SETTING_CTX(ctx) \
2628
0
    ((ctx) && (ctx)->verifyNone ? NO_VERIFY : VERIFY)
2629
/* Get verify settings for AddCA from SSL. */
2630
#define GET_VERIFY_SETTING_SSL(ssl) \
2631
0
    ((ssl)->options.verifyNone ? NO_VERIFY : VERIFY)
2632
2633
#ifndef NO_FILESYSTEM
2634
2635
/* Process data from a file as private keys, CRL or certificates.
2636
 *
2637
 * @param [in, out] ctx        SSL context object.
2638
 * @param [in]      fname      Name of file to read.
2639
 * @param [in]      format     Format of data:
2640
 *                               WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
2641
 * @param [in]      type       Type of data:
2642
 *                               CERT_TYPE, CA_TYPE, TRUSTED_PEER_TYPE,
2643
 *                               PRIVATEKEY_TYPE or ALT_PRIVATEKEY_TYPE.
2644
 * @param [in, out] ssl        SSL object.
2645
 * @param [in]      userChain  Whether file contains chain of certificates.
2646
 * @param [in, out] crl        CRL object to load data into.
2647
 * @param [in]      verify     How to verify certificates.
2648
 * @return  1 on success.
2649
 * @return  WOLFSSL_BAD_FILE when reading the file fails.
2650
 * @return  WOLFSSL_BAD_CERTTYPE when unable to detect certificate type.
2651
 */
2652
int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
2653
    WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl, int verify)
2654
0
{
2655
0
    int    ret = 0;
2656
0
#ifndef WOLFSSL_SMALL_STACK
2657
0
    byte   stackBuffer[FILE_BUFFER_SIZE];
2658
0
#endif
2659
0
    StaticBuffer content;
2660
0
    long   sz = 0;
2661
0
    void*  heap = WOLFSSL_HEAP(ctx, ssl);
2662
2663
0
    (void)crl;
2664
0
    (void)heap;
2665
2666
#ifdef WOLFSSL_SMALL_STACK
2667
    static_buffer_init(&content);
2668
#else
2669
0
    static_buffer_init(&content, stackBuffer, FILE_BUFFER_SIZE);
2670
0
#endif
2671
2672
    /* Read file into static buffer. */
2673
0
    ret = wolfssl_read_file_static(fname, &content, heap, DYNAMIC_TYPE_FILE,
2674
0
        &sz);
2675
0
    if ((ret == 0) && (type == DETECT_CERT_TYPE) &&
2676
0
            (format != WOLFSSL_FILETYPE_PEM)) {
2677
0
        WOLFSSL_MSG("Cannot detect certificate type when not PEM");
2678
0
        ret = WOLFSSL_BAD_CERTTYPE;
2679
0
    }
2680
    /* Try to detect type by parsing cert header and footer. */
2681
0
    if ((ret == 0) && (type == DETECT_CERT_TYPE)) {
2682
0
#if !defined(NO_CODING) && !defined(WOLFSSL_NO_PEM)
2683
0
        const char* header = NULL;
2684
0
        const char* footer = NULL;
2685
2686
        /* Look for CA header and footer - same as CERT_TYPE. */
2687
0
        if (wc_PemGetHeaderFooter(CA_TYPE, &header, &footer) == 0 &&
2688
0
                (XSTRNSTR((char*)content.buffer, header, (word32)sz) != NULL)) {
2689
0
            type = CA_TYPE;
2690
0
        }
2691
#ifdef HAVE_CRL
2692
        /* Look for CRL header and footer. */
2693
        else if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
2694
                (XSTRNSTR((char*)content.buffer, header, (word32)sz) != NULL)) {
2695
            type = CRL_TYPE;
2696
        }
2697
#endif
2698
        /* Look for cert header and footer - same as CA_TYPE. */
2699
0
        else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
2700
0
                (XSTRNSTR((char*)content.buffer, header, (word32)sz) !=
2701
0
                    NULL)) {
2702
0
            type = CERT_TYPE;
2703
0
        }
2704
0
        else
2705
0
#endif
2706
0
        {
2707
            /* Not a header that we support. */
2708
0
            WOLFSSL_MSG("Failed to detect certificate type");
2709
#ifdef WOLFSSL_DEBUG_CERTIFICATE_LOADS
2710
            WOLFSSL_DEBUG_PRINTF(
2711
                "ERROR: ProcessFile: Failed to detect certificate type"
2712
                " of \"%s\"\n",
2713
                fname);
2714
#endif
2715
0
            ret = WOLFSSL_BAD_CERTTYPE;
2716
0
        }
2717
0
    }
2718
0
    if (ret == 0) {
2719
        /* When CA or trusted peer and PEM - process as a chain buffer. */
2720
0
        if (((type == CA_TYPE) || (type == TRUSTED_PEER_TYPE)) &&
2721
0
                (format == WOLFSSL_FILETYPE_PEM)) {
2722
0
            ret = ProcessChainBuffer(ctx, ssl, content.buffer, sz, type,
2723
0
                verify, fname);
2724
0
        }
2725
#ifdef HAVE_CRL
2726
        else if (type == CRL_TYPE) {
2727
            /* Load the CRL. */
2728
            ret = BufferLoadCRL(crl, content.buffer, sz, format, verify);
2729
        }
2730
#endif
2731
#ifdef WOLFSSL_DUAL_ALG_CERTS
2732
        else if (type == PRIVATEKEY_TYPE) {
2733
            /* When support for dual algorithm certificates is enabled, the
2734
             * private key file may contain both the primary and the
2735
             * alternative private key. Hence, we have to parse both of them.
2736
             */
2737
            long consumed = 0;
2738
2739
            ret = ProcessBuffer(ctx, content.buffer, sz, format, type, ssl,
2740
                &consumed, userChain, verify, fname);
2741
            if ((ret == 1) && (consumed < sz)) {
2742
                ret = ProcessBuffer(ctx, content.buffer + consumed,
2743
                    sz - consumed, format, ALT_PRIVATEKEY_TYPE, ssl, NULL, 0,
2744
                    verify, fname);
2745
            }
2746
        }
2747
#endif
2748
0
        else {
2749
            /* Load all other certificate types. */
2750
0
            ret = ProcessBuffer(ctx, content.buffer, sz, format, type, ssl,
2751
0
                NULL, userChain, verify, fname);
2752
0
        }
2753
0
    }
2754
2755
    /* Dispose of dynamically allocated data. */
2756
0
    static_buffer_free(&content, heap, DYNAMIC_TYPE_FILE);
2757
0
    return ret;
2758
0
}
2759
2760
#ifndef NO_WOLFSSL_DIR
2761
/* Load file when filename is in the path.
2762
 *
2763
 * @param [in, out] ctx           SSL context object.
2764
 * @param [in]      name          Name of file.
2765
 * @param [in]      verify        How to verify a certificate.
2766
 * @param [in]      flags         Flags representing options for loading.
2767
 * @param [in, out] failCount     Number of files that failed to load.
2768
 * @param [in, out] successCount  Number of files successfully loaded.
2769
 * @return  1 on success.
2770
 * @return  Not 1 when loading PEM certificate failed.
2771
 */
2772
static int wolfssl_ctx_load_path_file(WOLFSSL_CTX* ctx, const char* name,
2773
    int verify, int flags, int* failCount, int* successCount)
2774
0
{
2775
0
    int ret;
2776
2777
    /* Attempt to load file as a CA. */
2778
0
    ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL,
2779
0
        verify);
2780
0
    if (ret != 1) {
2781
        /* When ignoring errors or loading PEM only and no PEM. don't fail. */
2782
0
        if ((flags & WOLFSSL_LOAD_FLAG_IGNORE_ERR) ||
2783
0
                ((flags & WOLFSSL_LOAD_FLAG_PEM_CA_ONLY) &&
2784
0
                 (ret == WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER)))) {
2785
0
            unsigned long err = 0;
2786
0
            CLEAR_ASN_NO_PEM_HEADER_ERROR(err);
2787
        #if defined(WOLFSSL_QT)
2788
            ret = 1;
2789
        #endif
2790
0
        }
2791
0
        else {
2792
0
            WOLFSSL_ERROR(ret);
2793
0
            WOLFSSL_MSG("Load CA file failed, continuing");
2794
            /* Add to fail count. */
2795
0
            (*failCount)++;
2796
0
        }
2797
0
    }
2798
0
    else {
2799
    #if defined(WOLFSSL_TRUST_PEER_CERT) && defined(OPENSSL_COMPATIBLE_DEFAULTS)
2800
        /* Try loading as a trusted peer certificate. */
2801
        ret = wolfSSL_CTX_trust_peer_cert(ctx, name, WOLFSSL_FILETYPE_PEM);
2802
        if (ret != 1) {
2803
            WOLFSSL_MSG("wolfSSL_CTX_trust_peer_cert error. "
2804
                        "Ignoring this error.");
2805
        }
2806
    #endif
2807
        /* Add to success count. */
2808
0
        (*successCount)++;
2809
0
    }
2810
2811
0
    return ret;
2812
0
}
2813
2814
/* Load PEM formatted CA files from a path.
2815
 *
2816
 * @param [in, out] ctx           SSL context object.
2817
 * @param [in]      path          Path to directory to read.
2818
 * @param [in]      flags         Flags representing options for loading.
2819
 * @param [in]      verify        How to verify a certificate.
2820
 * @param [in]      successCount  Number of files successfully loaded.
2821
 * @return  1 on success.
2822
 * @return  0 on failure.
2823
 * @return  MEMORY_E when dynamic memory allocation fails.
2824
 */
2825
static int wolfssl_ctx_load_path(WOLFSSL_CTX* ctx, const char* path,
2826
    word32 flags, int verify, int successCount)
2827
0
{
2828
0
    int ret = 1;
2829
0
    char* name = NULL;
2830
0
    int fileRet;
2831
0
    int failCount = 0;
2832
#ifdef WOLFSSL_SMALL_STACK
2833
    ReadDirCtx* readCtx;
2834
#else
2835
0
    ReadDirCtx readCtx[1];
2836
0
#endif
2837
2838
#ifdef WOLFSSL_SMALL_STACK
2839
    /* Allocate memory for directory reading context. */
2840
    readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
2841
        DYNAMIC_TYPE_DIRCTX);
2842
    if (readCtx == NULL) {
2843
        ret = MEMORY_E;
2844
    }
2845
#endif
2846
2847
0
    if (ret == 1) {
2848
        /* Get name of first file in path. */
2849
0
        fileRet = wc_ReadDirFirst(readCtx, path, &name);
2850
        /* While getting filename doesn't fail and name returned, process file.
2851
         */
2852
0
        while ((fileRet == 0) && (name != NULL)) {
2853
0
            WOLFSSL_MSG(name);
2854
            /* Load file. */
2855
0
            ret = wolfssl_ctx_load_path_file(ctx, name, verify, (int)flags,
2856
0
                &failCount, &successCount);
2857
            /* Get next filename. */
2858
0
            fileRet = wc_ReadDirNext(readCtx, path, &name);
2859
0
        }
2860
        /* Cleanup directory reading context. */
2861
0
        wc_ReadDirClose(readCtx);
2862
2863
        /* When not WOLFSSL_QT, ret is always overwritten. */
2864
0
        (void)ret;
2865
2866
        /* Return real directory read failure error codes. */
2867
0
        if (fileRet != WC_READDIR_NOFILE) {
2868
0
            ret = fileRet;
2869
        #if defined(WOLFSSL_QT) || defined(WOLFSSL_IGNORE_BAD_CERT_PATH)
2870
            /* Ignore bad path error when flag set. */
2871
            if ((ret == WC_NO_ERR_TRACE(BAD_PATH_ERROR)) &&
2872
                    (flags & WOLFSSL_LOAD_FLAG_IGNORE_BAD_PATH_ERR)) {
2873
               /* QSslSocket always loads certs in system folder
2874
                * when it is initialized.
2875
                * Compliant with OpenSSL when flag set.
2876
                */
2877
                ret = 1;
2878
            }
2879
            else {
2880
                /* qssl socket wants to know errors. */
2881
                WOLFSSL_ERROR(ret);
2882
            }
2883
        #endif
2884
0
        }
2885
        /* Report failure if no files successfully loaded or there were
2886
         * failures. */
2887
0
        else if ((successCount == 0) || (failCount > 0)) {
2888
            /* Use existing error code if exists. */
2889
        #if defined(WOLFSSL_QT)
2890
            /* Compliant with OpenSSL when flag set. */
2891
            if (!(flags & WOLFSSL_LOAD_FLAG_IGNORE_ZEROFILE))
2892
        #endif
2893
0
            {
2894
                /* Return 0 when no files loaded. */
2895
0
                ret = 0;
2896
0
            }
2897
0
        }
2898
0
        else {
2899
            /* We loaded something so it is a success. */
2900
0
            ret = 1;
2901
0
        }
2902
2903
    #ifdef WOLFSSL_SMALL_STACK
2904
        /* Dispose of dynamically allocated memory. */
2905
        XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_DIRCTX);
2906
    #endif
2907
0
    }
2908
2909
0
    return ret;
2910
0
}
2911
#endif
2912
2913
/* Load a file and/or files in path
2914
 *
2915
 * No c_rehash.
2916
 *
2917
 * @param [in, out] ctx    SSL context object.
2918
 * @param [in]      file   Name of file to load. May be NULL.
2919
 * @param [in]      path   Path to directory containing PEM CA files.
2920
 *                         May be NULL.
2921
 * @param [in]      flags  Flags representing options for loading.
2922
 * @return  1 on success.
2923
 * @return  0 on failure.
2924
 * @return  NOT_COMPILED_IN when directory reading not supported and path is
2925
 *          not NULL.
2926
 * @return  Other negative on error.
2927
 */
2928
int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file,
2929
    const char* path, word32 flags)
2930
0
{
2931
0
    int ret = 1;
2932
0
#ifndef NO_WOLFSSL_DIR
2933
0
    int successCount = 0;
2934
0
#endif
2935
0
    int verify = WOLFSSL_VERIFY_DEFAULT;
2936
2937
0
    WOLFSSL_MSG("wolfSSL_CTX_load_verify_locations_ex");
2938
2939
    /* Validate parameters. */
2940
0
    if ((ctx == NULL) || ((file == NULL) && (path == NULL))) {
2941
0
        ret = 0;
2942
0
    }
2943
2944
0
    if (ret == 1) {
2945
        /* Get setting on how to verify certificates. */
2946
0
        verify = GET_VERIFY_SETTING_CTX(ctx);
2947
        /* Overwrite setting when flag set. */
2948
0
        if (flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY) {
2949
0
            verify = VERIFY_SKIP_DATE;
2950
0
        }
2951
2952
0
        if (file != NULL) {
2953
            /* Load the PEM formatted CA file */
2954
0
            ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CA_TYPE, NULL, 0,
2955
0
                NULL, verify);
2956
0
    #ifndef NO_WOLFSSL_DIR
2957
0
            if (ret == 1) {
2958
                /* Include success in overall count. */
2959
0
                successCount++;
2960
0
            }
2961
0
    #endif
2962
    #if defined(WOLFSSL_TRUST_PEER_CERT) && defined(OPENSSL_COMPATIBLE_DEFAULTS)
2963
            /* Load CA as a trusted peer certificate. */
2964
            ret = wolfSSL_CTX_trust_peer_cert(ctx, file, WOLFSSL_FILETYPE_PEM);
2965
            if (ret != 1) {
2966
                WOLFSSL_MSG("wolfSSL_CTX_trust_peer_cert error");
2967
            }
2968
    #endif
2969
0
        }
2970
0
    }
2971
2972
0
    if ((ret == 1) && (path != NULL)) {
2973
0
#ifndef NO_WOLFSSL_DIR
2974
        /* Load CA files form path. */
2975
0
        ret = wolfssl_ctx_load_path(ctx, path, flags, verify, successCount);
2976
#else
2977
        /* Loading a path not supported. */
2978
        ret = NOT_COMPILED_IN;
2979
        (void)flags;
2980
#endif
2981
0
    }
2982
2983
0
    return ret;
2984
0
}
2985
2986
/* Load a file and/or files in path
2987
 *
2988
 * No c_rehash.
2989
 *
2990
 * @param [in, out] ctx    SSL context object.
2991
 * @param [in]      file   Name of file to load. May be NULL.
2992
 * @param [in]      path   Path to directory containing PEM CA files.
2993
 *                         May be NULL.
2994
 * @return  1 on success.
2995
 * @return  0 on failure.
2996
 */
2997
WOLFSSL_ABI
2998
int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
2999
                                     const char* path)
3000
0
{
3001
    /* Load using default flags/options. */
3002
0
    int ret = wolfSSL_CTX_load_verify_locations_ex(ctx, file, path,
3003
0
        WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
3004
3005
    /* Return 1 on success or 0 on failure. */
3006
0
    return WS_RETURN_CODE(ret, 0);
3007
0
}
3008
3009
/* Load a file and/or files in path, with OpenSSL-compatible semantics.
3010
 *
3011
 * No c_rehash.
3012
 *
3013
 * @param [in, out] ctx    SSL context object.
3014
 * @param [in]      file   Name of file to load. May be NULL.
3015
 * @param [in]      path   Path to directory containing PEM CA files.
3016
 *                         May be NULL.
3017
 * @return  1 on success.
3018
 * @return  0 on failure.
3019
 */
3020
int wolfSSL_CTX_load_verify_locations_compat(WOLFSSL_CTX* ctx, const char* file,
3021
                                     const char* path)
3022
0
{
3023
    /* We want to keep trying to load more CA certs even if one cert in the
3024
     * directory is bad and can't be used (e.g. if one is expired), and we
3025
     * want to return success if any were successfully loaded (mimicking
3026
     * OpenSSL SSL_CTX_load_verify_locations() semantics), so we use
3027
     * WOLFSSL_LOAD_FLAG_IGNORE_ERR.  OpenSSL (as of v3.3.2) actually
3028
     * returns success even if no certs are loaded (e.g. because the
3029
     * supplied "path" doesn't exist or access is prohibited), and only
3030
     * returns failure if the "file" is non-null and fails to load.
3031
     *
3032
     * Note that if a file is supplied and can't be successfully loaded, the
3033
     * overall call fails and the path is never even evaluated.  This is
3034
     * consistent with OpenSSL behavior.
3035
     */
3036
3037
0
    int ret = wolfSSL_CTX_load_verify_locations_ex(ctx, file, path,
3038
0
        WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS | WOLFSSL_LOAD_FLAG_IGNORE_ERR);
3039
3040
    /* Return 1 on success or 0 on failure. */
3041
0
    return WS_RETURN_CODE(ret, 0);
3042
0
}
3043
3044
#ifdef WOLFSSL_SYS_CA_CERTS
3045
3046
#ifdef USE_WINDOWS_API
3047
3048
/* Load CA certificate from Windows store.
3049
 *
3050
 * Assumes loaded is 0.
3051
 *
3052
 * @param [in, out] ctx     SSL context object.
3053
 * @param [out]     loaded  Whether CA certificates were loaded.
3054
 * @return  1 on success.
3055
 * @return  0 on failure.
3056
 */
3057
static int LoadSystemCaCertsWindows(WOLFSSL_CTX* ctx, byte* loaded)
3058
{
3059
    int ret = 1;
3060
    word32 i;
3061
    HANDLE handle = NULL;
3062
    PCCERT_CONTEXT certCtx = NULL;
3063
    LPCSTR storeNames[2] = {"ROOT", "CA"};
3064
    HCRYPTPROV_LEGACY hProv = (HCRYPTPROV_LEGACY)NULL;
3065
3066
    if ((ctx == NULL) || (loaded == NULL)) {
3067
        ret = 0;
3068
    }
3069
3070
    for (i = 0; (ret == 1) && (i < sizeof(storeNames)/sizeof(*storeNames));
3071
         ++i) {
3072
        handle = CertOpenSystemStoreA(hProv, storeNames[i]);
3073
        if (handle != NULL) {
3074
            while ((certCtx = CertEnumCertificatesInStore(handle, certCtx))
3075
                   != NULL) {
3076
                if (certCtx->dwCertEncodingType == X509_ASN_ENCODING) {
3077
                    if (ProcessBuffer(ctx, certCtx->pbCertEncoded,
3078
                          certCtx->cbCertEncoded, WOLFSSL_FILETYPE_ASN1,
3079
                          CA_TYPE, NULL, NULL, 0,
3080
                          GET_VERIFY_SETTING_CTX(ctx),
3081
                          storeNames[i]) == 1) {
3082
                        /*
3083
                         * Set "loaded" as long as we've loaded one CA
3084
                         * cert.
3085
                         */
3086
                        *loaded = 1;
3087
                    }
3088
                }
3089
            }
3090
        }
3091
        else {
3092
            WOLFSSL_MSG_EX("Failed to open cert store %s.", storeNames[i]);
3093
        }
3094
3095
        if (handle != NULL && !CertCloseStore(handle, 0)) {
3096
            WOLFSSL_MSG_EX("Failed to close cert store %s.", storeNames[i]);
3097
            ret = 0;
3098
        }
3099
    }
3100
3101
    return ret;
3102
}
3103
3104
#elif defined(__APPLE__)
3105
3106
#if defined(HAVE_SECURITY_SECTRUSTSETTINGS_H) \
3107
  && !defined(WOLFSSL_APPLE_NATIVE_CERT_VALIDATION)
3108
/* Manually obtains certificates from the system trust store and loads them
3109
 * directly into wolfSSL "the old way".
3110
 *
3111
 * As of MacOS 14.0 we are still able to use this method to access system
3112
 * certificates. Accessibility of this API is indicated by the presence of the
3113
 * Security/SecTrustSettings.h header. In the likely event that Apple removes
3114
 * access to this API on Macs, this function should be removed and the
3115
 * DoAppleNativeCertValidation() routine should be used for all devices.
3116
 *
3117
 * Assumes loaded is 0.
3118
 *
3119
 * @param [in, out] ctx     SSL context object.
3120
 * @param [out]     loaded  Whether CA certificates were loaded.
3121
 * @return  1 on success.
3122
 * @return  0 on failure.
3123
 */
3124
static int LoadSystemCaCertsMac(WOLFSSL_CTX* ctx, byte* loaded)
3125
{
3126
    int ret = 1;
3127
    word32 i;
3128
    const unsigned int trustDomains[] = {
3129
        kSecTrustSettingsDomainUser,
3130
        kSecTrustSettingsDomainAdmin,
3131
        kSecTrustSettingsDomainSystem
3132
    };
3133
    CFArrayRef certs;
3134
    OSStatus stat;
3135
    CFIndex numCerts;
3136
    CFDataRef der;
3137
    CFIndex j;
3138
3139
    if ((ctx == NULL) || (loaded == NULL)) {
3140
        ret = 0;
3141
    }
3142
3143
    for (i = 0; (ret == 1) && (i < sizeof(trustDomains)/sizeof(*trustDomains));
3144
         ++i) {
3145
        stat = SecTrustSettingsCopyCertificates(
3146
            (SecTrustSettingsDomain)trustDomains[i], &certs);
3147
        if (stat == errSecSuccess) {
3148
            numCerts = CFArrayGetCount(certs);
3149
            for (j = 0; j < numCerts; ++j) {
3150
                der = SecCertificateCopyData((SecCertificateRef)
3151
                          CFArrayGetValueAtIndex(certs, j));
3152
                if (der != NULL) {
3153
                    if (ProcessBuffer(ctx, CFDataGetBytePtr(der),
3154
                          CFDataGetLength(der), WOLFSSL_FILETYPE_ASN1,
3155
                          CA_TYPE, NULL, NULL, 0,
3156
                          GET_VERIFY_SETTING_CTX(ctx),
3157
                          "MacOSX trustDomains") == 1) {
3158
                        /*
3159
                         * Set "loaded" as long as we've loaded one CA
3160
                         * cert.
3161
                         */
3162
                        *loaded = 1;
3163
                    }
3164
3165
                    CFRelease(der);
3166
                }
3167
            }
3168
3169
            CFRelease(certs);
3170
        }
3171
        else if (stat == errSecNoTrustSettings) {
3172
            WOLFSSL_MSG_EX("No trust settings for domain %d, moving to next "
3173
                "domain.", trustDomains[i]);
3174
        }
3175
        else {
3176
            WOLFSSL_MSG_EX("SecTrustSettingsCopyCertificates failed with"
3177
                " status %d.", stat);
3178
            ret = 0;
3179
            break;
3180
        }
3181
    }
3182
3183
    return ret;
3184
}
3185
#endif /* defined(HAVE_SECURITY_SECTRUSTSETTINGS_H) */
3186
3187
#else
3188
3189
/* Potential system CA certs directories on Linux/Unix distros. */
3190
static const char* systemCaDirs[] = {
3191
#if defined(__ANDROID__) || defined(ANDROID)
3192
    "/system/etc/security/cacerts"      /* Android */
3193
#else
3194
    "/etc/ssl/certs",                   /* Debian, Ubuntu, Gentoo, others */
3195
    "/etc/pki/ca-trust/source/anchors", /* Fedora, RHEL */
3196
    "/etc/pki/tls/certs"                /* Older RHEL */
3197
#endif
3198
};
3199
3200
/* Get CA directory list.
3201
 *
3202
 * @param [out] num  Number of CA directories.
3203
 * @return  CA directory list.
3204
 * @return  NULL when num is NULL.
3205
 */
3206
const char** wolfSSL_get_system_CA_dirs(word32* num)
3207
0
{
3208
0
    const char** ret;
3209
3210
    /* Validate parameters. */
3211
0
    if (num == NULL) {
3212
0
        ret = NULL;
3213
0
    }
3214
0
    else {
3215
0
        ret = systemCaDirs;
3216
0
        *num = sizeof(systemCaDirs)/sizeof(*systemCaDirs);
3217
0
    }
3218
3219
0
    return ret;
3220
0
}
3221
3222
/* Load CA certificate from default system directories.
3223
 *
3224
 * Assumes loaded is 0.
3225
 *
3226
 * @param [in, out] ctx     SSL context object.
3227
 * @param [out]     loaded  Whether CA certificates were loaded.
3228
 * @return  1 on success.
3229
 * @return  0 on failure.
3230
 */
3231
0
static int LoadSystemCaCertsNix(WOLFSSL_CTX* ctx, byte* loaded) {
3232
0
    int ret = 1;
3233
0
    word32 i;
3234
3235
0
    if ((ctx == NULL) || (loaded == NULL)) {
3236
0
        ret = 0;
3237
0
    }
3238
3239
0
    for (i = 0; (ret == 1) && (i < sizeof(systemCaDirs)/sizeof(*systemCaDirs));
3240
0
         ++i) {
3241
0
        WOLFSSL_MSG_EX("Attempting to load system CA certs from %s.",
3242
0
            systemCaDirs[i]);
3243
        /*
3244
         * We want to keep trying to load more CA certs even if one cert in
3245
         * the directory is bad and can't be used (e.g. if one is expired),
3246
         * so we use WOLFSSL_LOAD_FLAG_IGNORE_ERR.
3247
         */
3248
0
        if (wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, systemCaDirs[i],
3249
0
                WOLFSSL_LOAD_FLAG_IGNORE_ERR) != 1) {
3250
0
            WOLFSSL_MSG_EX("Failed to load CA certs from %s, trying "
3251
0
                "next possible location.", systemCaDirs[i]);
3252
0
        }
3253
0
        else {
3254
0
            WOLFSSL_MSG_EX("Loaded CA certs from %s.",
3255
0
                systemCaDirs[i]);
3256
0
            *loaded = 1;
3257
            /* Stop searching after we've loaded one directory. */
3258
0
            break;
3259
0
        }
3260
0
    }
3261
3262
0
    return ret;
3263
0
}
3264
3265
#endif
3266
3267
/* Load CA certificates from system defined locations.
3268
 *
3269
 * @param [in, out] ctx  SSL context object.
3270
 * @return  1 on success.
3271
 * @return  0 on failure.
3272
 * @return  WOLFSSL_BAD_PATH when no error but no certificates loaded.
3273
 */
3274
int wolfSSL_CTX_load_system_CA_certs(WOLFSSL_CTX* ctx)
3275
0
{
3276
0
    int ret;
3277
0
    byte loaded = 0;
3278
3279
0
    WOLFSSL_ENTER("wolfSSL_CTX_load_system_CA_certs");
3280
3281
#ifdef USE_WINDOWS_API
3282
3283
    ret = LoadSystemCaCertsWindows(ctx, &loaded);
3284
3285
#elif defined(__APPLE__)
3286
3287
#if defined(HAVE_SECURITY_SECTRUSTSETTINGS_H) \
3288
  && !defined(WOLFSSL_APPLE_NATIVE_CERT_VALIDATION)
3289
    /* As of MacOS 14.0 we are still able to access system certificates and
3290
     * load them manually into wolfSSL "the old way". Accessibility of this API
3291
     * is indicated by the presence of the Security/SecTrustSettings.h header */
3292
    ret = LoadSystemCaCertsMac(ctx, &loaded);
3293
#elif defined(WOLFSSL_APPLE_NATIVE_CERT_VALIDATION)
3294
    /* For other Apple devices, Apple has removed the ability to obtain
3295
     * certificates from the trust store, so we can't use wolfSSL's built-in
3296
     * certificate validation mechanisms anymore. We instead must call into the
3297
     * Security Framework APIs to authenticate peer certificates when received.
3298
     * (see src/internal.c:DoAppleNativeCertValidation()).
3299
     * Thus, there is no CA "loading" required, but to keep behavior consistent
3300
     * with the current API (not using system CA certs unless this function has
3301
     * been called), we simply set a flag indicating that the new apple trust
3302
     * verification routine should be used later */
3303
    ctx->doAppleNativeCertValidationFlag = 1;
3304
    ret = 1;
3305
    loaded = 1;
3306
3307
#if FIPS_VERSION_GE(2,0) /* Gate back to cert 3389 FIPS modules */
3308
#warning "Cryptographic operations may occur outside the FIPS module boundary" \
3309
         "Please review FIPS claims for cryptography on this Apple device"
3310
#endif /* FIPS_VERSION_GE(2,0) */
3311
3312
#else
3313
/* HAVE_SECURITY_SECXXX_H macros are set by autotools or CMake when searching
3314
 * system for the required SDK headers. If building with user_settings.h, you
3315
 * will need to manually define WOLFSSL_APPLE_NATIVE_CERT_VALIDATION
3316
 * and ensure the appropriate Security.framework headers and libraries are
3317
 * visible to your compiler */
3318
#error "WOLFSSL_SYS_CA_CERTS on Apple devices requires Security.framework" \
3319
       " header files to be detected, or a manual override with" \
3320
       " WOLFSSL_APPLE_NATIVE_CERT_VALIDATION"
3321
#endif
3322
3323
#else
3324
3325
0
    ret = LoadSystemCaCertsNix(ctx, &loaded);
3326
3327
0
#endif
3328
3329
    /* If we didn't fail but didn't load then we error out. */
3330
0
    if ((ret == 1) && (!loaded)) {
3331
0
        ret = WOLFSSL_BAD_PATH;
3332
0
    }
3333
3334
0
    WOLFSSL_LEAVE("wolfSSL_CTX_load_system_CA_certs", ret);
3335
3336
0
    return ret;
3337
0
}
3338
3339
#endif /* WOLFSSL_SYS_CA_CERTS */
3340
3341
#ifdef WOLFSSL_TRUST_PEER_CERT
3342
/* Load a trusted peer certificate into SSL context.
3343
 *
3344
 * @param [in, out] ctx     SSL context object.
3345
 * @param [in]      file    Name of peer certificate file.
3346
 * @param [in]      format  Format of data:
3347
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3348
 * @return  1 on success.
3349
 * @return  0 when ctx or file is NULL.
3350
 */
3351
int wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX* ctx, const char* file, int format)
3352
{
3353
    int ret;
3354
3355
    WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_cert");
3356
3357
    /* Validate parameters. */
3358
    if ((ctx == NULL) || (file == NULL)) {
3359
        ret = 0;
3360
    }
3361
    else {
3362
        ret = ProcessFile(ctx, file, format, TRUSTED_PEER_TYPE, NULL, 0, NULL,
3363
            GET_VERIFY_SETTING_CTX(ctx));
3364
    }
3365
3366
    return ret;
3367
}
3368
3369
/* Load a trusted peer certificate into SSL.
3370
 *
3371
 * @param [in, out] ssl     SSL object.
3372
 * @param [in]      file    Name of peer certificate file.
3373
 * @param [in]      format  Format of data:
3374
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3375
 * @return  1 on success.
3376
 * @return  0 when ssl or file is NULL.
3377
 */
3378
int wolfSSL_trust_peer_cert(WOLFSSL* ssl, const char* file, int format)
3379
{
3380
    int ret;
3381
3382
    WOLFSSL_ENTER("wolfSSL_trust_peer_cert");
3383
3384
    /* Validate parameters. */
3385
    if ((ssl == NULL) || (file == NULL)) {
3386
        ret = 0;
3387
    }
3388
    else {
3389
        ret = ProcessFile(NULL, file, format, TRUSTED_PEER_TYPE, ssl, 0, NULL,
3390
            GET_VERIFY_SETTING_SSL(ssl));
3391
    }
3392
3393
    return ret;
3394
}
3395
#endif /* WOLFSSL_TRUST_PEER_CERT */
3396
3397
3398
#ifdef WOLFSSL_DER_LOAD
3399
3400
/* Load a CA certificate into SSL context.
3401
 *
3402
 * @param [in, out] ctx     SSL context object.
3403
 * @param [in]      file    Name of peer certificate file.
3404
 * @param [in]      format  Format of data:
3405
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3406
 * @return  1 on success.
3407
 * @return  0 on failure.
3408
 */
3409
int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
3410
    int format)
3411
{
3412
    int ret;
3413
3414
    WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
3415
3416
    /* Validate parameters. */
3417
    if ((ctx == NULL) || (file == NULL)) {
3418
        ret = 0;
3419
    }
3420
    else {
3421
        ret = ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL,
3422
            GET_VERIFY_SETTING_CTX(ctx));
3423
    }
3424
3425
    /* Return 1 on success or 0 on failure. */
3426
    return WS_RC(ret);
3427
}
3428
3429
#endif /* WOLFSSL_DER_LOAD */
3430
3431
3432
/* Load a user certificate into SSL context.
3433
 *
3434
 * @param [in, out] ctx     SSL context object.
3435
 * @param [in]      file    Name of user certificate file.
3436
 * @param [in]      format  Format of data:
3437
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3438
 * @return  1 on success.
3439
 * @return  0 on failure.
3440
 */
3441
WOLFSSL_ABI
3442
int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
3443
    int format)
3444
0
{
3445
0
    int ret;
3446
3447
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
3448
3449
0
    ret = ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL,
3450
0
        GET_VERIFY_SETTING_CTX(ctx));
3451
3452
    /* Return 1 on success or 0 on failure. */
3453
0
    return WS_RC(ret);
3454
0
}
3455
3456
3457
/* Load a private key into SSL context.
3458
 *
3459
 * @param [in, out] ctx     SSL context object.
3460
 * @param [in]      file    Name of private key file.
3461
 * @param [in]      format  Format of data:
3462
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3463
 * @return  1 on success.
3464
 * @return  0 on failure.
3465
 */
3466
WOLFSSL_ABI
3467
int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
3468
    int format)
3469
0
{
3470
0
    int ret;
3471
3472
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
3473
3474
0
    ret = ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL,
3475
0
        GET_VERIFY_SETTING_CTX(ctx));
3476
3477
    /* Return 1 on success or 0 on failure. */
3478
0
    return WS_RC(ret);
3479
0
}
3480
3481
#ifdef WOLFSSL_DUAL_ALG_CERTS
3482
/* Load an alternative private key into SSL context.
3483
 *
3484
 * @param [in, out] ctx     SSL context object.
3485
 * @param [in]      file    Name of private key file.
3486
 * @param [in]      format  Format of data:
3487
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3488
 * @return  1 on success.
3489
 * @return  0 on failure.
3490
 */
3491
int wolfSSL_CTX_use_AltPrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
3492
    int format)
3493
{
3494
    int ret;
3495
3496
    WOLFSSL_ENTER("wolfSSL_CTX_use_AltPrivateKey_file");
3497
3498
    ret = ProcessFile(ctx, file, format, ALT_PRIVATEKEY_TYPE, NULL, 0, NULL,
3499
        GET_VERIFY_SETTING_CTX(ctx));
3500
3501
    /* Return 1 on success or 0 on failure. */
3502
    return WS_RC(ret);
3503
}
3504
#endif /* WOLFSSL_DUAL_ALG_CERTS */
3505
3506
3507
/* Load a PEM certificate chain into SSL context.
3508
 *
3509
 * @param [in, out] ctx     SSL context object.
3510
 * @param [in]      file    Name of PEM certificate chain file.
3511
 * @return  1 on success.
3512
 * @return  0 on failure.
3513
 */
3514
WOLFSSL_ABI
3515
int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
3516
0
{
3517
0
    int ret;
3518
3519
    /* process up to MAX_CHAIN_DEPTH plus subject cert */
3520
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
3521
3522
0
    ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE, NULL, 1, NULL,
3523
0
        GET_VERIFY_SETTING_CTX(ctx));
3524
3525
    /* Return 1 on success or 0 on failure. */
3526
0
    return WS_RC(ret);
3527
0
}
3528
3529
/* Load certificate chain into SSL context.
3530
 *
3531
 * Processes up to MAX_CHAIN_DEPTH plus subject cert.
3532
 *
3533
 * @param [in, out] ctx     SSL context object.
3534
 * @param [in]      file    Name of private key file.
3535
 * @param [in]      format  Format of data:
3536
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3537
 * @return  1 on success.
3538
 * @return  0 on failure.
3539
 */
3540
int wolfSSL_CTX_use_certificate_chain_file_format(WOLFSSL_CTX* ctx,
3541
     const char* file, int format)
3542
0
{
3543
0
    int ret;
3544
3545
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file_format");
3546
3547
0
    ret = ProcessFile(ctx, file, format, CERT_TYPE, NULL, 1, NULL,
3548
0
        GET_VERIFY_SETTING_CTX(ctx));
3549
3550
    /* Return 1 on success or 0 on failure. */
3551
0
    return WS_RC(ret);
3552
0
}
3553
3554
#endif /* NO_FILESYSTEM */
3555
3556
#ifdef OPENSSL_EXTRA
3557
3558
/* Load a private key into SSL.
3559
 *
3560
 * @param [in, out] ssl   SSL object.
3561
 * @param [in]      pkey  EVP private key.
3562
 * @return  1 on success.
3563
 * @return  0 on failure.
3564
 */
3565
int wolfSSL_use_PrivateKey(WOLFSSL* ssl, WOLFSSL_EVP_PKEY* pkey)
3566
{
3567
    int ret;
3568
3569
    WOLFSSL_ENTER("wolfSSL_use_PrivateKey");
3570
3571
    /* Validate parameters. */
3572
    if ((ssl == NULL) || (pkey == NULL)) {
3573
        ret = 0;
3574
    }
3575
    else {
3576
        /* Get DER encoded key data from EVP private key. */
3577
        ret = wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)pkey->pkey.ptr,
3578
            pkey->pkey_sz, WOLFSSL_FILETYPE_ASN1);
3579
    }
3580
3581
    return ret;
3582
}
3583
3584
/* Load a DER encoded private key in a buffer into SSL.
3585
 *
3586
 * @param [in]      pri    Indicates type of private key. Ignored.
3587
 * @param [in, out] ssl    SSL object.
3588
 * @param [in]      der    Buffer holding DER encoded private key.
3589
 * @param [in]      derSz  Size of data in bytes.
3590
 * @return  1 on success.
3591
 * @return  0 on failure.
3592
 */
3593
int wolfSSL_use_PrivateKey_ASN1(int pri, WOLFSSL* ssl, const unsigned char* der,
3594
    long derSz)
3595
{
3596
    int ret;
3597
3598
    WOLFSSL_ENTER("wolfSSL_use_PrivateKey_ASN1");
3599
3600
    (void)pri;
3601
3602
    /* Validate parameters. */
3603
    if ((ssl == NULL) || (der == NULL)) {
3604
        ret = 0;
3605
    }
3606
    else {
3607
        ret = wolfSSL_use_PrivateKey_buffer(ssl, der, derSz,
3608
            WOLFSSL_FILETYPE_ASN1);
3609
    }
3610
3611
    return ret;
3612
}
3613
3614
/* Load a DER encoded private key in a buffer into SSL context.
3615
 *
3616
 * @param [in]      pri    Indicates type of private key. Ignored.
3617
 * @param [in, out] ctx    SSL context object.
3618
 * @param [in]      der    Buffer holding DER encoded private key.
3619
 * @param [in]      derSz  Size of data in bytes.
3620
 * @return  1 on success.
3621
 * @return  0 on failure.
3622
 */
3623
int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx,
3624
    unsigned char* der, long derSz)
3625
{
3626
    int ret;
3627
3628
    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_ASN1");
3629
3630
    (void)pri;
3631
3632
    /* Validate parameters. */
3633
    if ((ctx == NULL) || (der == NULL)) {
3634
        ret = 0;
3635
    }
3636
    else {
3637
        ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz,
3638
            WOLFSSL_FILETYPE_ASN1);
3639
    }
3640
3641
    return ret;
3642
}
3643
3644
3645
#ifndef NO_RSA
3646
/* Load a DER encoded RSA private key in a buffer into SSL.
3647
 *
3648
 * @param [in, out] ssl    SSL object.
3649
 * @param [in]      der    Buffer holding DER encoded RSA private key.
3650
 * @param [in]      derSz  Size of data in bytes.
3651
 * @return  1 on success.
3652
 * @return  0 on failure.
3653
 */
3654
int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, long derSz)
3655
{
3656
    int ret;
3657
3658
    WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_ASN1");
3659
3660
    /* Validate parameters. */
3661
    if ((ssl == NULL) || (der == NULL)) {
3662
        ret = 0;
3663
    }
3664
    else {
3665
        ret = wolfSSL_use_PrivateKey_buffer(ssl, der, derSz,
3666
            WOLFSSL_FILETYPE_ASN1);
3667
    }
3668
3669
    return ret;
3670
}
3671
#endif
3672
3673
/* Load a certificate into SSL.
3674
 *
3675
 * @param [in, out] ssl   SSL object.
3676
 * @param [in]      x509  X509 certificate object.
3677
 * @return  1 on success.
3678
 * @return  0 on failure.
3679
 */
3680
int wolfSSL_use_certificate(WOLFSSL* ssl, WOLFSSL_X509* x509)
3681
{
3682
    int ret;
3683
3684
    WOLFSSL_ENTER("wolfSSL_use_certificate");
3685
3686
    /* Validate parameters. */
3687
    if ((ssl == NULL) || (x509 == NULL) || (x509->derCert == NULL)) {
3688
        ret = 0;
3689
    }
3690
    else {
3691
        long idx = 0;
3692
3693
        /* Get DER encoded certificate data from X509 object. */
3694
        ret = ProcessBuffer(NULL, x509->derCert->buffer, x509->derCert->length,
3695
            WOLFSSL_FILETYPE_ASN1, CERT_TYPE, ssl, &idx, 0,
3696
            GET_VERIFY_SETTING_SSL(ssl),
3697
            "x509 buffer");
3698
    }
3699
3700
    /* Return 1 on success or 0 on failure. */
3701
    return WS_RC(ret);
3702
}
3703
3704
#endif /* OPENSSL_EXTRA */
3705
3706
/* Load a DER encoded certificate in a buffer into SSL.
3707
 *
3708
 * @param [in, out] ssl    SSL object.
3709
 * @param [in]      der    Buffer holding DER encoded certificate.
3710
 * @param [in]      derSz  Size of data in bytes.
3711
 * @return  1 on success.
3712
 * @return  0 on failure.
3713
 */
3714
int wolfSSL_use_certificate_ASN1(WOLFSSL* ssl, const unsigned char* der,
3715
    int derSz)
3716
0
{
3717
0
    int ret;
3718
3719
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_ASN1");
3720
3721
    /* Validate parameters. */
3722
0
    if ((ssl == NULL) || (der == NULL)) {
3723
0
        ret = 0;
3724
0
    }
3725
0
    else {
3726
0
        long idx = 0;
3727
3728
0
        ret = ProcessBuffer(NULL, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
3729
0
            ssl, &idx, 0, GET_VERIFY_SETTING_SSL(ssl),
3730
0
            "asn1 buffer");
3731
0
    }
3732
3733
    /* Return 1 on success or 0 on failure. */
3734
0
    return WS_RC(ret);
3735
0
}
3736
3737
#ifndef NO_FILESYSTEM
3738
3739
/* Load a certificate from a file into SSL.
3740
 *
3741
 * @param [in, out] ssl     SSL object.
3742
 * @param [in]      file    Name of file.
3743
 * @param [in]      format  Format of data:
3744
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3745
 * @return  1 on success.
3746
 * @return  0 on failure.
3747
 * @return  BAD_FUNC_ARG when ssl is NULL.
3748
 */
3749
WOLFSSL_ABI
3750
int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
3751
0
{
3752
0
    int ret;
3753
3754
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_file");
3755
3756
    /* Validate parameters. */
3757
0
    if (ssl == NULL) {
3758
0
        ret = BAD_FUNC_ARG;
3759
0
    }
3760
0
    else {
3761
0
        ret = ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0, NULL,
3762
0
            GET_VERIFY_SETTING_SSL(ssl));
3763
        /* Return 1 on success or 0 on failure. */
3764
0
        ret = WS_RC(ret);
3765
0
    }
3766
3767
0
    return ret;
3768
0
}
3769
3770
3771
/* Load a private key from a file into SSL.
3772
 *
3773
 * @param [in, out] ssl     SSL object.
3774
 * @param [in]      file    Name of file.
3775
 * @param [in]      format  Format of data:
3776
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3777
 * @return  1 on success.
3778
 * @return  0 on failure.
3779
 * @return  BAD_FUNC_ARG when ssl is NULL.
3780
 */
3781
WOLFSSL_ABI
3782
int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
3783
0
{
3784
0
    int ret;
3785
3786
0
    WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
3787
3788
    /* Validate parameters. */
3789
0
    if (ssl == NULL) {
3790
0
        ret = BAD_FUNC_ARG;
3791
0
    }
3792
0
    else {
3793
0
        ret = ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0, NULL,
3794
0
            GET_VERIFY_SETTING_SSL(ssl));
3795
        /* Return 1 on success or 0 on failure. */
3796
0
        ret = WS_RC(ret);
3797
0
    }
3798
3799
0
    return ret;
3800
0
}
3801
3802
3803
/* Load a PEM encoded certificate chain from a file into SSL.
3804
 *
3805
 * Process up to MAX_CHAIN_DEPTH plus subject cert.
3806
 *
3807
 * @param [in, out] ssl     SSL object.
3808
 * @param [in]      file    Name of file.
3809
 * @return  1 on success.
3810
 * @return  0 on failure.
3811
 * @return  BAD_FUNC_ARG when ssl is NULL.
3812
 */
3813
WOLFSSL_ABI
3814
int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
3815
0
{
3816
0
    int ret;
3817
3818
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
3819
3820
    /* Validate parameters. */
3821
0
    if (ssl == NULL) {
3822
0
        ret = BAD_FUNC_ARG;
3823
0
    }
3824
0
    else {
3825
0
        ret = ProcessFile(ssl->ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE, ssl,
3826
0
            1, NULL, GET_VERIFY_SETTING_SSL(ssl));
3827
        /* Return 1 on success or 0 on failure. */
3828
0
        ret = WS_RC(ret);
3829
0
    }
3830
3831
0
   return ret;
3832
0
}
3833
3834
/* Load a certificate chain from a file into SSL.
3835
 *
3836
 * @param [in, out] ssl     SSL object.
3837
 * @param [in]      file    Name of file.
3838
 * @param [in]      format  Format of data:
3839
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3840
 * @return  1 on success.
3841
 * @return  0 on failure.
3842
 * @return  BAD_FUNC_ARG when ssl is NULL.
3843
 */
3844
int wolfSSL_use_certificate_chain_file_format(WOLFSSL* ssl, const char* file,
3845
    int format)
3846
0
{
3847
0
    int ret;
3848
3849
    /* process up to MAX_CHAIN_DEPTH plus subject cert */
3850
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file_format");
3851
3852
    /* Validate parameters. */
3853
0
    if (ssl == NULL) {
3854
0
        ret = BAD_FUNC_ARG;
3855
0
    }
3856
0
    else {
3857
0
        ret = ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 1, NULL,
3858
0
            GET_VERIFY_SETTING_SSL(ssl));
3859
        /* Return 1 on success or 0 on failure. */
3860
0
        ret = WS_RC(ret);
3861
0
    }
3862
3863
0
    return ret;
3864
0
}
3865
3866
#endif /* !NO_FILESYSTEM */
3867
3868
#ifdef OPENSSL_EXTRA
3869
3870
#ifndef NO_FILESYSTEM
3871
/* Load an RSA private key from a file into SSL context.
3872
 *
3873
 * @param [in, out] ctx     SSL context object.
3874
 * @param [in]      file    Name of file.
3875
 * @param [in]      format  Format of data:
3876
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3877
 * @return  1 on success.
3878
 * @return  0 on failure.
3879
 */
3880
int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
3881
    int format)
3882
{
3883
    WOLFSSL_ENTER("wolfSSL_CTX_use_RSAPrivateKey_file");
3884
3885
    return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
3886
}
3887
3888
/* Load an RSA private key from a file into SSL.
3889
 *
3890
 * @param [in, out] ssl     SSL object.
3891
 * @param [in]      file    Name of file.
3892
 * @param [in]      format  Format of data:
3893
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3894
 * @return  1 on success.
3895
 * @return  0 on failure.
3896
 * @return  BAD_FUNC_ARG when ssl is NULL.
3897
 */
3898
int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
3899
{
3900
    WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
3901
3902
    return wolfSSL_use_PrivateKey_file(ssl, file, format);
3903
}
3904
#endif /* NO_FILESYSTEM */
3905
3906
#endif /* OPENSSL_EXTRA */
3907
3908
/* Load a buffer of certificate/s into SSL context.
3909
 *
3910
 * @param [in, out] ctx        SSL context object.
3911
 * @param [in]      in         Buffer holding certificate or private key.
3912
 * @param [in]      sz         Length of data in buffer in bytes.
3913
 * @param [in]      format     Format of data:
3914
 *                               WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3915
 * @param [in]      userChain  Whether file contains chain of certificates.
3916
 * @param [in]      flags      Flags representing options for loading.
3917
 * @return  1 on success.
3918
 * @return  0 on failure.
3919
 * @return  Negative on error.
3920
 */
3921
int wolfSSL_CTX_load_verify_buffer_ex(WOLFSSL_CTX* ctx, const unsigned char* in,
3922
    long sz, int format, int userChain, word32 flags)
3923
0
{
3924
0
    int ret;
3925
0
    int verify;
3926
3927
0
    WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer_ex");
3928
3929
    /* Get setting on how to verify certificates. */
3930
0
    verify = GET_VERIFY_SETTING_CTX(ctx);
3931
    /* Overwrite setting when flag set. */
3932
0
    if (flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY) {
3933
0
        verify = VERIFY_SKIP_DATE;
3934
0
    }
3935
3936
    /* When PEM, treat as certificate chain of CA certificates. */
3937
0
    if (format == WOLFSSL_FILETYPE_PEM) {
3938
0
        ret = ProcessChainBuffer(ctx, NULL, in, sz, CA_TYPE, verify,
3939
0
                                 "PEM buffer");
3940
0
    }
3941
    /* When DER, load the CA certificate. */
3942
0
    else {
3943
0
        ret = ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL, NULL,
3944
0
            userChain, verify, "buffer");
3945
0
    }
3946
#if defined(WOLFSSL_TRUST_PEER_CERT) && defined(OPENSSL_COMPATIBLE_DEFAULTS)
3947
    if (ret == 1) {
3948
        /* Load certificate/s as trusted peer certificate. */
3949
        ret = wolfSSL_CTX_trust_peer_buffer(ctx, in, sz, format);
3950
    }
3951
#endif
3952
3953
0
    WOLFSSL_LEAVE("wolfSSL_CTX_load_verify_buffer_ex", ret);
3954
0
    return ret;
3955
0
}
3956
3957
/* Load a buffer of certificate/s into SSL context.
3958
 *
3959
 * @param [in, out] ctx     SSL context object.
3960
 * @param [in]      in      Buffer holding certificate or private key.
3961
 * @param [in]      sz      Length of data in buffer in bytes.
3962
 * @param [in]      format  Format of data:
3963
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3964
 * @return  1 on success.
3965
 * @return  0 on failure.
3966
 * @return  Negative on error.
3967
 */
3968
int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx, const unsigned char* in,
3969
    long sz, int format)
3970
0
{
3971
0
    return wolfSSL_CTX_load_verify_buffer_ex(ctx, in, sz, format, 0,
3972
0
        WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
3973
0
}
3974
3975
/* Load a buffer of certificate chain into SSL context.
3976
 *
3977
 * @param [in, out] ctx     SSL context object.
3978
 * @param [in]      in      Buffer holding certificate chain.
3979
 * @param [in]      sz      Length of data in buffer in bytes.
3980
 * @param [in]      format  Format of data:
3981
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
3982
 * @return  1 on success.
3983
 * @return  0 on failure.
3984
 * @return  Negative on error.
3985
 */
3986
int wolfSSL_CTX_load_verify_chain_buffer_format(WOLFSSL_CTX* ctx,
3987
    const unsigned char* in, long sz, int format)
3988
0
{
3989
0
    return wolfSSL_CTX_load_verify_buffer_ex(ctx, in, sz, format, 1,
3990
0
        WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
3991
0
}
3992
3993
3994
#ifdef WOLFSSL_TRUST_PEER_CERT
3995
/* Load a buffer of certificate/s into SSL context.
3996
 *
3997
 * @param [in, out] ctx     SSL context object.
3998
 * @param [in]      in      Buffer holding certificate/s.
3999
 * @param [in]      sz      Length of data in buffer in bytes.
4000
 * @param [in]      format  Format of data:
4001
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
4002
 * @return  1 on success.
4003
 * @return  0 on failure.
4004
 * @return  BAD_FUNC_ARG when ctx or in is NULL, or sz is less than zero.
4005
 */
4006
int wolfSSL_CTX_trust_peer_buffer(WOLFSSL_CTX* ctx, const unsigned char* in,
4007
    long sz, int format)
4008
{
4009
    int ret;
4010
    int verify;
4011
4012
    WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_buffer");
4013
4014
    /* Validate parameters. */
4015
    if ((ctx == NULL) || (in == NULL) || (sz < 0)) {
4016
        ret = BAD_FUNC_ARG;
4017
    }
4018
    else {
4019
    #if WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY
4020
        verify = VERIFY_SKIP_DATE;
4021
    #else
4022
        verify = GET_VERIFY_SETTING_CTX(ctx);
4023
    #endif
4024
4025
        /* When PEM, treat as certificate chain of trusted peer certificates. */
4026
        if (format == WOLFSSL_FILETYPE_PEM) {
4027
            ret = ProcessChainBuffer(ctx, NULL, in, sz, TRUSTED_PEER_TYPE,
4028
                verify, "peer");
4029
        }
4030
        /* When DER, load the trusted peer certificate. */
4031
        else {
4032
            ret = ProcessBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE, NULL,
4033
                NULL, 0, verify, "peer");
4034
        }
4035
    }
4036
4037
    return ret;
4038
}
4039
#endif /* WOLFSSL_TRUST_PEER_CERT */
4040
4041
/* Load a certificate in a buffer into SSL context.
4042
 *
4043
 * @param [in, out] ctx     SSL context object.
4044
 * @param [in]      in      Buffer holding certificate.
4045
 * @param [in]      sz      Size of data in bytes.
4046
 * @param [in]      format  Format of data:
4047
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
4048
 * @return  1 on success.
4049
 * @return  0 on failure.
4050
 * @return  Negative on error.
4051
 */
4052
int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
4053
    const unsigned char* in, long sz, int format)
4054
0
{
4055
0
    int ret;
4056
4057
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
4058
0
    ret = ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0,
4059
0
        GET_VERIFY_SETTING_CTX(ctx), "buffer");
4060
0
    WOLFSSL_LEAVE("wolfSSL_CTX_use_certificate_buffer", ret);
4061
4062
0
    return ret;
4063
0
}
4064
4065
/* Load a private key in a buffer into SSL context.
4066
 *
4067
 * @param [in, out] ctx     SSL context object.
4068
 * @param [in]      in      Buffer holding private key.
4069
 * @param [in]      sz      Size of data in bytes.
4070
 * @param [in]      format  Format of data:
4071
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
4072
 * @return  1 on success.
4073
 * @return  0 on failure.
4074
 * @return  Negative on error.
4075
 */
4076
int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx, const unsigned char* in,
4077
    long sz, int format)
4078
0
{
4079
0
    int ret;
4080
0
    long consumed = 0;
4081
4082
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
4083
4084
0
    ret = ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL, &consumed,
4085
0
        0, GET_VERIFY_SETTING_CTX(ctx), "key buffer");
4086
#ifdef WOLFSSL_DUAL_ALG_CERTS
4087
    if ((ret == 1) && (consumed < sz)) {
4088
        /* When support for dual algorithm certificates is enabled, the
4089
         * buffer may contain both the primary and the alternative
4090
         * private key. Hence, we have to parse both of them.
4091
         */
4092
        ret = ProcessBuffer(ctx, in + consumed, sz - consumed, format,
4093
            ALT_PRIVATEKEY_TYPE, NULL, NULL, 0, GET_VERIFY_SETTING_CTX(ctx),
4094
            "key buffer");
4095
    }
4096
#endif
4097
4098
0
    (void)consumed;
4099
4100
0
    WOLFSSL_LEAVE("wolfSSL_CTX_use_PrivateKey_buffer", ret);
4101
0
    return ret;
4102
0
}
4103
4104
#ifdef WOLFSSL_DUAL_ALG_CERTS
4105
int wolfSSL_CTX_use_AltPrivateKey_buffer(WOLFSSL_CTX* ctx,
4106
    const unsigned char* in, long sz, int format)
4107
{
4108
    int ret;
4109
4110
    WOLFSSL_ENTER("wolfSSL_CTX_use_AltPrivateKey_buffer");
4111
    ret = ProcessBuffer(ctx, in, sz, format, ALT_PRIVATEKEY_TYPE, NULL,
4112
        NULL, 0, GET_VERIFY_SETTING_CTX(ctx), "alt key buffer");
4113
    WOLFSSL_LEAVE("wolfSSL_CTX_use_AltPrivateKey_buffer", ret);
4114
4115
    return ret;
4116
}
4117
#endif /* WOLFSSL_DUAL_ALG_CERTS */
4118
4119
#ifdef WOLF_PRIVATE_KEY_ID
4120
/* Load the id of a private key into SSL context.
4121
 *
4122
 * @param [in, out] ctx    SSL context object.
4123
 * @param [in]      id     Buffer holding id.
4124
 * @param [in]      sz     Size of data in bytes.
4125
 * @param [in]      devId  Device identifier.
4126
 * @return  1 on success.
4127
 * @return  0 on failure.
4128
 */
4129
int wolfSSL_CTX_use_PrivateKey_Id(WOLFSSL_CTX* ctx, const unsigned char* id,
4130
    long sz, int devId)
4131
{
4132
    int ret = 1;
4133
4134
    /* Dispose of old private key and allocate and copy in id. */
4135
    FreeDer(&ctx->privateKey);
4136
    if (AllocCopyDer(&ctx->privateKey, id, (word32)sz, PRIVATEKEY_TYPE,
4137
            ctx->heap) != 0) {
4138
        ret = 0;
4139
    }
4140
    if (ret == 1) {
4141
        /* Private key is an id. */
4142
        ctx->privateKeyId = 1;
4143
        ctx->privateKeyLabel = 0;
4144
        /* Set private key device id to be one passed in or for SSL context. */
4145
        if (devId != INVALID_DEVID) {
4146
            ctx->privateKeyDevId = devId;
4147
        }
4148
        else {
4149
            ctx->privateKeyDevId = ctx->devId;
4150
        }
4151
4152
    #ifdef WOLFSSL_DUAL_ALG_CERTS
4153
        /* Set the ID for the alternative key, too. User can still override that
4154
         * afterwards. */
4155
        ret = wolfSSL_CTX_use_AltPrivateKey_Id(ctx, id, sz, devId);
4156
    #endif
4157
    }
4158
4159
    return ret;
4160
}
4161
4162
/* Load the id of a private key into SSL context and set key size.
4163
 *
4164
 * @param [in, out] ctx    SSL context object.
4165
 * @param [in]      id     Buffer holding id.
4166
 * @param [in]      sz     Size of data in bytes.
4167
 * @param [in]      devId  Device identifier.
4168
 * @param [in]      keySz  Size of key.
4169
 * @return  1 on success.
4170
 * @return  0 on failure.
4171
 */
4172
int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX* ctx, const unsigned char* id,
4173
    long sz, int devId, long keySz)
4174
{
4175
    int ret = wolfSSL_CTX_use_PrivateKey_Id(ctx, id, sz, devId);
4176
    if (ret == 1) {
4177
        /* Set the key size which normally is calculated during decoding. */
4178
        ctx->privateKeySz = (int)keySz;
4179
    }
4180
4181
    return ret;
4182
}
4183
4184
/* Load the label name of a private key into SSL context.
4185
 *
4186
 * @param [in, out] ctx    SSL context object.
4187
 * @param [in]      label  Buffer holding label.
4188
 * @param [in]      devId  Device identifier.
4189
 * @return  1 on success.
4190
 * @return  0 on failure.
4191
 */
4192
int wolfSSL_CTX_use_PrivateKey_Label(WOLFSSL_CTX* ctx, const char* label,
4193
    int devId)
4194
{
4195
    int ret = 1;
4196
    word32 sz = (word32)XSTRLEN(label) + 1;
4197
4198
    /* Dispose of old private key and allocate and copy in label. */
4199
    FreeDer(&ctx->privateKey);
4200
    if (AllocCopyDer(&ctx->privateKey, (const byte*)label, (word32)sz,
4201
            PRIVATEKEY_TYPE, ctx->heap) != 0) {
4202
        ret = 0;
4203
    }
4204
    if (ret == 1) {
4205
        /* Private key is a label. */
4206
        ctx->privateKeyId = 0;
4207
        ctx->privateKeyLabel = 1;
4208
        /* Set private key device id to be one passed in or for SSL context. */
4209
        if (devId != INVALID_DEVID) {
4210
            ctx->privateKeyDevId = devId;
4211
        }
4212
        else {
4213
            ctx->privateKeyDevId = ctx->devId;
4214
        }
4215
4216
    #ifdef WOLFSSL_DUAL_ALG_CERTS
4217
        /* Set the ID for the alternative key, too. User can still override that
4218
         * afterwards. */
4219
        ret = wolfSSL_CTX_use_AltPrivateKey_Label(ctx, label, devId);
4220
    #endif
4221
    }
4222
4223
    return ret;
4224
}
4225
4226
#ifdef WOLFSSL_DUAL_ALG_CERTS
4227
int wolfSSL_CTX_use_AltPrivateKey_Id(WOLFSSL_CTX* ctx, const unsigned char* id,
4228
    long sz, int devId)
4229
{
4230
    int ret = 1;
4231
4232
    if ((ctx == NULL) || (id == NULL)) {
4233
        ret = 0;
4234
    }
4235
4236
    if (ret == 1) {
4237
        FreeDer(&ctx->altPrivateKey);
4238
        if (AllocDer(&ctx->altPrivateKey, (word32)sz, ALT_PRIVATEKEY_TYPE,
4239
                ctx->heap) != 0) {
4240
            ret = 0;
4241
        }
4242
    }
4243
    if (ret == 1) {
4244
        XMEMCPY(ctx->altPrivateKey->buffer, id, sz);
4245
        ctx->altPrivateKeyId = 1;
4246
        if (devId != INVALID_DEVID) {
4247
            ctx->altPrivateKeyDevId = devId;
4248
        }
4249
        else {
4250
            ctx->altPrivateKeyDevId = ctx->devId;
4251
        }
4252
    }
4253
4254
    return ret;
4255
}
4256
4257
int wolfSSL_CTX_use_AltPrivateKey_id(WOLFSSL_CTX* ctx, const unsigned char* id,
4258
    long sz, int devId, long keySz)
4259
{
4260
    int ret = wolfSSL_CTX_use_AltPrivateKey_Id(ctx, id, sz, devId);
4261
    if (ret == 1) {
4262
        ctx->altPrivateKeySz = (word32)keySz;
4263
    }
4264
4265
    return ret;
4266
}
4267
4268
int wolfSSL_CTX_use_AltPrivateKey_Label(WOLFSSL_CTX* ctx, const char* label,
4269
    int devId)
4270
{
4271
    int ret = 1;
4272
    word32 sz;
4273
4274
    if ((ctx == NULL) || (label == NULL)) {
4275
        ret = 0;
4276
    }
4277
4278
    if (ret == 1) {
4279
        sz = (word32)XSTRLEN(label) + 1;
4280
        FreeDer(&ctx->altPrivateKey);
4281
        if (AllocDer(&ctx->altPrivateKey, (word32)sz, ALT_PRIVATEKEY_TYPE,
4282
                ctx->heap) != 0) {
4283
            ret = 0;
4284
        }
4285
    }
4286
    if (ret == 1) {
4287
        XMEMCPY(ctx->altPrivateKey->buffer, label, sz);
4288
        ctx->altPrivateKeyLabel = 1;
4289
        if (devId != INVALID_DEVID) {
4290
            ctx->altPrivateKeyDevId = devId;
4291
        }
4292
        else {
4293
            ctx->altPrivateKeyDevId = ctx->devId;
4294
        }
4295
    }
4296
4297
    return ret;
4298
}
4299
#endif /* WOLFSSL_DUAL_ALG_CERTS */
4300
#endif /* WOLF_PRIVATE_KEY_ID */
4301
4302
#if defined(WOLF_CRYPTO_CB) && !defined(NO_CERTS)
4303
4304
static int wolfSSL_CTX_use_certificate_ex(WOLFSSL_CTX* ctx,
4305
    const char *label, const unsigned char *id, int idLen, int devId)
4306
{
4307
    int ret;
4308
    byte *certData = NULL;
4309
    word32 certDataLen = 0;
4310
    word32 labelLen = 0;
4311
    int certFormat = 0;
4312
4313
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_ex");
4314
4315
    if (label != NULL) {
4316
        labelLen = (word32)XSTRLEN(label);
4317
    }
4318
4319
    ret = wc_CryptoCb_GetCert(devId, label, labelLen, id, idLen,
4320
        &certData, &certDataLen, &certFormat, ctx->heap);
4321
    if (ret != 0) {
4322
        ret = WOLFSSL_FAILURE;
4323
        goto exit;
4324
    }
4325
4326
    ret = ProcessBuffer(ctx, certData, certDataLen, certFormat,
4327
        CERT_TYPE, NULL, NULL, 0, GET_VERIFY_SETTING_CTX(ctx),
4328
        label ? label : "cert buffer");
4329
4330
exit:
4331
    XFREE(certData, ctx->heap, DYNAMIC_TYPE_CERT);
4332
    return ret;
4333
}
4334
4335
/* Load the label name of a certificate into the SSL context.
4336
 *
4337
 * @param [in, out] ctx    SSL context object.
4338
 * @param [in]      label  Buffer holding label.
4339
 * @param [in]      devId  Device identifier.
4340
 * @return  1 on success.
4341
 * @return  0 on failure.
4342
 */
4343
int wolfSSL_CTX_use_certificate_label(WOLFSSL_CTX* ctx,
4344
    const char *label, int devId)
4345
{
4346
    if ((ctx == NULL) || (label == NULL)) {
4347
        return WOLFSSL_FAILURE;
4348
    }
4349
4350
    return wolfSSL_CTX_use_certificate_ex(ctx, label, NULL, 0, devId);
4351
}
4352
4353
/* Load the id of a certificate into SSL context.
4354
 *
4355
 * @param [in, out] ctx    SSL context object.
4356
 * @param [in]      id     Buffer holding id.
4357
 * @param [in]      idLen  Size of data in bytes.
4358
 * @param [in]      devId  Device identifier.
4359
 * @return  1 on success.
4360
 * @return  0 on failure.
4361
 */
4362
int wolfSSL_CTX_use_certificate_id(WOLFSSL_CTX* ctx,
4363
    const unsigned char *id, int idLen, int devId)
4364
{
4365
    if ((ctx == NULL) || (id == NULL) || (idLen <= 0)) {
4366
        return WOLFSSL_FAILURE;
4367
    }
4368
4369
    return wolfSSL_CTX_use_certificate_ex(ctx, NULL, id, idLen, devId);
4370
}
4371
4372
#endif /* if defined(WOLF_CRYPTO_CB) && !defined(NO_CERTS) */
4373
4374
/* Load a certificate chain in a buffer into SSL context.
4375
 *
4376
 * @param [in, out] ctx     SSL context object.
4377
 * @param [in]      in      Buffer holding DER encoded certificate chain.
4378
 * @param [in]      sz      Size of data in bytes.
4379
 * @param [in]      format  Format of data:
4380
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
4381
 * @return  1 on success.
4382
 * @return  0 on failure.
4383
 * @return  Negative on error.
4384
 */
4385
int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX* ctx,
4386
    const unsigned char* in, long sz, int format)
4387
0
{
4388
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer_format");
4389
0
    return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 1,
4390
0
        GET_VERIFY_SETTING_CTX(ctx), "cert chain buffer");
4391
0
}
4392
4393
/* Load a PEM encoded certificate chain in a buffer into SSL context.
4394
 *
4395
 * @param [in, out] ctx     SSL context object.
4396
 * @param [in]      in      Buffer holding DER encoded certificate chain.
4397
 * @param [in]      sz      Size of data in bytes.
4398
 * @return  1 on success.
4399
 * @return  0 on failure.
4400
 * @return  Negative on error.
4401
 */
4402
int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
4403
    const unsigned char* in, long sz)
4404
0
{
4405
0
    return wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, in, sz,
4406
0
        WOLFSSL_FILETYPE_PEM);
4407
0
}
4408
4409
/* Load a user certificate in a buffer into SSL.
4410
 *
4411
 * @param [in, out] ssl     SSL object.
4412
 * @param [in]      in      Buffer holding user certificate.
4413
 * @param [in]      sz      Size of data in bytes.
4414
 * @param [in]      format  Format of data:
4415
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
4416
 * @return  1 on success.
4417
 * @return  0 on failure.
4418
 * @return  BAD_FUNC_ARG when ssl is NULL.
4419
 */
4420
int wolfSSL_use_certificate_buffer(WOLFSSL* ssl, const unsigned char* in,
4421
    long sz, int format)
4422
0
{
4423
0
    int ret;
4424
4425
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
4426
4427
    /* Validate parameters. */
4428
0
    if (ssl == NULL) {
4429
0
        ret = BAD_FUNC_ARG;
4430
0
    }
4431
0
    else {
4432
0
        ret = ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE, ssl, NULL, 0,
4433
0
            GET_VERIFY_SETTING_SSL(ssl), "cert buffer");
4434
0
    }
4435
4436
0
    return ret;
4437
0
}
4438
4439
/* Load a private key in a buffer into SSL.
4440
 *
4441
 * @param [in, out] ssl     SSL object.
4442
 * @param [in]      in      Buffer holding private key.
4443
 * @param [in]      sz      Size of data in bytes.
4444
 * @param [in]      format  Format of data:
4445
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
4446
 * @return  1 on success.
4447
 * @return  0 on failure.
4448
 * @return  BAD_FUNC_ARG when ssl is NULL.
4449
 */
4450
int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl, const unsigned char* in,
4451
    long sz, int format)
4452
0
{
4453
0
    int ret;
4454
0
    long consumed = 0;
4455
4456
0
    WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
4457
4458
    /* Validate parameters. */
4459
0
    if (ssl == NULL) {
4460
0
        ret = BAD_FUNC_ARG;
4461
0
    }
4462
0
    else {
4463
0
        ret = ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE, ssl,
4464
0
            &consumed, 0, GET_VERIFY_SETTING_SSL(ssl), "key buffer");
4465
    #ifdef WOLFSSL_DUAL_ALG_CERTS
4466
        if ((ret == 1) && (consumed < sz)) {
4467
            /* When support for dual algorithm certificates is enabled, the
4468
             * buffer may contain both the primary and the alternative
4469
             * private key. Hence, we have to parse both of them.
4470
             */
4471
            ret = ProcessBuffer(ssl->ctx, in + consumed, sz - consumed, format,
4472
                ALT_PRIVATEKEY_TYPE, ssl, NULL, 0, GET_VERIFY_SETTING_SSL(ssl),
4473
                "key buffer");
4474
        }
4475
    #endif
4476
0
    }
4477
4478
0
    return ret;
4479
0
}
4480
4481
#ifdef WOLFSSL_DUAL_ALG_CERTS
4482
int wolfSSL_use_AltPrivateKey_buffer(WOLFSSL* ssl, const unsigned char* in,
4483
    long sz, int format)
4484
{
4485
    int ret;
4486
4487
    WOLFSSL_ENTER("wolfSSL_use_AltPrivateKey_buffer");
4488
    ret = ProcessBuffer(ssl->ctx, in, sz, format, ALT_PRIVATEKEY_TYPE, ssl,
4489
        NULL, 0, GET_VERIFY_SETTING_SSL(ssl), "alt key buffer");
4490
    WOLFSSL_LEAVE("wolfSSL_use_AltPrivateKey_buffer", ret);
4491
4492
    return ret;
4493
}
4494
#endif /* WOLFSSL_DUAL_ALG_CERTS */
4495
4496
#ifdef WOLF_PRIVATE_KEY_ID
4497
/* Load the id of a private key into SSL.
4498
 *
4499
 * @param [in, out] ssl    SSL object.
4500
 * @param [in]      id     Buffer holding id.
4501
 * @param [in]      sz     Size of data in bytes.
4502
 * @param [in]      devId  Device identifier.
4503
 * @return  1 on success.
4504
 * @return  0 on failure.
4505
 */
4506
int wolfSSL_use_PrivateKey_Id(WOLFSSL* ssl, const unsigned char* id,
4507
                              long sz, int devId)
4508
{
4509
    int ret = 1;
4510
4511
    /* Dispose of old private key if owned and allocate and copy in id. */
4512
    if (ssl->buffers.weOwnKey) {
4513
        FreeDer(&ssl->buffers.key);
4514
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
4515
        FreeDer(&ssl->buffers.keyMask);
4516
    #endif
4517
    }
4518
    if (AllocCopyDer(&ssl->buffers.key, id, (word32)sz, PRIVATEKEY_TYPE,
4519
            ssl->heap) != 0) {
4520
        ret = 0;
4521
    }
4522
    if (ret == 1) {
4523
        /* Buffer now ours. */
4524
        ssl->buffers.weOwnKey = 1;
4525
        /* Private key is an id. */
4526
        ssl->buffers.keyId = 1;
4527
        ssl->buffers.keyLabel = 0;
4528
        /* Set private key device id to be one passed in or for SSL. */
4529
        if (devId != INVALID_DEVID) {
4530
            ssl->buffers.keyDevId = devId;
4531
        }
4532
        else {
4533
            ssl->buffers.keyDevId = ssl->devId;
4534
        }
4535
4536
    #ifdef WOLFSSL_DUAL_ALG_CERTS
4537
        /* Set the ID for the alternative key, too. User can still override that
4538
         * afterwards. */
4539
        ret = wolfSSL_use_AltPrivateKey_Id(ssl, id, sz, devId);
4540
    #endif
4541
    }
4542
4543
    return ret;
4544
}
4545
4546
/* Load the id of a private key into SSL and set key size.
4547
 *
4548
 * @param [in, out] ssl    SSL object.
4549
 * @param [in]      id     Buffer holding id.
4550
 * @param [in]      sz     Size of data in bytes.
4551
 * @param [in]      devId  Device identifier.
4552
 * @param [in]      keySz  Size of key.
4553
 * @return  1 on success.
4554
 * @return  0 on failure.
4555
 */
4556
int wolfSSL_use_PrivateKey_id(WOLFSSL* ssl, const unsigned char* id,
4557
    long sz, int devId, long keySz)
4558
{
4559
    int ret = wolfSSL_use_PrivateKey_Id(ssl, id, sz, devId);
4560
    if (ret == 1) {
4561
        /* Set the key size which normally is calculated during decoding. */
4562
        ssl->buffers.keySz = (int)keySz;
4563
    }
4564
4565
    return ret;
4566
}
4567
4568
/* Load the label name of a private key into SSL.
4569
 *
4570
 * @param [in, out] ssl    SSL object.
4571
 * @param [in]      label  Buffer holding label.
4572
 * @param [in]      devId  Device identifier.
4573
 * @return  1 on success.
4574
 * @return  0 on failure.
4575
 */
4576
int wolfSSL_use_PrivateKey_Label(WOLFSSL* ssl, const char* label, int devId)
4577
{
4578
    int ret = 1;
4579
    word32 sz = (word32)XSTRLEN(label) + 1;
4580
4581
    /* Dispose of old private key if owned and allocate and copy in label. */
4582
    if (ssl->buffers.weOwnKey) {
4583
        FreeDer(&ssl->buffers.key);
4584
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
4585
        FreeDer(&ssl->buffers.keyMask);
4586
    #endif
4587
    }
4588
    if (AllocCopyDer(&ssl->buffers.key, (const byte*)label, (word32)sz,
4589
            PRIVATEKEY_TYPE, ssl->heap) != 0) {
4590
        ret = 0;
4591
    }
4592
    if (ret == 1) {
4593
        /* Buffer now ours. */
4594
        ssl->buffers.weOwnKey = 1;
4595
        /* Private key is a label. */
4596
        ssl->buffers.keyId = 0;
4597
        ssl->buffers.keyLabel = 1;
4598
        /* Set private key device id to be one passed in or for SSL. */
4599
        if (devId != INVALID_DEVID) {
4600
            ssl->buffers.keyDevId = devId;
4601
        }
4602
        else {
4603
            ssl->buffers.keyDevId = ssl->devId;
4604
        }
4605
4606
    #ifdef WOLFSSL_DUAL_ALG_CERTS
4607
        /* Set the label for the alternative key, too. User can still override
4608
         * that afterwards. */
4609
        ret = wolfSSL_use_AltPrivateKey_Label(ssl, label, devId);
4610
    #endif
4611
    }
4612
4613
    return ret;
4614
}
4615
4616
#ifdef WOLFSSL_DUAL_ALG_CERTS
4617
int wolfSSL_use_AltPrivateKey_Id(WOLFSSL* ssl, const unsigned char* id, long sz,
4618
    int devId)
4619
{
4620
    int ret = 1;
4621
4622
    if ((ssl == NULL) || (id == NULL)) {
4623
        ret = 0;
4624
    }
4625
4626
    if (ret == 1) {
4627
        if (ssl->buffers.weOwnAltKey) {
4628
            FreeDer(&ssl->buffers.altKey);
4629
        #ifdef WOLFSSL_BLIND_PRIVATE_KEY
4630
            FreeDer(&ssl->buffers.altKeyMask);
4631
        #endif
4632
        }
4633
        if (AllocDer(&ssl->buffers.altKey, (word32)sz, ALT_PRIVATEKEY_TYPE,
4634
                ssl->heap) == 0) {
4635
            ret = 0;
4636
        }
4637
    }
4638
    if (ret == 1) {
4639
        XMEMCPY(ssl->buffers.altKey->buffer, id, sz);
4640
        ssl->buffers.weOwnAltKey = 1;
4641
        ssl->buffers.altKeyId = 1;
4642
        if (devId != INVALID_DEVID) {
4643
            ssl->buffers.altKeyDevId = devId;
4644
        }
4645
        else {
4646
            ssl->buffers.altKeyDevId = ssl->devId;
4647
        }
4648
    }
4649
4650
    return ret;
4651
}
4652
4653
int wolfSSL_use_AltPrivateKey_id(WOLFSSL* ssl, const unsigned char* id, long sz,
4654
    int devId, long keySz)
4655
{
4656
    int ret = wolfSSL_use_AltPrivateKey_Id(ssl, id, sz, devId);
4657
    if (ret == 1) {
4658
        ssl->buffers.altKeySz = (word32)keySz;
4659
    }
4660
4661
    return ret;
4662
}
4663
4664
int wolfSSL_use_AltPrivateKey_Label(WOLFSSL* ssl, const char* label, int devId)
4665
{
4666
    int ret = 1;
4667
    word32 sz;
4668
4669
    if ((ssl == NULL) || (label == NULL)) {
4670
        ret = 0;
4671
    }
4672
4673
    if (ret == 1) {
4674
        sz = (word32)XSTRLEN(label) + 1;
4675
        if (ssl->buffers.weOwnAltKey) {
4676
            FreeDer(&ssl->buffers.altKey);
4677
        #ifdef WOLFSSL_BLIND_PRIVATE_KEY
4678
            FreeDer(&ssl->buffers.altKeyMask);
4679
        #endif
4680
        }
4681
        if (AllocDer(&ssl->buffers.altKey, (word32)sz, ALT_PRIVATEKEY_TYPE,
4682
                ssl->heap) == 0) {
4683
            ret = 0;
4684
        }
4685
    }
4686
    if (ret == 1) {
4687
        XMEMCPY(ssl->buffers.altKey->buffer, label, sz);
4688
        ssl->buffers.weOwnAltKey = 1;
4689
        ssl->buffers.altKeyLabel = 1;
4690
        if (devId != INVALID_DEVID) {
4691
            ssl->buffers.altKeyDevId = devId;
4692
        }
4693
        else {
4694
            ssl->buffers.altKeyDevId = ssl->devId;
4695
        }
4696
    }
4697
4698
    return ret;
4699
}
4700
#endif /* WOLFSSL_DUAL_ALG_CERTS */
4701
#endif /* WOLF_PRIVATE_KEY_ID */
4702
4703
/* Load a certificate chain in a buffer into SSL.
4704
 *
4705
 * @param [in, out] ssl     SSL object.
4706
 * @param [in]      in      Buffer holding DER encoded certificate chain.
4707
 * @param [in]      sz      Size of data in bytes.
4708
 * @param [in]      format  Format of data:
4709
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
4710
 * @return  1 on success.
4711
 * @return  0 on failure.
4712
 * @return  BAD_FUNC_ARG when ssl is NULL.
4713
 */
4714
int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL* ssl,
4715
    const unsigned char* in, long sz, int format)
4716
0
{
4717
0
    int ret;
4718
4719
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
4720
4721
    /* Validate parameters. */
4722
0
    if (ssl == NULL) {
4723
0
        ret = BAD_FUNC_ARG;
4724
0
    }
4725
0
    else {
4726
0
        ret = ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE, ssl, NULL, 1,
4727
0
            GET_VERIFY_SETTING_SSL(ssl), "cert chain buffer");
4728
0
    }
4729
4730
0
    return ret;
4731
0
}
4732
4733
/* Load a PEM encoded certificate chain in a buffer into SSL.
4734
 *
4735
 * @param [in, out] ssl     SSL object.
4736
 * @param [in]      in      Buffer holding DER encoded certificate chain.
4737
 * @param [in]      sz      Size of data in bytes.
4738
 * @return  1 on success.
4739
 * @return  0 on failure.
4740
 * @return  Negative on error.
4741
 */
4742
int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl, const unsigned char* in,
4743
    long sz)
4744
0
{
4745
0
    return wolfSSL_use_certificate_chain_buffer_format(ssl, in, sz,
4746
0
        WOLFSSL_FILETYPE_PEM);
4747
0
}
4748
4749
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
4750
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
4751
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
4752
    defined(WOLFSSL_HAPROXY)
4753
/* Add certificate to chain.
4754
 *
4755
 * @param [in, out] chain   Buffer holding encoded certificate for TLS.
4756
 * @param [in]      weOwn   Indicates we need to free chain if repleced.
4757
 * @param [in]      cert    Buffer holding DER encoded certificate.
4758
 * @param [in]      certSz  Size of DER encoded certificate in bytes.
4759
 * @param [in]      heap    Dynamic memory allocation hint.
4760
 * @return  1 on success.
4761
 * @return  0 on failure.
4762
 */
4763
static int wolfssl_add_to_chain(DerBuffer** chain, int weOwn, const byte* cert,
4764
    word32 certSz, void* heap)
4765
{
4766
    int res = 1;
4767
    int ret;
4768
    DerBuffer* oldChain = *chain;
4769
    DerBuffer* newChain = NULL;
4770
    word32 len = 0;
4771
4772
    if (oldChain != NULL) {
4773
        /* Get length of previous chain. */
4774
        len = oldChain->length;
4775
    }
4776
    /* Allocate DER buffer bug enough to hold old and new certificates. */
4777
    ret = AllocDer(&newChain, len + CERT_HEADER_SZ + certSz, CERT_TYPE, heap);
4778
    if (ret != 0) {
4779
        WOLFSSL_MSG("AllocDer error");
4780
        res = 0;
4781
    }
4782
4783
    if (res == 1) {
4784
        if (oldChain != NULL) {
4785
            /* Place old chain in new buffer. */
4786
            XMEMCPY(newChain->buffer, oldChain->buffer, len);
4787
        }
4788
        /* Append length and DER encoded certificate. */
4789
        c32to24(certSz, newChain->buffer + len);
4790
        XMEMCPY(newChain->buffer + len + CERT_HEADER_SZ, cert, certSz);
4791
4792
        /* Dispose of old chain if we own it. */
4793
        if (weOwn) {
4794
            FreeDer(chain);
4795
        }
4796
        /* Replace chain. */
4797
        *chain = newChain;
4798
    }
4799
4800
    return res;
4801
}
4802
#endif
4803
4804
#ifdef OPENSSL_EXTRA
4805
4806
/* Add a certificate to end of chain sent in TLS handshake.
4807
 *
4808
 * @param [in, out] ctx    SSL context.
4809
 * @param [in]      der    Buffer holding DER encoded certificate.
4810
 * @param [in]      derSz  Size of data in buffer.
4811
 * @return  1 on success.
4812
 * @return  0 on failure.
4813
 */
4814
static int wolfssl_ctx_add_to_chain(WOLFSSL_CTX* ctx, const byte* der,
4815
    int derSz)
4816
{
4817
    int res = 1;
4818
    int ret;
4819
    DerBuffer* derBuffer = NULL;
4820
4821
    /* Create a DER buffer from DER encoding. */
4822
    ret = AllocCopyDer(&derBuffer, der, (word32)derSz, CERT_TYPE, ctx->heap);
4823
    if (ret != 0) {
4824
        WOLFSSL_MSG("Memory Error");
4825
        res = 0;
4826
    }
4827
    if (res == 1) {
4828
        /* Add a user CA certificate to the certificate manager. */
4829
        res = AddCA(ctx->cm, &derBuffer, WOLFSSL_USER_CA,
4830
            GET_VERIFY_SETTING_CTX(ctx));
4831
        if (res != 1) {
4832
            res = 0;
4833
        }
4834
    }
4835
4836
    if (res == 1) {
4837
         /* Add chain to DER buffer. */
4838
         res = wolfssl_add_to_chain(&ctx->certChain, 1, der, (word32)derSz, ctx->heap);
4839
    #ifdef WOLFSSL_TLS13
4840
        /* Update count of certificates. */
4841
        ctx->certChainCnt++;
4842
    #endif
4843
    }
4844
4845
    return res;
4846
}
4847
4848
/* Add a certificate to chain sent in TLS handshake.
4849
 *
4850
 * @param [in, out] ctx   SSL context.
4851
 * @param [in]      x509  X509 certificate object.
4852
 * @return  1 on success.
4853
 * @return  0 on failure.
4854
 */
4855
long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
4856
{
4857
    int   ret = 1;
4858
    int   derSz = 0;
4859
    const byte* der = NULL;
4860
4861
    WOLFSSL_ENTER("wolfSSL_CTX_add_extra_chain_cert");
4862
4863
    /* Validate parameters. */
4864
    if ((ctx == NULL) || (x509 == NULL)) {
4865
        WOLFSSL_MSG("Bad Argument");
4866
        ret = 0;
4867
    }
4868
4869
    if (ret == 1) {
4870
        /* Get the DER encoding of the certificate from the X509 object. */
4871
        der = wolfSSL_X509_get_der(x509, &derSz);
4872
        /* Validate buffer. */
4873
        if ((der == NULL) || (derSz <= 0)) {
4874
            WOLFSSL_MSG("Error getting X509 DER");
4875
            ret = 0;
4876
        }
4877
    }
4878
4879
    if ((ret == 1) && (ctx->certificate == NULL)) {
4880
        WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
4881
4882
        /* Process buffer makes first certificate the leaf. */
4883
        ret = ProcessBuffer(ctx, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
4884
            NULL, NULL, 1, GET_VERIFY_SETTING_CTX(ctx), "extra chain buffer");
4885
        if (ret != 1) {
4886
            ret = 0;
4887
        }
4888
    }
4889
    else if (ret == 1) {
4890
        /* Add certificate to existing chain. */
4891
        ret = wolfssl_ctx_add_to_chain(ctx, der, derSz);
4892
    }
4893
4894
    if (ret == 1) {
4895
        /* On success WOLFSSL_X509 memory is responsibility of SSL context. */
4896
        wolfSSL_X509_free(x509);
4897
        x509 = NULL;
4898
    }
4899
4900
    WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
4901
    return ret;
4902
}
4903
4904
#endif /* OPENSSL_EXTRA */
4905
4906
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
4907
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
4908
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
4909
    defined(WOLFSSL_HAPROXY)
4910
/* Load a certificate into SSL context.
4911
 *
4912
 * @param [in, out] ctx   SSL context object.
4913
 * @param [in]      x509  X509 certificate object.
4914
 * @return  1 on success.
4915
 * @return  0 on failure.
4916
 */
4917
int wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x)
4918
{
4919
    int res = 1;
4920
    int ret;
4921
4922
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
4923
4924
    /* Validate parameters. */
4925
    if ((ctx == NULL) || (x == NULL) || (x->derCert == NULL)) {
4926
        WOLFSSL_MSG("Bad parameter");
4927
        res = 0;
4928
    }
4929
4930
    if (res == 1) {
4931
        /* Replace certificate buffer with one holding the new certificate. */
4932
        FreeDer(&ctx->certificate);
4933
        ret = AllocCopyDer(&ctx->certificate, x->derCert->buffer,
4934
            x->derCert->length, CERT_TYPE, ctx->heap);
4935
        if (ret != 0) {
4936
            res = 0;
4937
        }
4938
    }
4939
4940
#ifdef KEEP_OUR_CERT
4941
    if (res == 1) {
4942
        /* Dispose of our certificate if it is ours. */
4943
        if ((ctx->ourCert != NULL) && ctx->ownOurCert) {
4944
            wolfSSL_X509_free(ctx->ourCert);
4945
        }
4946
    #ifndef WOLFSSL_X509_STORE_CERTS
4947
        /* Keep a reference to the new certificate. */
4948
        ctx->ourCert = x;
4949
        if (wolfSSL_X509_up_ref(x) != 1) {
4950
            res = 0;
4951
        }
4952
    #else
4953
        /* Keep a copy of the new certificate. */
4954
        ctx->ourCert = wolfSSL_X509_d2i_ex(NULL, x->derCert->buffer,
4955
            x->derCert->length, ctx->heap);
4956
        if (ctx->ourCert == NULL) {
4957
            res = 0;
4958
        }
4959
    #endif
4960
        /* Now own our certificate. */
4961
        ctx->ownOurCert = 1;
4962
    }
4963
#endif
4964
4965
    if (res == 1) {
4966
        /* Set have options based on public key OID. */
4967
        wolfssl_set_have_from_key_oid(ctx, NULL, x->pubKeyOID);
4968
    }
4969
4970
    return res;
4971
}
4972
4973
/* Add the certificate to the chain in the SSL context and own the X509 object.
4974
 *
4975
 * @param [in, out] ctx   SSL context object.
4976
 * @param [in]      x509  X509 certificate object.
4977
 * @return  1 on success.
4978
 * @return  0 on failure.
4979
 */
4980
int wolfSSL_CTX_add0_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
4981
{
4982
    int ret;
4983
4984
    WOLFSSL_ENTER("wolfSSL_CTX_add0_chain_cert");
4985
4986
    /* Add certificate to chain and copy or up reference it. */
4987
    ret = wolfSSL_CTX_add1_chain_cert(ctx, x509);
4988
    if (ret == 1) {
4989
        /* Down reference or free original now as we own certificate. */
4990
        wolfSSL_X509_free(x509);
4991
        x509 = NULL;
4992
    }
4993
4994
    return ret;
4995
}
4996
4997
/* Add the certificate to the chain in the SSL context.
4998
 *
4999
 * X509 object copied or up referenced.
5000
 *
5001
 * @param [in, out] ctx   SSL context object.
5002
 * @param [in]      x509  X509 certificate object.
5003
 * @return  1 on success.
5004
 * @return  0 on failure.
5005
 */
5006
int wolfSSL_CTX_add1_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
5007
{
5008
    int ret = 1;
5009
5010
    WOLFSSL_ENTER("wolfSSL_CTX_add1_chain_cert");
5011
5012
    /* Validate parameters. */
5013
    if ((ctx == NULL) || (x509 == NULL) || (x509->derCert == NULL)) {
5014
        ret = 0;
5015
    }
5016
5017
    /* Check if we already have set a certificate. */
5018
    if ((ret == 1) && (ctx->certificate == NULL)) {
5019
        /* Use the certificate. */
5020
        ret = wolfSSL_CTX_use_certificate(ctx, x509);
5021
    }
5022
    /* Increase reference count as we will store it. */
5023
    else if ((ret == 1) && ((ret = wolfSSL_X509_up_ref(x509)) == 1)) {
5024
        /* Load the DER encoding. */
5025
        ret = wolfSSL_CTX_load_verify_buffer(ctx, x509->derCert->buffer,
5026
            x509->derCert->length, WOLFSSL_FILETYPE_ASN1);
5027
        if (ret == 1) {
5028
            /* Add DER encoding to chain. */
5029
            ret = wolfssl_add_to_chain(&ctx->certChain, 1,
5030
                x509->derCert->buffer, x509->derCert->length, ctx->heap);
5031
        }
5032
        /* Store cert in stack to free it later. */
5033
        if ((ret == 1) && (ctx->x509Chain == NULL)) {
5034
            /* Create a stack for certificates. */
5035
            ctx->x509Chain = wolfSSL_sk_X509_new_null();
5036
            if (ctx->x509Chain == NULL) {
5037
                WOLFSSL_MSG("wolfSSL_sk_X509_new_null error");
5038
                ret = 0;
5039
            }
5040
        }
5041
        if (ret == 1) {
5042
            /* Push the X509 object onto stack. */
5043
            ret = wolfSSL_sk_X509_push(ctx->x509Chain, x509) > 0
5044
                    ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5045
        }
5046
5047
        if (ret != 1) {
5048
            /* Decrease reference count on error as we didn't store it. */
5049
            wolfSSL_X509_free(x509);
5050
            x509 = NULL;
5051
        }
5052
    }
5053
5054
    return WS_RC(ret);
5055
}
5056
5057
#ifdef KEEP_OUR_CERT
5058
/* Add the certificate to the chain in the SSL and own the X509 object.
5059
 *
5060
 * @param [in, out] ssl   SSL object.
5061
 * @param [in]      x509  X509 certificate object.
5062
 * @return  1 on success.
5063
 * @return  0 on failure.
5064
 */
5065
int wolfSSL_add0_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
5066
{
5067
    int ret = 1;
5068
5069
    WOLFSSL_ENTER("wolfSSL_add0_chain_cert");
5070
5071
    /* Validate parameters. */
5072
    if ((ssl == NULL) || (x509 == NULL) || (x509->derCert == NULL)) {
5073
        ret = 0;
5074
    }
5075
5076
    /* Check if we already have set a certificate. */
5077
    if ((ret == 1) && (ssl->buffers.certificate == NULL)) {
5078
        /* Use the certificate. */
5079
        ret = wolfSSL_use_certificate(ssl, x509);
5080
        if (ret == 1) {
5081
            /* Dispose of old certificate if we own it. */
5082
            if (ssl->buffers.weOwnCert) {
5083
                wolfSSL_X509_free(ssl->ourCert);
5084
            }
5085
            /* Store cert to free it later. */
5086
            ssl->ourCert = x509;
5087
            ssl->buffers.weOwnCert = 1;
5088
        }
5089
    }
5090
    else if (ret == 1) {
5091
        /* Add DER encoding to chain. */
5092
        ret = wolfssl_add_to_chain(&ssl->buffers.certChain,
5093
            ssl->buffers.weOwnCertChain, x509->derCert->buffer,
5094
            x509->derCert->length, ssl->heap);
5095
        if (ret == 1) {
5096
            /* We now own cert chain. */
5097
            ssl->buffers.weOwnCertChain = 1;
5098
            /* Create a stack to put certificate into. */
5099
            if (ssl->ourCertChain == NULL) {
5100
                ssl->ourCertChain = wolfSSL_sk_X509_new_null();
5101
                if (ssl->ourCertChain == NULL) {
5102
                    WOLFSSL_MSG("wolfSSL_sk_X509_new_null error");
5103
                    ret = 0;
5104
                }
5105
            }
5106
        }
5107
        if (ret == 1) {
5108
            /* Push X509 object onto stack to be freed. */
5109
            ret = wolfSSL_sk_X509_push(ssl->ourCertChain, x509) > 0
5110
                    ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5111
            if (ret != 1) {
5112
                /* Free it now on error. */
5113
                wolfSSL_X509_free(x509);
5114
                x509 = NULL;
5115
            }
5116
        }
5117
    }
5118
    return WS_RC(ret);
5119
}
5120
5121
/* Add the certificate to the chain in the SSL.
5122
 *
5123
 * X509 object is up referenced.
5124
 *
5125
 * @param [in, out] ssl   SSL object.
5126
 * @param [in]      x509  X509 certificate object.
5127
 * @return  1 on success.
5128
 * @return  0 on failure.
5129
 */
5130
int wolfSSL_add1_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
5131
{
5132
    int ret = 1;
5133
5134
    WOLFSSL_ENTER("wolfSSL_add1_chain_cert");
5135
5136
    /* Validate parameters. */
5137
    if ((ssl == NULL) || (x509 == NULL) || (x509->derCert == NULL)) {
5138
        ret = 0;
5139
    }
5140
5141
    /* Increase reference count on X509 object before adding. */
5142
    if ((ret == 1) && ((ret == wolfSSL_X509_up_ref(x509)) == 1)) {
5143
        /* Add this to the chain. */
5144
        if ((ret = wolfSSL_add0_chain_cert(ssl, x509)) != 1) {
5145
            /* Decrease reference count on error as not stored. */
5146
            wolfSSL_X509_free(x509);
5147
            x509 = NULL;
5148
        }
5149
    }
5150
5151
    return ret;
5152
}
5153
#endif /* KEEP_OUR_CERT */
5154
#endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
5155
          WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY */
5156
5157
#ifdef OPENSSL_EXTRA
5158
5159
/* Load a private key into SSL context.
5160
 *
5161
 * @param [in, out] ctx   SSL context object.
5162
 * @param [in]      pkey  EVP private key.
5163
 * @return  1 on success.
5164
 * @return  0 on failure.
5165
 */
5166
int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
5167
{
5168
    int ret = 1;
5169
5170
    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey");
5171
5172
    /* Validate parameters. */
5173
    if ((ctx == NULL) || (pkey == NULL) || (pkey->pkey.ptr == NULL)) {
5174
        ret = 0;
5175
    }
5176
5177
    if (ret == 1) {
5178
        switch (pkey->type) {
5179
    #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
5180
        case WC_EVP_PKEY_RSA:
5181
            WOLFSSL_MSG("populating RSA key");
5182
            ret = PopulateRSAEvpPkeyDer(pkey);
5183
            break;
5184
    #endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
5185
    #if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
5186
            defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA)
5187
        case WC_EVP_PKEY_DSA:
5188
            break;
5189
    #endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) &&
5190
            * !NO_DSA */
5191
    #ifdef HAVE_ECC
5192
        case WC_EVP_PKEY_EC:
5193
            WOLFSSL_MSG("populating ECC key");
5194
            ret = ECC_populate_EVP_PKEY(pkey, pkey->ecc);
5195
            break;
5196
    #endif
5197
        default:
5198
            ret = 0;
5199
        }
5200
    }
5201
5202
    if (ret == 1) {
5203
        /* ptr for WOLFSSL_EVP_PKEY struct is expected to be DER format */
5204
        ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx,
5205
            (const unsigned char*)pkey->pkey.ptr, pkey->pkey_sz,
5206
            WOLFSSL_FILETYPE_ASN1);
5207
    }
5208
5209
    return ret;
5210
}
5211
5212
#endif /* OPENSSL_EXTRA */
5213
5214
#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || \
5215
    defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
5216
/* Load a DER encoded certificate in a buffer into SSL context.
5217
 *
5218
 * @param [in, out] ctx    SSL context object.
5219
 * @param [in]      der    Buffer holding DER encoded certificate.
5220
 * @param [in]      derSz  Size of data in bytes.
5221
 * @return  1 on success.
5222
 * @return  0 on failure.
5223
 */
5224
int wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX *ctx, int derSz,
5225
    const unsigned char *der)
5226
{
5227
    int ret = 1;
5228
5229
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_ASN1");
5230
5231
    /* Validate parameters. */
5232
    if ((ctx == NULL) || (der == NULL)) {
5233
        ret = 0;
5234
    }
5235
    /* Load DER encoded certificate into SSL context. */
5236
    if ((ret == 1) && (wolfSSL_CTX_use_certificate_buffer(ctx, der, derSz,
5237
            WOLFSSL_FILETYPE_ASN1) != 1)) {
5238
        ret = 0;
5239
    }
5240
5241
    return ret;
5242
}
5243
5244
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
5245
/* Load an RSA private key into SSL context.
5246
 *
5247
 * @param [in, out] ctx   SSL context object.
5248
 * @param [in]      rsa   RSA private key.
5249
 * @return  1 on success.
5250
 * @return  0 on failure.
5251
 * @return  BAD_FUNC_ARG when ctx or rsa is NULL.
5252
 * @return  MEMORY_E when dynamic memory allocation fails.
5253
 */
5254
int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa)
5255
{
5256
    int ret = 1;
5257
    int derSize = 0;
5258
    unsigned char* der = NULL;
5259
    unsigned char* p;
5260
5261
    WOLFSSL_ENTER("wolfSSL_CTX_use_RSAPrivateKey");
5262
5263
    /* Validate parameters. */
5264
    if ((ctx == NULL) || (rsa == NULL)) {
5265
        WOLFSSL_MSG("one or more inputs were NULL");
5266
        ret = BAD_FUNC_ARG;
5267
    }
5268
5269
    /* Get DER encoding size. */
5270
    if ((ret == 1) && ((derSize = wolfSSL_i2d_RSAPrivateKey(rsa, NULL)) <= 0)) {
5271
        ret = 0;
5272
    }
5273
5274
    if (ret == 1) {
5275
        /* Allocate memory to hold DER encoding.. */
5276
        der = (unsigned char*)XMALLOC((size_t)derSize, NULL,
5277
                                            DYNAMIC_TYPE_TMP_BUFFER);
5278
        if (der == NULL) {
5279
            WOLFSSL_MSG("Malloc failure");
5280
            ret = MEMORY_E;
5281
        }
5282
    }
5283
5284
    if (ret == 1) {
5285
        /* Pointer passed in is modified.. */
5286
        p = der;
5287
        /* Encode the RSA key as DER into buffer and get size. */
5288
        if ((derSize = wolfSSL_i2d_RSAPrivateKey(rsa, &p)) <= 0) {
5289
            WOLFSSL_MSG("wolfSSL_i2d_RSAPrivateKey() failure");
5290
            ret = 0;
5291
        }
5292
    }
5293
5294
    if (ret == 1) {
5295
        /* Load DER encoded certificate into SSL context. */
5296
        ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSize,
5297
            SSL_FILETYPE_ASN1);
5298
        if (ret != WOLFSSL_SUCCESS) {
5299
            WOLFSSL_MSG("wolfSSL_CTX_USE_PrivateKey_buffer() failure");
5300
            ret = 0;
5301
        }
5302
    }
5303
5304
    /* Dispos of dynamically allocated data. */
5305
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5306
    return ret;
5307
}
5308
#endif /* WOLFSSL_KEY_GEN && !NO_RSA */
5309
5310
#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */
5311
5312
#endif /* !NO_CERTS */
5313
5314
#ifdef OPENSSL_EXTRA
5315
5316
/* Use the default paths to look for CA certificate.
5317
 *
5318
 * This is an OpenSSL compatibility layer function, but it doesn't mirror
5319
 * the exact functionality of its OpenSSL counterpart. We don't support the
5320
 * notion of an "OpenSSL directory". This function will attempt to load the
5321
 * environment variables SSL_CERT_DIR and SSL_CERT_FILE, if either are
5322
 * found, they will be loaded. Otherwise, it will act as a wrapper around
5323
 * our native wolfSSL_CTX_load_system_CA_certs function. This function does
5324
 * conform to OpenSSL's return value conventions.
5325
 *
5326
 * @param [in] ctx  SSL context object.
5327
 * @return  1 on success.
5328
 * @return  0 on failure.
5329
 * @return  WOLFSSL_FATAL_ERROR when using a filesystem is not supported.
5330
 */
5331
int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
5332
{
5333
    int ret;
5334
#if defined(XGETENV) && !defined(NO_GETENV)
5335
    char* certDir = NULL;
5336
    char* certFile = NULL;
5337
    word32 flags = 0;
5338
#elif !defined(WOLFSSL_SYS_CA_CERTS)
5339
    (void)ctx;
5340
#endif
5341
5342
    WOLFSSL_ENTER("wolfSSL_CTX_set_default_verify_paths");
5343
5344
#if defined(XGETENV) && !defined(NO_GETENV)
5345
    /* // NOLINTBEGIN(concurrency-mt-unsafe) */
5346
    certDir = wc_strdup_ex(XGETENV("SSL_CERT_DIR"), DYNAMIC_TYPE_TMP_BUFFER);
5347
    certFile = wc_strdup_ex(XGETENV("SSL_CERT_FILE"), DYNAMIC_TYPE_TMP_BUFFER);
5348
    flags = WOLFSSL_LOAD_FLAG_PEM_CA_ONLY;
5349
5350
    if ((certDir != NULL) || (certFile != NULL)) {
5351
        if (certDir != NULL) {
5352
           /* We want to keep trying to load more CA certs even if one cert in
5353
            * the directory is bad and can't be used (e.g. if one is
5354
            * expired), so we use WOLFSSL_LOAD_FLAG_IGNORE_ERR.
5355
            */
5356
            flags |= WOLFSSL_LOAD_FLAG_IGNORE_ERR;
5357
        }
5358
5359
        /* Load CA certificates from environment variable locations. */
5360
        ret = wolfSSL_CTX_load_verify_locations_ex(ctx, certFile, certDir,
5361
            flags);
5362
        if (ret != 1) {
5363
            WOLFSSL_MSG_EX("Failed to load CA certs from SSL_CERT_FILE: %s"
5364
                            " SSL_CERT_DIR: %s. Error: %d", certFile,
5365
                            certDir, ret);
5366
            ret = 0;
5367
        }
5368
    }
5369
    /* // NOLINTEND(concurrency-mt-unsafe) */
5370
    else
5371
#endif
5372
5373
    {
5374
    #ifdef NO_FILESYSTEM
5375
        WOLFSSL_MSG("wolfSSL_CTX_set_default_verify_paths not supported"
5376
                    " with NO_FILESYSTEM enabled");
5377
        ret = WOLFSSL_FATAL_ERROR;
5378
    #elif defined(WOLFSSL_SYS_CA_CERTS)
5379
        /* Load the system CA certificates. */
5380
        ret = wolfSSL_CTX_load_system_CA_certs(ctx);
5381
        if (ret == WC_NO_ERR_TRACE(WOLFSSL_BAD_PATH)) {
5382
            /* OpenSSL doesn't treat the lack of a system CA cert directory as a
5383
             * failure. We do the same here.
5384
             */
5385
            ret = 1;
5386
        }
5387
    #else
5388
        /* OpenSSL's implementation of this API does not require loading the
5389
           system CA cert directory.  Allow skipping this without erroring out. */
5390
        ret = 1;
5391
    #endif
5392
    }
5393
5394
#if defined(XGETENV) && !defined(NO_GETENV)
5395
    XFREE(certFile, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5396
    XFREE(certDir, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5397
#endif
5398
    WOLFSSL_LEAVE("wolfSSL_CTX_set_default_verify_paths", ret);
5399
5400
    return ret;
5401
}
5402
5403
#endif /* OPENSSL_EXTRA */
5404
5405
#ifndef NO_DH
5406
5407
/* Set the temporary DH parameters against the SSL.
5408
 *
5409
 * @param [in, out] ssl   SSL object.
5410
 * @param [in]      p     Buffer holding prime.
5411
 * @param [in]      pSz   Length of prime in bytes.
5412
 * @param [in]      g     Buffer holding generator.
5413
 * @param [in]      gSz   Length of generator in bytes.
5414
 * @return  1 on success.
5415
 * @return  0 on failure.
5416
 * @return  DH_KEY_SIZE_E when the prime is too short or long.
5417
 * @return  SIDE_ERROR when the SSL is for a client.
5418
 */
5419
static int wolfssl_set_tmp_dh(WOLFSSL* ssl, unsigned char* p, int pSz,
5420
    unsigned char* g, int gSz)
5421
0
{
5422
0
    int ret = 1;
5423
5424
    /* Check the size of the prime meets the requirements of the SSL. */
5425
0
    if (((word16)pSz < ssl->options.minDhKeySz) ||
5426
0
            ((word16)pSz > ssl->options.maxDhKeySz)) {
5427
0
        ret = DH_KEY_SIZE_E;
5428
0
    }
5429
    /* Only able to set DH parameters on server. */
5430
0
    if ((ret == 1) && (ssl->options.side == WOLFSSL_CLIENT_END)) {
5431
0
        ret = SIDE_ERROR;
5432
0
    }
5433
5434
0
    if (ret == 1) {
5435
0
    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
5436
0
        !defined(HAVE_SELFTEST)
5437
        /* New DH parameters not tested for validity. */
5438
0
        ssl->options.dhKeyTested = 0;
5439
        /* New DH parameters must be tested for validity before use. */
5440
0
        ssl->options.dhDoKeyTest = 1;
5441
0
    #endif
5442
5443
        /* Dispose of old DH parameters if we own it. */
5444
0
        if (ssl->buffers.weOwnDH) {
5445
0
            XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
5446
0
                DYNAMIC_TYPE_PUBLIC_KEY);
5447
0
            XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
5448
0
                DYNAMIC_TYPE_PUBLIC_KEY);
5449
0
        }
5450
5451
        /* Assign the buffers and lengths to SSL. */
5452
0
        ssl->buffers.serverDH_P.buffer = p;
5453
0
        ssl->buffers.serverDH_G.buffer = g;
5454
0
        ssl->buffers.serverDH_P.length = (unsigned int)pSz;
5455
0
        ssl->buffers.serverDH_G.length = (unsigned int)gSz;
5456
        /* We own the buffers. */
5457
0
        ssl->buffers.weOwnDH = 1;
5458
        /* We have a DH parameters to use. */
5459
0
        ssl->options.haveDH = 1;
5460
0
    }
5461
5462
    /* Allocate space for cipher suites. */
5463
0
    if ((ret == 1) && (AllocateSuites(ssl) != 0)) {
5464
0
        ssl->buffers.serverDH_P.buffer = NULL;
5465
0
        ssl->buffers.serverDH_G.buffer = NULL;
5466
0
        ret = 0;
5467
0
    }
5468
0
    if (ret == 1) {
5469
        /* Reset the cipher suites based on having a DH parameters now. */
5470
0
        InitSuites(ssl->suites, ssl->version, SSL_KEY_SZ(ssl),
5471
0
            WOLFSSL_HAVE_RSA, SSL_HAVE_PSK(ssl), ssl->options.haveDH,
5472
0
            ssl->options.haveECDSAsig, ssl->options.haveECC, TRUE,
5473
0
            ssl->options.haveStaticECC,
5474
0
            ssl->options.useAnon, TRUE,
5475
0
            TRUE, TRUE, TRUE, ssl->options.side);
5476
0
    }
5477
5478
0
    return ret;
5479
0
}
5480
5481
/* Set the temporary DH parameters against the SSL.
5482
 *
5483
 * @param [in, out] ssl   SSL object.
5484
 * @param [in]      p     Buffer holding prime.
5485
 * @param [in]      pSz   Length of prime in bytes.
5486
 * @param [in]      g     Buffer holding generator.
5487
 * @param [in]      gSz   Length of generator in bytes.
5488
 * @return  1 on success.
5489
 * @return  0 on failure.
5490
 * @return  DH_KEY_SIZE_E when the prime is too short or long.
5491
 * @return  SIDE_ERROR when the SSL is for a client.
5492
 * @return  MEMORY_E when dynamic memory allocation fails.
5493
 */
5494
int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
5495
    const unsigned char* g, int gSz)
5496
0
{
5497
0
    int ret = 1;
5498
0
    byte* pAlloc = NULL;
5499
0
    byte* gAlloc = NULL;
5500
5501
0
    WOLFSSL_ENTER("wolfSSL_SetTmpDH");
5502
5503
    /* Validate parameters. */
5504
0
    if ((ssl == NULL) || (p == NULL) || (g == NULL)) {
5505
0
        ret = 0;
5506
0
    }
5507
5508
0
    if (ret == 1) {
5509
        /* Allocate buffers for p and g to be assigned into SSL. */
5510
0
        pAlloc = (byte*)XMALLOC((size_t)pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5511
0
        gAlloc = (byte*)XMALLOC((size_t)gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5512
0
        if ((pAlloc == NULL) || (gAlloc == NULL)) {
5513
            /* Memory will be freed below in the (ret != 1) block */
5514
0
            ret = MEMORY_E;
5515
0
        }
5516
0
    }
5517
0
    if (ret == 1) {
5518
        /* Copy p and g into allocated buffers. */
5519
0
        XMEMCPY(pAlloc, p, (size_t)pSz);
5520
0
        XMEMCPY(gAlloc, g, (size_t)gSz);
5521
        /* Set the buffers into SSL. */
5522
0
        ret = wolfssl_set_tmp_dh(ssl, pAlloc, pSz, gAlloc, gSz);
5523
0
    }
5524
5525
0
    if (ret != 1 && ssl != NULL) {
5526
        /* Free the allocated buffers if not assigned into SSL. */
5527
0
        XFREE(pAlloc, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5528
0
        XFREE(gAlloc, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5529
0
    }
5530
5531
0
    WOLFSSL_LEAVE("wolfSSL_SetTmpDH", ret);
5532
0
    return ret;
5533
0
}
5534
5535
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
5536
    !defined(HAVE_SELFTEST)
5537
/* Check the DH parameters is valid.
5538
 *
5539
 * @param [in]      p     Buffer holding prime.
5540
 * @param [in]      pSz   Length of prime in bytes.
5541
 * @param [in]      g     Buffer holding generator.
5542
 * @param [in]      gSz   Length of generator in bytes.
5543
 * @return  1 on success.
5544
 * @return  DH_CHECK_PUB_E when p is not a prime.
5545
 * @return  BAD_FUNC_ARG when p or g is NULL, or pSz or gSz is 0.
5546
 * @return  MEMORY_E when dynamic memory allocation fails.
5547
 */
5548
static int wolfssl_check_dh_key(unsigned char* p, int pSz, unsigned char* g,
5549
    int gSz)
5550
0
{
5551
0
    WC_RNG rng;
5552
0
    int ret = 0;
5553
0
#ifndef WOLFSSL_SMALL_STACK
5554
0
    DhKey checkKey[1];
5555
#else
5556
    DhKey *checkKey;
5557
#endif
5558
5559
#ifdef WOLFSSL_SMALL_STACK
5560
    checkKey = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
5561
    if (checkKey == NULL) {
5562
        ret = MEMORY_E;
5563
    }
5564
#endif
5565
    /* Initialize a new random number generator. */
5566
0
    if ((ret == 0) && ((ret = wc_InitRng(&rng)) == 0)) {
5567
        /* Initialize a DH object. */
5568
0
        if ((ret = wc_InitDhKey(checkKey)) == 0) {
5569
            /* Check DH parameters. */
5570
0
            ret = wc_DhSetCheckKey(checkKey, p, (word32)pSz, g, (word32)gSz, NULL, 0, 0, &rng);
5571
            /* Dispose of DH object. */
5572
0
            wc_FreeDhKey(checkKey);
5573
0
        }
5574
        /* Dispose of random number generator. */
5575
0
        wc_FreeRng(&rng);
5576
0
    }
5577
5578
#ifdef WOLFSSL_SMALL_STACK
5579
    /* Dispose of dynamically allocated data. */
5580
    XFREE(checkKey, NULL, DYNAMIC_TYPE_DH);
5581
#endif
5582
    /* Convert wolfCrypt return code to 1 on success and ret on failure. */
5583
0
    return WC_TO_WS_RC(ret);
5584
0
}
5585
#endif
5586
5587
/* Set the temporary DH parameters against the SSL context.
5588
 *
5589
 * @param [in, out] ctx   SSL context object.
5590
 * @param [in]      p     Buffer holding prime.
5591
 * @param [in]      pSz   Length of prime in bytes.
5592
 * @param [in]      g     Buffer holding generator.
5593
 * @param [in]      gSz   Length of generator in bytes.
5594
 * @return  1 on success.
5595
 * @return  0 on failure.
5596
 * @return  DH_KEY_SIZE_E when the prime is too short or long.
5597
 * @return  SIDE_ERROR when the SSL is for a client.
5598
 * @return  BAD_FUNC_ARG when ctx, p or g is NULL.
5599
 * @return  DH_CHECK_PUB_E when p is not a prime.
5600
 * @return  MEMORY_E when dynamic memory allocation fails.
5601
 */
5602
static int wolfssl_ctx_set_tmp_dh(WOLFSSL_CTX* ctx, unsigned char* p, int pSz,
5603
    unsigned char* g, int gSz)
5604
0
{
5605
0
    int ret = 1;
5606
5607
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
5608
5609
    /* Check the size of the prime meets the requirements of the SSL context. */
5610
0
    if (((word16)pSz < ctx->minDhKeySz) || ((word16)pSz > ctx->maxDhKeySz)) {
5611
0
        ret = DH_KEY_SIZE_E;
5612
0
    }
5613
5614
0
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
5615
0
    !defined(HAVE_SELFTEST)
5616
0
    if (ret == 1) {
5617
        /* Test DH parameters for validity. */
5618
0
        ret = wolfssl_check_dh_key(p, pSz, g, gSz);
5619
        /* Record as whether tested based on result of validity test. */
5620
0
        ctx->dhKeyTested = (ret == 1);
5621
0
    }
5622
0
#endif
5623
5624
0
    if (ret == 1) {
5625
        /* Dispose of old DH parameters. */
5626
0
        XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5627
0
        XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5628
        /* Assign the buffers and lengths to SSL context. */
5629
0
        ctx->serverDH_P.buffer = p;
5630
0
        ctx->serverDH_G.buffer = g;
5631
0
        ctx->serverDH_P.length = (unsigned int)pSz;
5632
0
        ctx->serverDH_G.length = (unsigned int)gSz;
5633
        /* We have a DH parameters to use. */
5634
0
        ctx->haveDH = 1;
5635
0
    }
5636
5637
0
    WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
5638
0
    return ret;
5639
0
}
5640
5641
/* Set the temporary DH parameters against the SSL context.
5642
 *
5643
 * @param [in, out] ctx   SSL context object.
5644
 * @param [in]      p     Buffer holding prime.
5645
 * @param [in]      pSz   Length of prime in bytes.
5646
 * @param [in]      g     Buffer holding generator.
5647
 * @param [in]      gSz   Length of generator in bytes.
5648
 * @return  1 on success.
5649
 * @return  0 on failure.
5650
 * @return  DH_KEY_SIZE_E when the prime is too short or long.
5651
 * @return  SIDE_ERROR when the SSL is for a client.
5652
 * @return  BAD_FUNC_ARG when ctx, p or g is NULL.
5653
 * @return  DH_CHECK_PUB_E when p is not a prime.
5654
 */
5655
int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
5656
                         const unsigned char* g, int gSz)
5657
0
{
5658
0
    int ret = 1;
5659
0
    byte* pAlloc = NULL;
5660
0
    byte* gAlloc = NULL;
5661
5662
    /* Validate parameters. */
5663
0
    if ((ctx == NULL) || (p == NULL) || (g == NULL)) {
5664
0
        ret = BAD_FUNC_ARG;
5665
0
    }
5666
5667
0
    if (ret == 1) {
5668
        /* Allocate buffers for p and g to be assigned into SSL context. */
5669
0
        pAlloc = (byte*)XMALLOC((size_t)pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5670
0
        gAlloc = (byte*)XMALLOC((size_t)gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5671
0
        if ((pAlloc == NULL) || (gAlloc == NULL)) {
5672
0
            ret = MEMORY_E;
5673
0
        }
5674
0
    }
5675
5676
0
    if (ret == 1) {
5677
        /* Copy p and g into allocated buffers. */
5678
0
        XMEMCPY(pAlloc, p, (size_t)pSz);
5679
0
        XMEMCPY(gAlloc, g, (size_t)gSz);
5680
        /* Set the buffers into SSL context. */
5681
0
        ret = wolfssl_ctx_set_tmp_dh(ctx, pAlloc, pSz, gAlloc, gSz);
5682
0
    }
5683
5684
0
    if ((ret != 1) && (ctx != NULL)) {
5685
        /* Free the allocated buffers if not assigned into SSL context. */
5686
0
        XFREE(pAlloc, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5687
0
        XFREE(gAlloc, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5688
0
    }
5689
0
    return ret;
5690
0
}
5691
5692
#ifdef OPENSSL_EXTRA
5693
/* Set the temporary DH parameters against the SSL.
5694
 *
5695
 * @param [in, out] ssl  SSL object.
5696
 * @param [in]      dh   DH object.
5697
 * @return  1 on success.
5698
 * @return  0 on failure.
5699
 * @return  WOLFSSL_FATAL_ERROR on failure.
5700
 * @return  BAD_FUNC_ARG when ssl or dh is NULL.
5701
 * @return  DH_KEY_SIZE_E when the prime is too short or long.
5702
 * @return  SIDE_ERROR when the SSL is for a client.
5703
 */
5704
long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh)
5705
{
5706
    int ret = 1;
5707
    byte* p = NULL;
5708
    byte* g = NULL;
5709
    int pSz = 0;
5710
    int gSz = 0;
5711
5712
    WOLFSSL_ENTER("wolfSSL_set_tmp_dh");
5713
5714
    /* Validate parameters. */
5715
    if ((ssl == NULL) || (dh == NULL)) {
5716
        ret = BAD_FUNC_ARG;
5717
    }
5718
5719
    if (ret == 1) {
5720
        /* Get sizes of p and g. */
5721
        pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
5722
        gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
5723
        /* Validate p and g size. */
5724
        if ((pSz <= 0) || (gSz <= 0)) {
5725
            ret = WOLFSSL_FATAL_ERROR;
5726
        }
5727
    }
5728
5729
    if (ret == 1) {
5730
        /* Allocate buffers for p and g to be assigned into SSL. */
5731
        p = (byte*)XMALLOC((size_t)pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5732
        g = (byte*)XMALLOC((size_t)gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5733
        if ((p == NULL) || (g == NULL)) {
5734
            ret = MEMORY_E;
5735
        }
5736
    }
5737
    if (ret == 1) {
5738
        /* Encode p and g and get sizes. */
5739
        pSz = wolfSSL_BN_bn2bin(dh->p, p);
5740
        gSz = wolfSSL_BN_bn2bin(dh->g, g);
5741
        /* Check encoding worked. */
5742
        if ((pSz <= 0) || (gSz <= 0)) {
5743
            ret = WOLFSSL_FATAL_ERROR;
5744
        }
5745
    }
5746
    if (ret == 1) {
5747
        /* Set the buffers into SSL. */
5748
        ret = wolfssl_set_tmp_dh(ssl, p, pSz, g, gSz);
5749
    }
5750
5751
    if ((ret != 1) && (ssl != NULL)) {
5752
        /* Free the allocated buffers if not assigned into SSL. */
5753
        XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5754
        XFREE(g, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5755
    }
5756
    return ret;
5757
}
5758
5759
/* Set the temporary DH parameters object against the SSL context.
5760
 *
5761
 * @param [in, out] ctx     SSL context object.
5762
 * @param [in]      dh      DH object.
5763
 * @return  1 on success.
5764
 * @return  0 on failure.
5765
 * @return  DH_KEY_SIZE_E when the prime is too short or long.
5766
 * @return  SIDE_ERROR when the SSL is for a client.
5767
 * @return  BAD_FUNC_ARG when ctx, p or g is NULL.
5768
 * @return  DH_CHECK_PUB_E when p is not a prime.
5769
 */
5770
long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
5771
{
5772
    int ret = 1;
5773
    int pSz = 0;
5774
    int gSz = 0;
5775
    byte* p = NULL;
5776
    byte* g = NULL;
5777
5778
    WOLFSSL_ENTER("wolfSSL_CTX_set_tmp_dh");
5779
5780
    /* Validate parameters. */
5781
    if ((ctx == NULL) || (dh == NULL)) {
5782
        ret = BAD_FUNC_ARG;
5783
    }
5784
5785
    if (ret == 1) {
5786
        /* Get sizes of p and g. */
5787
        pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
5788
        gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
5789
        /* Validate p and g size. */
5790
        if ((pSz <= 0) || (gSz <= 0)) {
5791
            ret = WOLFSSL_FATAL_ERROR;
5792
        }
5793
    }
5794
5795
    if (ret == 1) {
5796
        /* Allocate buffers for p and g to be assigned into SSL. */
5797
        p = (byte*)XMALLOC((size_t)pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5798
        g = (byte*)XMALLOC((size_t)gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5799
        if ((p == NULL) || (g == NULL)) {
5800
            ret = MEMORY_E;
5801
        }
5802
    }
5803
5804
    if (ret == 1) {
5805
        /* Encode p and g and get sizes. */
5806
        pSz = wolfSSL_BN_bn2bin(dh->p, p);
5807
        gSz = wolfSSL_BN_bn2bin(dh->g, g);
5808
        /* Check encoding worked. */
5809
        if ((pSz < 0) && (gSz < 0)) {
5810
            ret = WOLFSSL_FATAL_ERROR;
5811
        }
5812
    }
5813
    if (ret == 1) {
5814
        /* Set the buffers into SSL context. */
5815
        ret = wolfssl_ctx_set_tmp_dh(ctx, p, pSz, g, gSz);
5816
    }
5817
5818
    if ((ret != 1) && (ctx != NULL)) {
5819
        /* Free the allocated buffers if not assigned into SSL. */
5820
        XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5821
        XFREE(g, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5822
    }
5823
    return ret;
5824
}
5825
5826
#endif /* OPENSSL_EXTRA */
5827
5828
#ifndef NO_CERTS
5829
5830
/* Set the temporary DH parameters against the SSL context or SSL.
5831
 *
5832
 * @param [in, out] ctx     SSL context object.
5833
 * @param [in, out] ssl     SSL object.
5834
 * @param [in]      buf     Buffer holding encoded DH parameters.
5835
 * @param [in]      sz      Size of encoded DH parameters.
5836
 * @param [in]      format  Format of data:
5837
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
5838
 * @return  1 on success.
5839
 * @return  0 on failure.
5840
 * @return  BAD_FUNC_ARG when ctx and ssl NULL or buf is NULL.
5841
 * @return  NOT_COMPLED_IN when format is PEM but PEM is not supported.
5842
 * @return  WOLFSSL_BAD_FILETYPE if format is not supported.
5843
 */
5844
static int ws_ctx_ssl_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
5845
    const unsigned char* buf, long sz, int format)
5846
0
{
5847
0
    DerBuffer* der = NULL;
5848
0
    int res = 1;
5849
0
    int ret;
5850
    /* p and g size to allocate set to maximum valid size. */
5851
0
    word32 pSz = MAX_DH_SIZE;
5852
0
    word32 gSz = MAX_DH_SIZE;
5853
0
    byte* p = NULL;
5854
0
    byte* g = NULL;
5855
0
    void* heap = WOLFSSL_HEAP(ctx, ssl);
5856
5857
    /* Validate parameters. */
5858
0
    if (((ctx == NULL) && (ssl == NULL)) || (buf == NULL)) {
5859
0
        res = BAD_FUNC_ARG;
5860
0
    }
5861
    /* Check format is supported. */
5862
0
    if ((res == 1) && (format != WOLFSSL_FILETYPE_ASN1)) {
5863
0
        if (format != WOLFSSL_FILETYPE_PEM) {
5864
0
            res = WOLFSSL_BAD_FILETYPE;
5865
0
        }
5866
    #ifndef WOLFSSL_PEM_TO_DER
5867
        else {
5868
            res = NOT_COMPILED_IN;
5869
        }
5870
    #endif
5871
0
    }
5872
5873
    /* PemToDer allocates its own DER buffer. */
5874
0
    if ((res == 1) && (format != WOLFSSL_FILETYPE_PEM)) {
5875
        /* Create an empty DER buffer. */
5876
0
        ret = AllocDer(&der, 0, DH_PARAM_TYPE, heap);
5877
0
        if (ret == 0) {
5878
            /* Assign encoded DH parameters to DER buffer. */
5879
0
            der->buffer = (byte*)buf;
5880
0
            der->length = (word32)sz;
5881
0
        }
5882
0
        else {
5883
0
            res = ret;
5884
0
        }
5885
0
    }
5886
5887
0
    if (res == 1) {
5888
        /* Allocate enough memory to p and g to support valid use cases. */
5889
0
        p = (byte*)XMALLOC(pSz, heap, DYNAMIC_TYPE_PUBLIC_KEY);
5890
0
        g = (byte*)XMALLOC(gSz, heap, DYNAMIC_TYPE_PUBLIC_KEY);
5891
0
        if ((p == NULL) || (g == NULL)) {
5892
0
            res = MEMORY_E;
5893
0
        }
5894
0
    }
5895
5896
0
#ifdef WOLFSSL_PEM_TO_DER
5897
0
    if ((res == 1) && (format == WOLFSSL_FILETYPE_PEM)) {
5898
        /* Convert from PEM to DER. */
5899
        /* Try converting DH parameters from PEM to DER. */
5900
0
        ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, heap, NULL, NULL);
5901
0
        if (ret < 0) {
5902
            /* Otherwise, try converting X9.43 format DH parameters. */
5903
0
            ret = PemToDer(buf, sz, X942_PARAM_TYPE, &der, heap, NULL, NULL);
5904
0
        }
5905
    #if defined(WOLFSSL_WPAS) && !defined(NO_DSA)
5906
        if (ret < 0) {
5907
            /* Otherwise, try converting DSA parameters. */
5908
            ret = PemToDer(buf, sz, DSA_PARAM_TYPE, &der, heap, NULL, NULL);
5909
        }
5910
    #endif /* WOLFSSL_WPAS && !NO_DSA */
5911
0
       if (ret < 0) {
5912
           /* Return error from conversion. */
5913
0
           res = ret;
5914
0
       }
5915
0
    }
5916
0
#endif /* WOLFSSL_PEM_TO_DER */
5917
5918
0
    if (res == 1) {
5919
        /* Get the p and g from the DER encoded parameters. */
5920
0
        if (wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz) < 0) {
5921
0
            res = WOLFSSL_BAD_FILETYPE;
5922
0
        }
5923
0
        else if (ssl != NULL) {
5924
            /* Set p and g into SSL. */
5925
0
            res = wolfssl_set_tmp_dh(ssl, p, (int)pSz, g, (int)gSz);
5926
0
        }
5927
0
        else {
5928
            /* Set p and g into SSL context. */
5929
0
            res = wolfssl_ctx_set_tmp_dh(ctx, p, (int)pSz, g, (int)gSz);
5930
0
        }
5931
0
    }
5932
5933
    /* Dispose of the DER buffer. */
5934
0
    FreeDer(&der);
5935
0
    if (res != 1) {
5936
        /* Free the allocated buffers if not assigned into SSL or context. */
5937
0
        XFREE(p, heap, DYNAMIC_TYPE_PUBLIC_KEY);
5938
0
        XFREE(g, heap, DYNAMIC_TYPE_PUBLIC_KEY);
5939
0
    }
5940
0
    return res;
5941
0
}
5942
5943
5944
/* Set the temporary DH parameters against the SSL.
5945
 *
5946
 * @param [in, out] ssl     SSL object.
5947
 * @param [in]      buf     Buffer holding encoded DH parameters.
5948
 * @param [in]      sz      Size of encoded DH parameters.
5949
 * @param [in]      format  Format of data:
5950
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
5951
 * @return  1 on success.
5952
 * @return  BAD_FUNC_ARG when ssl or buf is NULL.
5953
 * @return  NOT_COMPLED_IN when format is PEM but PEM is not supported.
5954
 * @return  WOLFSSL_BAD_FILETYPE if format is not supported.
5955
 */
5956
int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
5957
    int format)
5958
0
{
5959
0
    return ws_ctx_ssl_set_tmp_dh(NULL, ssl, buf, sz, format);
5960
0
}
5961
5962
5963
/* Set the temporary DH parameters against the SSL context.
5964
 *
5965
 * @param [in, out] ctx     SSL context object.
5966
 * @param [in]      buf     Buffer holding encoded DH parameters.
5967
 * @param [in]      sz      Size of encoded DH parameters.
5968
 * @param [in]      format  Format of data:
5969
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
5970
 * @return  1 on success.
5971
 * @return  BAD_FUNC_ARG when ctx or buf is NULL.
5972
 * @return  NOT_COMPLED_IN when format is PEM but PEM is not supported.
5973
 * @return  WOLFSSL_BAD_FILETYPE if format is not supported.
5974
 */
5975
int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
5976
    long sz, int format)
5977
0
{
5978
0
    return ws_ctx_ssl_set_tmp_dh(ctx, NULL, buf, sz, format);
5979
0
}
5980
5981
#ifndef NO_FILESYSTEM
5982
5983
/* Set the temporary DH parameters file against the SSL context or SSL.
5984
 *
5985
 * @param [in, out] ctx     SSL context object.
5986
 * @param [in, out] ssl     SSL object.
5987
 * @param [in]      fname   Name of file to load.
5988
 * @param [in]      format  Format of data:
5989
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
5990
 * @return  1 on success.
5991
 * @return  BAD_FUNC_ARG when ctx and ssl NULL or fname is NULL.
5992
 * @return  NOT_COMPLED_IN when format is PEM but PEM is not supported.
5993
 * @return  WOLFSSL_BAD_FILETYPE if format is not supported.
5994
 */
5995
static int ws_ctx_ssl_set_tmp_dh_file(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
5996
    const char* fname, int format)
5997
0
{
5998
0
    int    res = 1;
5999
0
    int    ret;
6000
0
#ifndef WOLFSSL_SMALL_STACK
6001
0
    byte   stackBuffer[FILE_BUFFER_SIZE];
6002
0
#endif
6003
0
    StaticBuffer dhFile;
6004
0
    long   sz = 0;
6005
0
    void*  heap = WOLFSSL_HEAP(ctx, ssl);
6006
6007
    /* Setup buffer to hold file contents. */
6008
#ifdef WOLFSSL_SMALL_STACK
6009
    static_buffer_init(&dhFile);
6010
#else
6011
0
    static_buffer_init(&dhFile, stackBuffer, FILE_BUFFER_SIZE);
6012
0
#endif
6013
6014
    /* Validate parameters. */
6015
0
    if (((ctx == NULL) && (ssl == NULL)) || (fname == NULL)) {
6016
0
        res = BAD_FUNC_ARG;
6017
0
    }
6018
6019
0
    if (res == 1) {
6020
        /* Read file into static buffer. */
6021
0
        ret = wolfssl_read_file_static(fname, &dhFile, heap, DYNAMIC_TYPE_FILE,
6022
0
            &sz);
6023
0
        if (ret != 0) {
6024
0
            res = ret;
6025
0
        }
6026
0
    }
6027
0
    if (res == 1) {
6028
0
        if (ssl != NULL) {
6029
            /* Set encoded DH parameters into SSL. */
6030
0
            res = wolfSSL_SetTmpDH_buffer(ssl, dhFile.buffer, sz, format);
6031
0
        }
6032
0
        else {
6033
            /* Set encoded DH parameters into SSL context. */
6034
0
            res = wolfSSL_CTX_SetTmpDH_buffer(ctx, dhFile.buffer, sz, format);
6035
0
        }
6036
0
    }
6037
6038
    /* Dispose of any dynamically allocated data. */
6039
0
    static_buffer_free(&dhFile, heap, DYNAMIC_TYPE_FILE);
6040
0
    return res;
6041
0
}
6042
6043
/* Set the temporary DH parameters file against the SSL.
6044
 *
6045
 * @param [in, out] ssl     SSL object.
6046
 * @param [in]      fname   Name of file to load.
6047
 * @param [in]      format  Format of data:
6048
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
6049
 * @return  1 on success.
6050
 * @return  BAD_FUNC_ARG when ssl or fname is NULL.
6051
 * @return  NOT_COMPLED_IN when format is PEM but PEM is not supported.
6052
 * @return  WOLFSSL_BAD_FILETYPE if format is not supported.
6053
 */
6054
int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
6055
0
{
6056
0
    return ws_ctx_ssl_set_tmp_dh_file(NULL, ssl, fname, format);
6057
0
}
6058
6059
6060
/* Set the temporary DH parameters file against the SSL context.
6061
 *
6062
 * @param [in, out] ctx     SSL context object.
6063
 * @param [in]      fname   Name of file to load.
6064
 * @param [in]      format  Format of data:
6065
 *                            WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
6066
 * @return  1 on success.
6067
 * @return  BAD_FUNC_ARG when ctx or fname is NULL.
6068
 * @return  NOT_COMPLED_IN when format is PEM but PEM is not supported.
6069
 * @return  WOLFSSL_BAD_FILETYPE if format is not supported.
6070
 */
6071
int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
6072
0
{
6073
0
    return ws_ctx_ssl_set_tmp_dh_file(ctx, NULL, fname, format);
6074
0
}
6075
6076
#endif /* NO_FILESYSTEM */
6077
6078
#endif /* NO_CERTS */
6079
6080
#endif /* !NO_DH */
6081
6082
#endif /* !WOLFSSL_SSL_LOAD_INCLUDED */
6083