Coverage Report

Created: 2025-07-23 06:59

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