1 /* ssl.c
2  *
3  * Copyright (C) 2006-2021 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL.
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20  */
21 
22 
23 #ifdef HAVE_CONFIG_H
24     #include <config.h>
25 #endif
26 
27 #include <wolfssl/wolfcrypt/settings.h>
28 #if defined(OPENSSL_EXTRA) && !defined(_WIN32)
29     /* turn on GNU extensions for XVASPRINTF with wolfSSL_BIO_printf */
30     #undef  _GNU_SOURCE
31     #define _GNU_SOURCE
32 #endif
33 
34 #if !defined(WOLFCRYPT_ONLY) || defined(OPENSSL_EXTRA) || \
35     defined(OPENSSL_EXTRA_X509_SMALL)
36 
37 #include <wolfssl/internal.h>
38 #include <wolfssl/error-ssl.h>
39 #include <wolfssl/wolfcrypt/coding.h>
40 #include <wolfssl/wolfcrypt/kdf.h>
41 #ifdef NO_INLINE
42     #include <wolfssl/wolfcrypt/misc.h>
43 #else
44     #define WOLFSSL_MISC_INCLUDED
45     #include <wolfcrypt/src/misc.c>
46 #endif
47 
48 #ifdef HAVE_ERRNO_H
49     #include <errno.h>
50 #endif
51 
52 
53 #if !defined(WOLFSSL_ALLOW_NO_SUITES) && !defined(WOLFCRYPT_ONLY)
54     #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
55                 && !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK) \
56                 && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448)
57         #error "No cipher suites defined because DH disabled, ECC disabled, and no static suites defined. Please see top of README"
58     #endif
59     #ifdef WOLFSSL_CERT_GEN
60         /* need access to Cert struct for creating certificate */
61         #include <wolfssl/wolfcrypt/asn_public.h>
62     #endif
63 #endif
64 
65 #if !defined(WOLFCRYPT_ONLY) && (defined(OPENSSL_EXTRA)     \
66     || defined(OPENSSL_EXTRA_X509_SMALL)                    \
67     || defined(HAVE_WEBSERVER) || defined(WOLFSSL_KEY_GEN))
68     #include <wolfssl/openssl/evp.h>
69     /* openssl headers end, wolfssl internal headers next */
70 #endif
71 
72 #include <wolfssl/wolfcrypt/wc_encrypt.h>
73 
74 #ifndef NO_RSA
75     #include <wolfssl/wolfcrypt/rsa.h>
76 #endif
77 
78 #ifdef OPENSSL_EXTRA
79     /* openssl headers begin */
80     #include <wolfssl/openssl/ssl.h>
81     #include <wolfssl/openssl/aes.h>
82 #ifndef WOLFCRYPT_ONLY
83     #include <wolfssl/openssl/hmac.h>
84     #include <wolfssl/openssl/cmac.h>
85 #endif
86     #include <wolfssl/openssl/crypto.h>
87     #include <wolfssl/openssl/des.h>
88     #include <wolfssl/openssl/bn.h>
89     #include <wolfssl/openssl/buffer.h>
90     #include <wolfssl/openssl/dh.h>
91     #include <wolfssl/openssl/rsa.h>
92 #ifndef WOLFCRYPT_ONLY
93     #include <wolfssl/openssl/pem.h>
94 #endif
95     #include <wolfssl/openssl/ec.h>
96     #include <wolfssl/openssl/ec25519.h>
97     #include <wolfssl/openssl/ed25519.h>
98     #include <wolfssl/openssl/ec448.h>
99     #include <wolfssl/openssl/ed448.h>
100     #include <wolfssl/openssl/ecdsa.h>
101     #include <wolfssl/openssl/ecdh.h>
102     #include <wolfssl/openssl/err.h>
103     #include <wolfssl/openssl/modes.h>
104     #include <wolfssl/openssl/opensslv.h>
105     #include <wolfssl/openssl/rc4.h>
106     #include <wolfssl/openssl/stack.h>
107     #include <wolfssl/openssl/x509_vfy.h>
108     /* openssl headers end, wolfssl internal headers next */
109     #include <wolfssl/wolfcrypt/hmac.h>
110     #include <wolfssl/wolfcrypt/random.h>
111     #include <wolfssl/wolfcrypt/des3.h>
112     #include <wolfssl/wolfcrypt/ecc.h>
113     #include <wolfssl/wolfcrypt/md4.h>
114     #include <wolfssl/wolfcrypt/md5.h>
115     #include <wolfssl/wolfcrypt/arc4.h>
116     #include <wolfssl/wolfcrypt/idea.h>
117     #include <wolfssl/wolfcrypt/curve25519.h>
118     #include <wolfssl/wolfcrypt/ed25519.h>
119     #include <wolfssl/wolfcrypt/curve448.h>
120     #if defined(HAVE_PQC)
121         #include <wolfssl/wolfcrypt/falcon.h>
122     #endif
123     #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL)
124         #ifdef HAVE_OCSP
125             #include <wolfssl/openssl/ocsp.h>
126         #endif
127         #include <wolfssl/openssl/lhash.h>
128         #include <wolfssl/openssl/txt_db.h>
129     #endif /* WITH_STUNNEL */
130     #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
131         #include <wolfssl/wolfcrypt/sha512.h>
132     #endif
133     #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
134         && !defined(WC_NO_RNG)
135         #include <wolfssl/wolfcrypt/srp.h>
136     #endif
137     #if defined(HAVE_FIPS) || defined(HAVE_SELFTEST)
138         #include <wolfssl/wolfcrypt/pkcs7.h>
139     #endif
140     #if defined(OPENSSL_ALL) && defined(HAVE_PKCS7)
141         #include <wolfssl/openssl/pkcs7.h>
142     #endif /* OPENSSL_ALL && HAVE_PKCS7 */
143 #endif
144 
145 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
146     #include <wolfssl/openssl/x509v3.h>
147     int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi);
148     int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi);
149 #endif
150 
151 #if defined(WOLFSSL_QT)
152     #include <wolfssl/wolfcrypt/sha.h>
153 #endif
154 
155 #ifdef NO_ASN
156     #include <wolfssl/wolfcrypt/dh.h>
157 #endif
158 #endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */
159 
160 /*
161  * OPENSSL_COMPATIBLE_DEFAULTS:
162  *     Enable default behaviour that is compatible with OpenSSL. For example
163  *     SSL_CTX by default doesn't verify the loaded certs. Enabling this
164  *     should make porting to new projects easier.
165  * WOLFSSL_CHECK_ALERT_ON_ERR:
166  *     Check for alerts during the handshake in the event of an error.
167  */
168 
169 #define WOLFSSL_EVP_INCLUDED
170 #include "wolfcrypt/src/evp.c"
171 
172 #ifndef WOLFCRYPT_ONLY
173 
174 #ifdef OPENSSL_EXTRA
175     /* Global pointer to constant BN on */
176     static WOLFSSL_BIGNUM* bn_one = NULL;
177 
178     /* WOLFSSL_NO_OPENSSL_RAND_CB: Allows way to reduce code size for
179      *                OPENSSL_EXTRA where RAND callbacks are not used */
180     #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
181         static const WOLFSSL_RAND_METHOD* gRandMethods = NULL;
182         static int gRandMethodsInit = 0;
183         static wolfSSL_Mutex gRandMethodMutex;
184     #endif /* !WOLFSSL_NO_OPENSSL_RAND_CB */
185 #endif /* OPENSSL_EXTRA */
186 
187 #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
188 const WOLF_EC_NIST_NAME kNistCurves[] = {
189     {XSTR_SIZEOF("P-192"),   "P-192",   NID_X9_62_prime192v1},
190     {XSTR_SIZEOF("P-256"),   "P-256",   NID_X9_62_prime256v1},
191     {XSTR_SIZEOF("P-112"),   "P-112",   NID_secp112r1},
192     {XSTR_SIZEOF("P-112-2"), "P-112-2", NID_secp112r2},
193     {XSTR_SIZEOF("P-128"),   "P-128",   NID_secp128r1},
194     {XSTR_SIZEOF("P-128-2"), "P-128-2", NID_secp128r2},
195     {XSTR_SIZEOF("P-160"),   "P-160",   NID_secp160r1},
196     {XSTR_SIZEOF("P-160-2"), "P-160-2", NID_secp160r2},
197     {XSTR_SIZEOF("P-224"),   "P-224",   NID_secp224r1},
198     {XSTR_SIZEOF("P-384"),   "P-384",   NID_secp384r1},
199     {XSTR_SIZEOF("P-521"),   "P-521",   NID_secp521r1},
200     {XSTR_SIZEOF("K-160"),   "K-160",   NID_secp160k1},
201     {XSTR_SIZEOF("K-192"),   "K-192",   NID_secp192k1},
202     {XSTR_SIZEOF("K-224"),   "K-224",   NID_secp224k1},
203     {XSTR_SIZEOF("K-256"),   "K-256",   NID_secp256k1},
204     {XSTR_SIZEOF("B-160"),   "B-160",   NID_brainpoolP160r1},
205     {XSTR_SIZEOF("B-192"),   "B-192",   NID_brainpoolP192r1},
206     {XSTR_SIZEOF("B-224"),   "B-224",   NID_brainpoolP224r1},
207     {XSTR_SIZEOF("B-256"),   "B-256",   NID_brainpoolP256r1},
208     {XSTR_SIZEOF("B-320"),   "B-320",   NID_brainpoolP320r1},
209     {XSTR_SIZEOF("B-384"),   "B-384",   NID_brainpoolP384r1},
210     {XSTR_SIZEOF("B-512"),   "B-512",   NID_brainpoolP512r1},
211 #ifdef HAVE_PQC
212     {XSTR_SIZEOF("KYBER_LEVEL1"), "KYBER_LEVEL1", WOLFSSL_KYBER_LEVEL1},
213     {XSTR_SIZEOF("KYBER_LEVEL3"), "KYBER_LEVEL3", WOLFSSL_KYBER_LEVEL3},
214     {XSTR_SIZEOF("KYBER_LEVEL5"), "KYBER_LEVEL5", WOLFSSL_KYBER_LEVEL5},
215     {XSTR_SIZEOF("NTRU_HPS_LEVEL1"), "NTRU_HPS_LEVEL1", WOLFSSL_NTRU_HPS_LEVEL1},
216     {XSTR_SIZEOF("NTRU_HPS_LEVEL3"), "NTRU_HPS_LEVEL3", WOLFSSL_NTRU_HPS_LEVEL3},
217     {XSTR_SIZEOF("NTRU_HPS_LEVEL5"), "NTRU_HPS_LEVEL5", WOLFSSL_NTRU_HPS_LEVEL5},
218     {XSTR_SIZEOF("NTRU_HRSS_LEVEL3"), "NTRU_HRSS_LEVEL3", WOLFSSL_NTRU_HRSS_LEVEL3},
219     {XSTR_SIZEOF("SABER_LEVEL1"), "SABER_LEVEL1", WOLFSSL_SABER_LEVEL1},
220     {XSTR_SIZEOF("SABER_LEVEL3"), "SABER_LEVEL3", WOLFSSL_SABER_LEVEL3},
221     {XSTR_SIZEOF("SABER_LEVEL5"), "SABER_LEVEL5", WOLFSSL_SABER_LEVEL5},
222     {XSTR_SIZEOF("KYBER_90S_LEVEL1"), "KYBER_90S_LEVEL1", WOLFSSL_KYBER_90S_LEVEL1},
223     {XSTR_SIZEOF("KYBER_90S_LEVEL3"), "KYBER_90S_LEVEL3", WOLFSSL_KYBER_90S_LEVEL3},
224     {XSTR_SIZEOF("KYBER_90S_LEVEL5"), "KYBER_90S_LEVEL5", WOLFSSL_KYBER_90S_LEVEL5},
225     {XSTR_SIZEOF("P256_NTRU_HPS_LEVEL1"), "P256_NTRU_HPS_LEVEL1", WOLFSSL_P256_NTRU_HPS_LEVEL1},
226     {XSTR_SIZEOF("P384_NTRU_HPS_LEVEL3"), "P384_NTRU_HPS_LEVEL3", WOLFSSL_P384_NTRU_HPS_LEVEL3},
227     {XSTR_SIZEOF("P521_NTRU_HPS_LEVEL5"), "P521_NTRU_HPS_LEVEL5", WOLFSSL_P521_NTRU_HPS_LEVEL5},
228     {XSTR_SIZEOF("P384_NTRU_HRSS_LEVEL3"), "P384_NTRU_HRSS_LEVEL3", WOLFSSL_P384_NTRU_HRSS_LEVEL3},
229     {XSTR_SIZEOF("P256_SABER_LEVEL1"), "P256_SABER_LEVEL1", WOLFSSL_P256_SABER_LEVEL1},
230     {XSTR_SIZEOF("P384_SABER_LEVEL3"), "P384_SABER_LEVEL3", WOLFSSL_P384_SABER_LEVEL3},
231     {XSTR_SIZEOF("P521_SABER_LEVEL5"), "P521_SABER_LEVEL5", WOLFSSL_P521_SABER_LEVEL5},
232     {XSTR_SIZEOF("P256_KYBER_LEVEL1"), "P256_KYBER_LEVEL1", WOLFSSL_P256_KYBER_LEVEL1},
233     {XSTR_SIZEOF("P384_KYBER_LEVEL3"), "P384_KYBER_LEVEL3", WOLFSSL_P384_KYBER_LEVEL3},
234     {XSTR_SIZEOF("P521_KYBER_LEVEL5"), "P521_KYBER_LEVEL5", WOLFSSL_P521_KYBER_LEVEL5},
235     {XSTR_SIZEOF("P256_KYBER_90S_LEVEL1"), "P256_KYBER_90S_LEVEL1", WOLFSSL_P256_KYBER_90S_LEVEL1},
236     {XSTR_SIZEOF("P384_KYBER_90S_LEVEL3"), "P384_KYBER_90S_LEVEL3", WOLFSSL_P384_KYBER_90S_LEVEL3},
237     {XSTR_SIZEOF("P521_KYBER_90S_LEVEL5"), "P521_KYBER_90S_LEVEL5", WOLFSSL_P521_KYBER_90S_LEVEL5},
238 #endif
239     {0, NULL, 0},
240 };
241 #endif
242 
243 #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
244 #include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
245 #endif
246 
247 #ifdef WOLFSSL_SESSION_EXPORT
248 /* Used to import a serialized TLS session.
249  * WARNING: buf contains sensitive information about the state and is best to be
250  *          encrypted before storing if stored.
251  *
252  * @param ssl WOLFSSL structure to import the session into
253  * @param buf serialized session
254  * @param sz  size of buffer 'buf'
255  * @return the number of bytes read from buffer 'buf'
256  */
wolfSSL_tls_import(WOLFSSL * ssl,const unsigned char * buf,unsigned int sz)257 int wolfSSL_tls_import(WOLFSSL* ssl, const unsigned char* buf, unsigned int sz)
258 {
259     if (ssl == NULL || buf == NULL) {
260         return BAD_FUNC_ARG;
261     }
262     return wolfSSL_session_import_internal(ssl, buf, sz, WOLFSSL_EXPORT_TLS);
263 }
264 
265 
266 /* Used to export a serialized TLS session.
267  * WARNING: buf contains sensitive information about the state and is best to be
268  *          encrypted before storing if stored.
269  *
270  * @param ssl WOLFSSL structure to export the session from
271  * @param buf output of serialized session
272  * @param sz  size in bytes set in 'buf'
273  * @return the number of bytes written into buffer 'buf'
274  */
wolfSSL_tls_export(WOLFSSL * ssl,unsigned char * buf,unsigned int * sz)275 int wolfSSL_tls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
276 {
277     if (ssl == NULL || sz == NULL) {
278         return BAD_FUNC_ARG;
279     }
280     return wolfSSL_session_export_internal(ssl, buf, sz, WOLFSSL_EXPORT_TLS);
281 }
282 
283 #ifdef WOLFSSL_DTLS
wolfSSL_dtls_import(WOLFSSL * ssl,const unsigned char * buf,unsigned int sz)284 int wolfSSL_dtls_import(WOLFSSL* ssl, const unsigned char* buf, unsigned int sz)
285 {
286     WOLFSSL_ENTER("wolfSSL_session_import");
287 
288     if (ssl == NULL || buf == NULL) {
289         return BAD_FUNC_ARG;
290     }
291 
292     /* sanity checks on buffer and protocol are done in internal function */
293     return wolfSSL_session_import_internal(ssl, buf, sz, WOLFSSL_EXPORT_DTLS);
294 }
295 
296 
297 /* Sets the function to call for serializing the session. This function is
298  * called right after the handshake is completed. */
wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX * ctx,wc_dtls_export func)299 int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx, wc_dtls_export func)
300 {
301 
302     WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_export");
303 
304     /* purposefully allow func to be NULL */
305     if (ctx == NULL) {
306         return BAD_FUNC_ARG;
307     }
308 
309     ctx->dtls_export = func;
310 
311     return WOLFSSL_SUCCESS;
312 }
313 
314 
315 /* Sets the function in WOLFSSL struct to call for serializing the session. This
316  * function is called right after the handshake is completed. */
wolfSSL_dtls_set_export(WOLFSSL * ssl,wc_dtls_export func)317 int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func)
318 {
319 
320     WOLFSSL_ENTER("wolfSSL_dtls_set_export");
321 
322     /* purposefully allow func to be NULL */
323     if (ssl == NULL) {
324         return BAD_FUNC_ARG;
325     }
326 
327     ssl->dtls_export = func;
328 
329     return WOLFSSL_SUCCESS;
330 }
331 
332 
333 /* This function allows for directly serializing a session rather than using
334  * callbacks. It has less overhead by removing a temporary buffer and gives
335  * control over when the session gets serialized. When using callbacks the
336  * session is always serialized immediately after the handshake is finished.
337  *
338  * buf is the argument to contain the serialized session
339  * sz  is the size of the buffer passed in
340  * ssl is the WOLFSSL struct to serialize
341  * returns the size of serialized session on success, 0 on no action, and
342  *         negative value on error */
wolfSSL_dtls_export(WOLFSSL * ssl,unsigned char * buf,unsigned int * sz)343 int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
344 {
345     WOLFSSL_ENTER("wolfSSL_dtls_export");
346 
347     if (ssl == NULL || sz == NULL) {
348         return BAD_FUNC_ARG;
349     }
350 
351     if (buf == NULL) {
352         *sz = MAX_EXPORT_BUFFER;
353         return 0;
354     }
355 
356     /* if not DTLS do nothing */
357     if (!ssl->options.dtls) {
358         WOLFSSL_MSG("Currently only DTLS export is supported");
359         return 0;
360     }
361 
362     /* copy over keys, options, and dtls state struct */
363     return wolfSSL_session_export_internal(ssl, buf, sz, WOLFSSL_EXPORT_DTLS);
364 }
365 
366 
367 /* This function is similar to wolfSSL_dtls_export but only exports the portion
368  * of the WOLFSSL structure related to the state of the connection, i.e. peer
369  * sequence number, epoch, AEAD state etc.
370  *
371  * buf is the argument to contain the serialized state, if null then set "sz" to
372  *     buffer size required
373  * sz  is the size of the buffer passed in
374  * ssl is the WOLFSSL struct to serialize
375  * returns the size of serialized session on success, 0 on no action, and
376  *         negative value on error */
wolfSSL_dtls_export_state_only(WOLFSSL * ssl,unsigned char * buf,unsigned int * sz)377 int wolfSSL_dtls_export_state_only(WOLFSSL* ssl, unsigned char* buf,
378         unsigned int* sz)
379 {
380     WOLFSSL_ENTER("wolfSSL_dtls_export_state_only");
381 
382     if (ssl == NULL || sz == NULL) {
383         return BAD_FUNC_ARG;
384     }
385 
386     if (buf == NULL) {
387         *sz = MAX_EXPORT_STATE_BUFFER;
388         return 0;
389     }
390 
391     /* if not DTLS do nothing */
392     if (!ssl->options.dtls) {
393         WOLFSSL_MSG("Currently only DTLS export state is supported");
394         return 0;
395     }
396 
397     /* copy over keys, options, and dtls state struct */
398     return wolfSSL_dtls_export_state_internal(ssl, buf, *sz);
399 }
400 
401 
402 /* returns 0 on success */
wolfSSL_send_session(WOLFSSL * ssl)403 int wolfSSL_send_session(WOLFSSL* ssl)
404 {
405     int ret;
406     byte* buf;
407     word32 bufSz = MAX_EXPORT_BUFFER;
408 
409     WOLFSSL_ENTER("wolfSSL_send_session");
410 
411     if (ssl == NULL) {
412         return BAD_FUNC_ARG;
413     }
414 
415     buf = (byte*)XMALLOC(bufSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
416     if (buf == NULL) {
417         return MEMORY_E;
418     }
419 
420     /* if not DTLS do nothing */
421     if (!ssl->options.dtls) {
422         XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
423         WOLFSSL_MSG("Currently only DTLS export is supported");
424         return 0;
425     }
426 
427     /* copy over keys, options, and dtls state struct */
428     ret = wolfSSL_session_export_internal(ssl, buf, &bufSz, WOLFSSL_EXPORT_DTLS);
429     if (ret < 0) {
430         XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
431         return ret;
432     }
433 
434     /* if no error ret has size of buffer */
435     ret = ssl->dtls_export(ssl, buf, ret, NULL);
436     if (ret != WOLFSSL_SUCCESS) {
437         XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
438         return ret;
439     }
440 
441     XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
442     return 0;
443 }
444 #endif /* WOLFSSL_DTLS */
445 #endif /* WOLFSSL_SESSION_EXPORT */
446 
447 /* prevent multiple mutex initializations */
448 static volatile WOLFSSL_GLOBAL int initRefCount = 0;
449 static WOLFSSL_GLOBAL wolfSSL_Mutex count_mutex;   /* init ref count mutex */
450 static WOLFSSL_GLOBAL int count_mutex_valid = 0;
451 
452 /* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
453    WOLFSSL_METHOD pointer passed in is given to ctx to manage.
454    This function frees the passed in WOLFSSL_METHOD struct on failure and on
455    success is freed when ctx is freed.
456  */
wolfSSL_CTX_new_ex(WOLFSSL_METHOD * method,void * heap)457 WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap)
458 {
459     WOLFSSL_CTX* ctx = NULL;
460 
461     WOLFSSL_ENTER("wolfSSL_CTX_new_ex");
462 
463     if (initRefCount == 0) {
464         /* user no longer forced to call Init themselves */
465         int ret = wolfSSL_Init();
466         if (ret != WOLFSSL_SUCCESS) {
467             WOLFSSL_MSG("wolfSSL_Init failed");
468             WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
469             if (method != NULL) {
470                 XFREE(method, heap, DYNAMIC_TYPE_METHOD);
471             }
472             return NULL;
473         }
474     }
475 
476     if (method == NULL)
477         return ctx;
478 
479     ctx = (WOLFSSL_CTX*)XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX);
480     if (ctx) {
481         int ret;
482 
483         ret = InitSSL_Ctx(ctx, method, heap);
484     #ifdef WOLFSSL_STATIC_MEMORY
485         if (heap != NULL) {
486             ctx->onHeapHint = 1; /* free the memory back to heap when done */
487         }
488     #endif
489         if (ret < 0) {
490             WOLFSSL_MSG("Init CTX failed");
491             wolfSSL_CTX_free(ctx);
492             ctx = NULL;
493         }
494 #if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
495                            && !defined(NO_SHA256) && !defined(WC_NO_RNG)
496         else {
497             ctx->srp = (Srp*)XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP);
498             if (ctx->srp == NULL){
499                 WOLFSSL_MSG("Init CTX failed");
500                 wolfSSL_CTX_free(ctx);
501                 return NULL;
502             }
503             XMEMSET(ctx->srp, 0, sizeof(Srp));
504         }
505 #endif
506     }
507     else {
508         WOLFSSL_MSG("Alloc CTX failed, method freed");
509         XFREE(method, heap, DYNAMIC_TYPE_METHOD);
510     }
511 
512 #ifdef OPENSSL_COMPATIBLE_DEFAULTS
513     if (ctx) {
514         wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
515         wolfSSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
516         if (wolfSSL_CTX_set_min_proto_version(ctx,
517                 SSL3_VERSION) != WOLFSSL_SUCCESS ||
518 #ifdef HAVE_ANON
519                 wolfSSL_CTX_allow_anon_cipher(ctx) != WOLFSSL_SUCCESS ||
520 #endif
521                 wolfSSL_CTX_set_group_messages(ctx) != WOLFSSL_SUCCESS) {
522             WOLFSSL_MSG("Setting OpenSSL CTX defaults failed");
523             wolfSSL_CTX_free(ctx);
524             ctx = NULL;
525         }
526     }
527 #endif
528 
529     WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
530     return ctx;
531 }
532 
533 
534 WOLFSSL_ABI
wolfSSL_CTX_new(WOLFSSL_METHOD * method)535 WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
536 {
537 #ifdef WOLFSSL_HEAP_TEST
538     /* if testing the heap hint then set top level CTX to have test value */
539     return wolfSSL_CTX_new_ex(method, (void*)WOLFSSL_HEAP_TEST);
540 #else
541     return wolfSSL_CTX_new_ex(method, NULL);
542 #endif
543 }
544 
545 #ifdef OPENSSL_EXTRA
546 /* increases CTX reference count to track proper time to "free" */
wolfSSL_CTX_up_ref(WOLFSSL_CTX * ctx)547 int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx)
548 {
549     int refCount = SSL_CTX_RefCount(ctx, 1);
550     return ((refCount > 1) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
551 }
552 #endif
553 
554 WOLFSSL_ABI
wolfSSL_CTX_free(WOLFSSL_CTX * ctx)555 void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
556 {
557     WOLFSSL_ENTER("SSL_CTX_free");
558     if (ctx) {
559 #if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
560 && !defined(NO_SHA256) && !defined(WC_NO_RNG)
561         if (ctx->srp != NULL) {
562             if (ctx->srp_password != NULL){
563                 XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
564                 ctx->srp_password = NULL;
565             }
566             wc_SrpTerm(ctx->srp);
567             XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
568             ctx->srp = NULL;
569         }
570 #endif
571         FreeSSL_Ctx(ctx);
572     }
573 
574     WOLFSSL_LEAVE("SSL_CTX_free", 0);
575 }
576 
577 
578 #ifdef HAVE_ENCRYPT_THEN_MAC
579 /**
580  * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
581  * The default value: enabled.
582  *
583  * ctx  SSL/TLS context.
584  * set  Whether to allow or not: 1 is allow and 0 is disallow.
585  * returns WOLFSSL_SUCCESS
586  */
wolfSSL_CTX_AllowEncryptThenMac(WOLFSSL_CTX * ctx,int set)587 int wolfSSL_CTX_AllowEncryptThenMac(WOLFSSL_CTX *ctx, int set)
588 {
589     ctx->disallowEncThenMac = !set;
590     return WOLFSSL_SUCCESS;
591 }
592 
593 /**
594  * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
595  * The default value comes from context.
596  *
597  * ctx  SSL/TLS context.
598  * set  Whether to allow or not: 1 is allow and 0 is disallow.
599  * returns WOLFSSL_SUCCESS
600  */
wolfSSL_AllowEncryptThenMac(WOLFSSL * ssl,int set)601 int wolfSSL_AllowEncryptThenMac(WOLFSSL *ssl, int set)
602 {
603     ssl->options.disallowEncThenMac = !set;
604     return WOLFSSL_SUCCESS;
605 }
606 #endif
607 
608 #ifdef SINGLE_THREADED
609 /* no locking in single threaded mode, allow a CTX level rng to be shared with
610  * WOLFSSL objects, WOLFSSL_SUCCESS on ok */
wolfSSL_CTX_new_rng(WOLFSSL_CTX * ctx)611 int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
612 {
613     WC_RNG* rng;
614     int     ret;
615 
616     if (ctx == NULL) {
617         return BAD_FUNC_ARG;
618     }
619 
620     rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
621     if (rng == NULL) {
622         return MEMORY_E;
623     }
624 
625 #ifndef HAVE_FIPS
626     ret = wc_InitRng_ex(rng, ctx->heap, ctx->devId);
627 #else
628     ret = wc_InitRng(rng);
629 #endif
630     if (ret != 0) {
631         XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
632         return ret;
633     }
634 
635     ctx->rng = rng;
636     return WOLFSSL_SUCCESS;
637 }
638 #endif
639 
640 
641 WOLFSSL_ABI
wolfSSL_new(WOLFSSL_CTX * ctx)642 WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
643 {
644     WOLFSSL* ssl = NULL;
645     int ret = 0;
646 
647     WOLFSSL_ENTER("SSL_new");
648 
649     if (ctx == NULL)
650         return ssl;
651 
652     ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
653     if (ssl)
654         if ( (ret = InitSSL(ssl, ctx, 0)) < 0) {
655             FreeSSL(ssl, ctx->heap);
656             ssl = 0;
657         }
658 
659     WOLFSSL_LEAVE("SSL_new", ret);
660     (void)ret;
661 
662     return ssl;
663 }
664 
665 
666 WOLFSSL_ABI
wolfSSL_free(WOLFSSL * ssl)667 void wolfSSL_free(WOLFSSL* ssl)
668 {
669     WOLFSSL_ENTER("SSL_free");
670     if (ssl)
671         FreeSSL(ssl, ssl->ctx->heap);
672     WOLFSSL_LEAVE("SSL_free", 0);
673 }
674 
675 
wolfSSL_is_server(WOLFSSL * ssl)676 int wolfSSL_is_server(WOLFSSL* ssl)
677 {
678     if (ssl == NULL)
679         return BAD_FUNC_ARG;
680     return ssl->options.side == WOLFSSL_SERVER_END;
681 }
682 
683 #ifdef HAVE_WRITE_DUP
684 
685 /*
686  * Release resources around WriteDup object
687  *
688  * ssl WOLFSSL object
689  *
690  * no return, destruction so make best attempt
691 */
FreeWriteDup(WOLFSSL * ssl)692 void FreeWriteDup(WOLFSSL* ssl)
693 {
694     int doFree = 0;
695 
696     WOLFSSL_ENTER("FreeWriteDup");
697 
698     if (ssl->dupWrite) {
699         if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
700             ssl->dupWrite->dupCount--;
701             if (ssl->dupWrite->dupCount == 0) {
702                 doFree = 1;
703             } else {
704                 WOLFSSL_MSG("WriteDup count not zero, no full free");
705             }
706             wc_UnLockMutex(&ssl->dupWrite->dupMutex);
707         }
708     }
709 
710     if (doFree) {
711         WOLFSSL_MSG("Doing WriteDup full free, count to zero");
712         wc_FreeMutex(&ssl->dupWrite->dupMutex);
713         XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
714     }
715 }
716 
717 
718 /*
719  * duplicate existing ssl members into dup needed for writing
720  *
721  * dup write only WOLFSSL
722  * ssl existing WOLFSSL
723  *
724  * 0 on success
725 */
DupSSL(WOLFSSL * dup,WOLFSSL * ssl)726 static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
727 {
728     /* shared dupWrite setup */
729     ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
730                                        DYNAMIC_TYPE_WRITEDUP);
731     if (ssl->dupWrite == NULL) {
732         return MEMORY_E;
733     }
734     XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
735 
736     if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
737         XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
738         ssl->dupWrite = NULL;
739         return BAD_MUTEX_E;
740     }
741     ssl->dupWrite->dupCount = 2;    /* both sides have a count to start */
742     dup->dupWrite = ssl->dupWrite; /* each side uses */
743 
744     /* copy write parts over to dup writer */
745     XMEMCPY(&dup->specs,   &ssl->specs,   sizeof(CipherSpecs));
746     XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
747     XMEMCPY(&dup->keys,    &ssl->keys,    sizeof(Keys));
748     XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
749     /* dup side now owns encrypt/write ciphers */
750     XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
751 
752     dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
753     dup->CBIOSend = ssl->CBIOSend;
754 #ifdef OPENSSL_EXTRA
755     dup->cbioFlag = ssl->cbioFlag;
756 #endif
757     dup->wfd    = ssl->wfd;
758     dup->wflags = ssl->wflags;
759 #ifndef WOLFSSL_AEAD_ONLY
760     dup->hmac   = ssl->hmac;
761 #endif
762 #ifdef HAVE_TRUNCATED_HMAC
763     dup->truncated_hmac = ssl->truncated_hmac;
764 #endif
765 
766     /* unique side dup setup */
767     dup->dupSide = WRITE_DUP_SIDE;
768     ssl->dupSide = READ_DUP_SIDE;
769 
770     return 0;
771 }
772 
773 
774 /*
775  * duplicate a WOLFSSL object post handshake for writing only
776  * turn existing object into read only.  Allows concurrent access from two
777  * different threads.
778  *
779  * ssl existing WOLFSSL object
780  *
781  * return dup'd WOLFSSL object on success
782 */
wolfSSL_write_dup(WOLFSSL * ssl)783 WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
784 {
785     WOLFSSL* dup = NULL;
786     int ret = 0;
787 
788     (void)ret;
789     WOLFSSL_ENTER("wolfSSL_write_dup");
790 
791     if (ssl == NULL) {
792         return ssl;
793     }
794 
795     if (ssl->options.handShakeDone == 0) {
796         WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
797         return NULL;
798     }
799 
800     if (ssl->dupWrite) {
801         WOLFSSL_MSG("wolfSSL_write_dup already called once");
802         return NULL;
803     }
804 
805     dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
806     if (dup) {
807         if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
808             FreeSSL(dup, ssl->ctx->heap);
809             dup = NULL;
810         } else if ( (ret = DupSSL(dup, ssl)) < 0) {
811             FreeSSL(dup, ssl->ctx->heap);
812             dup = NULL;
813         }
814     }
815 
816     WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
817 
818     return dup;
819 }
820 
821 
822 /*
823  * Notify write dup side of fatal error or close notify
824  *
825  * ssl WOLFSSL object
826  * err Notify err
827  *
828  * 0 on success
829 */
NotifyWriteSide(WOLFSSL * ssl,int err)830 int NotifyWriteSide(WOLFSSL* ssl, int err)
831 {
832     int ret;
833 
834     WOLFSSL_ENTER("NotifyWriteSide");
835 
836     ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
837     if (ret == 0) {
838         ssl->dupWrite->dupErr = err;
839         ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
840     }
841 
842     return ret;
843 }
844 
845 
846 #endif /* HAVE_WRITE_DUP */
847 
848 
849 #ifdef HAVE_POLY1305
850 /* set if to use old poly 1 for yes 0 to use new poly */
wolfSSL_use_old_poly(WOLFSSL * ssl,int value)851 int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
852 {
853     (void)ssl;
854     (void)value;
855 
856 #ifndef WOLFSSL_NO_TLS12
857     WOLFSSL_ENTER("SSL_use_old_poly");
858     WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
859             "is depreciated");
860     ssl->options.oldPoly = (word16)value;
861     WOLFSSL_LEAVE("SSL_use_old_poly", 0);
862 #endif
863     return 0;
864 }
865 #endif
866 
867 
868 WOLFSSL_ABI
wolfSSL_set_fd(WOLFSSL * ssl,int fd)869 int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
870 {
871     int ret;
872 
873     WOLFSSL_ENTER("SSL_set_fd");
874 
875     if (ssl == NULL) {
876         return BAD_FUNC_ARG;
877     }
878 
879     ret = wolfSSL_set_read_fd(ssl, fd);
880     if (ret == WOLFSSL_SUCCESS) {
881         ret = wolfSSL_set_write_fd(ssl, fd);
882     }
883 
884     return ret;
885 }
886 
887 
wolfSSL_set_read_fd(WOLFSSL * ssl,int fd)888 int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd)
889 {
890     WOLFSSL_ENTER("SSL_set_read_fd");
891 
892     if (ssl == NULL) {
893         return BAD_FUNC_ARG;
894     }
895 
896     ssl->rfd = fd;      /* not used directly to allow IO callbacks */
897     ssl->IOCB_ReadCtx  = &ssl->rfd;
898 
899     #ifdef WOLFSSL_DTLS
900         if (ssl->options.dtls) {
901             ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
902             ssl->buffers.dtlsCtx.rfd = fd;
903         }
904     #endif
905 
906     WOLFSSL_LEAVE("SSL_set_read_fd", WOLFSSL_SUCCESS);
907     return WOLFSSL_SUCCESS;
908 }
909 
910 
wolfSSL_set_write_fd(WOLFSSL * ssl,int fd)911 int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd)
912 {
913     WOLFSSL_ENTER("SSL_set_write_fd");
914 
915     if (ssl == NULL) {
916         return BAD_FUNC_ARG;
917     }
918 
919     ssl->wfd = fd;      /* not used directly to allow IO callbacks */
920     ssl->IOCB_WriteCtx  = &ssl->wfd;
921 
922     #ifdef WOLFSSL_DTLS
923         if (ssl->options.dtls) {
924             ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
925             ssl->buffers.dtlsCtx.wfd = fd;
926         }
927     #endif
928 
929     WOLFSSL_LEAVE("SSL_set_write_fd", WOLFSSL_SUCCESS);
930     return WOLFSSL_SUCCESS;
931 }
932 
933 
934 /**
935   * Get the name of cipher at priority level passed in.
936   */
wolfSSL_get_cipher_list(int priority)937 char* wolfSSL_get_cipher_list(int priority)
938 {
939     const CipherSuiteInfo* ciphers = GetCipherNames();
940 
941     if (priority >= GetCipherNamesSize() || priority < 0) {
942         return 0;
943     }
944 
945     return (char*)ciphers[priority].name;
946 }
947 
948 
949 /**
950   * Get the name of cipher at priority level passed in.
951   */
wolfSSL_get_cipher_list_ex(WOLFSSL * ssl,int priority)952 char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority)
953 {
954 
955     if (ssl == NULL) {
956         return NULL;
957     }
958     else {
959         const char* cipher;
960 
961         if ((cipher = wolfSSL_get_cipher_name_internal(ssl)) != NULL) {
962             if (priority == 0) {
963                 return (char*)cipher;
964             }
965             else {
966                 return NULL;
967             }
968         }
969         else {
970             return wolfSSL_get_cipher_list(priority);
971         }
972     }
973 }
974 
975 
wolfSSL_get_ciphers(char * buf,int len)976 int wolfSSL_get_ciphers(char* buf, int len)
977 {
978     const CipherSuiteInfo* ciphers = GetCipherNames();
979     int ciphersSz = GetCipherNamesSize();
980     int i;
981     int cipherNameSz;
982 
983     if (buf == NULL || len <= 0)
984         return BAD_FUNC_ARG;
985 
986     /* Add each member to the buffer delimited by a : */
987     for (i = 0; i < ciphersSz; i++) {
988         cipherNameSz = (int)XSTRLEN(ciphers[i].name);
989         if (cipherNameSz + 1 < len) {
990             XSTRNCPY(buf, ciphers[i].name, len);
991             buf += cipherNameSz;
992 
993             if (i < ciphersSz - 1)
994                 *buf++ = ':';
995             *buf = 0;
996 
997             len -= cipherNameSz + 1;
998         }
999         else
1000             return BUFFER_E;
1001     }
1002     return WOLFSSL_SUCCESS;
1003 }
1004 
1005 
1006 #ifndef NO_ERROR_STRINGS
1007 /* places a list of all supported cipher suites in TLS_* format into "buf"
1008  * return WOLFSSL_SUCCESS on success */
wolfSSL_get_ciphers_iana(char * buf,int len)1009 int wolfSSL_get_ciphers_iana(char* buf, int len)
1010 {
1011     const CipherSuiteInfo* ciphers = GetCipherNames();
1012     int ciphersSz = GetCipherNamesSize();
1013     int i;
1014     int cipherNameSz;
1015 
1016     if (buf == NULL || len <= 0)
1017         return BAD_FUNC_ARG;
1018 
1019     /* Add each member to the buffer delimited by a : */
1020     for (i = 0; i < ciphersSz; i++) {
1021 #ifndef NO_CIPHER_SUITE_ALIASES
1022         if (ciphers[i].flags & WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS)
1023             continue;
1024 #endif
1025         cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana);
1026         if (cipherNameSz + 1 < len) {
1027             XSTRNCPY(buf, ciphers[i].name_iana, len);
1028             buf += cipherNameSz;
1029 
1030             if (i < ciphersSz - 1)
1031                 *buf++ = ':';
1032             *buf = 0;
1033 
1034             len -= cipherNameSz + 1;
1035         }
1036         else
1037             return BUFFER_E;
1038     }
1039     return WOLFSSL_SUCCESS;
1040 }
1041 #endif /* NO_ERROR_STRINGS */
1042 
1043 
wolfSSL_get_shared_ciphers(WOLFSSL * ssl,char * buf,int len)1044 const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
1045 {
1046     const char* cipher;
1047 
1048     if (ssl == NULL)
1049         return NULL;
1050 
1051     cipher = wolfSSL_get_cipher_name_iana(ssl);
1052     len = min(len, (int)(XSTRLEN(cipher) + 1));
1053     XMEMCPY(buf, cipher, len);
1054     return buf;
1055 }
1056 
wolfSSL_get_fd(const WOLFSSL * ssl)1057 int wolfSSL_get_fd(const WOLFSSL* ssl)
1058 {
1059     int fd = -1;
1060     WOLFSSL_ENTER("SSL_get_fd");
1061     if (ssl) {
1062         fd = ssl->rfd;
1063     }
1064     WOLFSSL_LEAVE("SSL_get_fd", fd);
1065     return fd;
1066 }
1067 
1068 
wolfSSL_dtls(WOLFSSL * ssl)1069 int wolfSSL_dtls(WOLFSSL* ssl)
1070 {
1071     int dtlsOpt = 0;
1072     if (ssl)
1073         dtlsOpt = ssl->options.dtls;
1074     return dtlsOpt;
1075 }
1076 
1077 #if !defined(NO_CERTS)
1078 /* Set whether mutual authentication is required for connections.
1079  * Server side only.
1080  *
1081  * ctx  The SSL/TLS CTX object.
1082  * req  1 to indicate required and 0 when not.
1083  * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and
1084  * 0 on success.
1085  */
wolfSSL_CTX_mutual_auth(WOLFSSL_CTX * ctx,int req)1086 int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req)
1087 {
1088     if (ctx == NULL)
1089         return BAD_FUNC_ARG;
1090     if (ctx->method->side == WOLFSSL_CLIENT_END)
1091         return SIDE_ERROR;
1092 
1093     ctx->mutualAuth = (byte)req;
1094 
1095     return 0;
1096 }
1097 
1098 /* Set whether mutual authentication is required for the connection.
1099  * Server side only.
1100  *
1101  * ssl  The SSL/TLS object.
1102  * req  1 to indicate required and 0 when not.
1103  * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
1104  * SIDE_ERROR when not a client and 0 on success.
1105  */
wolfSSL_mutual_auth(WOLFSSL * ssl,int req)1106 int wolfSSL_mutual_auth(WOLFSSL* ssl, int req)
1107 {
1108     if (ssl == NULL)
1109         return BAD_FUNC_ARG;
1110     if (ssl->options.side == WOLFSSL_SERVER_END)
1111         return SIDE_ERROR;
1112 
1113     ssl->options.mutualAuth = (word16)req;
1114 
1115     return 0;
1116 }
1117 #endif /* NO_CERTS */
1118 
1119 #ifdef WOLFSSL_WOLFSENTRY_HOOKS
1120 
wolfSSL_CTX_set_AcceptFilter(WOLFSSL_CTX * ctx,NetworkFilterCallback_t AcceptFilter,void * AcceptFilter_arg)1121 int wolfSSL_CTX_set_AcceptFilter(
1122     WOLFSSL_CTX *ctx,
1123     NetworkFilterCallback_t AcceptFilter,
1124     void *AcceptFilter_arg)
1125 {
1126     if (ctx == NULL)
1127         return BAD_FUNC_ARG;
1128     ctx->AcceptFilter = AcceptFilter;
1129     ctx->AcceptFilter_arg = AcceptFilter_arg;
1130     return 0;
1131 }
1132 
wolfSSL_set_AcceptFilter(WOLFSSL * ssl,NetworkFilterCallback_t AcceptFilter,void * AcceptFilter_arg)1133 int wolfSSL_set_AcceptFilter(
1134     WOLFSSL *ssl,
1135     NetworkFilterCallback_t AcceptFilter,
1136     void *AcceptFilter_arg)
1137 {
1138     if (ssl == NULL)
1139         return BAD_FUNC_ARG;
1140     ssl->AcceptFilter = AcceptFilter;
1141     ssl->AcceptFilter_arg = AcceptFilter_arg;
1142     return 0;
1143 }
1144 
wolfSSL_CTX_set_ConnectFilter(WOLFSSL_CTX * ctx,NetworkFilterCallback_t ConnectFilter,void * ConnectFilter_arg)1145 int wolfSSL_CTX_set_ConnectFilter(
1146     WOLFSSL_CTX *ctx,
1147     NetworkFilterCallback_t ConnectFilter,
1148     void *ConnectFilter_arg)
1149 {
1150     if (ctx == NULL)
1151         return BAD_FUNC_ARG;
1152     ctx->ConnectFilter = ConnectFilter;
1153     ctx->ConnectFilter_arg = ConnectFilter_arg;
1154     return 0;
1155 }
1156 
wolfSSL_set_ConnectFilter(WOLFSSL * ssl,NetworkFilterCallback_t ConnectFilter,void * ConnectFilter_arg)1157 int wolfSSL_set_ConnectFilter(
1158     WOLFSSL *ssl,
1159     NetworkFilterCallback_t ConnectFilter,
1160     void *ConnectFilter_arg)
1161 {
1162     if (ssl == NULL)
1163         return BAD_FUNC_ARG;
1164     ssl->ConnectFilter = ConnectFilter;
1165     ssl->ConnectFilter_arg = ConnectFilter_arg;
1166     return 0;
1167 }
1168 
1169 #endif /* WOLFSSL_WOLFSENTRY_HOOKS */
1170 
1171 #ifndef WOLFSSL_LEANPSK
wolfSSL_dtls_set_peer(WOLFSSL * ssl,void * peer,unsigned int peerSz)1172 int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
1173 {
1174 #ifdef WOLFSSL_DTLS
1175     void* sa;
1176 
1177     if (ssl == NULL)
1178         return WOLFSSL_FAILURE;
1179 
1180     sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
1181     if (sa != NULL) {
1182         if (ssl->buffers.dtlsCtx.peer.sa != NULL) {
1183             XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
1184             ssl->buffers.dtlsCtx.peer.sa = NULL;
1185         }
1186         XMEMCPY(sa, peer, peerSz);
1187         ssl->buffers.dtlsCtx.peer.sa = sa;
1188         ssl->buffers.dtlsCtx.peer.sz = peerSz;
1189         return WOLFSSL_SUCCESS;
1190     }
1191     return WOLFSSL_FAILURE;
1192 #else
1193     (void)ssl;
1194     (void)peer;
1195     (void)peerSz;
1196     return WOLFSSL_NOT_IMPLEMENTED;
1197 #endif
1198 }
1199 
wolfSSL_dtls_get_peer(WOLFSSL * ssl,void * peer,unsigned int * peerSz)1200 int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
1201 {
1202 #ifdef WOLFSSL_DTLS
1203     if (ssl == NULL) {
1204         return WOLFSSL_FAILURE;
1205     }
1206 
1207     if (peer != NULL && peerSz != NULL
1208             && *peerSz >= ssl->buffers.dtlsCtx.peer.sz
1209             && ssl->buffers.dtlsCtx.peer.sa != NULL) {
1210         *peerSz = ssl->buffers.dtlsCtx.peer.sz;
1211         XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
1212         return WOLFSSL_SUCCESS;
1213     }
1214     return WOLFSSL_FAILURE;
1215 #else
1216     (void)ssl;
1217     (void)peer;
1218     (void)peerSz;
1219     return WOLFSSL_NOT_IMPLEMENTED;
1220 #endif
1221 }
1222 
1223 
1224 #if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
1225 
wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX * ctx)1226 int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
1227 {
1228     WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp()");
1229 
1230     if (ctx == NULL)
1231         return BAD_FUNC_ARG;
1232 
1233     ctx->dtlsSctp = 1;
1234     return WOLFSSL_SUCCESS;
1235 }
1236 
1237 
wolfSSL_dtls_set_sctp(WOLFSSL * ssl)1238 int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
1239 {
1240     WOLFSSL_ENTER("wolfSSL_dtls_set_sctp()");
1241 
1242     if (ssl == NULL)
1243         return BAD_FUNC_ARG;
1244 
1245     ssl->options.dtlsSctp = 1;
1246     return WOLFSSL_SUCCESS;
1247 }
1248 
1249 #endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */
1250 
1251 #if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
1252                                                            defined(WOLFSSL_DTLS)
1253 
wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX * ctx,word16 newMtu)1254 int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
1255 {
1256     if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
1257         return BAD_FUNC_ARG;
1258 
1259     ctx->dtlsMtuSz = newMtu;
1260     return WOLFSSL_SUCCESS;
1261 }
1262 
1263 
wolfSSL_dtls_set_mtu(WOLFSSL * ssl,word16 newMtu)1264 int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
1265 {
1266     if (ssl == NULL)
1267         return BAD_FUNC_ARG;
1268 
1269     if (newMtu > MAX_RECORD_SIZE) {
1270         ssl->error = BAD_FUNC_ARG;
1271         return WOLFSSL_FAILURE;
1272     }
1273 
1274     ssl->dtlsMtuSz = newMtu;
1275     return WOLFSSL_SUCCESS;
1276 }
1277 
1278 #endif /* WOLFSSL_DTLS && (WOLFSSL_SCTP || WOLFSSL_DTLS_MTU) */
1279 
1280 
1281 #ifdef WOLFSSL_DTLS_DROP_STATS
1282 
wolfSSL_dtls_get_drop_stats(WOLFSSL * ssl,word32 * macDropCount,word32 * replayDropCount)1283 int wolfSSL_dtls_get_drop_stats(WOLFSSL* ssl,
1284                                 word32* macDropCount, word32* replayDropCount)
1285 {
1286     int ret;
1287 
1288     WOLFSSL_ENTER("wolfSSL_dtls_get_drop_stats()");
1289 
1290     if (ssl == NULL)
1291         ret = BAD_FUNC_ARG;
1292     else {
1293         ret = WOLFSSL_SUCCESS;
1294         if (macDropCount != NULL)
1295             *macDropCount = ssl->macDropCount;
1296         if (replayDropCount != NULL)
1297             *replayDropCount = ssl->replayDropCount;
1298     }
1299 
1300     WOLFSSL_LEAVE("wolfSSL_dtls_get_drop_stats()", ret);
1301     return ret;
1302 }
1303 
1304 #endif /* WOLFSSL_DTLS_DROP_STATS */
1305 
1306 
1307 #if defined(WOLFSSL_MULTICAST)
1308 
wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX * ctx,word16 id)1309 int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, word16 id)
1310 {
1311     int ret = 0;
1312 
1313     WOLFSSL_ENTER("wolfSSL_CTX_mcast_set_member_id()");
1314 
1315     if (ctx == NULL || id > 255)
1316         ret = BAD_FUNC_ARG;
1317 
1318     if (ret == 0) {
1319         ctx->haveEMS = 0;
1320         ctx->haveMcast = 1;
1321         ctx->mcastID = (byte)id;
1322 #ifndef WOLFSSL_USER_IO
1323         ctx->CBIORecv = EmbedReceiveFromMcast;
1324 #endif /* WOLFSSL_USER_IO */
1325 
1326         ret = WOLFSSL_SUCCESS;
1327     }
1328     WOLFSSL_LEAVE("wolfSSL_CTX_mcast_set_member_id()", ret);
1329     return ret;
1330 }
1331 
wolfSSL_mcast_get_max_peers(void)1332 int wolfSSL_mcast_get_max_peers(void)
1333 {
1334     return WOLFSSL_MULTICAST_PEERS;
1335 }
1336 
1337 #ifdef WOLFSSL_DTLS
UpdateHighwaterMark(word32 cur,word32 first,word32 second,word32 high)1338 static WC_INLINE word32 UpdateHighwaterMark(word32 cur, word32 first,
1339                                          word32 second, word32 high)
1340 {
1341     word32 newCur = 0;
1342 
1343     if (cur < first)
1344         newCur = first;
1345     else if (cur < second)
1346         newCur = second;
1347     else if (cur < high)
1348         newCur = high;
1349 
1350     return newCur;
1351 }
1352 #endif /* WOLFSSL_DTLS */
1353 
1354 
wolfSSL_set_secret(WOLFSSL * ssl,word16 epoch,const byte * preMasterSecret,word32 preMasterSz,const byte * clientRandom,const byte * serverRandom,const byte * suite)1355 int wolfSSL_set_secret(WOLFSSL* ssl, word16 epoch,
1356                        const byte* preMasterSecret, word32 preMasterSz,
1357                        const byte* clientRandom, const byte* serverRandom,
1358                        const byte* suite)
1359 {
1360     int ret = 0;
1361 
1362     WOLFSSL_ENTER("wolfSSL_set_secret()");
1363 
1364     if (ssl == NULL || preMasterSecret == NULL ||
1365         preMasterSz == 0 || preMasterSz > ENCRYPT_LEN ||
1366         clientRandom == NULL || serverRandom == NULL || suite == NULL) {
1367 
1368         ret = BAD_FUNC_ARG;
1369     }
1370 
1371     if (ret == 0 && ssl->arrays->preMasterSecret == NULL) {
1372         ssl->arrays->preMasterSz = ENCRYPT_LEN;
1373         ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN, ssl->heap,
1374             DYNAMIC_TYPE_SECRET);
1375         if (ssl->arrays->preMasterSecret == NULL) {
1376             ret = MEMORY_E;
1377         }
1378     }
1379 
1380     if (ret == 0) {
1381         XMEMCPY(ssl->arrays->preMasterSecret, preMasterSecret, preMasterSz);
1382         XMEMSET(ssl->arrays->preMasterSecret + preMasterSz, 0, ENCRYPT_LEN - preMasterSz);
1383         ssl->arrays->preMasterSz = preMasterSz;
1384         XMEMCPY(ssl->arrays->clientRandom, clientRandom, RAN_LEN);
1385         XMEMCPY(ssl->arrays->serverRandom, serverRandom, RAN_LEN);
1386         ssl->options.cipherSuite0 = suite[0];
1387         ssl->options.cipherSuite = suite[1];
1388 
1389         ret = SetCipherSpecs(ssl);
1390     }
1391 
1392     if (ret == 0)
1393         ret = MakeTlsMasterSecret(ssl);
1394 
1395     if (ret == 0) {
1396         ssl->keys.encryptionOn = 1;
1397         ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
1398     }
1399 
1400     if (ret == 0) {
1401         if (ssl->options.dtls) {
1402         #ifdef WOLFSSL_DTLS
1403             WOLFSSL_DTLS_PEERSEQ* peerSeq;
1404             int i;
1405 
1406             ssl->keys.dtls_epoch = epoch;
1407             for (i = 0, peerSeq = ssl->keys.peerSeq;
1408                  i < WOLFSSL_DTLS_PEERSEQ_SZ;
1409                  i++, peerSeq++) {
1410 
1411                 peerSeq->nextEpoch = epoch;
1412                 peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
1413                 peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
1414                 peerSeq->nextSeq_lo = 0;
1415                 peerSeq->nextSeq_hi = 0;
1416                 XMEMCPY(peerSeq->prevWindow, peerSeq->window, DTLS_SEQ_SZ);
1417                 XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
1418                 peerSeq->highwaterMark = UpdateHighwaterMark(0,
1419                         ssl->ctx->mcastFirstSeq,
1420                         ssl->ctx->mcastSecondSeq,
1421                         ssl->ctx->mcastMaxSeq);
1422             }
1423         #else
1424             (void)epoch;
1425         #endif
1426         }
1427         FreeHandshakeResources(ssl);
1428         ret = WOLFSSL_SUCCESS;
1429     }
1430     else {
1431         if (ssl)
1432             ssl->error = ret;
1433         ret = WOLFSSL_FATAL_ERROR;
1434     }
1435     WOLFSSL_LEAVE("wolfSSL_set_secret()", ret);
1436     return ret;
1437 }
1438 
1439 
1440 #ifdef WOLFSSL_DTLS
1441 
wolfSSL_mcast_peer_add(WOLFSSL * ssl,word16 peerId,int remove)1442 int wolfSSL_mcast_peer_add(WOLFSSL* ssl, word16 peerId, int remove)
1443 {
1444     WOLFSSL_DTLS_PEERSEQ* p = NULL;
1445     int ret = WOLFSSL_SUCCESS;
1446     int i;
1447 
1448     WOLFSSL_ENTER("wolfSSL_mcast_peer_add()");
1449     if (ssl == NULL || peerId > 255)
1450         return BAD_FUNC_ARG;
1451 
1452     if (!remove) {
1453         /* Make sure it isn't already present, while keeping the first
1454          * open spot. */
1455         for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
1456             if (ssl->keys.peerSeq[i].peerId == INVALID_PEER_ID)
1457                 p = &ssl->keys.peerSeq[i];
1458             if (ssl->keys.peerSeq[i].peerId == peerId) {
1459                 WOLFSSL_MSG("Peer ID already in multicast peer list.");
1460                 p = NULL;
1461             }
1462         }
1463 
1464         if (p != NULL) {
1465             XMEMSET(p, 0, sizeof(WOLFSSL_DTLS_PEERSEQ));
1466             p->peerId = peerId;
1467             p->highwaterMark = UpdateHighwaterMark(0,
1468                 ssl->ctx->mcastFirstSeq,
1469                 ssl->ctx->mcastSecondSeq,
1470                 ssl->ctx->mcastMaxSeq);
1471         }
1472         else {
1473             WOLFSSL_MSG("No room in peer list.");
1474             ret = -1;
1475         }
1476     }
1477     else {
1478         for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
1479             if (ssl->keys.peerSeq[i].peerId == peerId)
1480                 p = &ssl->keys.peerSeq[i];
1481         }
1482 
1483         if (p != NULL) {
1484             p->peerId = INVALID_PEER_ID;
1485         }
1486         else {
1487             WOLFSSL_MSG("Peer not found in list.");
1488         }
1489     }
1490 
1491     WOLFSSL_LEAVE("wolfSSL_mcast_peer_add()", ret);
1492     return ret;
1493 }
1494 
1495 
1496 /* If peerId is in the list of peers and its last sequence number is non-zero,
1497  * return 1, otherwise return 0. */
wolfSSL_mcast_peer_known(WOLFSSL * ssl,unsigned short peerId)1498 int wolfSSL_mcast_peer_known(WOLFSSL* ssl, unsigned short peerId)
1499 {
1500     int known = 0;
1501     int i;
1502 
1503     WOLFSSL_ENTER("wolfSSL_mcast_peer_known()");
1504 
1505     if (ssl == NULL || peerId > 255) {
1506         return BAD_FUNC_ARG;
1507     }
1508 
1509     for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
1510         if (ssl->keys.peerSeq[i].peerId == peerId) {
1511             if (ssl->keys.peerSeq[i].nextSeq_hi ||
1512                 ssl->keys.peerSeq[i].nextSeq_lo) {
1513 
1514                 known = 1;
1515             }
1516             break;
1517         }
1518     }
1519 
1520     WOLFSSL_LEAVE("wolfSSL_mcast_peer_known()", known);
1521     return known;
1522 }
1523 
1524 
wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX * ctx,word32 maxSeq,word32 first,word32 second,CallbackMcastHighwater cb)1525 int wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX* ctx, word32 maxSeq,
1526                                        word32 first, word32 second,
1527                                        CallbackMcastHighwater cb)
1528 {
1529     if (ctx == NULL || (second && first > second) ||
1530         first > maxSeq || second > maxSeq || cb == NULL) {
1531 
1532         return BAD_FUNC_ARG;
1533     }
1534 
1535     ctx->mcastHwCb = cb;
1536     ctx->mcastFirstSeq = first;
1537     ctx->mcastSecondSeq = second;
1538     ctx->mcastMaxSeq = maxSeq;
1539 
1540     return WOLFSSL_SUCCESS;
1541 }
1542 
1543 
wolfSSL_mcast_set_highwater_ctx(WOLFSSL * ssl,void * ctx)1544 int wolfSSL_mcast_set_highwater_ctx(WOLFSSL* ssl, void* ctx)
1545 {
1546     if (ssl == NULL || ctx == NULL)
1547         return BAD_FUNC_ARG;
1548 
1549     ssl->mcastHwCbCtx = ctx;
1550 
1551     return WOLFSSL_SUCCESS;
1552 }
1553 
1554 #endif /* WOLFSSL_DTLS */
1555 
1556 #endif /* WOLFSSL_MULTICAST */
1557 
1558 
1559 #endif /* WOLFSSL_LEANPSK */
1560 
1561 
1562 /* return underlying connect or accept, WOLFSSL_SUCCESS on ok */
wolfSSL_negotiate(WOLFSSL * ssl)1563 int wolfSSL_negotiate(WOLFSSL* ssl)
1564 {
1565     int err = WOLFSSL_FATAL_ERROR;
1566 
1567     WOLFSSL_ENTER("wolfSSL_negotiate");
1568 #ifndef NO_WOLFSSL_SERVER
1569     if (ssl->options.side == WOLFSSL_SERVER_END) {
1570 #ifdef WOLFSSL_TLS13
1571         if (IsAtLeastTLSv1_3(ssl->version))
1572             err = wolfSSL_accept_TLSv13(ssl);
1573         else
1574 #endif
1575             err = wolfSSL_accept(ssl);
1576     }
1577 #endif
1578 
1579 #ifndef NO_WOLFSSL_CLIENT
1580     if (ssl->options.side == WOLFSSL_CLIENT_END) {
1581 #ifdef WOLFSSL_TLS13
1582         if (IsAtLeastTLSv1_3(ssl->version))
1583             err = wolfSSL_connect_TLSv13(ssl);
1584         else
1585 #endif
1586             err = wolfSSL_connect(ssl);
1587     }
1588 #endif
1589 
1590     (void)ssl;
1591 
1592     WOLFSSL_LEAVE("wolfSSL_negotiate", err);
1593 
1594     return err;
1595 }
1596 
1597 
1598 WOLFSSL_ABI
wolfSSL_GetRNG(WOLFSSL * ssl)1599 WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl)
1600 {
1601     if (ssl) {
1602         return ssl->rng;
1603     }
1604 
1605     return NULL;
1606 }
1607 
1608 
1609 #ifndef WOLFSSL_LEANPSK
1610 /* object size based on build */
wolfSSL_GetObjectSize(void)1611 int wolfSSL_GetObjectSize(void)
1612 {
1613 #ifdef SHOW_SIZES
1614     printf("sizeof suites           = %lu\n", (unsigned long)sizeof(Suites));
1615     printf("sizeof ciphers(2)       = %lu\n", (unsigned long)sizeof(Ciphers));
1616 #ifndef NO_RC4
1617     printf("\tsizeof arc4         = %lu\n", (unsigned long)sizeof(Arc4));
1618 #endif
1619     printf("\tsizeof aes          = %lu\n", (unsigned long)sizeof(Aes));
1620 #ifndef NO_DES3
1621     printf("\tsizeof des3         = %lu\n", (unsigned long)sizeof(Des3));
1622 #endif
1623 #ifndef NO_RABBIT
1624     printf("\tsizeof rabbit       = %lu\n", (unsigned long)sizeof(Rabbit));
1625 #endif
1626 #ifdef HAVE_CHACHA
1627     printf("\tsizeof chacha       = %lu\n", (unsigned long)sizeof(ChaCha));
1628 #endif
1629     printf("sizeof cipher specs     = %lu\n", (unsigned long)sizeof(CipherSpecs));
1630     printf("sizeof keys             = %lu\n", (unsigned long)sizeof(Keys));
1631     printf("sizeof Hashes(2)        = %lu\n", (unsigned long)sizeof(Hashes));
1632 #ifndef NO_MD5
1633     printf("\tsizeof MD5          = %lu\n", (unsigned long)sizeof(wc_Md5));
1634 #endif
1635 #ifndef NO_SHA
1636     printf("\tsizeof SHA          = %lu\n", (unsigned long)sizeof(wc_Sha));
1637 #endif
1638 #ifdef WOLFSSL_SHA224
1639     printf("\tsizeof SHA224       = %lu\n", (unsigned long)sizeof(wc_Sha224));
1640 #endif
1641 #ifndef NO_SHA256
1642     printf("\tsizeof SHA256       = %lu\n", (unsigned long)sizeof(wc_Sha256));
1643 #endif
1644 #ifdef WOLFSSL_SHA384
1645     printf("\tsizeof SHA384       = %lu\n", (unsigned long)sizeof(wc_Sha384));
1646 #endif
1647 #ifdef WOLFSSL_SHA384
1648     printf("\tsizeof SHA512       = %lu\n", (unsigned long)sizeof(wc_Sha512));
1649 #endif
1650     printf("sizeof Buffers          = %lu\n", (unsigned long)sizeof(Buffers));
1651     printf("sizeof Options          = %lu\n", (unsigned long)sizeof(Options));
1652     printf("sizeof Arrays           = %lu\n", (unsigned long)sizeof(Arrays));
1653 #ifndef NO_RSA
1654     printf("sizeof RsaKey           = %lu\n", (unsigned long)sizeof(RsaKey));
1655 #endif
1656 #ifdef HAVE_ECC
1657     printf("sizeof ecc_key          = %lu\n", (unsigned long)sizeof(ecc_key));
1658 #endif
1659     printf("sizeof WOLFSSL_CIPHER    = %lu\n", (unsigned long)sizeof(WOLFSSL_CIPHER));
1660     printf("sizeof WOLFSSL_SESSION   = %lu\n", (unsigned long)sizeof(WOLFSSL_SESSION));
1661     printf("sizeof WOLFSSL           = %lu\n", (unsigned long)sizeof(WOLFSSL));
1662     printf("sizeof WOLFSSL_CTX       = %lu\n", (unsigned long)sizeof(WOLFSSL_CTX));
1663 #endif
1664 
1665     return sizeof(WOLFSSL);
1666 }
1667 
wolfSSL_CTX_GetObjectSize(void)1668 int wolfSSL_CTX_GetObjectSize(void)
1669 {
1670     return sizeof(WOLFSSL_CTX);
1671 }
1672 
wolfSSL_METHOD_GetObjectSize(void)1673 int wolfSSL_METHOD_GetObjectSize(void)
1674 {
1675     return sizeof(WOLFSSL_METHOD);
1676 }
1677 #endif
1678 
1679 
1680 #ifdef WOLFSSL_STATIC_MEMORY
1681 
wolfSSL_CTX_load_static_memory(WOLFSSL_CTX ** ctx,wolfSSL_method_func method,unsigned char * buf,unsigned int sz,int flag,int maxSz)1682 int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, wolfSSL_method_func method,
1683                                    unsigned char* buf, unsigned int sz,
1684                                    int flag, int maxSz)
1685 {
1686     WOLFSSL_HEAP*      heap;
1687     WOLFSSL_HEAP_HINT* hint;
1688     word32 idx = 0;
1689 
1690     if (ctx == NULL || buf == NULL) {
1691         return BAD_FUNC_ARG;
1692     }
1693 
1694     if (*ctx == NULL && method == NULL) {
1695         return BAD_FUNC_ARG;
1696     }
1697 
1698     if (*ctx == NULL || (*ctx)->heap == NULL) {
1699         if (sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT) > sz - idx) {
1700             return BUFFER_E; /* not enough memory for structures */
1701         }
1702         heap = (WOLFSSL_HEAP*)buf;
1703         idx += sizeof(WOLFSSL_HEAP);
1704         if (wolfSSL_init_memory_heap(heap) != 0) {
1705             return WOLFSSL_FAILURE;
1706         }
1707         hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
1708         idx += sizeof(WOLFSSL_HEAP_HINT);
1709         XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
1710         hint->memory = heap;
1711 
1712         if (*ctx && (*ctx)->heap == NULL) {
1713             (*ctx)->heap = (void*)hint;
1714         }
1715     }
1716     else {
1717 #ifdef WOLFSSL_HEAP_TEST
1718         /* do not load in memory if test has been set */
1719         if ((*ctx)->heap == (void*)WOLFSSL_HEAP_TEST) {
1720             return WOLFSSL_SUCCESS;
1721         }
1722 #endif
1723         hint = (WOLFSSL_HEAP_HINT*)((*ctx)->heap);
1724         heap = hint->memory;
1725     }
1726 
1727     if (wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap) != 1) {
1728         WOLFSSL_MSG("Error partitioning memory");
1729         return WOLFSSL_FAILURE;
1730     }
1731 
1732     /* create ctx if needed */
1733     if (*ctx == NULL) {
1734         *ctx = wolfSSL_CTX_new_ex(method(hint), hint);
1735         if (*ctx == NULL) {
1736             WOLFSSL_MSG("Error creating ctx");
1737             return WOLFSSL_FAILURE;
1738         }
1739     }
1740 
1741     /* determine what max applies too */
1742     if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
1743         heap->maxIO = maxSz;
1744     }
1745     else { /* general memory used in handshakes */
1746         heap->maxHa = maxSz;
1747     }
1748 
1749     heap->flag |= flag;
1750 
1751     (void)maxSz;
1752     (void)method;
1753 
1754     return WOLFSSL_SUCCESS;
1755 }
1756 
1757 
wolfSSL_is_static_memory(WOLFSSL * ssl,WOLFSSL_MEM_CONN_STATS * mem_stats)1758 int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats)
1759 {
1760     if (ssl == NULL) {
1761         return BAD_FUNC_ARG;
1762     }
1763     WOLFSSL_ENTER("wolfSSL_is_static_memory");
1764 
1765     /* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
1766     if (mem_stats != NULL && ssl->heap != NULL) {
1767         WOLFSSL_HEAP_HINT* hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
1768         WOLFSSL_HEAP* heap      = hint->memory;
1769         if (heap->flag & WOLFMEM_TRACK_STATS && hint->stats != NULL) {
1770             XMEMCPY(mem_stats, hint->stats, sizeof(WOLFSSL_MEM_CONN_STATS));
1771         }
1772     }
1773 
1774     return (ssl->heap) ? 1 : 0;
1775 }
1776 
1777 
wolfSSL_CTX_is_static_memory(WOLFSSL_CTX * ctx,WOLFSSL_MEM_STATS * mem_stats)1778 int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats)
1779 {
1780     if (ctx == NULL) {
1781         return BAD_FUNC_ARG;
1782     }
1783     WOLFSSL_ENTER("wolfSSL_CTX_is_static_memory");
1784 
1785     /* fill out statistics if wanted */
1786     if (mem_stats != NULL && ctx->heap != NULL) {
1787         WOLFSSL_HEAP* heap = ((WOLFSSL_HEAP_HINT*)(ctx->heap))->memory;
1788         if (wolfSSL_GetMemStats(heap, mem_stats) != 1) {
1789             return MEMORY_E;
1790         }
1791     }
1792 
1793     return (ctx->heap) ? 1 : 0;
1794 }
1795 
1796 #endif /* WOLFSSL_STATIC_MEMORY */
1797 
1798 
1799 /* return max record layer size plaintext input size */
wolfSSL_GetMaxOutputSize(WOLFSSL * ssl)1800 int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
1801 {
1802     WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
1803 
1804     if (ssl == NULL)
1805         return BAD_FUNC_ARG;
1806 
1807     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
1808         WOLFSSL_MSG("Handshake not complete yet");
1809         return BAD_FUNC_ARG;
1810     }
1811 
1812     return wolfSSL_GetMaxFragSize(ssl, OUTPUT_RECORD_SIZE);
1813 }
1814 
1815 
1816 /* return record layer size of plaintext input size */
wolfSSL_GetOutputSize(WOLFSSL * ssl,int inSz)1817 int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
1818 {
1819     int maxSize;
1820 
1821     WOLFSSL_ENTER("wolfSSL_GetOutputSize");
1822 
1823     if (inSz < 0)
1824         return BAD_FUNC_ARG;
1825 
1826     maxSize = wolfSSL_GetMaxOutputSize(ssl);
1827     if (maxSize < 0)
1828         return maxSize;   /* error */
1829     if (inSz > maxSize)
1830         return INPUT_SIZE_E;
1831 
1832     return BuildMessage(ssl, NULL, 0, NULL, inSz, application_data, 0, 1, 0, CUR_ORDER);
1833 }
1834 
1835 
1836 #ifdef HAVE_ECC
wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX * ctx,short keySz)1837 int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
1838 {
1839     if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
1840         WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
1841         return BAD_FUNC_ARG;
1842     }
1843 
1844     ctx->minEccKeySz     = keySz / 8;
1845 #ifndef NO_CERTS
1846     ctx->cm->minEccKeySz = keySz / 8;
1847 #endif
1848     return WOLFSSL_SUCCESS;
1849 }
1850 
1851 
wolfSSL_SetMinEccKey_Sz(WOLFSSL * ssl,short keySz)1852 int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
1853 {
1854     if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
1855         WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
1856         return BAD_FUNC_ARG;
1857     }
1858 
1859     ssl->options.minEccKeySz = keySz / 8;
1860     return WOLFSSL_SUCCESS;
1861 }
1862 
1863 #endif /* HAVE_ECC */
1864 
1865 #ifndef NO_RSA
wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX * ctx,short keySz)1866 int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz)
1867 {
1868     if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
1869         WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
1870         return BAD_FUNC_ARG;
1871     }
1872 
1873     ctx->minRsaKeySz     = keySz / 8;
1874     ctx->cm->minRsaKeySz = keySz / 8;
1875     return WOLFSSL_SUCCESS;
1876 }
1877 
1878 
wolfSSL_SetMinRsaKey_Sz(WOLFSSL * ssl,short keySz)1879 int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
1880 {
1881     if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
1882         WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
1883         return BAD_FUNC_ARG;
1884     }
1885 
1886     ssl->options.minRsaKeySz = keySz / 8;
1887     return WOLFSSL_SUCCESS;
1888 }
1889 #endif /* !NO_RSA */
1890 
1891 #ifndef NO_DH
1892 /* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
wolfSSL_SetTmpDH(WOLFSSL * ssl,const unsigned char * p,int pSz,const unsigned char * g,int gSz)1893 int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
1894                     const unsigned char* g, int gSz)
1895 {
1896     WOLFSSL_ENTER("wolfSSL_SetTmpDH");
1897 
1898     if (ssl == NULL || p == NULL || g == NULL)
1899         return BAD_FUNC_ARG;
1900 
1901     if ((word16)pSz < ssl->options.minDhKeySz)
1902         return DH_KEY_SIZE_E;
1903     if ((word16)pSz > ssl->options.maxDhKeySz)
1904         return DH_KEY_SIZE_E;
1905 
1906     /* this function is for server only */
1907     if (ssl->options.side == WOLFSSL_CLIENT_END)
1908         return SIDE_ERROR;
1909 
1910     #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
1911         !defined(HAVE_SELFTEST)
1912         ssl->options.dhKeyTested = 0;
1913         ssl->options.dhDoKeyTest = 1;
1914     #endif
1915 
1916     if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
1917         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
1918         ssl->buffers.serverDH_P.buffer = NULL;
1919     }
1920     if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
1921         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
1922         ssl->buffers.serverDH_G.buffer = NULL;
1923     }
1924 
1925     ssl->buffers.weOwnDH = 1;  /* SSL owns now */
1926     ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->heap,
1927                                                     DYNAMIC_TYPE_PUBLIC_KEY);
1928     if (ssl->buffers.serverDH_P.buffer == NULL)
1929             return MEMORY_E;
1930 
1931     ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->heap,
1932                                                     DYNAMIC_TYPE_PUBLIC_KEY);
1933     if (ssl->buffers.serverDH_G.buffer == NULL) {
1934         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
1935         ssl->buffers.serverDH_P.buffer = NULL;
1936         return MEMORY_E;
1937     }
1938 
1939     ssl->buffers.serverDH_P.length = pSz;
1940     ssl->buffers.serverDH_G.length = gSz;
1941 
1942     XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
1943     XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
1944 
1945     ssl->options.haveDH = 1;
1946 
1947     if (ssl->options.side != WOLFSSL_NEITHER_END) {
1948         word16 havePSK;
1949         word16 haveRSA;
1950         int    keySz   = 0;
1951 
1952     #ifndef NO_PSK
1953         havePSK = ssl->options.havePSK;
1954     #else
1955         havePSK = 0;
1956     #endif
1957     #ifdef NO_RSA
1958         haveRSA = 0;
1959     #else
1960         haveRSA = 1;
1961     #endif
1962     #ifndef NO_CERTS
1963         keySz = ssl->buffers.keySz;
1964     #endif
1965         InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
1966                    ssl->options.haveDH, ssl->options.haveECDSAsig,
1967                    ssl->options.haveECC, ssl->options.haveStaticECC,
1968                    ssl->options.haveFalconSig, ssl->options.haveAnon,
1969                    ssl->options.side);
1970     }
1971 
1972     WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
1973 
1974     return WOLFSSL_SUCCESS;
1975 }
1976 
1977 
1978 #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
1979     !defined(HAVE_SELFTEST)
1980 /* Enables or disables the session's DH key prime test. */
wolfSSL_SetEnableDhKeyTest(WOLFSSL * ssl,int enable)1981 int wolfSSL_SetEnableDhKeyTest(WOLFSSL* ssl, int enable)
1982 {
1983     WOLFSSL_ENTER("wolfSSL_SetEnableDhKeyTest");
1984 
1985     if (ssl == NULL)
1986         return BAD_FUNC_ARG;
1987 
1988     if (!enable)
1989         ssl->options.dhDoKeyTest = 0;
1990     else
1991         ssl->options.dhDoKeyTest = 1;
1992 
1993     WOLFSSL_LEAVE("wolfSSL_SetEnableDhKeyTest", WOLFSSL_SUCCESS);
1994     return WOLFSSL_SUCCESS;
1995 }
1996 #endif
1997 
1998 
1999 /* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX * ctx,const unsigned char * p,int pSz,const unsigned char * g,int gSz)2000 int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
2001                          const unsigned char* g, int gSz)
2002 {
2003     WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
2004     if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
2005 
2006     if ((word16)pSz < ctx->minDhKeySz)
2007         return DH_KEY_SIZE_E;
2008     if ((word16)pSz > ctx->maxDhKeySz)
2009         return DH_KEY_SIZE_E;
2010 
2011     #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
2012         !defined(HAVE_SELFTEST)
2013     {
2014         WC_RNG rng;
2015         int error, freeKey = 0;
2016     #ifdef WOLFSSL_SMALL_STACK
2017         DhKey *checkKey = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
2018         if (checkKey == NULL)
2019             return MEMORY_E;
2020     #else
2021         DhKey checkKey[1];
2022     #endif
2023 
2024         error = wc_InitRng(&rng);
2025         if (!error)
2026             error = wc_InitDhKey(checkKey);
2027         if (!error) {
2028             freeKey = 1;
2029             error = wc_DhSetCheckKey(checkKey,
2030                                  p, pSz, g, gSz, NULL, 0, 0, &rng);
2031         }
2032         if (freeKey)
2033             wc_FreeDhKey(checkKey);
2034     #ifdef WOLFSSL_SMALL_STACK
2035         XFREE(checkKey, NULL, DYNAMIC_TYPE_DH);
2036     #endif
2037         wc_FreeRng(&rng);
2038         if (error)
2039             return error;
2040 
2041         ctx->dhKeyTested = 1;
2042     }
2043     #endif
2044 
2045     XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2046     ctx->serverDH_P.buffer = NULL;
2047     XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2048     ctx->serverDH_G.buffer = NULL;
2049 
2050     ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2051     if (ctx->serverDH_P.buffer == NULL)
2052        return MEMORY_E;
2053 
2054     ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2055     if (ctx->serverDH_G.buffer == NULL) {
2056         XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2057         ctx->serverDH_P.buffer = NULL;
2058         return MEMORY_E;
2059     }
2060 
2061     ctx->serverDH_P.length = pSz;
2062     ctx->serverDH_G.length = gSz;
2063 
2064     XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
2065     XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
2066 
2067     ctx->haveDH = 1;
2068 
2069     WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
2070     return WOLFSSL_SUCCESS;
2071 }
2072 
2073 
wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX * ctx,word16 keySz_bits)2074 int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
2075 {
2076     if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2077         return BAD_FUNC_ARG;
2078 
2079     ctx->minDhKeySz = keySz_bits / 8;
2080     return WOLFSSL_SUCCESS;
2081 }
2082 
2083 
wolfSSL_SetMinDhKey_Sz(WOLFSSL * ssl,word16 keySz_bits)2084 int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
2085 {
2086     if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2087         return BAD_FUNC_ARG;
2088 
2089     ssl->options.minDhKeySz = keySz_bits / 8;
2090     return WOLFSSL_SUCCESS;
2091 }
2092 
2093 
wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX * ctx,word16 keySz_bits)2094 int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
2095 {
2096     if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2097         return BAD_FUNC_ARG;
2098 
2099     ctx->maxDhKeySz = keySz_bits / 8;
2100     return WOLFSSL_SUCCESS;
2101 }
2102 
2103 
wolfSSL_SetMaxDhKey_Sz(WOLFSSL * ssl,word16 keySz_bits)2104 int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
2105 {
2106     if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2107         return BAD_FUNC_ARG;
2108 
2109     ssl->options.maxDhKeySz = keySz_bits / 8;
2110     return WOLFSSL_SUCCESS;
2111 }
2112 
2113 
wolfSSL_GetDhKey_Sz(WOLFSSL * ssl)2114 int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
2115 {
2116     if (ssl == NULL)
2117         return BAD_FUNC_ARG;
2118 
2119     return (ssl->options.dhKeySz * 8);
2120 }
2121 
2122 #endif /* !NO_DH */
2123 
2124 
2125 WOLFSSL_ABI
wolfSSL_write(WOLFSSL * ssl,const void * data,int sz)2126 int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
2127 {
2128     int ret;
2129 
2130     WOLFSSL_ENTER("SSL_write()");
2131 
2132     if (ssl == NULL || data == NULL || sz < 0)
2133         return BAD_FUNC_ARG;
2134 
2135 #ifdef WOLFSSL_EARLY_DATA
2136     if (ssl->earlyData != no_early_data && (ret = wolfSSL_negotiate(ssl)) < 0) {
2137         ssl->error = ret;
2138         return WOLFSSL_FATAL_ERROR;
2139     }
2140     ssl->earlyData = no_early_data;
2141 #endif
2142 
2143 #ifdef HAVE_WRITE_DUP
2144     { /* local variable scope */
2145         int dupErr = 0;   /* local copy */
2146 
2147         ret = 0;
2148 
2149         if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
2150             WOLFSSL_MSG("Read dup side cannot write");
2151             return WRITE_DUP_WRITE_E;
2152         }
2153         if (ssl->dupWrite) {
2154             if (wc_LockMutex(&ssl->dupWrite->dupMutex) != 0) {
2155                 return BAD_MUTEX_E;
2156             }
2157             dupErr = ssl->dupWrite->dupErr;
2158             ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
2159         }
2160 
2161         if (ret != 0) {
2162             ssl->error = ret;  /* high priority fatal error */
2163             return WOLFSSL_FATAL_ERROR;
2164         }
2165         if (dupErr != 0) {
2166             WOLFSSL_MSG("Write dup error from other side");
2167             ssl->error = dupErr;
2168             return WOLFSSL_FATAL_ERROR;
2169         }
2170     }
2171 #endif
2172 
2173 #ifdef HAVE_ERRNO_H
2174     errno = 0;
2175 #endif
2176 
2177     #ifdef OPENSSL_EXTRA
2178     if (ssl->CBIS != NULL) {
2179         ssl->CBIS(ssl, SSL_CB_WRITE, WOLFSSL_SUCCESS);
2180         ssl->cbmode = SSL_CB_WRITE;
2181     }
2182     #endif
2183     ret = SendData(ssl, data, sz);
2184 
2185     WOLFSSL_LEAVE("SSL_write()", ret);
2186 
2187     if (ret < 0)
2188         return WOLFSSL_FATAL_ERROR;
2189     else
2190         return ret;
2191 }
2192 
wolfSSL_read_internal(WOLFSSL * ssl,void * data,int sz,int peek)2193 static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
2194 {
2195     int ret;
2196 
2197     WOLFSSL_ENTER("wolfSSL_read_internal()");
2198 
2199     if (ssl == NULL || data == NULL || sz < 0)
2200         return BAD_FUNC_ARG;
2201 
2202 #if defined(WOLFSSL_ERROR_CODE_OPENSSL) && defined(OPENSSL_EXTRA)
2203     /* This additional logic is meant to simulate following openSSL behavior:
2204      * After bidirectional SSL_shutdown complete, SSL_read returns 0 and
2205      * SSL_get_error_code returns SSL_ERROR_ZERO_RETURN.
2206      * This behavior is used to know the disconnect of the underlying
2207      * transport layer.
2208      *
2209      * In this logic, CBIORecv is called with a read size of 0 to check the
2210      * transport layer status. It also returns WOLFSSL_FAILURE so that
2211      * SSL_read does not return a positive number on failure.
2212      */
2213 
2214     /* make sure bidirectional TLS shutdown completes */
2215     if (ssl->error == WOLFSSL_ERROR_SYSCALL) {
2216         /* ask the underlying transport the connection is closed */
2217         if (ssl->CBIORecv(ssl, (char*)data, 0, ssl->IOCB_ReadCtx) ==
2218                                             WOLFSSL_CBIO_ERR_CONN_CLOSE) {
2219             ssl->options.isClosed = 1;
2220             ssl->error = WOLFSSL_ERROR_ZERO_RETURN;
2221         }
2222         return WOLFSSL_FAILURE;
2223     }
2224 #endif
2225 
2226 #ifdef HAVE_WRITE_DUP
2227     if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE) {
2228         WOLFSSL_MSG("Write dup side cannot read");
2229         return WRITE_DUP_READ_E;
2230     }
2231 #endif
2232 
2233 #ifdef HAVE_ERRNO_H
2234         errno = 0;
2235 #endif
2236 
2237 #ifdef WOLFSSL_DTLS
2238     if (ssl->options.dtls) {
2239         ssl->dtls_expected_rx = max(sz + DTLS_MTU_ADDITIONAL_READ_BUFFER,
2240                 MAX_MTU);
2241 #ifdef WOLFSSL_SCTP
2242         if (ssl->options.dtlsSctp)
2243 #endif
2244 #if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
2245             /* Add some bytes so that we can operate with slight difference
2246              * in set MTU size on each peer */
2247             ssl->dtls_expected_rx = max(ssl->dtls_expected_rx,
2248                     ssl->dtlsMtuSz + DTLS_MTU_ADDITIONAL_READ_BUFFER);
2249 #endif
2250     }
2251 #endif
2252 
2253     ret = ReceiveData(ssl, (byte*)data, sz, peek);
2254 
2255 #ifdef HAVE_WRITE_DUP
2256     if (ssl->dupWrite) {
2257         if (ssl->error != 0 && ssl->error != WANT_READ
2258         #ifdef WOLFSSL_ASYNC_CRYPT
2259             && ssl->error != WC_PENDING_E
2260         #endif
2261         ) {
2262             int notifyErr;
2263 
2264             WOLFSSL_MSG("Notifying write side of fatal read error");
2265             notifyErr  = NotifyWriteSide(ssl, ssl->error);
2266             if (notifyErr < 0) {
2267                 ret = ssl->error = notifyErr;
2268             }
2269         }
2270     }
2271 #endif
2272 
2273     WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
2274 
2275     if (ret < 0)
2276         return WOLFSSL_FATAL_ERROR;
2277     else
2278         return ret;
2279 }
2280 
2281 
wolfSSL_peek(WOLFSSL * ssl,void * data,int sz)2282 int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
2283 {
2284     WOLFSSL_ENTER("wolfSSL_peek()");
2285 
2286     return wolfSSL_read_internal(ssl, data, sz, TRUE);
2287 }
2288 
2289 
2290 WOLFSSL_ABI
wolfSSL_read(WOLFSSL * ssl,void * data,int sz)2291 int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
2292 {
2293     WOLFSSL_ENTER("wolfSSL_read()");
2294 
2295     #ifdef OPENSSL_EXTRA
2296     if (ssl == NULL) {
2297         return BAD_FUNC_ARG;
2298     }
2299     if (ssl->CBIS != NULL) {
2300         ssl->CBIS(ssl, SSL_CB_READ, WOLFSSL_SUCCESS);
2301         ssl->cbmode = SSL_CB_READ;
2302     }
2303     #endif
2304     return wolfSSL_read_internal(ssl, data, sz, FALSE);
2305 }
2306 
2307 
2308 #ifdef WOLFSSL_MULTICAST
2309 
wolfSSL_mcast_read(WOLFSSL * ssl,word16 * id,void * data,int sz)2310 int wolfSSL_mcast_read(WOLFSSL* ssl, word16* id, void* data, int sz)
2311 {
2312     int ret = 0;
2313 
2314     WOLFSSL_ENTER("wolfSSL_mcast_read()");
2315 
2316     if (ssl == NULL)
2317         return BAD_FUNC_ARG;
2318 
2319     ret = wolfSSL_read_internal(ssl, data, sz, FALSE);
2320     if (ssl->options.dtls && ssl->options.haveMcast && id != NULL)
2321         *id = ssl->keys.curPeerId;
2322     return ret;
2323 }
2324 
2325 #endif /* WOLFSSL_MULTICAST */
2326 
2327 
2328 /* helpers to set the device id, WOLFSSL_SUCCESS on ok */
2329 WOLFSSL_ABI
wolfSSL_SetDevId(WOLFSSL * ssl,int devId)2330 int wolfSSL_SetDevId(WOLFSSL* ssl, int devId)
2331 {
2332     if (ssl == NULL)
2333         return BAD_FUNC_ARG;
2334 
2335     ssl->devId = devId;
2336 
2337     return WOLFSSL_SUCCESS;
2338 }
2339 
2340 WOLFSSL_ABI
wolfSSL_CTX_SetDevId(WOLFSSL_CTX * ctx,int devId)2341 int wolfSSL_CTX_SetDevId(WOLFSSL_CTX* ctx, int devId)
2342 {
2343     if (ctx == NULL)
2344         return BAD_FUNC_ARG;
2345 
2346     ctx->devId = devId;
2347 
2348     return WOLFSSL_SUCCESS;
2349 }
2350 
2351 /* helpers to get device id and heap */
2352 WOLFSSL_ABI
wolfSSL_CTX_GetDevId(WOLFSSL_CTX * ctx,WOLFSSL * ssl)2353 int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
2354 {
2355     int devId = INVALID_DEVID;
2356     if (ssl != NULL)
2357         devId = ssl->devId;
2358     if (ctx != NULL && devId == INVALID_DEVID)
2359         devId = ctx->devId;
2360     return devId;
2361 }
wolfSSL_CTX_GetHeap(WOLFSSL_CTX * ctx,WOLFSSL * ssl)2362 void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
2363 {
2364     void* heap = NULL;
2365     if (ctx != NULL)
2366         heap = ctx->heap;
2367     else if (ssl != NULL)
2368         heap = ssl->heap;
2369     return heap;
2370 }
2371 
2372 
2373 #ifdef HAVE_SNI
2374 
2375 WOLFSSL_ABI
wolfSSL_UseSNI(WOLFSSL * ssl,byte type,const void * data,word16 size)2376 int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
2377 {
2378     if (ssl == NULL)
2379         return BAD_FUNC_ARG;
2380 
2381     return TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
2382 }
2383 
2384 
2385 WOLFSSL_ABI
wolfSSL_CTX_UseSNI(WOLFSSL_CTX * ctx,byte type,const void * data,word16 size)2386 int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
2387                                                                     word16 size)
2388 {
2389     if (ctx == NULL)
2390         return BAD_FUNC_ARG;
2391 
2392     return TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
2393 }
2394 
2395 #ifndef NO_WOLFSSL_SERVER
2396 
wolfSSL_SNI_SetOptions(WOLFSSL * ssl,byte type,byte options)2397 void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
2398 {
2399     if (ssl && ssl->extensions)
2400         TLSX_SNI_SetOptions(ssl->extensions, type, options);
2401 }
2402 
2403 
wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX * ctx,byte type,byte options)2404 void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
2405 {
2406     if (ctx && ctx->extensions)
2407         TLSX_SNI_SetOptions(ctx->extensions, type, options);
2408 }
2409 
2410 
wolfSSL_SNI_Status(WOLFSSL * ssl,byte type)2411 byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
2412 {
2413     return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
2414 }
2415 
2416 
wolfSSL_SNI_GetRequest(WOLFSSL * ssl,byte type,void ** data)2417 word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
2418 {
2419     if (data)
2420         *data = NULL;
2421 
2422     if (ssl && ssl->extensions)
2423         return TLSX_SNI_GetRequest(ssl->extensions, type, data);
2424 
2425     return 0;
2426 }
2427 
2428 
wolfSSL_SNI_GetFromBuffer(const byte * clientHello,word32 helloSz,byte type,byte * sni,word32 * inOutSz)2429 int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
2430                               byte type, byte* sni, word32* inOutSz)
2431 {
2432     if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
2433         return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
2434 
2435     return BAD_FUNC_ARG;
2436 }
2437 
2438 #endif /* NO_WOLFSSL_SERVER */
2439 
2440 #endif /* HAVE_SNI */
2441 
2442 
2443 #ifdef HAVE_TRUSTED_CA
2444 
wolfSSL_UseTrustedCA(WOLFSSL * ssl,byte type,const byte * certId,word32 certIdSz)2445 WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type,
2446             const byte* certId, word32 certIdSz)
2447 {
2448     if (ssl == NULL)
2449         return BAD_FUNC_ARG;
2450 
2451     if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED) {
2452         if (certId != NULL || certIdSz != 0)
2453             return BAD_FUNC_ARG;
2454     }
2455     else if (type == WOLFSSL_TRUSTED_CA_X509_NAME) {
2456         if (certId == NULL || certIdSz == 0)
2457             return BAD_FUNC_ARG;
2458     }
2459     #ifndef NO_SHA
2460     else if (type == WOLFSSL_TRUSTED_CA_KEY_SHA1 ||
2461             type == WOLFSSL_TRUSTED_CA_CERT_SHA1) {
2462         if (certId == NULL || certIdSz != WC_SHA_DIGEST_SIZE)
2463             return BAD_FUNC_ARG;
2464     }
2465     #endif
2466     else
2467         return BAD_FUNC_ARG;
2468 
2469     return TLSX_UseTrustedCA(&ssl->extensions,
2470             type, certId, certIdSz, ssl->heap);
2471 }
2472 
2473 #endif /* HAVE_TRUSTED_CA */
2474 
2475 
2476 #ifdef HAVE_MAX_FRAGMENT
2477 #ifndef NO_WOLFSSL_CLIENT
2478 
wolfSSL_UseMaxFragment(WOLFSSL * ssl,byte mfl)2479 int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
2480 {
2481     if (ssl == NULL)
2482         return BAD_FUNC_ARG;
2483 
2484 #ifdef WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST
2485     /* The following is a non-standard way to reconfigure the max packet size
2486         post-handshake for wolfSSL_write/wolfSSL_read */
2487     if (ssl->options.handShakeState == HANDSHAKE_DONE) {
2488         switch (mfl) {
2489             case WOLFSSL_MFL_2_8 : ssl->max_fragment =  256; break;
2490             case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
2491             case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
2492             case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
2493             case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
2494             case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
2495             default: ssl->max_fragment = MAX_RECORD_SIZE; break;
2496         }
2497         return WOLFSSL_SUCCESS;
2498     }
2499 #endif /* WOLFSSL_MAX_FRAGMENT_ADJUST */
2500 
2501     /* This call sets the max fragment TLS extension, which gets sent to server.
2502         The server_hello response is what sets the `ssl->max_fragment` in
2503         TLSX_MFL_Parse */
2504     return TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
2505 }
2506 
2507 
wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX * ctx,byte mfl)2508 int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
2509 {
2510     if (ctx == NULL)
2511         return BAD_FUNC_ARG;
2512 
2513     return TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
2514 }
2515 
2516 #endif /* NO_WOLFSSL_CLIENT */
2517 #endif /* HAVE_MAX_FRAGMENT */
2518 
2519 #ifdef HAVE_TRUNCATED_HMAC
2520 #ifndef NO_WOLFSSL_CLIENT
2521 
wolfSSL_UseTruncatedHMAC(WOLFSSL * ssl)2522 int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
2523 {
2524     if (ssl == NULL)
2525         return BAD_FUNC_ARG;
2526 
2527     return TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
2528 }
2529 
2530 
wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX * ctx)2531 int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
2532 {
2533     if (ctx == NULL)
2534         return BAD_FUNC_ARG;
2535 
2536     return TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
2537 }
2538 
2539 #endif /* NO_WOLFSSL_CLIENT */
2540 #endif /* HAVE_TRUNCATED_HMAC */
2541 
2542 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
2543 
wolfSSL_UseOCSPStapling(WOLFSSL * ssl,byte status_type,byte options)2544 int wolfSSL_UseOCSPStapling(WOLFSSL* ssl, byte status_type, byte options)
2545 {
2546     if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
2547         return BAD_FUNC_ARG;
2548 
2549     return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
2550                                           options, NULL, ssl->heap, ssl->devId);
2551 }
2552 
2553 
wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX * ctx,byte status_type,byte options)2554 int wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX* ctx, byte status_type,
2555                                                                    byte options)
2556 {
2557     if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
2558         return BAD_FUNC_ARG;
2559 
2560     return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type,
2561                                           options, NULL, ctx->heap, ctx->devId);
2562 }
2563 
2564 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
2565 
2566 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
2567 
wolfSSL_UseOCSPStaplingV2(WOLFSSL * ssl,byte status_type,byte options)2568 int wolfSSL_UseOCSPStaplingV2(WOLFSSL* ssl, byte status_type, byte options)
2569 {
2570     if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
2571         return BAD_FUNC_ARG;
2572 
2573     return TLSX_UseCertificateStatusRequestV2(&ssl->extensions, status_type,
2574                                                 options, ssl->heap, ssl->devId);
2575 }
2576 
2577 
wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX * ctx,byte status_type,byte options)2578 int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, byte status_type,
2579                                                                    byte options)
2580 {
2581     if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
2582         return BAD_FUNC_ARG;
2583 
2584     return TLSX_UseCertificateStatusRequestV2(&ctx->extensions, status_type,
2585                                                 options, ctx->heap, ctx->devId);
2586 }
2587 
2588 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
2589 
2590 /* Elliptic Curves */
2591 #if defined(HAVE_SUPPORTED_CURVES)
2592 
isValidCurveGroup(word16 name)2593 static int isValidCurveGroup(word16 name)
2594 {
2595     switch (name) {
2596         case WOLFSSL_ECC_SECP160K1:
2597         case WOLFSSL_ECC_SECP160R1:
2598         case WOLFSSL_ECC_SECP160R2:
2599         case WOLFSSL_ECC_SECP192K1:
2600         case WOLFSSL_ECC_SECP192R1:
2601         case WOLFSSL_ECC_SECP224K1:
2602         case WOLFSSL_ECC_SECP224R1:
2603         case WOLFSSL_ECC_SECP256K1:
2604         case WOLFSSL_ECC_SECP256R1:
2605         case WOLFSSL_ECC_SECP384R1:
2606         case WOLFSSL_ECC_SECP521R1:
2607         case WOLFSSL_ECC_BRAINPOOLP256R1:
2608         case WOLFSSL_ECC_BRAINPOOLP384R1:
2609         case WOLFSSL_ECC_BRAINPOOLP512R1:
2610         case WOLFSSL_ECC_X25519:
2611         case WOLFSSL_ECC_X448:
2612 
2613         case WOLFSSL_FFDHE_2048:
2614         case WOLFSSL_FFDHE_3072:
2615         case WOLFSSL_FFDHE_4096:
2616         case WOLFSSL_FFDHE_6144:
2617         case WOLFSSL_FFDHE_8192:
2618 
2619 #ifdef HAVE_PQC
2620         case WOLFSSL_KYBER_LEVEL1:
2621         case WOLFSSL_KYBER_LEVEL3:
2622         case WOLFSSL_KYBER_LEVEL5:
2623         case WOLFSSL_NTRU_HPS_LEVEL1:
2624         case WOLFSSL_NTRU_HPS_LEVEL3:
2625         case WOLFSSL_NTRU_HPS_LEVEL5:
2626         case WOLFSSL_NTRU_HRSS_LEVEL3:
2627         case WOLFSSL_SABER_LEVEL1:
2628         case WOLFSSL_SABER_LEVEL3:
2629         case WOLFSSL_SABER_LEVEL5:
2630         case WOLFSSL_KYBER_90S_LEVEL1:
2631         case WOLFSSL_KYBER_90S_LEVEL3:
2632         case WOLFSSL_KYBER_90S_LEVEL5:
2633         case WOLFSSL_P256_NTRU_HPS_LEVEL1:
2634         case WOLFSSL_P384_NTRU_HPS_LEVEL3:
2635         case WOLFSSL_P521_NTRU_HPS_LEVEL5:
2636         case WOLFSSL_P384_NTRU_HRSS_LEVEL3:
2637         case WOLFSSL_P256_SABER_LEVEL1:
2638         case WOLFSSL_P384_SABER_LEVEL3:
2639         case WOLFSSL_P521_SABER_LEVEL5:
2640         case WOLFSSL_P256_KYBER_LEVEL1:
2641         case WOLFSSL_P384_KYBER_LEVEL3:
2642         case WOLFSSL_P521_KYBER_LEVEL5:
2643         case WOLFSSL_P256_KYBER_90S_LEVEL1:
2644         case WOLFSSL_P384_KYBER_90S_LEVEL3:
2645         case WOLFSSL_P521_KYBER_90S_LEVEL5:
2646 #endif
2647             return 1;
2648 
2649         default:
2650             return 0;
2651     }
2652 }
2653 
wolfSSL_UseSupportedCurve(WOLFSSL * ssl,word16 name)2654 int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
2655 {
2656     if (ssl == NULL || !isValidCurveGroup(name))
2657         return BAD_FUNC_ARG;
2658 
2659     ssl->options.userCurves = 1;
2660 
2661     return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
2662 }
2663 
2664 
wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX * ctx,word16 name)2665 int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
2666 {
2667     if (ctx == NULL || !isValidCurveGroup(name))
2668         return BAD_FUNC_ARG;
2669 
2670     ctx->userCurves = 1;
2671 
2672     return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap);
2673 }
2674 
2675 #if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13)
wolfSSL_CTX_set1_groups(WOLFSSL_CTX * ctx,int * groups,int count)2676 int  wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
2677                                         int count)
2678 {
2679     int i;
2680     int _groups[WOLFSSL_MAX_GROUP_COUNT];
2681     WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
2682     if (count == 0) {
2683         WOLFSSL_MSG("Group count is zero");
2684         return WOLFSSL_FAILURE;
2685     }
2686     for (i = 0; i < count; i++) {
2687         if (isValidCurveGroup((word16)groups[i])) {
2688             _groups[i] = groups[i];
2689         }
2690 #ifdef HAVE_ECC
2691         else {
2692             /* groups may be populated with curve NIDs */
2693             int oid = nid2oid(groups[i], oidCurveType);
2694             int name = (int)GetCurveByOID(oid);
2695             if (name == 0) {
2696                 WOLFSSL_MSG("Invalid group name");
2697                 return WOLFSSL_FAILURE;
2698             }
2699             _groups[i] = name;
2700         }
2701 #else
2702         else {
2703             WOLFSSL_MSG("Invalid group name");
2704             return WOLFSSL_FAILURE;
2705         }
2706 #endif
2707     }
2708     return wolfSSL_CTX_set_groups(ctx, _groups, count) == WOLFSSL_SUCCESS ?
2709             WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
2710 }
2711 
wolfSSL_set1_groups(WOLFSSL * ssl,int * groups,int count)2712 int  wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count)
2713 {
2714     int i;
2715     int _groups[WOLFSSL_MAX_GROUP_COUNT];
2716     WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
2717     if (count == 0) {
2718         WOLFSSL_MSG("Group count is zero");
2719         return WOLFSSL_FAILURE;
2720     }
2721     for (i = 0; i < count; i++) {
2722         if (isValidCurveGroup((word16)groups[i])) {
2723             _groups[i] = groups[i];
2724         }
2725 #ifdef HAVE_ECC
2726         else {
2727             /* groups may be populated with curve NIDs */
2728             int oid = nid2oid(groups[i], oidCurveType);
2729             int name = (int)GetCurveByOID(oid);
2730             if (name == 0) {
2731                 WOLFSSL_MSG("Invalid group name");
2732                 return WOLFSSL_FAILURE;
2733             }
2734             _groups[i] = name;
2735         }
2736 #else
2737         else {
2738             WOLFSSL_MSG("Invalid group name");
2739             return WOLFSSL_FAILURE;
2740         }
2741 #endif
2742     }
2743     return wolfSSL_set_groups(ssl, _groups, count) == WOLFSSL_SUCCESS ?
2744             WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
2745 }
2746 #endif /* OPENSSL_EXTRA && WOLFSSL_TLS13 */
2747 #endif /* HAVE_SUPPORTED_CURVES */
2748 
2749 /* Application-Layer Protocol Negotiation */
2750 #ifdef HAVE_ALPN
2751 
2752 WOLFSSL_ABI
wolfSSL_UseALPN(WOLFSSL * ssl,char * protocol_name_list,word32 protocol_name_listSz,byte options)2753 int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
2754                     word32 protocol_name_listSz, byte options)
2755 {
2756     char    *list, *ptr, **token;
2757     word16  len;
2758     int     idx = 0;
2759     int     ret = WOLFSSL_FAILURE;
2760 
2761     WOLFSSL_ENTER("wolfSSL_UseALPN");
2762 
2763     if (ssl == NULL || protocol_name_list == NULL)
2764         return BAD_FUNC_ARG;
2765 
2766     if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
2767                                 WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
2768                                 WOLFSSL_MAX_ALPN_NUMBER)) {
2769         WOLFSSL_MSG("Invalid arguments, protocol name list too long");
2770         return BAD_FUNC_ARG;
2771     }
2772 
2773     if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
2774         !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
2775             WOLFSSL_MSG("Invalid arguments, options not supported");
2776             return BAD_FUNC_ARG;
2777         }
2778 
2779 
2780     list = (char *)XMALLOC(protocol_name_listSz+1, ssl->heap,
2781                            DYNAMIC_TYPE_ALPN);
2782     if (list == NULL) {
2783         WOLFSSL_MSG("Memory failure");
2784         return MEMORY_ERROR;
2785     }
2786 
2787     token = (char **)XMALLOC(sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1), ssl->heap, DYNAMIC_TYPE_ALPN);
2788     if (token == NULL) {
2789         XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
2790         WOLFSSL_MSG("Memory failure");
2791         return MEMORY_ERROR;
2792     }
2793     XMEMSET(token, 0, sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1));
2794 
2795     XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
2796     list[protocol_name_listSz] = '\0';
2797 
2798     /* read all protocol name from the list */
2799     token[idx] = XSTRTOK(list, ",", &ptr);
2800     while (idx < WOLFSSL_MAX_ALPN_NUMBER && token[idx] != NULL)
2801         token[++idx] = XSTRTOK(NULL, ",", &ptr);
2802 
2803     /* add protocol name list in the TLS extension in reverse order */
2804     while ((idx--) > 0) {
2805         len = (word16)XSTRLEN(token[idx]);
2806 
2807         ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
2808                                                                      ssl->heap);
2809         if (ret != WOLFSSL_SUCCESS) {
2810             WOLFSSL_MSG("TLSX_UseALPN failure");
2811             break;
2812         }
2813     }
2814 
2815     XFREE(token, ssl->heap, DYNAMIC_TYPE_ALPN);
2816     XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
2817 
2818     return ret;
2819 }
2820 
wolfSSL_ALPN_GetProtocol(WOLFSSL * ssl,char ** protocol_name,word16 * size)2821 int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
2822 {
2823     return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
2824                                (void **)protocol_name, size);
2825 }
2826 
wolfSSL_ALPN_GetPeerProtocol(WOLFSSL * ssl,char ** list,word16 * listSz)2827 int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
2828 {
2829     if (list == NULL || listSz == NULL)
2830         return BAD_FUNC_ARG;
2831 
2832     if (ssl->alpn_client_list == NULL)
2833         return BUFFER_ERROR;
2834 
2835     *listSz = (word16)XSTRLEN(ssl->alpn_client_list);
2836     if (*listSz == 0)
2837         return BUFFER_ERROR;
2838 
2839     *list = (char *)XMALLOC((*listSz)+1, ssl->heap, DYNAMIC_TYPE_TLSX);
2840     if (*list == NULL)
2841         return MEMORY_ERROR;
2842 
2843     XSTRNCPY(*list, ssl->alpn_client_list, (*listSz)+1);
2844     (*list)[*listSz] = 0;
2845 
2846     return WOLFSSL_SUCCESS;
2847 }
2848 
2849 
2850 /* used to free memory allocated by wolfSSL_ALPN_GetPeerProtocol */
wolfSSL_ALPN_FreePeerProtocol(WOLFSSL * ssl,char ** list)2851 int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
2852 {
2853     if (ssl == NULL) {
2854         return BAD_FUNC_ARG;
2855     }
2856 
2857     XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
2858     *list = NULL;
2859 
2860     return WOLFSSL_SUCCESS;
2861 }
2862 
2863 #endif /* HAVE_ALPN */
2864 
2865 /* Secure Renegotiation */
2866 #ifdef HAVE_SECURE_RENEGOTIATION
2867 
2868 /* user is forcing ability to use secure renegotiation, we discourage it */
wolfSSL_UseSecureRenegotiation(WOLFSSL * ssl)2869 int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
2870 {
2871     int ret = BAD_FUNC_ARG;
2872 
2873     if (ssl)
2874         ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
2875 
2876     if (ret == WOLFSSL_SUCCESS) {
2877         TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
2878 
2879         if (extension)
2880             ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
2881     }
2882 
2883     return ret;
2884 }
2885 
wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX * ctx)2886 int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx)
2887 {
2888     if (ctx == NULL)
2889         return BAD_FUNC_ARG;
2890 
2891     ctx->useSecureReneg = 1;
2892     return WOLFSSL_SUCCESS;
2893 }
2894 
2895 
2896 /* do a secure renegotiation handshake, user forced, we discourage */
_Rehandshake(WOLFSSL * ssl)2897 static int _Rehandshake(WOLFSSL* ssl)
2898 {
2899     int ret;
2900 
2901     if (ssl == NULL)
2902         return BAD_FUNC_ARG;
2903 
2904     if (ssl->secure_renegotiation == NULL) {
2905         WOLFSSL_MSG("Secure Renegotiation not forced on by user");
2906         return SECURE_RENEGOTIATION_E;
2907     }
2908 
2909     if (ssl->secure_renegotiation->enabled == 0) {
2910         WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
2911         return SECURE_RENEGOTIATION_E;
2912     }
2913 
2914     /* If the client started the renegotiation, the server will already
2915      * have processed the client's hello. */
2916     if (ssl->options.side != WOLFSSL_SERVER_END ||
2917         ssl->options.acceptState != ACCEPT_FIRST_REPLY_DONE) {
2918 
2919         if (ssl->options.handShakeState != HANDSHAKE_DONE) {
2920             if (!ssl->options.handShakeDone) {
2921                 WOLFSSL_MSG("Can't renegotiate until initial "
2922                             "handshake complete");
2923                 return SECURE_RENEGOTIATION_E;
2924             }
2925             else {
2926                 WOLFSSL_MSG("Renegotiation already started. "
2927                             "Moving it forward.");
2928                 ret = wolfSSL_negotiate(ssl);
2929                 if (ret == WOLFSSL_SUCCESS)
2930                     ssl->secure_rene_count++;
2931                 return ret;
2932             }
2933         }
2934 
2935 #ifndef NO_FORCE_SCR_SAME_SUITE
2936         /* force same suite */
2937         if (ssl->suites) {
2938             ssl->suites->suiteSz = SUITE_LEN;
2939             ssl->suites->suites[0] = ssl->options.cipherSuite0;
2940             ssl->suites->suites[1] = ssl->options.cipherSuite;
2941         }
2942 #endif
2943 
2944         /* reset handshake states */
2945         ssl->options.sendVerify = 0;
2946         ssl->options.serverState = NULL_STATE;
2947         ssl->options.clientState = NULL_STATE;
2948         ssl->options.connectState  = CONNECT_BEGIN;
2949         ssl->options.acceptState   = ACCEPT_BEGIN_RENEG;
2950         ssl->options.handShakeState = NULL_STATE;
2951         ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
2952 
2953         XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
2954 
2955         ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
2956 
2957 #if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SERVER_RENEGOTIATION_INFO)
2958         if (ssl->options.side == WOLFSSL_SERVER_END) {
2959             ret = SendHelloRequest(ssl);
2960             if (ret != 0) {
2961                 ssl->error = ret;
2962                 return WOLFSSL_FATAL_ERROR;
2963             }
2964         }
2965 #endif /* NO_WOLFSSL_SERVER && HAVE_SERVER_RENEGOTIATION_INFO */
2966 
2967         ret = InitHandshakeHashes(ssl);
2968         if (ret != 0) {
2969             ssl->error = ret;
2970             return WOLFSSL_FATAL_ERROR;
2971         }
2972     }
2973     ret = wolfSSL_negotiate(ssl);
2974     if (ret == WOLFSSL_SUCCESS)
2975         ssl->secure_rene_count++;
2976     return ret;
2977 }
2978 
2979 
2980 /* do a secure renegotiation handshake, user forced, we discourage */
wolfSSL_Rehandshake(WOLFSSL * ssl)2981 int wolfSSL_Rehandshake(WOLFSSL* ssl)
2982 {
2983     int ret;
2984     WOLFSSL_ENTER("wolfSSL_Rehandshake");
2985 
2986     if (ssl == NULL)
2987         return WOLFSSL_FAILURE;
2988 
2989 #ifdef HAVE_SESSION_TICKET
2990     ret = WOLFSSL_SUCCESS;
2991 #endif
2992 
2993     if (ssl->options.side == WOLFSSL_SERVER_END) {
2994         /* Reset option to send certificate verify. */
2995         ssl->options.sendVerify = 0;
2996     }
2997     else {
2998         /* Reset resuming flag to do full secure handshake. */
2999         ssl->options.resuming = 0;
3000         #ifdef HAVE_SESSION_TICKET
3001             /* Clearing the ticket. */
3002             ret = wolfSSL_UseSessionTicket(ssl);
3003         #endif
3004     }
3005 
3006 #ifdef HAVE_SESSION_TICKET
3007     if (ret == WOLFSSL_SUCCESS)
3008 #endif
3009         ret = _Rehandshake(ssl);
3010 
3011     return ret;
3012 }
3013 
3014 
3015 #ifndef NO_WOLFSSL_CLIENT
3016 
3017 /* do a secure resumption handshake, user forced, we discourage */
wolfSSL_SecureResume(WOLFSSL * ssl)3018 int wolfSSL_SecureResume(WOLFSSL* ssl)
3019 {
3020     WOLFSSL_ENTER("wolfSSL_SecureResume");
3021 
3022     if (ssl == NULL)
3023         return BAD_FUNC_ARG;
3024 
3025     if (ssl->options.side == WOLFSSL_SERVER_END) {
3026         ssl->error = SIDE_ERROR;
3027         return SSL_FATAL_ERROR;
3028     }
3029 
3030     return _Rehandshake(ssl);
3031 }
3032 
3033 #endif /* NO_WOLFSSL_CLIENT */
3034 
wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL * ssl)3035 long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
3036 {
3037     WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
3038 
3039     if (!ssl || !ssl->secure_renegotiation)
3040         return WOLFSSL_FAILURE;
3041     return ssl->secure_renegotiation->enabled;
3042 }
3043 
3044 #endif /* HAVE_SECURE_RENEGOTIATION */
3045 
3046 #if defined(HAVE_SESSION_TICKET)
3047 /* Session Ticket */
3048 
3049 #if !defined(NO_WOLFSSL_SERVER)
wolfSSL_CTX_NoTicketTLSv12(WOLFSSL_CTX * ctx)3050 int wolfSSL_CTX_NoTicketTLSv12(WOLFSSL_CTX* ctx)
3051 {
3052     if (ctx == NULL)
3053         return BAD_FUNC_ARG;
3054 
3055     ctx->noTicketTls12 = 1;
3056 
3057     return WOLFSSL_SUCCESS;
3058 }
3059 
wolfSSL_NoTicketTLSv12(WOLFSSL * ssl)3060 int wolfSSL_NoTicketTLSv12(WOLFSSL* ssl)
3061 {
3062     if (ssl == NULL)
3063         return BAD_FUNC_ARG;
3064 
3065     ssl->options.noTicketTls12 = 1;
3066 
3067     return WOLFSSL_SUCCESS;
3068 }
3069 
3070 /* WOLFSSL_SUCCESS on ok */
wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX * ctx,SessionTicketEncCb cb)3071 int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
3072 {
3073     if (ctx == NULL)
3074         return BAD_FUNC_ARG;
3075 
3076     ctx->ticketEncCb = cb;
3077 
3078     return WOLFSSL_SUCCESS;
3079 }
3080 
3081 /* set hint interval, WOLFSSL_SUCCESS on ok */
wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX * ctx,int hint)3082 int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
3083 {
3084     if (ctx == NULL)
3085         return BAD_FUNC_ARG;
3086 
3087     ctx->ticketHint = hint;
3088 
3089     return WOLFSSL_SUCCESS;
3090 }
3091 
3092 /* set user context, WOLFSSL_SUCCESS on ok */
wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX * ctx,void * userCtx)3093 int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
3094 {
3095     if (ctx == NULL)
3096         return BAD_FUNC_ARG;
3097 
3098     ctx->ticketEncCtx = userCtx;
3099 
3100     return WOLFSSL_SUCCESS;
3101 }
3102 
3103 /* get user context - returns userCtx on success, NULL on failure */
wolfSSL_CTX_get_TicketEncCtx(WOLFSSL_CTX * ctx)3104 void* wolfSSL_CTX_get_TicketEncCtx(WOLFSSL_CTX* ctx)
3105 {
3106     if (ctx == NULL)
3107         return NULL;
3108 
3109     return ctx->ticketEncCtx;
3110 }
3111 
3112 #ifdef WOLFSSL_TLS13
3113 /* set the maximum number of tickets to send
3114  * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
3115  */
wolfSSL_CTX_set_num_tickets(WOLFSSL_CTX * ctx,size_t mxTickets)3116 int wolfSSL_CTX_set_num_tickets(WOLFSSL_CTX* ctx, size_t mxTickets)
3117 {
3118     if (ctx == NULL)
3119         return WOLFSSL_FAILURE;
3120 
3121     ctx->maxTicketTls13 = (unsigned int)mxTickets;
3122     return WOLFSSL_SUCCESS;
3123 }
3124 
3125 /* get the maximum number of tickets to send
3126  * return number of tickets set to be sent
3127  */
wolfSSL_CTX_get_num_tickets(WOLFSSL_CTX * ctx)3128 size_t wolfSSL_CTX_get_num_tickets(WOLFSSL_CTX* ctx)
3129 {
3130     if (ctx == NULL)
3131         return 0;
3132 
3133     return (size_t)ctx->maxTicketTls13;
3134 }
3135 #endif /* WOLFSSL_TLS13 */
3136 #endif /* !NO_WOLFSSL_SERVER */
3137 
3138 #if !defined(NO_WOLFSSL_CLIENT)
wolfSSL_UseSessionTicket(WOLFSSL * ssl)3139 int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
3140 {
3141     if (ssl == NULL)
3142         return BAD_FUNC_ARG;
3143 
3144     return TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
3145 }
3146 
wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX * ctx)3147 int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
3148 {
3149     if (ctx == NULL)
3150         return BAD_FUNC_ARG;
3151 
3152     return TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
3153 }
3154 
wolfSSL_get_SessionTicket(WOLFSSL * ssl,byte * buf,word32 * bufSz)3155 WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl,
3156                                           byte* buf, word32* bufSz)
3157 {
3158     if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
3159         return BAD_FUNC_ARG;
3160 
3161     if (ssl->session.ticketLen <= *bufSz) {
3162         XMEMCPY(buf, ssl->session.ticket, ssl->session.ticketLen);
3163         *bufSz = ssl->session.ticketLen;
3164     }
3165     else
3166         *bufSz = 0;
3167 
3168     return WOLFSSL_SUCCESS;
3169 }
3170 
wolfSSL_set_SessionTicket(WOLFSSL * ssl,const byte * buf,word32 bufSz)3171 WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
3172                                           word32 bufSz)
3173 {
3174     if (ssl == NULL || (buf == NULL && bufSz > 0))
3175         return BAD_FUNC_ARG;
3176 
3177     if (bufSz > 0) {
3178         /* Ticket will fit into static ticket */
3179         if (bufSz <= SESSION_TICKET_LEN) {
3180             if (ssl->session.ticketLenAlloc > 0) {
3181                 XFREE(ssl->session.ticket, ssl->heap,
3182                       DYNAMIC_TYPE_SESSION_TICK);
3183                 ssl->session.ticketLenAlloc = 0;
3184                 ssl->session.ticket = ssl->session._staticTicket;
3185             }
3186         }
3187         else { /* Ticket requires dynamic ticket storage */
3188             if (ssl->session.ticketLen < bufSz) { /* is dyn buffer big enough */
3189                 if (ssl->session.ticketLenAlloc > 0) {
3190                     XFREE(ssl->session.ticket, ssl->heap,
3191                           DYNAMIC_TYPE_SESSION_TICK);
3192                 }
3193                 ssl->session.ticket = (byte*)XMALLOC(bufSz, ssl->heap,
3194                         DYNAMIC_TYPE_SESSION_TICK);
3195                 if(ssl->session.ticket == NULL) {
3196                     ssl->session.ticket = ssl->session._staticTicket;
3197                     ssl->session.ticketLenAlloc = 0;
3198                     return MEMORY_ERROR;
3199                 }
3200                 ssl->session.ticketLenAlloc = (word16)bufSz;
3201             }
3202         }
3203         XMEMCPY(ssl->session.ticket, buf, bufSz);
3204     }
3205     ssl->session.ticketLen = (word16)bufSz;
3206 
3207     return WOLFSSL_SUCCESS;
3208 }
3209 
3210 
wolfSSL_set_SessionTicket_cb(WOLFSSL * ssl,CallbackSessionTicket cb,void * ctx)3211 WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
3212                                             CallbackSessionTicket cb, void* ctx)
3213 {
3214     if (ssl == NULL)
3215         return BAD_FUNC_ARG;
3216 
3217     ssl->session_ticket_cb = cb;
3218     ssl->session_ticket_ctx = ctx;
3219 
3220     return WOLFSSL_SUCCESS;
3221 }
3222 #endif /* !NO_WOLFSSL_CLIENT */
3223 
3224 #endif /* HAVE_SESSION_TICKET */
3225 
3226 
3227 #ifdef HAVE_EXTENDED_MASTER
3228 #ifndef NO_WOLFSSL_CLIENT
3229 
wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX * ctx)3230 int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
3231 {
3232     if (ctx == NULL)
3233         return BAD_FUNC_ARG;
3234 
3235     ctx->haveEMS = 0;
3236 
3237     return WOLFSSL_SUCCESS;
3238 }
3239 
3240 
wolfSSL_DisableExtendedMasterSecret(WOLFSSL * ssl)3241 int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
3242 {
3243     if (ssl == NULL)
3244         return BAD_FUNC_ARG;
3245 
3246     ssl->options.haveEMS = 0;
3247 
3248     return WOLFSSL_SUCCESS;
3249 }
3250 
3251 #endif
3252 #endif
3253 
3254 
3255 #ifndef WOLFSSL_LEANPSK
3256 
wolfSSL_send(WOLFSSL * ssl,const void * data,int sz,int flags)3257 int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
3258 {
3259     int ret;
3260     int oldFlags;
3261 
3262     WOLFSSL_ENTER("wolfSSL_send()");
3263 
3264     if (ssl == NULL || data == NULL || sz < 0)
3265         return BAD_FUNC_ARG;
3266 
3267     oldFlags = ssl->wflags;
3268 
3269     ssl->wflags = flags;
3270     ret = wolfSSL_write(ssl, data, sz);
3271     ssl->wflags = oldFlags;
3272 
3273     WOLFSSL_LEAVE("wolfSSL_send()", ret);
3274 
3275     return ret;
3276 }
3277 
3278 
wolfSSL_recv(WOLFSSL * ssl,void * data,int sz,int flags)3279 int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
3280 {
3281     int ret;
3282     int oldFlags;
3283 
3284     WOLFSSL_ENTER("wolfSSL_recv()");
3285 
3286     if (ssl == NULL || data == NULL || sz < 0)
3287         return BAD_FUNC_ARG;
3288 
3289     oldFlags = ssl->rflags;
3290 
3291     ssl->rflags = flags;
3292     ret = wolfSSL_read(ssl, data, sz);
3293     ssl->rflags = oldFlags;
3294 
3295     WOLFSSL_LEAVE("wolfSSL_recv()", ret);
3296 
3297     return ret;
3298 }
3299 #endif
3300 
3301 
3302 /* WOLFSSL_SUCCESS on ok */
3303 WOLFSSL_ABI
wolfSSL_shutdown(WOLFSSL * ssl)3304 int wolfSSL_shutdown(WOLFSSL* ssl)
3305 {
3306     int  ret = WOLFSSL_FATAL_ERROR;
3307     WOLFSSL_ENTER("SSL_shutdown()");
3308 
3309     if (ssl == NULL)
3310         return WOLFSSL_FATAL_ERROR;
3311 
3312     if (ssl->options.quietShutdown) {
3313         WOLFSSL_MSG("quiet shutdown, no close notify sent");
3314         ret = WOLFSSL_SUCCESS;
3315     }
3316     else {
3317         /* try to send close notify, not an error if can't */
3318         if (!ssl->options.isClosed && !ssl->options.connReset &&
3319                                       !ssl->options.sentNotify) {
3320             ssl->error = SendAlert(ssl, alert_warning, close_notify);
3321             if (ssl->error < 0) {
3322                 WOLFSSL_ERROR(ssl->error);
3323                 return WOLFSSL_FATAL_ERROR;
3324             }
3325             ssl->options.sentNotify = 1;  /* don't send close_notify twice */
3326             if (ssl->options.closeNotify)
3327                 ret = WOLFSSL_SUCCESS;
3328             else {
3329                 ret = WOLFSSL_SHUTDOWN_NOT_DONE;
3330                 WOLFSSL_LEAVE("SSL_shutdown()", ret);
3331                 return ret;
3332             }
3333         }
3334 
3335 #ifdef WOLFSSL_SHUTDOWNONCE
3336         if (ssl->options.isClosed || ssl->options.connReset) {
3337             /* Shutdown has already occurred.
3338              * Caller is free to ignore this error. */
3339             return SSL_SHUTDOWN_ALREADY_DONE_E;
3340         }
3341 #endif
3342 
3343         /* call wolfSSL_shutdown again for bidirectional shutdown */
3344         if (ssl->options.sentNotify && !ssl->options.closeNotify) {
3345             ret = ProcessReply(ssl);
3346             if (ret == ZERO_RETURN) {
3347                 /* simulate OpenSSL behavior */
3348                 ssl->error = WOLFSSL_ERROR_SYSCALL;
3349                 ret = WOLFSSL_SUCCESS;
3350             } else if (ssl->error == WOLFSSL_ERROR_NONE) {
3351                 ret = WOLFSSL_SHUTDOWN_NOT_DONE;
3352             } else {
3353                 WOLFSSL_ERROR(ssl->error);
3354                 ret = WOLFSSL_FATAL_ERROR;
3355             }
3356         }
3357     }
3358 
3359 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
3360     /* reset WOLFSSL structure state for possible re-use */
3361     if (ret == WOLFSSL_SUCCESS) {
3362         if (wolfSSL_clear(ssl) != WOLFSSL_SUCCESS) {
3363             WOLFSSL_MSG("could not clear WOLFSSL");
3364             ret = WOLFSSL_FATAL_ERROR;
3365         }
3366     }
3367 #endif
3368 
3369     WOLFSSL_LEAVE("SSL_shutdown()", ret);
3370 
3371     return ret;
3372 }
3373 
3374 
3375 /* get current error state value */
wolfSSL_state(WOLFSSL * ssl)3376 int wolfSSL_state(WOLFSSL* ssl)
3377 {
3378     if (ssl == NULL) {
3379         return BAD_FUNC_ARG;
3380     }
3381 
3382     return ssl->error;
3383 }
3384 
3385 
3386 WOLFSSL_ABI
wolfSSL_get_error(WOLFSSL * ssl,int ret)3387 int wolfSSL_get_error(WOLFSSL* ssl, int ret)
3388 {
3389     WOLFSSL_ENTER("SSL_get_error");
3390 
3391     if (ret > 0)
3392         return WOLFSSL_ERROR_NONE;
3393     if (ssl == NULL)
3394         return BAD_FUNC_ARG;
3395 
3396     WOLFSSL_LEAVE("SSL_get_error", ssl->error);
3397 
3398     /* make sure converted types are handled in SetErrorString() too */
3399     if (ssl->error == WANT_READ)
3400         return WOLFSSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
3401     else if (ssl->error == WANT_WRITE)
3402         return WOLFSSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
3403     else if (ssl->error == ZERO_RETURN)
3404         return WOLFSSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
3405     return ssl->error;
3406 }
3407 
3408 
3409 /* retrieve alert history, WOLFSSL_SUCCESS on ok */
wolfSSL_get_alert_history(WOLFSSL * ssl,WOLFSSL_ALERT_HISTORY * h)3410 int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
3411 {
3412     if (ssl && h) {
3413         *h = ssl->alert_history;
3414     }
3415     return WOLFSSL_SUCCESS;
3416 }
3417 
3418 #ifdef OPENSSL_EXTRA
3419 /* returns SSL_WRITING, SSL_READING or SSL_NOTHING */
wolfSSL_want(WOLFSSL * ssl)3420 int wolfSSL_want(WOLFSSL* ssl)
3421 {
3422     int rw_state = SSL_NOTHING;
3423     if (ssl) {
3424         if (ssl->error == WANT_READ)
3425             rw_state = SSL_READING;
3426         else if (ssl->error == WANT_WRITE)
3427             rw_state = SSL_WRITING;
3428     }
3429     return rw_state;
3430 }
3431 #endif
3432 
3433 /* return TRUE if current error is want read */
wolfSSL_want_read(WOLFSSL * ssl)3434 int wolfSSL_want_read(WOLFSSL* ssl)
3435 {
3436     WOLFSSL_ENTER("SSL_want_read");
3437     if (ssl->error == WANT_READ)
3438         return 1;
3439 
3440     return 0;
3441 }
3442 
3443 
3444 /* return TRUE if current error is want write */
wolfSSL_want_write(WOLFSSL * ssl)3445 int wolfSSL_want_write(WOLFSSL* ssl)
3446 {
3447     WOLFSSL_ENTER("SSL_want_write");
3448     if (ssl->error == WANT_WRITE)
3449         return 1;
3450 
3451     return 0;
3452 }
3453 
3454 
wolfSSL_ERR_error_string(unsigned long errNumber,char * data)3455 char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
3456 {
3457     static char tmp[WOLFSSL_MAX_ERROR_SZ] = {0};
3458 
3459     WOLFSSL_ENTER("ERR_error_string");
3460     if (data) {
3461         SetErrorString((int)errNumber, data);
3462         return data;
3463     }
3464     else {
3465         SetErrorString((int)errNumber, tmp);
3466         return tmp;
3467     }
3468 }
3469 
3470 
wolfSSL_ERR_error_string_n(unsigned long e,char * buf,unsigned long len)3471 void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
3472 {
3473     WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
3474     if (len >= WOLFSSL_MAX_ERROR_SZ)
3475         wolfSSL_ERR_error_string(e, buf);
3476     else {
3477         char tmp[WOLFSSL_MAX_ERROR_SZ];
3478 
3479         WOLFSSL_MSG("Error buffer too short, truncating");
3480         if (len) {
3481             wolfSSL_ERR_error_string(e, tmp);
3482             XMEMCPY(buf, tmp, len-1);
3483             buf[len-1] = '\0';
3484         }
3485     }
3486 }
3487 
3488 
3489 /* don't free temporary arrays at end of handshake */
wolfSSL_KeepArrays(WOLFSSL * ssl)3490 void wolfSSL_KeepArrays(WOLFSSL* ssl)
3491 {
3492     if (ssl)
3493         ssl->options.saveArrays = 1;
3494 }
3495 
3496 
3497 /* user doesn't need temporary arrays anymore, Free */
wolfSSL_FreeArrays(WOLFSSL * ssl)3498 void wolfSSL_FreeArrays(WOLFSSL* ssl)
3499 {
3500     if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
3501         ssl->options.saveArrays = 0;
3502         FreeArrays(ssl, 1);
3503     }
3504 }
3505 
3506 /* Set option to indicate that the resources are not to be freed after
3507  * handshake.
3508  *
3509  * ssl  The SSL/TLS object.
3510  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3511  */
wolfSSL_KeepHandshakeResources(WOLFSSL * ssl)3512 int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl)
3513 {
3514     if (ssl == NULL)
3515         return BAD_FUNC_ARG;
3516 
3517     ssl->options.keepResources = 1;
3518 
3519     return 0;
3520 }
3521 
3522 /* Free the handshake resources after handshake.
3523  *
3524  * ssl  The SSL/TLS object.
3525  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3526  */
wolfSSL_FreeHandshakeResources(WOLFSSL * ssl)3527 int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl)
3528 {
3529     if (ssl == NULL)
3530         return BAD_FUNC_ARG;
3531 
3532     FreeHandshakeResources(ssl);
3533 
3534     return 0;
3535 }
3536 
3537 /* Use the client's order of preference when matching cipher suites.
3538  *
3539  * ssl  The SSL/TLS context object.
3540  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3541  */
wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX * ctx)3542 int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx)
3543 {
3544     if (ctx == NULL)
3545         return BAD_FUNC_ARG;
3546 
3547     ctx->useClientOrder = 1;
3548 
3549     return 0;
3550 }
3551 
3552 /* Use the client's order of preference when matching cipher suites.
3553  *
3554  * ssl  The SSL/TLS object.
3555  * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3556  */
wolfSSL_UseClientSuites(WOLFSSL * ssl)3557 int wolfSSL_UseClientSuites(WOLFSSL* ssl)
3558 {
3559     if (ssl == NULL)
3560         return BAD_FUNC_ARG;
3561 
3562     ssl->options.useClientOrder = 1;
3563 
3564     return 0;
3565 }
3566 
3567 #ifdef WOLFSSL_DTLS
wolfSSL_GetDtlsMacSecret(WOLFSSL * ssl,int verify,int epochOrder)3568 const byte* wolfSSL_GetDtlsMacSecret(WOLFSSL* ssl, int verify, int epochOrder)
3569 {
3570 #ifndef WOLFSSL_AEAD_ONLY
3571     Keys* keys = NULL;
3572 
3573     (void)epochOrder;
3574 
3575     if (ssl == NULL)
3576         return NULL;
3577 
3578 #ifdef HAVE_SECURE_RENEGOTIATION
3579     switch (epochOrder) {
3580     case PEER_ORDER:
3581         if (IsDtlsMsgSCRKeys(ssl))
3582             keys = &ssl->secure_renegotiation->tmp_keys;
3583         else
3584             keys = &ssl->keys;
3585         break;
3586     case PREV_ORDER:
3587         keys = &ssl->keys;
3588         break;
3589     case CUR_ORDER:
3590         if (DtlsUseSCRKeys(ssl))
3591             keys = &ssl->secure_renegotiation->tmp_keys;
3592         else
3593             keys = &ssl->keys;
3594         break;
3595     default:
3596         WOLFSSL_MSG("Unknown epoch order");
3597         return NULL;
3598     }
3599 #else
3600     keys = &ssl->keys;
3601 #endif
3602 
3603     if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
3604          (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
3605         return keys->client_write_MAC_secret;
3606     else
3607         return keys->server_write_MAC_secret;
3608 #else
3609     (void)ssl;
3610     (void)verify;
3611     (void)epochOrder;
3612 
3613     return NULL;
3614 #endif
3615 }
3616 #endif /* WOLFSSL_DTLS */
3617 
wolfSSL_GetMacSecret(WOLFSSL * ssl,int verify)3618 const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
3619 {
3620 #ifndef WOLFSSL_AEAD_ONLY
3621     if (ssl == NULL)
3622         return NULL;
3623 
3624     if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
3625          (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
3626         return ssl->keys.client_write_MAC_secret;
3627     else
3628         return ssl->keys.server_write_MAC_secret;
3629 #else
3630     (void)ssl;
3631     (void)verify;
3632 
3633     return NULL;
3634 #endif
3635 }
3636 
3637 
3638 #ifdef ATOMIC_USER
3639 
wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX * ctx,CallbackMacEncrypt cb)3640 void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
3641 {
3642     if (ctx)
3643         ctx->MacEncryptCb = cb;
3644 }
3645 
3646 
wolfSSL_SetMacEncryptCtx(WOLFSSL * ssl,void * ctx)3647 void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
3648 {
3649     if (ssl)
3650         ssl->MacEncryptCtx = ctx;
3651 }
3652 
3653 
wolfSSL_GetMacEncryptCtx(WOLFSSL * ssl)3654 void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
3655 {
3656     if (ssl)
3657         return ssl->MacEncryptCtx;
3658 
3659     return NULL;
3660 }
3661 
3662 
wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX * ctx,CallbackDecryptVerify cb)3663 void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
3664 {
3665     if (ctx)
3666         ctx->DecryptVerifyCb = cb;
3667 }
3668 
3669 
wolfSSL_SetDecryptVerifyCtx(WOLFSSL * ssl,void * ctx)3670 void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
3671 {
3672     if (ssl)
3673         ssl->DecryptVerifyCtx = ctx;
3674 }
3675 
3676 
wolfSSL_GetDecryptVerifyCtx(WOLFSSL * ssl)3677 void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
3678 {
3679     if (ssl)
3680         return ssl->DecryptVerifyCtx;
3681 
3682     return NULL;
3683 }
3684 
3685 #if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
3686 /**
3687  * Set the callback, against the context, that encrypts then MACs.
3688  *
3689  * ctx  SSL/TLS context.
3690  * cb   Callback function to use with Encrypt-Then-MAC.
3691  */
wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX * ctx,CallbackEncryptMac cb)3692 void  wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX* ctx, CallbackEncryptMac cb)
3693 {
3694     if (ctx)
3695         ctx->EncryptMacCb = cb;
3696 }
3697 
3698 /**
3699  * Set the context to use with callback that encrypts then MACs.
3700  *
3701  * ssl  SSL/TLS object.
3702  * ctx  Callback function's context.
3703  */
wolfSSL_SetEncryptMacCtx(WOLFSSL * ssl,void * ctx)3704 void  wolfSSL_SetEncryptMacCtx(WOLFSSL* ssl, void *ctx)
3705 {
3706     if (ssl)
3707         ssl->EncryptMacCtx = ctx;
3708 }
3709 
3710 /**
3711  * Get the context being used with callback that encrypts then MACs.
3712  *
3713  * ssl  SSL/TLS object.
3714  * returns callback function's context or NULL if SSL/TLS object is NULL.
3715  */
wolfSSL_GetEncryptMacCtx(WOLFSSL * ssl)3716 void* wolfSSL_GetEncryptMacCtx(WOLFSSL* ssl)
3717 {
3718     if (ssl)
3719         return ssl->EncryptMacCtx;
3720 
3721     return NULL;
3722 }
3723 
3724 
3725 /**
3726  * Set the callback, against the context, that MAC verifies then decrypts.
3727  *
3728  * ctx  SSL/TLS context.
3729  * cb   Callback function to use with Encrypt-Then-MAC.
3730  */
wolfSSL_CTX_SetVerifyDecryptCb(WOLFSSL_CTX * ctx,CallbackVerifyDecrypt cb)3731 void  wolfSSL_CTX_SetVerifyDecryptCb(WOLFSSL_CTX* ctx, CallbackVerifyDecrypt cb)
3732 {
3733     if (ctx)
3734         ctx->VerifyDecryptCb = cb;
3735 }
3736 
3737 /**
3738  * Set the context to use with callback that MAC verifies then decrypts.
3739  *
3740  * ssl  SSL/TLS object.
3741  * ctx  Callback function's context.
3742  */
wolfSSL_SetVerifyDecryptCtx(WOLFSSL * ssl,void * ctx)3743 void  wolfSSL_SetVerifyDecryptCtx(WOLFSSL* ssl, void *ctx)
3744 {
3745     if (ssl)
3746         ssl->VerifyDecryptCtx = ctx;
3747 }
3748 
3749 /**
3750  * Get the context being used with callback that MAC verifies then decrypts.
3751  *
3752  * ssl  SSL/TLS object.
3753  * returns callback function's context or NULL if SSL/TLS object is NULL.
3754  */
wolfSSL_GetVerifyDecryptCtx(WOLFSSL * ssl)3755 void* wolfSSL_GetVerifyDecryptCtx(WOLFSSL* ssl)
3756 {
3757     if (ssl)
3758         return ssl->VerifyDecryptCtx;
3759 
3760     return NULL;
3761 }
3762 #endif /* HAVE_ENCRYPT_THEN_MAC !WOLFSSL_AEAD_ONLY */
3763 
3764 
3765 
wolfSSL_GetClientWriteKey(WOLFSSL * ssl)3766 const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
3767 {
3768     if (ssl)
3769         return ssl->keys.client_write_key;
3770 
3771     return NULL;
3772 }
3773 
3774 
wolfSSL_GetClientWriteIV(WOLFSSL * ssl)3775 const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
3776 {
3777     if (ssl)
3778         return ssl->keys.client_write_IV;
3779 
3780     return NULL;
3781 }
3782 
3783 
wolfSSL_GetServerWriteKey(WOLFSSL * ssl)3784 const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
3785 {
3786     if (ssl)
3787         return ssl->keys.server_write_key;
3788 
3789     return NULL;
3790 }
3791 
3792 
wolfSSL_GetServerWriteIV(WOLFSSL * ssl)3793 const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
3794 {
3795     if (ssl)
3796         return ssl->keys.server_write_IV;
3797 
3798     return NULL;
3799 }
3800 
wolfSSL_GetKeySize(WOLFSSL * ssl)3801 int wolfSSL_GetKeySize(WOLFSSL* ssl)
3802 {
3803     if (ssl)
3804         return ssl->specs.key_size;
3805 
3806     return BAD_FUNC_ARG;
3807 }
3808 
3809 
wolfSSL_GetIVSize(WOLFSSL * ssl)3810 int wolfSSL_GetIVSize(WOLFSSL* ssl)
3811 {
3812     if (ssl)
3813         return ssl->specs.iv_size;
3814 
3815     return BAD_FUNC_ARG;
3816 }
3817 
3818 
wolfSSL_GetBulkCipher(WOLFSSL * ssl)3819 int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
3820 {
3821     if (ssl)
3822         return ssl->specs.bulk_cipher_algorithm;
3823 
3824     return BAD_FUNC_ARG;
3825 }
3826 
3827 
wolfSSL_GetCipherType(WOLFSSL * ssl)3828 int wolfSSL_GetCipherType(WOLFSSL* ssl)
3829 {
3830     if (ssl == NULL)
3831         return BAD_FUNC_ARG;
3832 
3833 #ifndef WOLFSSL_AEAD_ONLY
3834     if (ssl->specs.cipher_type == block)
3835         return WOLFSSL_BLOCK_TYPE;
3836     if (ssl->specs.cipher_type == stream)
3837         return WOLFSSL_STREAM_TYPE;
3838 #endif
3839     if (ssl->specs.cipher_type == aead)
3840         return WOLFSSL_AEAD_TYPE;
3841 
3842     return -1;
3843 }
3844 
3845 
wolfSSL_GetCipherBlockSize(WOLFSSL * ssl)3846 int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
3847 {
3848     if (ssl == NULL)
3849         return BAD_FUNC_ARG;
3850 
3851     return ssl->specs.block_size;
3852 }
3853 
3854 
wolfSSL_GetAeadMacSize(WOLFSSL * ssl)3855 int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
3856 {
3857     if (ssl == NULL)
3858         return BAD_FUNC_ARG;
3859 
3860     return ssl->specs.aead_mac_size;
3861 }
3862 
3863 
wolfSSL_IsTLSv1_1(WOLFSSL * ssl)3864 int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
3865 {
3866     if (ssl == NULL)
3867         return BAD_FUNC_ARG;
3868 
3869     if (ssl->options.tls1_1)
3870         return 1;
3871 
3872     return 0;
3873 }
3874 
3875 
wolfSSL_GetSide(WOLFSSL * ssl)3876 int wolfSSL_GetSide(WOLFSSL* ssl)
3877 {
3878     if (ssl)
3879         return ssl->options.side;
3880 
3881     return BAD_FUNC_ARG;
3882 }
3883 
3884 
wolfSSL_GetHmacSize(WOLFSSL * ssl)3885 int wolfSSL_GetHmacSize(WOLFSSL* ssl)
3886 {
3887     /* AEAD ciphers don't have HMAC keys */
3888     if (ssl)
3889         return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
3890 
3891     return BAD_FUNC_ARG;
3892 }
3893 
3894 #endif /* ATOMIC_USER */
3895 
3896 #ifndef NO_CERTS
3897 
wolfSSL_CTX_GetCertManager(WOLFSSL_CTX * ctx)3898 WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx)
3899 {
3900     WOLFSSL_CERT_MANAGER* cm = NULL;
3901     if (ctx)
3902         cm = ctx->cm;
3903     return cm;
3904 }
3905 
wolfSSL_CertManagerNew_ex(void * heap)3906 WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
3907 {
3908     WOLFSSL_CERT_MANAGER* cm;
3909 
3910     WOLFSSL_ENTER("wolfSSL_CertManagerNew");
3911 
3912     cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), heap,
3913                                          DYNAMIC_TYPE_CERT_MANAGER);
3914     if (cm) {
3915         XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
3916         cm->refCount = 1;
3917 
3918         if (wc_InitMutex(&cm->caLock) != 0) {
3919             WOLFSSL_MSG("Bad mutex init");
3920             wolfSSL_CertManagerFree(cm);
3921             return NULL;
3922         }
3923         #ifndef SINGLE_THREADED
3924         if (wc_InitMutex(&cm->refMutex) != 0) {
3925             WOLFSSL_MSG("Bad mutex init");
3926             wolfSSL_CertManagerFree(cm);
3927             return NULL;
3928         }
3929         #endif
3930 
3931         #ifdef WOLFSSL_TRUST_PEER_CERT
3932         if (wc_InitMutex(&cm->tpLock) != 0) {
3933             WOLFSSL_MSG("Bad mutex init");
3934             wolfSSL_CertManagerFree(cm);
3935             return NULL;
3936         }
3937         #endif
3938 
3939         /* set default minimum key size allowed */
3940         #ifndef NO_RSA
3941             cm->minRsaKeySz = MIN_RSAKEY_SZ;
3942         #endif
3943         #ifdef HAVE_ECC
3944             cm->minEccKeySz = MIN_ECCKEY_SZ;
3945         #endif
3946         #ifdef HAVE_PQC
3947             cm->minFalconKeySz = MIN_FALCONKEY_SZ;
3948         #endif
3949 
3950             cm->heap = heap;
3951     }
3952 
3953     return cm;
3954 }
3955 
3956 
wolfSSL_CertManagerNew(void)3957 WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
3958 {
3959     return wolfSSL_CertManagerNew_ex(NULL);
3960 }
3961 
3962 
wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER * cm)3963 void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
3964 {
3965     int doFree = 0;
3966     WOLFSSL_ENTER("wolfSSL_CertManagerFree");
3967 
3968     if (cm) {
3969         #ifndef SINGLE_THREADED
3970         if (wc_LockMutex(&cm->refMutex) != 0) {
3971             WOLFSSL_MSG("Couldn't lock cm mutex");
3972         }
3973         #endif
3974         cm->refCount--;
3975         if (cm->refCount == 0)
3976             doFree = 1;
3977         #ifndef SINGLE_THREADED
3978         wc_UnLockMutex(&cm->refMutex);
3979         #endif
3980         if (doFree) {
3981             #ifdef HAVE_CRL
3982                 if (cm->crl)
3983                     FreeCRL(cm->crl, 1);
3984             #endif
3985             #ifdef HAVE_OCSP
3986                 if (cm->ocsp)
3987                     FreeOCSP(cm->ocsp, 1);
3988                 XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
3989             #if !defined(NO_WOLFSSL_SERVER) && \
3990                 (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
3991                  defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
3992                 if (cm->ocsp_stapling)
3993                     FreeOCSP(cm->ocsp_stapling, 1);
3994             #endif
3995             #endif
3996             FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
3997             wc_FreeMutex(&cm->caLock);
3998 
3999             #ifdef WOLFSSL_TRUST_PEER_CERT
4000             FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
4001             wc_FreeMutex(&cm->tpLock);
4002             #endif
4003             #ifndef SINGLE_THREADED
4004             if (wc_FreeMutex(&cm->refMutex) != 0) {
4005                 WOLFSSL_MSG("Couldn't free refMutex mutex");
4006             }
4007             #endif
4008             XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER);
4009         }
4010     }
4011 
4012 }
4013 
wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER * cm)4014 int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm)
4015 {
4016     if (cm) {
4017 #ifndef SINGLE_THREADED
4018         if (wc_LockMutex(&cm->refMutex) != 0) {
4019             WOLFSSL_MSG("Failed to lock cm mutex");
4020         }
4021 #endif
4022         cm->refCount++;
4023 #ifndef SINGLE_THREADED
4024         wc_UnLockMutex(&cm->refMutex);
4025 #endif
4026 
4027         return WOLFSSL_SUCCESS;
4028     }
4029 
4030     return WOLFSSL_FAILURE;
4031 }
4032 
4033 #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
4034 #if defined(WOLFSSL_SIGNER_DER_CERT)
4035 /******************************************************************************
4036 * wolfSSL_CertManagerGetCerts - retrieve stack of X509 certificates in a
4037 * certificate manager (CM).
4038 *
4039 * RETURNS:
4040 * returns stack of X509 certs on success, otherwise returns a NULL.
4041 */
wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER * cm)4042 WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm)
4043 {
4044     WOLFSSL_STACK* sk = NULL;
4045     int numCerts = 0;
4046     DerBuffer** certBuffers = NULL;
4047     const byte* derBuffer = NULL;
4048     Signer* signers = NULL;
4049     word32  row = 0;
4050     WOLFSSL_X509* x509 = NULL;
4051     int i = 0;
4052     int ret = 0;
4053 
4054     if (cm == NULL)
4055         return NULL;
4056 
4057     sk = wolfSSL_sk_X509_new();
4058     if (sk == NULL)
4059         goto error;
4060 
4061     if (wc_LockMutex(&cm->caLock) != 0)
4062         goto error;
4063 
4064     /* Iterate once to get the number of certs, for memory allocation
4065        purposes. */
4066     for (row = 0; row < CA_TABLE_SIZE; row++) {
4067         signers = cm->caTable[row];
4068         while (signers && signers->derCert && signers->derCert->buffer) {
4069             ++numCerts;
4070             signers = signers->next;
4071         }
4072     }
4073 
4074     if (numCerts == 0) {
4075         wc_UnLockMutex(&cm->caLock);
4076         goto error;
4077     }
4078 
4079     certBuffers = (DerBuffer**)XMALLOC(sizeof(DerBuffer*) * numCerts, cm->heap,
4080                                        DYNAMIC_TYPE_TMP_BUFFER);
4081     if (certBuffers == NULL) {
4082         wc_UnLockMutex(&cm->caLock);
4083         goto error;
4084     }
4085     XMEMSET(certBuffers, 0, sizeof(DerBuffer*) * numCerts);
4086 
4087     /* Copy the certs locally so that we can release the caLock. If the lock is
4088        held when wolfSSL_d2i_X509 is called, GetCA will also try to get the
4089        lock, leading to deadlock. */
4090     for (row = 0; row < CA_TABLE_SIZE; row++) {
4091         signers = cm->caTable[row];
4092         while (signers && signers->derCert && signers->derCert->buffer) {
4093             ret = AllocDer(&certBuffers[i], signers->derCert->length, CA_TYPE,
4094                            cm->heap);
4095             if (ret < 0) {
4096                 wc_UnLockMutex(&cm->caLock);
4097                 goto error;
4098             }
4099 
4100             XMEMCPY(certBuffers[i]->buffer, signers->derCert->buffer,
4101                     signers->derCert->length);
4102             certBuffers[i]->length = signers->derCert->length;
4103 
4104             ++i;
4105             signers = signers->next;
4106         }
4107     }
4108 
4109     wc_UnLockMutex(&cm->caLock);
4110 
4111     for (i = 0; i < numCerts; ++i) {
4112         derBuffer = certBuffers[i]->buffer;
4113         wolfSSL_d2i_X509(&x509, &derBuffer, certBuffers[i]->length);
4114         if (x509 == NULL)
4115             goto error;
4116 
4117         if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS)
4118             goto error;
4119     }
4120 
4121     for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) {
4122         FreeDer(&certBuffers[i]);
4123     }
4124 
4125     XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4126 
4127     return sk;
4128 
4129 error:
4130     if (sk)
4131         wolfSSL_sk_X509_pop_free(sk, NULL);
4132 
4133     if (certBuffers != NULL) {
4134         for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) {
4135             FreeDer(&certBuffers[i]);
4136         }
4137     }
4138 
4139     if (certBuffers)
4140         XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4141 
4142     return NULL;
4143 }
4144 
4145 #endif /* WOLFSSL_SIGNER_DER_CERT */
4146 #endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */
4147 
4148 /* Unload the CA signer list */
wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER * cm)4149 int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
4150 {
4151     WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
4152 
4153     if (cm == NULL)
4154         return BAD_FUNC_ARG;
4155 
4156     if (wc_LockMutex(&cm->caLock) != 0)
4157         return BAD_MUTEX_E;
4158 
4159     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
4160 
4161     wc_UnLockMutex(&cm->caLock);
4162 
4163 
4164     return WOLFSSL_SUCCESS;
4165 }
4166 
4167 
4168 #ifdef WOLFSSL_TRUST_PEER_CERT
wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER * cm)4169 int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm)
4170 {
4171     WOLFSSL_ENTER("wolfSSL_CertManagerUnload_trust_peers");
4172 
4173     if (cm == NULL)
4174         return BAD_FUNC_ARG;
4175 
4176     if (wc_LockMutex(&cm->tpLock) != 0)
4177         return BAD_MUTEX_E;
4178 
4179     FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
4180 
4181     wc_UnLockMutex(&cm->tpLock);
4182 
4183 
4184     return WOLFSSL_SUCCESS;
4185 }
4186 #endif /* WOLFSSL_TRUST_PEER_CERT */
4187 
4188 #endif /* NO_CERTS */
4189 
4190 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
4191 
wolfSSL_ERR_print_errors_fp(XFILE fp,int err)4192 void wolfSSL_ERR_print_errors_fp(XFILE fp, int err)
4193 {
4194     char data[WOLFSSL_MAX_ERROR_SZ + 1];
4195 
4196     WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
4197     SetErrorString(err, data);
4198     XFPRINTF(fp, "%s", data);
4199 }
4200 
4201 #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
wolfSSL_ERR_dump_errors_fp(XFILE fp)4202 void wolfSSL_ERR_dump_errors_fp(XFILE fp)
4203 {
4204     wc_ERR_print_errors_fp(fp);
4205 }
4206 
wolfSSL_ERR_print_errors_cb(int (* cb)(const char * str,size_t len,void * u),void * u)4207 void wolfSSL_ERR_print_errors_cb (int (*cb)(const char *str, size_t len,
4208                                             void *u), void *u)
4209 {
4210     wc_ERR_print_errors_cb(cb, u);
4211 }
4212 #endif
4213 #endif
4214 
4215 WOLFSSL_ABI
wolfSSL_pending(WOLFSSL * ssl)4216 int wolfSSL_pending(WOLFSSL* ssl)
4217 {
4218     WOLFSSL_ENTER("SSL_pending");
4219     if (ssl == NULL)
4220         return WOLFSSL_FAILURE;
4221 
4222     return ssl->buffers.clearOutputBuffer.length;
4223 }
4224 
4225 
4226 #ifndef WOLFSSL_LEANPSK
4227 /* turn on handshake group messages for context */
wolfSSL_CTX_set_group_messages(WOLFSSL_CTX * ctx)4228 int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
4229 {
4230     if (ctx == NULL)
4231        return BAD_FUNC_ARG;
4232 
4233     ctx->groupMessages = 1;
4234 
4235     return WOLFSSL_SUCCESS;
4236 }
4237 #endif
4238 
4239 
4240 #ifndef NO_WOLFSSL_CLIENT
4241 /* connect enough to get peer cert chain */
wolfSSL_connect_cert(WOLFSSL * ssl)4242 int wolfSSL_connect_cert(WOLFSSL* ssl)
4243 {
4244     int  ret;
4245 
4246     if (ssl == NULL)
4247         return WOLFSSL_FAILURE;
4248 
4249     ssl->options.certOnly = 1;
4250     ret = wolfSSL_connect(ssl);
4251     ssl->options.certOnly   = 0;
4252 
4253     return ret;
4254 }
4255 #endif
4256 
4257 
4258 #ifndef WOLFSSL_LEANPSK
4259 /* turn on handshake group messages for ssl object */
wolfSSL_set_group_messages(WOLFSSL * ssl)4260 int wolfSSL_set_group_messages(WOLFSSL* ssl)
4261 {
4262     if (ssl == NULL)
4263        return BAD_FUNC_ARG;
4264 
4265     ssl->options.groupMessages = 1;
4266 
4267     return WOLFSSL_SUCCESS;
4268 }
4269 
4270 
4271 /* make minVersion the internal equivalent SSL version */
SetMinVersionHelper(byte * minVersion,int version)4272 static int SetMinVersionHelper(byte* minVersion, int version)
4273 {
4274 #ifdef NO_TLS
4275     (void)minVersion;
4276 #endif
4277 
4278     switch (version) {
4279 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
4280         case WOLFSSL_SSLV3:
4281             *minVersion = SSLv3_MINOR;
4282             break;
4283 #endif
4284 
4285 #ifndef NO_TLS
4286     #ifndef NO_OLD_TLS
4287         #ifdef WOLFSSL_ALLOW_TLSV10
4288         case WOLFSSL_TLSV1:
4289             *minVersion = TLSv1_MINOR;
4290             break;
4291         #endif
4292 
4293         case WOLFSSL_TLSV1_1:
4294             *minVersion = TLSv1_1_MINOR;
4295             break;
4296     #endif
4297     #ifndef WOLFSSL_NO_TLS12
4298         case WOLFSSL_TLSV1_2:
4299             *minVersion = TLSv1_2_MINOR;
4300             break;
4301     #endif
4302 #endif
4303     #ifdef WOLFSSL_TLS13
4304         case WOLFSSL_TLSV1_3:
4305             *minVersion = TLSv1_3_MINOR;
4306             break;
4307     #endif
4308 
4309         default:
4310             WOLFSSL_MSG("Bad function argument");
4311             return BAD_FUNC_ARG;
4312     }
4313 
4314     return WOLFSSL_SUCCESS;
4315 }
4316 
4317 
4318 /* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
4319 WOLFSSL_ABI
wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX * ctx,int version)4320 int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
4321 {
4322     WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
4323 
4324     if (ctx == NULL) {
4325         WOLFSSL_MSG("Bad function argument");
4326         return BAD_FUNC_ARG;
4327     }
4328 
4329     return SetMinVersionHelper(&ctx->minDowngrade, version);
4330 }
4331 
4332 
4333 /* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
wolfSSL_SetMinVersion(WOLFSSL * ssl,int version)4334 int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
4335 {
4336     WOLFSSL_ENTER("wolfSSL_SetMinVersion");
4337 
4338     if (ssl == NULL) {
4339         WOLFSSL_MSG("Bad function argument");
4340         return BAD_FUNC_ARG;
4341     }
4342 
4343     return SetMinVersionHelper(&ssl->options.minDowngrade, version);
4344 }
4345 
4346 
4347 /* Function to get version as WOLFSSL_ enum value for wolfSSL_SetVersion */
wolfSSL_GetVersion(const WOLFSSL * ssl)4348 int wolfSSL_GetVersion(const WOLFSSL* ssl)
4349 {
4350     if (ssl == NULL)
4351         return BAD_FUNC_ARG;
4352 
4353     if (ssl->version.major == SSLv3_MAJOR) {
4354         switch (ssl->version.minor) {
4355             case SSLv3_MINOR :
4356                 return WOLFSSL_SSLV3;
4357             case TLSv1_MINOR :
4358                 return WOLFSSL_TLSV1;
4359             case TLSv1_1_MINOR :
4360                 return WOLFSSL_TLSV1_1;
4361             case TLSv1_2_MINOR :
4362                 return WOLFSSL_TLSV1_2;
4363             case TLSv1_3_MINOR :
4364                 return WOLFSSL_TLSV1_3;
4365             default:
4366                 break;
4367         }
4368     }
4369 
4370     return VERSION_ERROR;
4371 }
4372 
wolfSSL_SetVersion(WOLFSSL * ssl,int version)4373 int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
4374 {
4375     word16 haveRSA = 1;
4376     word16 havePSK = 0;
4377     int    keySz   = 0;
4378 
4379     WOLFSSL_ENTER("wolfSSL_SetVersion");
4380 
4381     if (ssl == NULL) {
4382         WOLFSSL_MSG("Bad function argument");
4383         return BAD_FUNC_ARG;
4384     }
4385 
4386     switch (version) {
4387 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
4388         case WOLFSSL_SSLV3:
4389             ssl->version = MakeSSLv3();
4390             break;
4391 #endif
4392 
4393 #ifndef NO_TLS
4394     #ifndef NO_OLD_TLS
4395         #ifdef WOLFSSL_ALLOW_TLSV10
4396         case WOLFSSL_TLSV1:
4397             ssl->version = MakeTLSv1();
4398             break;
4399         #endif
4400 
4401         case WOLFSSL_TLSV1_1:
4402             ssl->version = MakeTLSv1_1();
4403             break;
4404     #endif
4405     #ifndef WOLFSSL_NO_TLS12
4406         case WOLFSSL_TLSV1_2:
4407             ssl->version = MakeTLSv1_2();
4408             break;
4409     #endif
4410 #endif
4411 #ifdef WOLFSSL_TLS13
4412         case WOLFSSL_TLSV1_3:
4413             ssl->version = MakeTLSv1_3();
4414             break;
4415 
4416 #endif
4417 
4418         default:
4419             WOLFSSL_MSG("Bad function argument");
4420             return BAD_FUNC_ARG;
4421     }
4422 
4423     #ifdef NO_RSA
4424         haveRSA = 0;
4425     #endif
4426     #ifndef NO_PSK
4427         havePSK = ssl->options.havePSK;
4428     #endif
4429     #ifndef NO_CERTS
4430         keySz = ssl->buffers.keySz;
4431     #endif
4432 
4433     InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
4434                ssl->options.haveDH, ssl->options.haveECDSAsig,
4435                ssl->options.haveECC, ssl->options.haveStaticECC,
4436                ssl->options.haveFalconSig, ssl->options.haveAnon,
4437                ssl->options.side);
4438 
4439     return WOLFSSL_SUCCESS;
4440 }
4441 #endif /* !leanpsk */
4442 
4443 
4444 #if !defined(NO_CERTS) || !defined(NO_SESSION_CACHE)
4445 
4446 /* Make a work from the front of random hash */
MakeWordFromHash(const byte * hashID)4447 static WC_INLINE word32 MakeWordFromHash(const byte* hashID)
4448 {
4449     return ((word32)hashID[0] << 24) | ((word32)hashID[1] << 16) |
4450            ((word32)hashID[2] <<  8) |  (word32)hashID[3];
4451 }
4452 
4453 #endif /* !NO_CERTS || !NO_SESSION_CACHE */
4454 
4455 
4456 #ifndef NO_CERTS
4457 
4458 /* hash is the SHA digest of name, just use first 32 bits as hash */
HashSigner(const byte * hash)4459 static WC_INLINE word32 HashSigner(const byte* hash)
4460 {
4461     return MakeWordFromHash(hash) % CA_TABLE_SIZE;
4462 }
4463 
4464 
4465 /* does CA already exist on signer list */
AlreadySigner(WOLFSSL_CERT_MANAGER * cm,byte * hash)4466 int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
4467 {
4468     Signer* signers;
4469     int     ret = 0;
4470     word32  row;
4471 
4472     if (cm == NULL || hash == NULL) {
4473         return ret;
4474     }
4475 
4476     row = HashSigner(hash);
4477 
4478     if (wc_LockMutex(&cm->caLock) != 0) {
4479         return ret;
4480     }
4481     signers = cm->caTable[row];
4482     while (signers) {
4483         byte* subjectHash;
4484 
4485     #ifndef NO_SKID
4486         subjectHash = signers->subjectKeyIdHash;
4487     #else
4488         subjectHash = signers->subjectNameHash;
4489     #endif
4490 
4491         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
4492             ret = 1; /* success */
4493             break;
4494         }
4495         signers = signers->next;
4496     }
4497     wc_UnLockMutex(&cm->caLock);
4498 
4499     return ret;
4500 }
4501 
4502 
4503 #ifdef WOLFSSL_TRUST_PEER_CERT
4504 /* hash is the SHA digest of name, just use first 32 bits as hash */
TrustedPeerHashSigner(const byte * hash)4505 static WC_INLINE word32 TrustedPeerHashSigner(const byte* hash)
4506 {
4507     return MakeWordFromHash(hash) % TP_TABLE_SIZE;
4508 }
4509 
4510 /* does trusted peer already exist on signer list */
AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER * cm,byte * hash)4511 int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, byte* hash)
4512 {
4513     TrustedPeerCert* tp;
4514     int     ret = 0;
4515     word32  row = TrustedPeerHashSigner(hash);
4516 
4517     if (wc_LockMutex(&cm->tpLock) != 0)
4518         return  ret;
4519     tp = cm->tpTable[row];
4520     while (tp) {
4521         byte* subjectHash;
4522         #ifndef NO_SKID
4523             subjectHash = tp->subjectKeyIdHash;
4524         #else
4525             subjectHash = tp->subjectNameHash;
4526         #endif
4527         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
4528             ret = 1;
4529             break;
4530         }
4531         tp = tp->next;
4532     }
4533     wc_UnLockMutex(&cm->tpLock);
4534 
4535     return ret;
4536 }
4537 
4538 
4539 /* return Trusted Peer if found, otherwise NULL
4540     type is what to match on
4541  */
GetTrustedPeer(void * vp,byte * hash,int type)4542 TrustedPeerCert* GetTrustedPeer(void* vp, byte* hash, int type)
4543 {
4544     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
4545     TrustedPeerCert* ret = NULL;
4546     TrustedPeerCert* tp  = NULL;
4547     word32  row;
4548 
4549     if (cm == NULL || hash == NULL)
4550         return NULL;
4551 
4552     row = TrustedPeerHashSigner(hash);
4553 
4554     if (wc_LockMutex(&cm->tpLock) != 0)
4555         return ret;
4556 
4557     tp = cm->tpTable[row];
4558     while (tp) {
4559         byte* subjectHash;
4560         switch (type) {
4561             #ifndef NO_SKID
4562             case WC_MATCH_SKID:
4563                 subjectHash = tp->subjectKeyIdHash;
4564                 break;
4565             #endif
4566             case WC_MATCH_NAME:
4567                 subjectHash = tp->subjectNameHash;
4568                 break;
4569             default:
4570                 WOLFSSL_MSG("Unknown search type");
4571                 wc_UnLockMutex(&cm->tpLock);
4572                 return NULL;
4573         }
4574         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
4575             ret = tp;
4576             break;
4577         }
4578         tp = tp->next;
4579     }
4580     wc_UnLockMutex(&cm->tpLock);
4581 
4582     return ret;
4583 }
4584 
4585 
MatchTrustedPeer(TrustedPeerCert * tp,DecodedCert * cert)4586 int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert)
4587 {
4588     if (tp == NULL || cert == NULL)
4589         return BAD_FUNC_ARG;
4590 
4591     /* subject key id or subject hash has been compared when searching
4592        tpTable for the cert from function GetTrustedPeer */
4593 
4594     /* compare signatures */
4595     if (tp->sigLen == cert->sigLength) {
4596         if (XMEMCMP(tp->sig, cert->signature, cert->sigLength)) {
4597             return WOLFSSL_FAILURE;
4598         }
4599     }
4600     else {
4601         return WOLFSSL_FAILURE;
4602     }
4603 
4604     return WOLFSSL_SUCCESS;
4605 }
4606 #endif /* WOLFSSL_TRUST_PEER_CERT */
4607 
4608 
4609 /* return CA if found, otherwise NULL */
GetCA(void * vp,byte * hash)4610 Signer* GetCA(void* vp, byte* hash)
4611 {
4612     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
4613     Signer* ret = NULL;
4614     Signer* signers;
4615     word32  row = 0;
4616 
4617     if (cm == NULL || hash == NULL)
4618         return NULL;
4619 
4620     row = HashSigner(hash);
4621 
4622     if (wc_LockMutex(&cm->caLock) != 0)
4623         return ret;
4624 
4625     signers = cm->caTable[row];
4626     while (signers) {
4627         byte* subjectHash;
4628         #ifndef NO_SKID
4629             subjectHash = signers->subjectKeyIdHash;
4630         #else
4631             subjectHash = signers->subjectNameHash;
4632         #endif
4633         if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
4634             ret = signers;
4635             break;
4636         }
4637         signers = signers->next;
4638     }
4639     wc_UnLockMutex(&cm->caLock);
4640 
4641     return ret;
4642 }
4643 
4644 
4645 #ifndef NO_SKID
4646 /* return CA if found, otherwise NULL. Walk through hash table. */
GetCAByName(void * vp,byte * hash)4647 Signer* GetCAByName(void* vp, byte* hash)
4648 {
4649     WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
4650     Signer* ret = NULL;
4651     Signer* signers;
4652     word32  row;
4653 
4654     if (cm == NULL)
4655         return NULL;
4656 
4657     if (wc_LockMutex(&cm->caLock) != 0)
4658         return ret;
4659 
4660     for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
4661         signers = cm->caTable[row];
4662         while (signers && ret == NULL) {
4663             if (XMEMCMP(hash, signers->subjectNameHash,
4664                         SIGNER_DIGEST_SIZE) == 0) {
4665                 ret = signers;
4666             }
4667             signers = signers->next;
4668         }
4669     }
4670     wc_UnLockMutex(&cm->caLock);
4671 
4672     return ret;
4673 }
4674 #endif
4675 
4676 
4677 #ifdef WOLFSSL_TRUST_PEER_CERT
4678 /* add a trusted peer cert to linked list */
AddTrustedPeer(WOLFSSL_CERT_MANAGER * cm,DerBuffer ** pDer,int verify)4679 int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
4680 {
4681     int ret, row;
4682     TrustedPeerCert* peerCert;
4683     DecodedCert* cert;
4684     DerBuffer*   der = *pDer;
4685     byte* subjectHash = NULL;
4686 
4687     WOLFSSL_MSG("Adding a Trusted Peer Cert");
4688 
4689     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
4690                                  DYNAMIC_TYPE_DCERT);
4691     if (cert == NULL) {
4692         FreeDer(&der);
4693         return MEMORY_E;
4694     }
4695 
4696     InitDecodedCert(cert, der->buffer, der->length, cm->heap);
4697     if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) {
4698         FreeDecodedCert(cert);
4699         XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
4700         FreeDer(&der);
4701         return ret;
4702     }
4703     WOLFSSL_MSG("\tParsed new trusted peer cert");
4704 
4705     peerCert = (TrustedPeerCert*)XMALLOC(sizeof(TrustedPeerCert), cm->heap,
4706                                                              DYNAMIC_TYPE_CERT);
4707     if (peerCert == NULL) {
4708         FreeDecodedCert(cert);
4709         XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
4710         FreeDer(&der);
4711         return MEMORY_E;
4712     }
4713     XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
4714 
4715 #ifndef NO_SKID
4716     if (cert->extAuthKeyIdSet) {
4717         subjectHash = cert->extSubjKeyId;
4718     }
4719     else {
4720         subjectHash = cert->subjectHash;
4721     }
4722 #else
4723     subjectHash = cert->subjectHash;
4724 #endif
4725 
4726     #ifndef IGNORE_NAME_CONSTRAINTS
4727         if (peerCert->permittedNames)
4728             FreeNameSubtrees(peerCert->permittedNames, cm->heap);
4729         if (peerCert->excludedNames)
4730             FreeNameSubtrees(peerCert->excludedNames, cm->heap);
4731     #endif
4732 
4733     if (AlreadyTrustedPeer(cm, subjectHash)) {
4734         WOLFSSL_MSG("\tAlready have this CA, not adding again");
4735         FreeTrustedPeer(peerCert, cm->heap);
4736         (void)ret;
4737     }
4738     else {
4739         /* add trusted peer signature */
4740         peerCert->sigLen = cert->sigLength;
4741         peerCert->sig = (byte *)XMALLOC(cert->sigLength, cm->heap,
4742                                                         DYNAMIC_TYPE_SIGNATURE);
4743         if (peerCert->sig == NULL) {
4744             FreeDecodedCert(cert);
4745             XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
4746             FreeTrustedPeer(peerCert, cm->heap);
4747             FreeDer(&der);
4748             return MEMORY_E;
4749         }
4750         XMEMCPY(peerCert->sig, cert->signature, cert->sigLength);
4751 
4752         /* add trusted peer name */
4753         peerCert->nameLen = cert->subjectCNLen;
4754         peerCert->name    = cert->subjectCN;
4755         #ifndef IGNORE_NAME_CONSTRAINTS
4756             peerCert->permittedNames = cert->permittedNames;
4757             peerCert->excludedNames  = cert->excludedNames;
4758         #endif
4759 
4760         /* add SKID when available and hash of name */
4761         #ifndef NO_SKID
4762             XMEMCPY(peerCert->subjectKeyIdHash, cert->extSubjKeyId,
4763                     SIGNER_DIGEST_SIZE);
4764         #endif
4765             XMEMCPY(peerCert->subjectNameHash, cert->subjectHash,
4766                     SIGNER_DIGEST_SIZE);
4767             peerCert->next    = NULL; /* If Key Usage not set, all uses valid. */
4768             cert->subjectCN = 0;
4769         #ifndef IGNORE_NAME_CONSTRAINTS
4770             cert->permittedNames = NULL;
4771             cert->excludedNames = NULL;
4772         #endif
4773 
4774         #ifndef NO_SKID
4775             if (cert->extAuthKeyIdSet) {
4776                 row = TrustedPeerHashSigner(peerCert->subjectKeyIdHash);
4777             }
4778             else {
4779                 row = TrustedPeerHashSigner(peerCert->subjectNameHash);
4780             }
4781         #else
4782             row = TrustedPeerHashSigner(peerCert->subjectNameHash);
4783         #endif
4784 
4785             if (wc_LockMutex(&cm->tpLock) == 0) {
4786                 peerCert->next = cm->tpTable[row];
4787                 cm->tpTable[row] = peerCert;   /* takes ownership */
4788                 wc_UnLockMutex(&cm->tpLock);
4789             }
4790             else {
4791                 WOLFSSL_MSG("\tTrusted Peer Cert Mutex Lock failed");
4792                 FreeDecodedCert(cert);
4793                 XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
4794                 FreeTrustedPeer(peerCert, cm->heap);
4795                 FreeDer(&der);
4796                 return BAD_MUTEX_E;
4797             }
4798         }
4799 
4800     WOLFSSL_MSG("\tFreeing parsed trusted peer cert");
4801     FreeDecodedCert(cert);
4802     XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
4803     WOLFSSL_MSG("\tFreeing der trusted peer cert");
4804     FreeDer(&der);
4805     WOLFSSL_MSG("\t\tOK Freeing der trusted peer cert");
4806     WOLFSSL_LEAVE("AddTrustedPeer", ret);
4807 
4808     return WOLFSSL_SUCCESS;
4809 }
4810 #endif /* WOLFSSL_TRUST_PEER_CERT */
4811 
4812 
4813 /* owns der, internal now uses too */
4814 /* type flag ids from user or from chain received during verify
4815    don't allow chain ones to be added w/o isCA extension */
AddCA(WOLFSSL_CERT_MANAGER * cm,DerBuffer ** pDer,int type,int verify)4816 int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
4817 {
4818     int         ret;
4819     Signer*     signer = NULL;
4820     word32      row;
4821     byte*       subjectHash;
4822 #ifdef WOLFSSL_SMALL_STACK
4823     DecodedCert* cert = NULL;
4824 #else
4825     DecodedCert  cert[1];
4826 #endif
4827     DerBuffer*   der = *pDer;
4828 
4829     WOLFSSL_MSG("Adding a CA");
4830 
4831     if (cm == NULL) {
4832         FreeDer(pDer);
4833         return BAD_FUNC_ARG;
4834     }
4835 
4836 #ifdef WOLFSSL_SMALL_STACK
4837     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
4838                                  DYNAMIC_TYPE_DCERT);
4839     if (cert == NULL) {
4840         FreeDer(pDer);
4841         return MEMORY_E;
4842     }
4843 #endif
4844 
4845     InitDecodedCert(cert, der->buffer, der->length, cm->heap);
4846     ret = ParseCert(cert, CA_TYPE, verify, cm);
4847     WOLFSSL_MSG("\tParsed new CA");
4848 
4849 #ifndef NO_SKID
4850     subjectHash = cert->extSubjKeyId;
4851 #else
4852     subjectHash = cert->subjectHash;
4853 #endif
4854 
4855     /* check CA key size */
4856     if (verify) {
4857         switch (cert->keyOID) {
4858             #ifndef NO_RSA
4859             case RSAk:
4860                 if (cm->minRsaKeySz < 0 ||
4861                                    cert->pubKeySize < (word16)cm->minRsaKeySz) {
4862                     ret = RSA_KEY_SIZE_E;
4863                     WOLFSSL_MSG("\tCA RSA key size error");
4864                 }
4865                 break;
4866             #endif /* !NO_RSA */
4867             #ifdef HAVE_ECC
4868             case ECDSAk:
4869                 if (cm->minEccKeySz < 0 ||
4870                                    cert->pubKeySize < (word16)cm->minEccKeySz) {
4871                     ret = ECC_KEY_SIZE_E;
4872                     WOLFSSL_MSG("\tCA ECC key size error");
4873                 }
4874                 break;
4875             #endif /* HAVE_ECC */
4876             #ifdef HAVE_ED25519
4877             case ED25519k:
4878                 if (cm->minEccKeySz < 0 ||
4879                                    ED25519_KEY_SIZE < (word16)cm->minEccKeySz) {
4880                     ret = ECC_KEY_SIZE_E;
4881                     WOLFSSL_MSG("\tCA ECC key size error");
4882                 }
4883                 break;
4884             #endif /* HAVE_ED25519 */
4885             #ifdef HAVE_ED448
4886             case ED448k:
4887                 if (cm->minEccKeySz < 0 ||
4888                                      ED448_KEY_SIZE < (word16)cm->minEccKeySz) {
4889                     ret = ECC_KEY_SIZE_E;
4890                     WOLFSSL_MSG("\tCA ECC key size error");
4891                 }
4892                 break;
4893             #endif /* HAVE_ED448 */
4894             #ifdef HAVE_PQC
4895             case FALCON_LEVEL1k:
4896                 if (cm->minFalconKeySz < 0 ||
4897                           FALCON_LEVEL1_KEY_SIZE < (word16)cm->minFalconKeySz) {
4898                     ret = FALCON_KEY_SIZE_E;
4899                     WOLFSSL_MSG("\tCA Falcon level 1 key size error");
4900                 }
4901                 break;
4902             case FALCON_LEVEL5k:
4903                 if (cm->minFalconKeySz < 0 ||
4904                           FALCON_LEVEL5_KEY_SIZE < (word16)cm->minFalconKeySz) {
4905                     ret = FALCON_KEY_SIZE_E;
4906                     WOLFSSL_MSG("\tCA Falcon level 5 key size error");
4907                 }
4908                 break;
4909             #endif /* HAVE_PQC */
4910 
4911             default:
4912                 WOLFSSL_MSG("\tNo key size check done on CA");
4913                 break; /* no size check if key type is not in switch */
4914         }
4915     }
4916 
4917     if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
4918         WOLFSSL_MSG("\tCan't add as CA if not actually one");
4919         ret = NOT_CA_ERROR;
4920     }
4921 #ifndef ALLOW_INVALID_CERTSIGN
4922     else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
4923         !cert->selfSigned && (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
4924         /* Intermediate CA certs are required to have the keyCertSign
4925         * extension set. User loaded root certs are not. */
4926         WOLFSSL_MSG("\tDoesn't have key usage certificate signing");
4927         ret = NOT_CA_ERROR;
4928     }
4929 #endif
4930     else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
4931         WOLFSSL_MSG("\tAlready have this CA, not adding again");
4932         (void)ret;
4933     }
4934     else if (ret == 0) {
4935         /* take over signer parts */
4936         signer = MakeSigner(cm->heap);
4937         if (!signer)
4938             ret = MEMORY_ERROR;
4939     }
4940     if (ret == 0 && signer != NULL) {
4941     #ifdef WOLFSSL_SIGNER_DER_CERT
4942         ret = AllocDer(&signer->derCert, der->length, der->type, NULL);
4943     }
4944     if (ret == 0 && signer != NULL) {
4945         XMEMCPY(signer->derCert->buffer, der->buffer, der->length);
4946     #endif
4947         signer->keyOID         = cert->keyOID;
4948         if (cert->pubKeyStored) {
4949             signer->publicKey      = cert->publicKey;
4950             signer->pubKeySize     = cert->pubKeySize;
4951         }
4952         if (cert->subjectCNStored) {
4953             signer->nameLen        = cert->subjectCNLen;
4954             signer->name           = cert->subjectCN;
4955         }
4956         signer->pathLength     = cert->pathLength;
4957         signer->maxPathLen     = cert->maxPathLen;
4958         signer->pathLengthSet  = cert->pathLengthSet;
4959         signer->selfSigned     = cert->selfSigned;
4960     #ifndef IGNORE_NAME_CONSTRAINTS
4961         signer->permittedNames = cert->permittedNames;
4962         signer->excludedNames  = cert->excludedNames;
4963     #endif
4964     #ifndef NO_SKID
4965         XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
4966                 SIGNER_DIGEST_SIZE);
4967     #endif
4968         XMEMCPY(signer->subjectNameHash, cert->subjectHash,
4969                 SIGNER_DIGEST_SIZE);
4970     #ifdef HAVE_OCSP
4971         XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash,
4972                 KEYID_SIZE);
4973     #endif
4974         signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
4975                                                 : 0xFFFF;
4976         signer->next    = NULL; /* If Key Usage not set, all uses valid. */
4977         cert->publicKey = 0;    /* in case lock fails don't free here.   */
4978         cert->subjectCN = 0;
4979     #ifndef IGNORE_NAME_CONSTRAINTS
4980         cert->permittedNames = NULL;
4981         cert->excludedNames = NULL;
4982     #endif
4983 
4984     #ifndef NO_SKID
4985         row = HashSigner(signer->subjectKeyIdHash);
4986     #else
4987         row = HashSigner(signer->subjectNameHash);
4988     #endif
4989 
4990         if (wc_LockMutex(&cm->caLock) == 0) {
4991             signer->next = cm->caTable[row];
4992             cm->caTable[row] = signer;   /* takes ownership */
4993             wc_UnLockMutex(&cm->caLock);
4994             if (cm->caCacheCallback)
4995                 cm->caCacheCallback(der->buffer, (int)der->length, type);
4996         }
4997         else {
4998             WOLFSSL_MSG("\tCA Mutex Lock failed");
4999             ret = BAD_MUTEX_E;
5000             FreeSigner(signer, cm->heap);
5001         }
5002     }
5003 #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
5004     /* Verify CA by TSIP so that generated tsip key is going to be able to */
5005     /* be used for peer's cert verification                                */
5006     /* TSIP is only able to handle USER CA, and only one CA.               */
5007     /* Therefore, it doesn't need to call TSIP again if there is already   */
5008     /* verified CA.                                                        */
5009     if ( ret == 0 && signer != NULL ) {
5010         signer->cm_idx = row;
5011         if (type == WOLFSSL_USER_CA) {
5012             if ((ret = wc_Renesas_cmn_RootCertVerify(cert->source, cert->maxIdx,
5013                  cert->sigCtx.CertAtt.pubkey_n_start,
5014                  cert->sigCtx.CertAtt.pubkey_n_len - 1,
5015                  cert->sigCtx.CertAtt.pubkey_e_start,
5016                 cert->sigCtx.CertAtt.pubkey_e_len - 1,
5017                  row/* cm index */))
5018                 < 0)
5019                 WOLFSSL_MSG("Renesas_RootCertVerify() failed");
5020             else
5021                 WOLFSSL_MSG("Renesas_RootCertVerify() succeed or skipped");
5022         }
5023     }
5024 #endif /* TSIP or SCE */
5025 
5026     WOLFSSL_MSG("\tFreeing Parsed CA");
5027     FreeDecodedCert(cert);
5028 #ifdef WOLFSSL_SMALL_STACK
5029     XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
5030 #endif
5031     WOLFSSL_MSG("\tFreeing der CA");
5032     FreeDer(pDer);
5033     WOLFSSL_MSG("\t\tOK Freeing der CA");
5034 
5035     WOLFSSL_LEAVE("AddCA", ret);
5036 
5037     return ret == 0 ? WOLFSSL_SUCCESS : ret;
5038 }
5039 
5040 #endif /* !NO_CERTS */
5041 
5042 
5043 #ifndef NO_SESSION_CACHE
5044 
5045     /* basic config gives a cache with 33 sessions, adequate for clients and
5046        embedded servers
5047 
5048        TITAN_SESSION_CACHE allows just over 2 million sessions, for servers
5049        with titanic amounts of memory with long session ID timeouts and high
5050        levels of traffic.
5051 
5052        ENABLE_SESSION_CACHE_ROW_LOCK: Allows row level locking for increased
5053        performance with large session caches
5054 
5055        HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
5056        allows over 13,000 new sessions per minute or over 200 new sessions per
5057        second
5058 
5059        BIG_SESSION_CACHE yields 20,027 sessions
5060 
5061        MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
5062        aren't under heavy load, basically allows 200 new sessions per minute
5063 
5064        SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
5065        or systems where the default of nearly 3kB is too much RAM, this define
5066        uses less than 500 bytes RAM
5067 
5068        default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
5069     */
5070     #if defined(TITAN_SESSION_CACHE)
5071         #define SESSIONS_PER_ROW 31
5072         #define SESSION_ROWS 64937
5073         #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5074         #define ENABLE_SESSION_CACHE_ROW_LOCK
5075         #endif
5076     #elif defined(HUGE_SESSION_CACHE)
5077         #define SESSIONS_PER_ROW 11
5078         #define SESSION_ROWS 5981
5079     #elif defined(BIG_SESSION_CACHE)
5080         #define SESSIONS_PER_ROW 7
5081         #define SESSION_ROWS 2861
5082     #elif defined(MEDIUM_SESSION_CACHE)
5083         #define SESSIONS_PER_ROW 5
5084         #define SESSION_ROWS 211
5085     #elif defined(SMALL_SESSION_CACHE)
5086         #define SESSIONS_PER_ROW 2
5087         #define SESSION_ROWS 3
5088     #else
5089         #define SESSIONS_PER_ROW 3
5090         #define SESSION_ROWS 11
5091     #endif
5092 
5093     #ifdef NO_SESSION_CACHE_ROW_LOCK
5094         #undef ENABLE_SESSION_CACHE_ROW_LOCK
5095     #endif
5096 
5097     typedef struct SessionRow {
5098         int nextIdx;                           /* where to place next one   */
5099         int totalCount;                        /* sessions ever on this row */
5100         WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
5101 
5102     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5103         /* not included in import/export */
5104         wolfSSL_Mutex row_mutex;
5105         int mutex_valid;
5106     #endif
5107     } SessionRow;
5108     #define SIZEOF_SESSION_ROW (sizeof(WOLFSSL_SESSION) + (sizeof(int) * 2))
5109 
5110     static WOLFSSL_GLOBAL SessionRow SessionCache[SESSION_ROWS];
5111 
5112     #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
5113         static WOLFSSL_GLOBAL word32 PeakSessions;
5114     #endif
5115 
5116     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5117     #define SESSION_ROW_LOCK(row)   wc_LockMutex(&(row)->row_mutex)
5118     #define SESSION_ROW_UNLOCK(row) wc_UnLockMutex(&(row)->row_mutex);
5119     #else
5120     static WOLFSSL_GLOBAL wolfSSL_Mutex session_mutex; /* SessionCache mutex */
5121     static WOLFSSL_GLOBAL int session_mutex_valid = 0;
5122     #define SESSION_ROW_LOCK(row)   wc_LockMutex(&session_mutex)
5123     #define SESSION_ROW_UNLOCK(row) wc_UnLockMutex(&session_mutex);
5124     #endif
5125 
5126     #ifndef NO_CLIENT_CACHE
5127 
5128         typedef struct ClientSession {
5129             word16 serverRow;            /* SessionCache Row id */
5130             word16 serverIdx;            /* SessionCache Idx (column) */
5131         } ClientSession;
5132 
5133         typedef struct ClientRow {
5134             int nextIdx;                /* where to place next one   */
5135             int totalCount;             /* sessions ever on this row */
5136             ClientSession Clients[SESSIONS_PER_ROW];
5137         } ClientRow;
5138 
5139         static WOLFSSL_GLOBAL ClientRow ClientCache[SESSION_ROWS];
5140                                                      /* Client Cache */
5141                                                      /* uses session mutex */
5142 
5143         static WOLFSSL_GLOBAL wolfSSL_Mutex clisession_mutex; /* ClientCache mutex */
5144         static WOLFSSL_GLOBAL int clisession_mutex_valid = 0;
5145     #endif /* !NO_CLIENT_CACHE */
5146 
5147 #endif /* !NO_SESSION_CACHE */
5148 
5149 #if defined(OPENSSL_EXTRA) || \
5150     (defined(OPENSSL_EXTRA_X509_SMALL) && !defined(NO_RSA))
5151 
5152     #define HAVE_GLOBAL_RNG /* consolidate flags for using globalRNG */
5153     static WC_RNG globalRNG;
5154     static int initGlobalRNG = 0;
5155     static wolfSSL_Mutex globalRNGMutex;
5156     static int globalRNGMutex_valid = 0;
5157 #endif
5158 
5159 #if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
5160 static int wolfSSL_RAND_InitMutex(void);
5161 #endif
5162 
5163 #if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
AtExitCleanup(void)5164 static void AtExitCleanup(void)
5165 {
5166     if (initRefCount > 0) {
5167         initRefCount = 1;
5168         (void)wolfSSL_Cleanup();
5169     }
5170 }
5171 #endif
5172 
5173 WOLFSSL_ABI
wolfSSL_Init(void)5174 int wolfSSL_Init(void)
5175 {
5176     int ret = WOLFSSL_SUCCESS;
5177 #if !defined(NO_SESSION_CACHE) && defined(ENABLE_SESSION_CACHE_ROW_LOCK)
5178     int i;
5179 #endif
5180 
5181     WOLFSSL_ENTER("wolfSSL_Init");
5182 
5183     #if defined(HAVE_FIPS_VERSION) && ((HAVE_FIPS_VERSION > 5) || ((HAVE_FIPS_VERSION == 5) && (HAVE_FIPS_VERSION_MINOR >= 1)))
5184         ret = wolfCrypt_SetPrivateKeyReadEnable_fips(1, WC_KEYTYPE_ALL);
5185         if (ret != 0)
5186             return ret;
5187         else
5188             ret = WOLFSSL_SUCCESS;
5189     #endif
5190 
5191     if (initRefCount == 0) {
5192         /* Initialize crypto for use with TLS connection */
5193         if (wolfCrypt_Init() != 0) {
5194             WOLFSSL_MSG("Bad wolfCrypt Init");
5195             ret = WC_INIT_E;
5196         }
5197 
5198 #ifdef HAVE_GLOBAL_RNG
5199         if ((ret == WOLFSSL_SUCCESS) && (wc_InitMutex(&globalRNGMutex) != 0)) {
5200             WOLFSSL_MSG("Bad Init Mutex rng");
5201             ret = BAD_MUTEX_E;
5202         }
5203         else {
5204             globalRNGMutex_valid = 1;
5205         }
5206 #endif
5207 
5208     #ifdef WC_RNG_SEED_CB
5209         wc_SetSeed_Cb(wc_GenerateSeed);
5210     #endif
5211 
5212 #ifdef OPENSSL_EXTRA
5213     #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
5214         if ((ret == WOLFSSL_SUCCESS) && (wolfSSL_RAND_InitMutex() != 0)) {
5215             ret = BAD_MUTEX_E;
5216         }
5217     #endif
5218         if ((ret == WOLFSSL_SUCCESS) &&
5219             (wolfSSL_RAND_seed(NULL, 0) != WOLFSSL_SUCCESS)) {
5220             WOLFSSL_MSG("wolfSSL_RAND_Seed failed");
5221             ret = WC_INIT_E;
5222         }
5223 #endif
5224 
5225 #ifndef NO_SESSION_CACHE
5226     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5227         for (i = 0; i < SESSION_ROWS; ++i) {
5228             SessionCache[i].mutex_valid = 0;
5229         }
5230         for (i = 0; (ret == WOLFSSL_SUCCESS) && (i < SESSION_ROWS); ++i) {
5231             if (wc_InitMutex(&SessionCache[i].row_mutex) != 0) {
5232                 WOLFSSL_MSG("Bad Init Mutex session");
5233                 ret = BAD_MUTEX_E;
5234             }
5235             else {
5236                 SessionCache[i].mutex_valid = 1;
5237             }
5238         }
5239     #else
5240         if ((ret == WOLFSSL_SUCCESS) && (wc_InitMutex(&session_mutex) != 0)) {
5241             WOLFSSL_MSG("Bad Init Mutex session");
5242             ret = BAD_MUTEX_E;
5243         }
5244         else {
5245             session_mutex_valid = 1;
5246         }
5247     #endif
5248     #ifndef NO_CLIENT_CACHE
5249         if ((ret == WOLFSSL_SUCCESS) &&
5250             (wc_InitMutex(&clisession_mutex) != 0)) {
5251             WOLFSSL_MSG("Bad Init Mutex session");
5252             ret = BAD_MUTEX_E;
5253         }
5254         else {
5255             clisession_mutex_valid = 1;
5256         }
5257     #endif
5258 #endif
5259         if ((ret == WOLFSSL_SUCCESS) && (wc_InitMutex(&count_mutex) != 0)) {
5260             WOLFSSL_MSG("Bad Init Mutex count");
5261             ret = BAD_MUTEX_E;
5262         }
5263         else {
5264             count_mutex_valid = 1;
5265         }
5266 
5267 #if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
5268         /* OpenSSL registers cleanup using atexit */
5269         if ((ret == WOLFSSL_SUCCESS) && (atexit(AtExitCleanup) != 0)) {
5270             WOLFSSL_MSG("Bad atexit registration");
5271             ret = WC_INIT_E;
5272         }
5273 #endif
5274     }
5275 
5276     if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&count_mutex) != 0)) {
5277         WOLFSSL_MSG("Bad Lock Mutex count");
5278         ret = BAD_MUTEX_E;
5279     }
5280     else {
5281         initRefCount++;
5282         wc_UnLockMutex(&count_mutex);
5283     }
5284 
5285     if (ret != WOLFSSL_SUCCESS) {
5286         initRefCount = 1; /* Force cleanup */
5287         (void)wolfSSL_Cleanup(); /* Ignore any error from cleanup */
5288     }
5289 
5290     return ret;
5291 }
5292 
5293 
5294 
5295 #ifndef NO_CERTS
5296 
5297 /* process user cert chain to pass during the handshake */
ProcessUserChain(WOLFSSL_CTX * ctx,const unsigned char * buff,long sz,int format,int type,WOLFSSL * ssl,long * used,EncryptedInfo * info,int verify)5298 static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
5299                          long sz, int format, int type, WOLFSSL* ssl,
5300                          long* used, EncryptedInfo* info, int verify)
5301 {
5302     int ret = 0;
5303     void* heap = wolfSSL_CTX_GetHeap(ctx, ssl);
5304 #ifdef WOLFSSL_TLS13
5305     int cnt = 0;
5306 #endif
5307 
5308     if ((type == CA_TYPE) && (ctx == NULL)) {
5309         WOLFSSL_MSG("Need context for CA load");
5310         return BAD_FUNC_ARG;
5311     }
5312 
5313     /* we may have a user cert chain, try to consume */
5314     if ((type == CERT_TYPE || type == CA_TYPE) && (info->consumed < sz)) {
5315     #ifdef WOLFSSL_SMALL_STACK
5316         byte   staticBuffer[1];                 /* force heap usage */
5317     #else
5318         byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
5319     #endif
5320         byte*  chainBuffer = staticBuffer;
5321         int    dynamicBuffer = 0;
5322         word32 bufferSz;
5323         long   consumed = info->consumed;
5324         word32 idx = 0;
5325         int    gotOne = 0;
5326 
5327         /* Calculate max possible size, including max headers */
5328         bufferSz = (word32)(sz - consumed) + (CERT_HEADER_SZ * MAX_CHAIN_DEPTH);
5329         if (bufferSz > sizeof(staticBuffer)) {
5330             WOLFSSL_MSG("Growing Tmp Chain Buffer");
5331             /* will shrink to actual size */
5332             chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
5333             if (chainBuffer == NULL) {
5334                 return MEMORY_E;
5335             }
5336             dynamicBuffer = 1;
5337         }
5338 
5339         WOLFSSL_MSG("Processing Cert Chain");
5340         while (consumed < sz) {
5341             DerBuffer* part = NULL;
5342             word32 remain = (word32)(sz - consumed);
5343             info->consumed = 0;
5344 
5345             if (format == WOLFSSL_FILETYPE_PEM) {
5346             #ifdef WOLFSSL_PEM_TO_DER
5347                 ret = PemToDer(buff + consumed, remain, type, &part,
5348                                heap, info, NULL);
5349             #else
5350                 ret = NOT_COMPILED_IN;
5351             #endif
5352             }
5353             else {
5354                 int length = remain;
5355                 if (format == WOLFSSL_FILETYPE_ASN1) {
5356                     /* get length of der (read sequence) */
5357                     word32 inOutIdx = 0;
5358                     if (GetSequence(buff + consumed, &inOutIdx, &length,
5359                             remain) < 0) {
5360                         ret = ASN_NO_PEM_HEADER;
5361                     }
5362                     length += inOutIdx; /* include leading sequence */
5363                 }
5364                 info->consumed = length;
5365                 if (ret == 0) {
5366                     ret = AllocDer(&part, length, type, heap);
5367                     if (ret == 0) {
5368                         XMEMCPY(part->buffer, buff + consumed, length);
5369                     }
5370                 }
5371             }
5372             if (ret == 0) {
5373                 gotOne = 1;
5374 #ifdef WOLFSSL_TLS13
5375                 cnt++;
5376 #endif
5377                 if ((idx + part->length + CERT_HEADER_SZ) > bufferSz) {
5378                     WOLFSSL_MSG("   Cert Chain bigger than buffer");
5379                     ret = BUFFER_E;
5380                 }
5381                 else {
5382                     c32to24(part->length, &chainBuffer[idx]);
5383                     idx += CERT_HEADER_SZ;
5384                     XMEMCPY(&chainBuffer[idx], part->buffer, part->length);
5385                     idx += part->length;
5386                     consumed  += info->consumed;
5387                     if (used)
5388                         *used += info->consumed;
5389                 }
5390 
5391                 /* add CA's to certificate manager */
5392                 if (type == CA_TYPE) {
5393                     /* verify CA unless user set to no verify */
5394                     ret = AddCA(ctx->cm, &part, WOLFSSL_USER_CA, verify);
5395                     gotOne = 0; /* don't exit loop for CA type */
5396                 }
5397             }
5398 
5399             FreeDer(&part);
5400 
5401             if (ret == ASN_NO_PEM_HEADER && gotOne) {
5402                 WOLFSSL_MSG("We got one good cert, so stuff at end ok");
5403                 break;
5404             }
5405 
5406             if (ret < 0) {
5407                 WOLFSSL_MSG("   Error in Cert in Chain");
5408                 if (dynamicBuffer)
5409                     XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
5410                 return ret;
5411             }
5412             WOLFSSL_MSG("   Consumed another Cert in Chain");
5413         }
5414         WOLFSSL_MSG("Finished Processing Cert Chain");
5415 
5416         /* only retain actual size used */
5417         ret = 0;
5418         if (idx > 0) {
5419             if (ssl) {
5420                 if (ssl->buffers.weOwnCertChain) {
5421                     FreeDer(&ssl->buffers.certChain);
5422                 }
5423                 ret = AllocDer(&ssl->buffers.certChain, idx, type, heap);
5424                 if (ret == 0) {
5425                     XMEMCPY(ssl->buffers.certChain->buffer, chainBuffer,
5426                             idx);
5427                     ssl->buffers.weOwnCertChain = 1;
5428                 }
5429             #ifdef WOLFSSL_TLS13
5430                 ssl->buffers.certChainCnt = cnt;
5431             #endif
5432             } else if (ctx) {
5433                 FreeDer(&ctx->certChain);
5434                 ret = AllocDer(&ctx->certChain, idx, type, heap);
5435                 if (ret == 0) {
5436                     XMEMCPY(ctx->certChain->buffer, chainBuffer, idx);
5437                 }
5438             #ifdef WOLFSSL_TLS13
5439                 ctx->certChainCnt = cnt;
5440             #endif
5441             }
5442         }
5443 
5444         if (dynamicBuffer)
5445             XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
5446     }
5447 
5448     return ret;
5449 }
5450 
ProcessBufferTryDecode(WOLFSSL_CTX * ctx,WOLFSSL * ssl,DerBuffer * der,int * keySz,word32 * idx,int * resetSuites,int * keyFormat,void * heap,int devId)5451 static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der,
5452     int* keySz, word32* idx, int* resetSuites, int* keyFormat, void* heap, int devId)
5453 {
5454     int ret = 0;
5455 
5456     (void)heap;
5457     (void)devId;
5458 
5459     if (ctx == NULL && ssl == NULL)
5460         ret = BAD_FUNC_ARG;
5461     if (!der || !keySz || !idx || !resetSuites || !keyFormat)
5462         ret = BAD_FUNC_ARG;
5463 
5464 #ifndef NO_RSA
5465     if (ret == 0 && (*keyFormat == 0 || *keyFormat == RSAk)) {
5466         /* make sure RSA key can be used */
5467     #ifdef WOLFSSL_SMALL_STACK
5468         RsaKey* key;
5469     #else
5470         RsaKey  key[1];
5471     #endif
5472 
5473     #ifdef WOLFSSL_SMALL_STACK
5474         key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA);
5475         if (key == NULL)
5476             return MEMORY_E;
5477     #endif
5478 
5479         ret = wc_InitRsaKey_ex(key, heap, devId);
5480         if (ret == 0) {
5481             *idx = 0;
5482             ret = wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length);
5483         #if defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS)
5484             if (ret != 0 && devId != INVALID_DEVID) {
5485                 /* if using crypto or PK callbacks, try public key decode */
5486                 *idx = 0;
5487                 ret = wc_RsaPublicKeyDecode(der->buffer, idx, key, der->length);
5488             }
5489         #endif
5490             if (ret != 0) {
5491             #if !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
5492                 !defined(HAVE_ED448) && !defined(HAVE_PQC)
5493                 WOLFSSL_MSG("RSA decode failed and other algorithms "
5494                             "not enabled to try");
5495                 ret = WOLFSSL_BAD_FILE;
5496             #else
5497                 ret = 0; /* continue trying other algorithms */
5498             #endif
5499             }
5500             else {
5501                 /* check that the size of the RSA key is enough */
5502                 int minRsaSz = ssl ? ssl->options.minRsaKeySz :
5503                     ctx->minRsaKeySz;
5504                 *keySz = wc_RsaEncryptSize((RsaKey*)key);
5505                 if (*keySz < minRsaSz) {
5506                     ret = RSA_KEY_SIZE_E;
5507                     WOLFSSL_MSG("Private Key size too small");
5508                 }
5509 
5510                 if (ssl) {
5511                     ssl->buffers.keyType = rsa_sa_algo;
5512                     ssl->buffers.keySz = *keySz;
5513                 }
5514                 else {
5515                     ctx->privateKeyType = rsa_sa_algo;
5516                     ctx->privateKeySz = *keySz;
5517                 }
5518 
5519                 *keyFormat = RSAk;
5520 
5521                 if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
5522                     ssl->options.haveStaticECC = 0;
5523                     *resetSuites = 1;
5524                 }
5525             }
5526 
5527             wc_FreeRsaKey(key);
5528         }
5529 
5530     #ifdef WOLFSSL_SMALL_STACK
5531         XFREE(key, heap, DYNAMIC_TYPE_RSA);
5532     #endif
5533     }
5534 #endif
5535 #ifdef HAVE_ECC
5536     if (ret == 0 && (*keyFormat == 0 || *keyFormat == ECDSAk)) {
5537         /* make sure ECC key can be used */
5538     #ifdef WOLFSSL_SMALL_STACK
5539         ecc_key* key;
5540     #else
5541         ecc_key  key[1];
5542     #endif
5543 
5544     #ifdef WOLFSSL_SMALL_STACK
5545         key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
5546         if (key == NULL)
5547             return MEMORY_E;
5548     #endif
5549 
5550         if (wc_ecc_init_ex(key, heap, devId) == 0) {
5551             *idx = 0;
5552             ret = wc_EccPrivateKeyDecode(der->buffer, idx, key, der->length);
5553         #if defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS)
5554             if (ret != 0 && devId != INVALID_DEVID) {
5555                 /* if using crypto or PK callbacks, try public key decode */
5556                 *idx = 0;
5557                 ret = wc_EccPublicKeyDecode(der->buffer, idx, key, der->length);
5558             }
5559         #endif
5560             if (ret == 0) {
5561                 /* check for minimum ECC key size and then free */
5562                 int minKeySz = ssl ? ssl->options.minEccKeySz :
5563                                                         ctx->minEccKeySz;
5564                 *keySz = wc_ecc_size(key);
5565                 if (*keySz < minKeySz) {
5566                     WOLFSSL_MSG("ECC private key too small");
5567                     ret = ECC_KEY_SIZE_E;
5568                 }
5569 
5570                 *keyFormat = ECDSAk;
5571                 if (ssl) {
5572                     ssl->options.haveStaticECC = 1;
5573                     ssl->buffers.keyType = ecc_dsa_sa_algo;
5574                     ssl->buffers.keySz = *keySz;
5575                 }
5576                 else {
5577                     ctx->haveStaticECC = 1;
5578                     ctx->privateKeyType = ecc_dsa_sa_algo;
5579                     ctx->privateKeySz = *keySz;
5580                 }
5581 
5582                 if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
5583                     *resetSuites = 1;
5584                 }
5585             }
5586             else {
5587                 ret = 0; /* continue trying other algorithms */
5588             }
5589 
5590             wc_ecc_free(key);
5591         }
5592 
5593     #ifdef WOLFSSL_SMALL_STACK
5594         XFREE(key, heap, DYNAMIC_TYPE_ECC);
5595     #endif
5596     }
5597 #endif /* HAVE_ECC */
5598 #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
5599     if (ret == 0 && (*keyFormat == 0 || *keyFormat == ED25519k)) {
5600         /* make sure Ed25519 key can be used */
5601     #ifdef WOLFSSL_SMALL_STACK
5602         ed25519_key* key;
5603     #else
5604         ed25519_key  key[1];
5605     #endif
5606 
5607     #ifdef WOLFSSL_SMALL_STACK
5608         key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
5609                                                       DYNAMIC_TYPE_ED25519);
5610         if (key == NULL)
5611             return MEMORY_E;
5612     #endif
5613 
5614         ret = wc_ed25519_init_ex(key, heap, devId);
5615         if (ret == 0) {
5616             *idx = 0;
5617             ret = wc_Ed25519PrivateKeyDecode(der->buffer, idx, key, der->length);
5618         #if defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS)
5619             if (ret != 0 && devId != INVALID_DEVID) {
5620                 /* if using crypto or PK callbacks, try public key decode */
5621                 *idx = 0;
5622                 ret = wc_Ed25519PublicKeyDecode(der->buffer, idx, key, der->length);
5623             }
5624         #endif
5625             if (ret == 0) {
5626                 /* check for minimum key size and then free */
5627                 int minKeySz = ssl ? ssl->options.minEccKeySz :
5628                                                            ctx->minEccKeySz;
5629                 *keySz = ED25519_KEY_SIZE;
5630                 if (*keySz < minKeySz) {
5631                     WOLFSSL_MSG("ED25519 private key too small");
5632                     ret = ECC_KEY_SIZE_E;
5633                 }
5634                 if (ret == 0) {
5635                     if (ssl) {
5636                         ssl->buffers.keyType = ed25519_sa_algo;
5637                         ssl->buffers.keySz = *keySz;
5638                     }
5639                     else if (ctx) {
5640                         ctx->privateKeyType = ed25519_sa_algo;
5641                         ctx->privateKeySz = *keySz;
5642                     }
5643 
5644                     *keyFormat = ED25519k;
5645                     if (ssl != NULL) {
5646                         /* ED25519 requires caching enabled for tracking message
5647                          * hash used in EdDSA_Update for signing */
5648                         ssl->options.cacheMessages = 1;
5649                         if (ssl->options.side == WOLFSSL_SERVER_END) {
5650                             *resetSuites = 1;
5651                         }
5652                     }
5653                 }
5654             }
5655             else {
5656                 ret = 0; /* continue trying other algorithms */
5657             }
5658 
5659             wc_ed25519_free(key);
5660         }
5661 
5662     #ifdef WOLFSSL_SMALL_STACK
5663         XFREE(key, heap, DYNAMIC_TYPE_ED25519);
5664     #endif
5665     }
5666 #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
5667 #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
5668     if (ret == 0 && (*keyFormat == 0 || *keyFormat == ED448k)) {
5669         /* make sure Ed448 key can be used */
5670     #ifdef WOLFSSL_SMALL_STACK
5671         ed448_key* key = NULL;
5672     #else
5673         ed448_key  key[1];
5674     #endif
5675 
5676     #ifdef WOLFSSL_SMALL_STACK
5677         key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
5678         if (key == NULL)
5679             return MEMORY_E;
5680     #endif
5681 
5682         ret = wc_ed448_init(key);
5683         if (ret == 0) {
5684             *idx = 0;
5685             ret = wc_Ed448PrivateKeyDecode(der->buffer, idx, key, der->length);
5686             if (ret == 0) {
5687                 /* check for minimum key size and then free */
5688                 int minKeySz = ssl ? ssl->options.minEccKeySz :
5689                                                                ctx->minEccKeySz;
5690                 *keySz = ED448_KEY_SIZE;
5691                 if (*keySz < minKeySz) {
5692                     WOLFSSL_MSG("ED448 private key too small");
5693                     ret = ECC_KEY_SIZE_E;
5694                 }
5695             }
5696             if (ret == 0) {
5697                 if (ssl) {
5698                     ssl->buffers.keyType = ed448_sa_algo;
5699                     ssl->buffers.keySz = *keySz;
5700                 }
5701                 else if (ctx) {
5702                     ctx->privateKeyType = ed448_sa_algo;
5703                     ctx->privateKeySz = *keySz;
5704                 }
5705 
5706                 *keyFormat = ED448k;
5707                 if (ssl != NULL) {
5708                     /* ED448 requires caching enabled for tracking message
5709                      * hash used in EdDSA_Update for signing */
5710                     ssl->options.cacheMessages = 1;
5711                     if (ssl->options.side == WOLFSSL_SERVER_END) {
5712                         *resetSuites = 1;
5713                     }
5714                 }
5715             }
5716 
5717             wc_ed448_free(key);
5718         }
5719 
5720     #ifdef WOLFSSL_SMALL_STACK
5721         XFREE(key, heap, DYNAMIC_TYPE_ED448);
5722     #endif
5723     }
5724 #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
5725 #ifdef HAVE_PQC
5726     if (ret == 0 && ((*keyFormat == 0) || (*keyFormat == FALCON_LEVEL1k) ||
5727                      (*keyFormat == FALCON_LEVEL5k))) {
5728         /* make sure Falcon key can be used */
5729         falcon_key* key = (falcon_key*)XMALLOC(sizeof(falcon_key), heap,
5730                                                DYNAMIC_TYPE_FALCON);
5731         if (key == NULL) {
5732             return MEMORY_E;
5733         }
5734         ret = wc_falcon_init(key);
5735         if (ret == 0) {
5736             if (*keyFormat == FALCON_LEVEL1k) {
5737                 ret = wc_falcon_set_level(key, 1);
5738             }
5739             else if (*keyFormat == FALCON_LEVEL5k) {
5740                 ret = wc_falcon_set_level(key, 5);
5741             }
5742             else {
5743                 /* What if *keyformat is 0? We might want to do something more
5744                  * graceful here. */
5745                 wc_falcon_free(key);
5746                 ret = ALGO_ID_E;
5747             }
5748         }
5749 
5750         if (ret == 0) {
5751             *idx = 0;
5752             ret = wc_falcon_import_private_only(der->buffer, der->length, key);
5753             if (ret == 0) {
5754                 /* check for minimum key size and then free */
5755                 int minKeySz = ssl ? ssl->options.minFalconKeySz :
5756                                      ctx->minFalconKeySz;
5757                 *keySz = FALCON_MAX_KEY_SIZE;
5758                 if (*keySz < minKeySz) {
5759                     WOLFSSL_MSG("Falcon private key too small");
5760                     ret = FALCON_KEY_SIZE_E;
5761                 }
5762                 if (ssl) {
5763                     if (*keyFormat == FALCON_LEVEL1k) {
5764                         ssl->buffers.keyType = falcon_level1_sa_algo;
5765                     }
5766                     else {
5767                         ssl->buffers.keyType = falcon_level5_sa_algo;
5768                     }
5769                     ssl->buffers.keySz = *keySz;
5770                 }
5771                 else if (ctx) {
5772                     if (*keyFormat == FALCON_LEVEL1k) {
5773                         ctx->privateKeyType = falcon_level1_sa_algo;
5774                     }
5775                     else {
5776                         ctx->privateKeyType = falcon_level5_sa_algo;
5777                     }
5778                     ctx->privateKeySz = *keySz;
5779                 }
5780 
5781                 if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
5782                     *resetSuites = 1;
5783                 }
5784             }
5785             wc_falcon_free(key);
5786         }
5787         XFREE(key, heap, DYNAMIC_TYPE_FALCON);
5788     }
5789 #endif /* HAVE_PQC */
5790     return ret;
5791 }
5792 
5793 /* process the buffer buff, length sz, into ctx of format and type
5794    used tracks bytes consumed, userChain specifies a user cert chain
5795    to pass during the handshake */
ProcessBuffer(WOLFSSL_CTX * ctx,const unsigned char * buff,long sz,int format,int type,WOLFSSL * ssl,long * used,int userChain,int verify)5796 int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
5797                          long sz, int format, int type, WOLFSSL* ssl,
5798                          long* used, int userChain, int verify)
5799 {
5800     DerBuffer*    der = NULL;
5801     int           ret = 0;
5802     int           done = 0;
5803     int           keyFormat = 0;
5804     int           resetSuites = 0;
5805     void*         heap = wolfSSL_CTX_GetHeap(ctx, ssl);
5806     int           devId = wolfSSL_CTX_GetDevId(ctx, ssl);
5807     word32        idx = 0;
5808     int           keySz = 0;
5809 #if (defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)) || \
5810      defined(HAVE_PKCS8)
5811     word32        algId = 0;
5812 #endif
5813 #ifdef WOLFSSL_SMALL_STACK
5814     EncryptedInfo* info = NULL;
5815 #else
5816     EncryptedInfo  info[1];
5817 #endif
5818 
5819     (void)devId;
5820     (void)idx;
5821     (void)keySz;
5822 
5823     if (used)
5824         *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
5825 
5826     /* check args */
5827     if (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM)
5828         return WOLFSSL_BAD_FILETYPE;
5829 
5830     if (ctx == NULL && ssl == NULL)
5831         return BAD_FUNC_ARG;
5832 
5833 #ifdef WOLFSSL_SMALL_STACK
5834     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
5835                                    DYNAMIC_TYPE_ENCRYPTEDINFO);
5836     if (info == NULL)
5837         return MEMORY_E;
5838 #endif
5839 
5840     XMEMSET(info, 0, sizeof(EncryptedInfo));
5841 #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
5842     if (ctx) {
5843         info->passwd_cb       = ctx->passwd_cb;
5844         info->passwd_userdata = ctx->passwd_userdata;
5845     }
5846 #endif
5847 
5848     if (format == WOLFSSL_FILETYPE_PEM) {
5849     #ifdef WOLFSSL_PEM_TO_DER
5850         ret = PemToDer(buff, sz, type, &der, heap, info, &keyFormat);
5851     #else
5852         ret = NOT_COMPILED_IN;
5853     #endif
5854     }
5855     else {
5856         /* ASN1 (DER) */
5857         int length = (int)sz;
5858         if (format == WOLFSSL_FILETYPE_ASN1) {
5859             /* get length of der (read sequence or octet string) */
5860             word32 inOutIdx = 0;
5861             if (GetSequence(buff, &inOutIdx, &length, (word32)sz) >= 0) {
5862                 length += inOutIdx; /* include leading sequence */
5863             }
5864             /* get length using octect string (allowed for private key types) */
5865             else if (type == PRIVATEKEY_TYPE &&
5866                     GetOctetString(buff, &inOutIdx, &length, (word32)sz) >= 0) {
5867                 length += inOutIdx; /* include leading oct string */
5868             }
5869             else {
5870                 ret = ASN_PARSE_E;
5871             }
5872         }
5873 
5874         info->consumed = length;
5875 
5876         if (ret == 0) {
5877             ret = AllocDer(&der, (word32)length, type, heap);
5878             if (ret == 0) {
5879                 XMEMCPY(der->buffer, buff, length);
5880             }
5881 
5882         #ifdef HAVE_PKCS8
5883             /* if private key try and remove PKCS8 header */
5884             if (type == PRIVATEKEY_TYPE) {
5885                 if ((ret = ToTraditional_ex(der->buffer, der->length, &algId)) > 0) {
5886                     /* Found PKCS8 header */
5887                     /* ToTraditional_ex moves buff and returns adjusted length */
5888                     der->length = ret;
5889                     keyFormat = algId;
5890                 }
5891                 ret = 0; /* failures should be ignored */
5892             }
5893         #endif
5894         }
5895     }
5896 
5897     if (used) {
5898         *used = info->consumed;
5899     }
5900 
5901     /* process user chain */
5902     if (ret >= 0) {
5903         /* Chain should have server cert first, then intermediates, then root.
5904          * First certificate in chain is processed below after ProcessUserChain
5905          *   and is loaded into ssl->buffers.certificate.
5906          * Remainder are processed using ProcessUserChain and are loaded into
5907          *   ssl->buffers.certChain. */
5908         if (userChain) {
5909             ret = ProcessUserChain(ctx, buff, sz, format, type, ssl, used, info,
5910                                    verify);
5911         }
5912     }
5913 
5914     /* info is only used for private key with DER or PEM, so free now */
5915     if (ret < 0 || type != PRIVATEKEY_TYPE) {
5916     #ifdef WOLFSSL_SMALL_STACK
5917         XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
5918     #endif
5919     }
5920 
5921     /* check for error */
5922     if (ret < 0) {
5923         FreeDer(&der);
5924         done = 1;
5925     }
5926 
5927     if (done == 1) {
5928         /* No operation, just skip the next section */
5929     }
5930     /* Handle DER owner */
5931     else if (type == CA_TYPE) {
5932         if (ctx == NULL) {
5933             WOLFSSL_MSG("Need context for CA load");
5934             FreeDer(&der);
5935             return BAD_FUNC_ARG;
5936         }
5937         /* verify CA unless user set to no verify */
5938         ret = AddCA(ctx->cm, &der, WOLFSSL_USER_CA, verify);
5939         done = 1;
5940     }
5941 #ifdef WOLFSSL_TRUST_PEER_CERT
5942     else if (type == TRUSTED_PEER_TYPE) {
5943         if (ctx == NULL) {
5944             WOLFSSL_MSG("Need context for trusted peer cert load");
5945             FreeDer(&der);
5946             return BAD_FUNC_ARG;
5947         }
5948         /* add trusted peer cert. der is freed within */
5949         ret = AddTrustedPeer(ctx->cm, &der, !ctx->verifyNone);
5950         if (ret != WOLFSSL_SUCCESS) {
5951             WOLFSSL_MSG("Error adding trusted peer");
5952         }
5953         done = 1;
5954     }
5955 #endif /* WOLFSSL_TRUST_PEER_CERT */
5956     else if (type == CERT_TYPE) {
5957         if (ssl) {
5958              /* Make sure previous is free'd */
5959             if (ssl->buffers.weOwnCert) {
5960                 FreeDer(&ssl->buffers.certificate);
5961             #ifdef KEEP_OUR_CERT
5962                 wolfSSL_X509_free(ssl->ourCert);
5963                 ssl->ourCert = NULL;
5964             #endif
5965             }
5966             ssl->buffers.certificate = der;
5967         #ifdef KEEP_OUR_CERT
5968             ssl->keepCert = 1; /* hold cert for ssl lifetime */
5969         #endif
5970             ssl->buffers.weOwnCert = 1;
5971         }
5972         else if (ctx) {
5973             FreeDer(&ctx->certificate); /* Make sure previous is free'd */
5974         #ifdef KEEP_OUR_CERT
5975             if (ctx->ourCert) {
5976                 if (ctx->ownOurCert)
5977                     wolfSSL_X509_free(ctx->ourCert);
5978                 ctx->ourCert = NULL;
5979             }
5980         #endif
5981             ctx->certificate = der;
5982         }
5983     }
5984     else if (type == PRIVATEKEY_TYPE) {
5985         if (ssl) {
5986              /* Make sure previous is free'd */
5987             if (ssl->buffers.weOwnKey) {
5988                 FreeDer(&ssl->buffers.key);
5989             }
5990             ssl->buffers.key = der;
5991             ssl->buffers.weOwnKey = 1;
5992         }
5993         else if (ctx) {
5994             FreeDer(&ctx->privateKey);
5995             ctx->privateKey = der;
5996         }
5997     }
5998     else {
5999         FreeDer(&der);
6000         return WOLFSSL_BAD_CERTTYPE;
6001     }
6002 
6003     if (done == 1) {
6004         /* No operation, just skip the next section */
6005     }
6006     else if (type == PRIVATEKEY_TYPE) {
6007         ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx, &resetSuites,
6008                 &keyFormat, heap, devId);
6009 
6010     #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
6011         /* for WOLFSSL_FILETYPE_PEM, PemToDer manages the decryption */
6012         /* If private key type PKCS8 header wasn't already removed (algoId == 0) */
6013         if ((ret != 0 || keyFormat == 0)
6014             && format != WOLFSSL_FILETYPE_PEM && info->passwd_cb && algId == 0)
6015         {
6016             int   passwordSz = NAME_SZ;
6017         #ifndef WOLFSSL_SMALL_STACK
6018             char  password[NAME_SZ];
6019         #else
6020             char* password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
6021             if (password == NULL) {
6022             #ifdef WOLFSSL_SMALL_STACK
6023                 XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
6024             #endif
6025                 FreeDer(&der);
6026                 return MEMORY_E;
6027             }
6028         #endif
6029             /* get password */
6030             ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
6031                 info->passwd_userdata);
6032             if (ret >= 0) {
6033                 passwordSz = ret;
6034 
6035                 /* PKCS8 decrypt */
6036                 ret = ToTraditionalEnc(der->buffer, der->length,
6037                                        password, passwordSz, &algId);
6038                 if (ret >= 0) {
6039                     der->length = ret;
6040                 }
6041                 /* ignore failures and try parsing as unencrypted */
6042 
6043                 ForceZero(password, passwordSz);
6044             }
6045 
6046         #ifdef WOLFSSL_SMALL_STACK
6047             XFREE(password, heap, DYNAMIC_TYPE_STRING);
6048         #endif
6049             ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx,
6050                 &resetSuites, &keyFormat, heap, devId);
6051         }
6052     #endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */
6053 
6054     #ifdef WOLFSSL_SMALL_STACK
6055         XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
6056     #endif
6057 
6058         if (ret != 0)
6059             return ret;
6060         if (keyFormat == 0) {
6061 #ifdef OPENSSL_EXTRA
6062             /* Reaching this point probably means that the
6063              * decryption password is wrong */
6064             if (info->passwd_cb)
6065                 EVPerr(0, EVP_R_BAD_DECRYPT);
6066 #endif
6067             WOLFSSL_ERROR(WOLFSSL_BAD_FILE);
6068             return WOLFSSL_BAD_FILE;
6069         }
6070 
6071         (void)devId;
6072     }
6073     else if (type == CERT_TYPE) {
6074     #ifdef WOLFSSL_SMALL_STACK
6075         DecodedCert* cert;
6076     #else
6077         DecodedCert  cert[1];
6078     #endif
6079     #if defined(HAVE_PKCS11) || defined(HAVE_PK_CALLBACKS)
6080         int keyType = 0;
6081     #endif
6082 
6083     #ifdef WOLFSSL_SMALL_STACK
6084         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
6085                                      DYNAMIC_TYPE_DCERT);
6086         if (cert == NULL)
6087             return MEMORY_E;
6088     #endif
6089 
6090         WOLFSSL_MSG("Checking cert signature type");
6091         InitDecodedCert(cert, der->buffer, der->length, heap);
6092 
6093         if (DecodeToKey(cert, 0) < 0) {
6094             WOLFSSL_MSG("Decode to key failed");
6095             FreeDecodedCert(cert);
6096         #ifdef WOLFSSL_SMALL_STACK
6097             XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
6098         #endif
6099             return WOLFSSL_BAD_FILE;
6100         }
6101 
6102         if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
6103             resetSuites = 1;
6104         }
6105         if (ssl && ssl->ctx->haveECDSAsig) {
6106             WOLFSSL_MSG("SSL layer setting cert, CTX had ECDSA, turning off");
6107             ssl->options.haveECDSAsig = 0;   /* may turn back on next */
6108         }
6109 
6110         switch (cert->signatureOID) {
6111             case CTC_SHAwECDSA:
6112             case CTC_SHA256wECDSA:
6113             case CTC_SHA384wECDSA:
6114             case CTC_SHA512wECDSA:
6115             case CTC_ED25519:
6116             case CTC_ED448:
6117                 WOLFSSL_MSG("ECDSA/ED25519/ED448 cert signature");
6118                 if (ssl)
6119                     ssl->options.haveECDSAsig = 1;
6120                 else if (ctx)
6121                     ctx->haveECDSAsig = 1;
6122                 break;
6123             case CTC_FALCON_LEVEL1:
6124             case CTC_FALCON_LEVEL5:
6125                 WOLFSSL_MSG("Falcon cert signature");
6126                 if (ssl)
6127                     ssl->options.haveFalconSig = 1;
6128                 else if (ctx)
6129                     ctx->haveFalconSig = 1;
6130                 break;
6131             default:
6132                 WOLFSSL_MSG("Not ECDSA cert signature");
6133                 break;
6134         }
6135 
6136     #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
6137         defined(HAVE_PQC)
6138         if (ssl) {
6139             ssl->pkCurveOID = cert->pkCurveOID;
6140         #ifndef WC_STRICT_SIG
6141             if (cert->keyOID == ECDSAk) {
6142                 ssl->options.haveECC = 1;
6143             }
6144             #ifdef HAVE_ED25519
6145                 else if (cert->keyOID == ED25519k) {
6146                     ssl->options.haveECC = 1;
6147                 }
6148             #endif
6149             #ifdef HAVE_ED448
6150                 else if (cert->keyOID == ED448k) {
6151                     ssl->options.haveECC = 1;
6152                 }
6153             #endif
6154             #ifdef HAVE_PQC
6155                 else if (cert->keyOID == FALCON_LEVEL1k ||
6156                          cert->keyOID == FALCON_LEVEL5k) {
6157                     ssl->options.haveFalconSig = 1;
6158                 }
6159             #endif
6160         #else
6161             ssl->options.haveECC = ssl->options.haveECDSAsig;
6162         #endif
6163         }
6164         else if (ctx) {
6165             ctx->pkCurveOID = cert->pkCurveOID;
6166         #ifndef WC_STRICT_SIG
6167             if (cert->keyOID == ECDSAk) {
6168                 ctx->haveECC = 1;
6169             }
6170             #ifdef HAVE_ED25519
6171                 else if (cert->keyOID == ED25519k) {
6172                     ctx->haveECC = 1;
6173                 }
6174             #endif
6175             #ifdef HAVE_ED448
6176                 else if (cert->keyOID == ED448k) {
6177                     ctx->haveECC = 1;
6178                 }
6179             #endif
6180             #ifdef HAVE_PQC
6181                 else if (cert->keyOID == FALCON_LEVEL1k ||
6182                          cert->keyOID == FALCON_LEVEL5k) {
6183                     ctx->haveFalconSig = 1;
6184                 }
6185             #endif
6186         #else
6187             ctx->haveECC = ctx->haveECDSAsig;
6188         #endif
6189         }
6190     #endif
6191 
6192         /* check key size of cert unless specified not to */
6193         switch (cert->keyOID) {
6194         #ifndef NO_RSA
6195             case RSAk:
6196             #if defined(HAVE_PKCS11) || defined(HAVE_PK_CALLBACKS)
6197                 keyType = rsa_sa_algo;
6198             #endif
6199                 /* Determine RSA key size by parsing public key */
6200                 idx = 0;
6201                 ret = wc_RsaPublicKeyDecode_ex(cert->publicKey, &idx,
6202                     cert->pubKeySize, NULL, (word32*)&keySz, NULL, NULL);
6203                 if (ret < 0)
6204                     break;
6205 
6206                 if (ssl && !ssl->options.verifyNone) {
6207                     if (ssl->options.minRsaKeySz < 0 ||
6208                           keySz < (int)ssl->options.minRsaKeySz) {
6209                         ret = RSA_KEY_SIZE_E;
6210                         WOLFSSL_MSG("Certificate RSA key size too small");
6211                     }
6212                 }
6213                 else if (ctx && !ctx->verifyNone) {
6214                     if (ctx->minRsaKeySz < 0 ||
6215                                   keySz < (int)ctx->minRsaKeySz) {
6216                         ret = RSA_KEY_SIZE_E;
6217                         WOLFSSL_MSG("Certificate RSA key size too small");
6218                     }
6219                 }
6220                 break;
6221         #endif /* !NO_RSA */
6222         #ifdef HAVE_ECC
6223             case ECDSAk:
6224             #if defined(HAVE_PKCS11) || defined(HAVE_PK_CALLBACKS)
6225                 keyType = ecc_dsa_sa_algo;
6226             #endif
6227                 /* Determine ECC key size based on curve */
6228                 keySz = wc_ecc_get_curve_size_from_id(
6229                     wc_ecc_get_oid(cert->pkCurveOID, NULL, NULL));
6230 
6231                 if (ssl && !ssl->options.verifyNone) {
6232                     if (ssl->options.minEccKeySz < 0 ||
6233                           keySz < (int)ssl->options.minEccKeySz) {
6234                         ret = ECC_KEY_SIZE_E;
6235                         WOLFSSL_MSG("Certificate ECC key size error");
6236                     }
6237                 }
6238                 else if (ctx && !ctx->verifyNone) {
6239                     if (ctx->minEccKeySz < 0 ||
6240                                   keySz < (int)ctx->minEccKeySz) {
6241                         ret = ECC_KEY_SIZE_E;
6242                         WOLFSSL_MSG("Certificate ECC key size error");
6243                     }
6244                 }
6245                 break;
6246         #endif /* HAVE_ECC */
6247         #ifdef HAVE_ED25519
6248             case ED25519k:
6249             #if defined(HAVE_PKCS11) || defined(HAVE_PK_CALLBACKS)
6250                 keyType = ed25519_sa_algo;
6251             #endif
6252                 /* ED25519 is fixed key size */
6253                 keySz = ED25519_KEY_SIZE;
6254                 if (ssl && !ssl->options.verifyNone) {
6255                     if (ssl->options.minEccKeySz < 0 ||
6256                           keySz < (int)ssl->options.minEccKeySz) {
6257                         ret = ECC_KEY_SIZE_E;
6258                         WOLFSSL_MSG("Certificate Ed key size error");
6259                     }
6260                 }
6261                 else if (ctx && !ctx->verifyNone) {
6262                     if (ctx->minEccKeySz < 0 ||
6263                                   keySz < (int)ctx->minEccKeySz) {
6264                         ret = ECC_KEY_SIZE_E;
6265                         WOLFSSL_MSG("Certificate ECC key size error");
6266                     }
6267                 }
6268                 break;
6269         #endif /* HAVE_ED25519 */
6270         #ifdef HAVE_ED448
6271             case ED448k:
6272             #if defined(HAVE_PKCS11) || defined(HAVE_PK_CALLBACKS)
6273                 keyType = ed448_sa_algo;
6274             #endif
6275                 /* ED448 is fixed key size */
6276                 keySz = ED448_KEY_SIZE;
6277                 if (ssl && !ssl->options.verifyNone) {
6278                     if (ssl->options.minEccKeySz < 0 ||
6279                           keySz < (int)ssl->options.minEccKeySz) {
6280                         ret = ECC_KEY_SIZE_E;
6281                         WOLFSSL_MSG("Certificate Ed key size error");
6282                     }
6283                 }
6284                 else if (ctx && !ctx->verifyNone) {
6285                     if (ctx->minEccKeySz < 0 ||
6286                                   keySz < (int)ctx->minEccKeySz) {
6287                         ret = ECC_KEY_SIZE_E;
6288                         WOLFSSL_MSG("Certificate ECC key size error");
6289                     }
6290                 }
6291                 break;
6292         #endif /* HAVE_ED448 */
6293         #ifdef HAVE_PQC
6294             case FALCON_LEVEL1k:
6295             case FALCON_LEVEL5k:
6296                 /* Falcon is fixed key size */
6297                 keySz = FALCON_MAX_KEY_SIZE;
6298                 if (ssl && !ssl->options.verifyNone) {
6299                     if (ssl->options.minFalconKeySz < 0 ||
6300                           keySz < (int)ssl->options.minFalconKeySz) {
6301                         ret = FALCON_KEY_SIZE_E;
6302                         WOLFSSL_MSG("Certificate Falcon key size error");
6303                     }
6304                 }
6305                 else if (ctx && !ctx->verifyNone) {
6306                     if (ctx->minFalconKeySz < 0 ||
6307                                   keySz < (int)ctx->minFalconKeySz) {
6308                         ret = FALCON_KEY_SIZE_E;
6309                         WOLFSSL_MSG("Certificate Falcon key size error");
6310                     }
6311                 }
6312                 break;
6313         #endif /* HAVE_PQC */
6314 
6315             default:
6316                 WOLFSSL_MSG("No key size check done on certificate");
6317                 break; /* do no check if not a case for the key */
6318         }
6319 
6320     #if defined(HAVE_PKCS11) || defined(HAVE_PK_CALLBACKS)
6321         if (ssl
6322         #ifdef HAVE_PK_CALLBACKS
6323                 && ssl->buffers.keyType == 0
6324         #endif
6325             ) {
6326             ssl->buffers.keyType = keyType;
6327             ssl->buffers.keySz = keySz;
6328         }
6329         else if (ctx
6330         #ifdef HAVE_PK_CALLBACKS
6331                      && ctx->privateKeyType == 0
6332         #endif
6333             ) {
6334             ctx->privateKeyType = keyType;
6335             ctx->privateKeySz = keySz;
6336         }
6337     #endif
6338 
6339         FreeDecodedCert(cert);
6340     #ifdef WOLFSSL_SMALL_STACK
6341         XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
6342     #endif
6343 
6344         if (ret != 0) {
6345             done = 1;
6346         }
6347     }
6348 
6349     if (done == 1) {
6350     #if !defined(NO_WOLFSSL_CM_VERIFY) && (!defined(NO_WOLFSSL_CLIENT) || \
6351                                            !defined(WOLFSSL_NO_CLIENT_AUTH))
6352         if ((type == CA_TYPE) || (type == CERT_TYPE)) {
6353             /* Call to over-ride status */
6354             if ((ctx != NULL) && (ctx->cm != NULL) &&
6355                 (ctx->cm->verifyCallback != NULL)) {
6356                 ret = CM_VerifyBuffer_ex(ctx->cm, buff,
6357                         sz, format, (ret == WOLFSSL_SUCCESS ? 0 : ret));
6358             }
6359         }
6360     #endif /* NO_WOLFSSL_CM_VERIFY */
6361 
6362         return ret;
6363     }
6364 
6365 
6366     if (ssl && resetSuites) {
6367         word16 havePSK = 0;
6368         word16 haveRSA = 0;
6369 
6370         #ifndef NO_PSK
6371         if (ssl->options.havePSK) {
6372             havePSK = 1;
6373         }
6374         #endif
6375         #ifndef NO_RSA
6376             haveRSA = 1;
6377         #endif
6378         #ifndef NO_CERTS
6379             keySz = ssl->buffers.keySz;
6380         #endif
6381 
6382         /* let's reset suites */
6383         InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
6384                    havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig,
6385                    ssl->options.haveECC, ssl->options.haveStaticECC,
6386                    ssl->options.haveFalconSig, ssl->options.haveAnon,
6387                    ssl->options.side);
6388     }
6389 
6390     return WOLFSSL_SUCCESS;
6391 }
6392 
6393 
6394 /* CA PEM file for verification, may have multiple/chain certs to process */
ProcessChainBuffer(WOLFSSL_CTX * ctx,const unsigned char * buff,long sz,int format,int type,WOLFSSL * ssl,int verify)6395 static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
6396                         long sz, int format, int type, WOLFSSL* ssl, int verify)
6397 {
6398     long used   = 0;
6399     int  ret    = 0;
6400     int  gotOne = 0;
6401 
6402     WOLFSSL_MSG("Processing CA PEM file");
6403     while (used < sz) {
6404         long consumed = 0;
6405 
6406         ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
6407                             &consumed, 0, verify);
6408 
6409         if (ret < 0) {
6410 #if defined(WOLFSSL_WPAS) && defined(HAVE_CRL)
6411             DerBuffer*    der = NULL;
6412             EncryptedInfo info;
6413 
6414             WOLFSSL_MSG("Trying a CRL");
6415             if (PemToDer(buff + used, sz - used, CRL_TYPE, &der, NULL, &info,
6416                                                                    NULL) == 0) {
6417                 WOLFSSL_MSG("   Processed a CRL");
6418                 wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, der->buffer,
6419                                             der->length, WOLFSSL_FILETYPE_ASN1);
6420                 FreeDer(&der);
6421                 used += info.consumed;
6422                 continue;
6423             }
6424 #endif
6425 
6426             if (consumed > 0) { /* Made progress in file */
6427                 WOLFSSL_ERROR(ret);
6428                 WOLFSSL_MSG("CA Parse failed, with progress in file.");
6429                 WOLFSSL_MSG("Search for other certs in file");
6430             }
6431             else {
6432                 WOLFSSL_MSG("CA Parse failed, no progress in file.");
6433                 WOLFSSL_MSG("Do not continue search for other certs in file");
6434                 break;
6435             }
6436         }
6437         else {
6438             WOLFSSL_MSG("   Processed a CA");
6439             gotOne = 1;
6440         }
6441         used += consumed;
6442     }
6443 
6444     if (gotOne) {
6445         WOLFSSL_MSG("Processed at least one valid CA. Other stuff OK");
6446         return WOLFSSL_SUCCESS;
6447     }
6448     return ret;
6449 }
6450 
6451 
cm_pick_method(void)6452 static WC_INLINE WOLFSSL_METHOD* cm_pick_method(void)
6453 {
6454     #ifndef NO_WOLFSSL_CLIENT
6455         #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3)
6456             return wolfSSLv3_client_method();
6457         #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
6458             return wolfTLSv1_client_method();
6459         #elif !defined(NO_OLD_TLS)
6460             return wolfTLSv1_1_client_method();
6461         #elif !defined(WOLFSSL_NO_TLS12)
6462             return wolfTLSv1_2_client_method();
6463         #elif defined(WOLFSSL_TLS13)
6464             return wolfTLSv1_3_client_method();
6465         #else
6466             return NULL;
6467         #endif
6468     #elif !defined(NO_WOLFSSL_SERVER)
6469         #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3)
6470             return wolfSSLv3_server_method();
6471         #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
6472             return wolfTLSv1_server_method();
6473         #elif !defined(NO_OLD_TLS)
6474             return wolfTLSv1_1_server_method();
6475         #elif !defined(WOLFSSL_NO_TLS12)
6476             return wolfTLSv1_2_server_method();
6477         #elif defined(WOLFSSL_TLS13)
6478             return wolfTLSv1_3_server_method();
6479         #else
6480             return NULL;
6481         #endif
6482     #else
6483         return NULL;
6484     #endif
6485 }
6486 
6487 
6488 /* like load verify locations, 1 for success, < 0 for error */
wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER * cm,const unsigned char * in,long sz,int format)6489 int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm,
6490                                    const unsigned char* in, long sz, int format)
6491 {
6492     int ret = WOLFSSL_FATAL_ERROR;
6493     WOLFSSL_CTX* tmp;
6494 
6495     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer");
6496 
6497     if (cm == NULL) {
6498         WOLFSSL_MSG("No CertManager error");
6499         return ret;
6500     }
6501     tmp = wolfSSL_CTX_new(cm_pick_method());
6502 
6503     if (tmp == NULL) {
6504         WOLFSSL_MSG("CTX new failed");
6505         return ret;
6506     }
6507 
6508     /* for tmp use */
6509     wolfSSL_CertManagerFree(tmp->cm);
6510     tmp->cm = cm;
6511 
6512     ret = wolfSSL_CTX_load_verify_buffer(tmp, in, sz, format);
6513 
6514     /* don't loose our good one */
6515     tmp->cm = NULL;
6516     wolfSSL_CTX_free(tmp);
6517 
6518     return ret;
6519 }
6520 
6521 #ifdef HAVE_CRL
6522 
wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER * cm,const unsigned char * buff,long sz,int type)6523 int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
6524                                    const unsigned char* buff, long sz, int type)
6525 {
6526     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer");
6527     if (cm == NULL)
6528         return BAD_FUNC_ARG;
6529 
6530     if (cm->crl == NULL) {
6531         if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
6532             WOLFSSL_MSG("Enable CRL failed");
6533             return WOLFSSL_FATAL_ERROR;
6534         }
6535     }
6536 
6537     return BufferLoadCRL(cm->crl, buff, sz, type, VERIFY);
6538 }
6539 
wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER * cm)6540 int wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER* cm)
6541 {
6542     WOLFSSL_ENTER("wolfSSL_CertManagerFreeCRL");
6543     if (cm == NULL)
6544         return BAD_FUNC_ARG;
6545     if (cm->crl != NULL){
6546         FreeCRL(cm->crl, 1);
6547         cm->crl = NULL;
6548     }
6549     return WOLFSSL_SUCCESS;
6550 }
6551 
wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX * ctx,const unsigned char * buff,long sz,int type)6552 int wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
6553                               long sz, int type)
6554 {
6555     WOLFSSL_ENTER("wolfSSL_CTX_LoadCRLBuffer");
6556 
6557     if (ctx == NULL)
6558         return BAD_FUNC_ARG;
6559 
6560     return wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, buff, sz, type);
6561 }
6562 
6563 
wolfSSL_LoadCRLBuffer(WOLFSSL * ssl,const unsigned char * buff,long sz,int type)6564 int wolfSSL_LoadCRLBuffer(WOLFSSL* ssl, const unsigned char* buff,
6565                           long sz, int type)
6566 {
6567     WOLFSSL_ENTER("wolfSSL_LoadCRLBuffer");
6568 
6569     if (ssl == NULL || ssl->ctx == NULL)
6570         return BAD_FUNC_ARG;
6571 
6572     return wolfSSL_CertManagerLoadCRLBuffer(SSL_CM(ssl), buff, sz, type);
6573 }
6574 
6575 
6576 #endif /* HAVE_CRL */
6577 
6578 /* turn on CRL if off and compiled in, set options */
wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER * cm,int options)6579 int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
6580 {
6581     int ret = WOLFSSL_SUCCESS;
6582 
6583     (void)options;
6584 
6585     WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
6586     if (cm == NULL)
6587         return BAD_FUNC_ARG;
6588 
6589     #ifdef HAVE_CRL
6590         if (cm->crl == NULL) {
6591             cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
6592                                             DYNAMIC_TYPE_CRL);
6593             if (cm->crl == NULL)
6594                 return MEMORY_E;
6595 
6596             if (InitCRL(cm->crl, cm) != 0) {
6597                 WOLFSSL_MSG("Init CRL failed");
6598                 FreeCRL(cm->crl, 1);
6599                 cm->crl = NULL;
6600                 return WOLFSSL_FAILURE;
6601             }
6602 
6603         #if defined(HAVE_CRL_IO) && defined(USE_WOLFSSL_IO)
6604             cm->crl->crlIOCb = EmbedCrlLookup;
6605         #endif
6606         }
6607 
6608         cm->crlEnabled = 1;
6609         if (options & WOLFSSL_CRL_CHECKALL)
6610             cm->crlCheckAll = 1;
6611     #else
6612         ret = NOT_COMPILED_IN;
6613     #endif
6614 
6615     return ret;
6616 }
6617 
6618 
wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER * cm)6619 int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
6620 {
6621     WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
6622     if (cm == NULL)
6623         return BAD_FUNC_ARG;
6624 
6625     cm->crlEnabled = 0;
6626 
6627     return WOLFSSL_SUCCESS;
6628 }
6629 
6630 #ifndef NO_WOLFSSL_CM_VERIFY
wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER * cm,VerifyCallback vc)6631 void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm, VerifyCallback vc)
6632 {
6633     WOLFSSL_ENTER("wolfSSL_CertManagerSetVerify");
6634     if (cm == NULL)
6635         return;
6636 
6637     cm->verifyCallback = vc;
6638 }
6639 #endif /* NO_WOLFSSL_CM_VERIFY */
6640 
6641 #if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
6642 /* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER * cm,const byte * buff,long sz,int format,int err_val)6643 int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
6644                                     long sz, int format, int err_val)
6645 {
6646     int ret = 0;
6647     DerBuffer* der = NULL;
6648 #ifdef WOLFSSL_SMALL_STACK
6649     DecodedCert* cert;
6650 #else
6651     DecodedCert  cert[1];
6652 #endif
6653 
6654     WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
6655 
6656 #ifdef WOLFSSL_SMALL_STACK
6657     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
6658                                  DYNAMIC_TYPE_DCERT);
6659     if (cert == NULL)
6660         return MEMORY_E;
6661 #endif
6662 
6663     if (format == WOLFSSL_FILETYPE_PEM) {
6664 #ifdef WOLFSSL_PEM_TO_DER
6665         ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, NULL, NULL);
6666         if (ret != 0) {
6667             FreeDer(&der);
6668         #ifdef WOLFSSL_SMALL_STACK
6669             XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
6670         #endif
6671             return ret;
6672         }
6673         InitDecodedCert(cert, der->buffer, der->length, cm->heap);
6674 #else
6675         ret = NOT_COMPILED_IN;
6676 #endif
6677     }
6678     else {
6679         InitDecodedCert(cert, buff, (word32)sz, cm->heap);
6680     }
6681 
6682     if (ret == 0)
6683         ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
6684 
6685 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
6686     /* ret needs to be self-singer error for Qt compat */
6687     if (ret == ASN_NO_SIGNER_E && cert->selfSigned)
6688         ret = ASN_SELF_SIGNED_E;
6689 #endif
6690 
6691 #ifdef HAVE_CRL
6692     if (ret == 0 && cm->crlEnabled)
6693         ret = CheckCertCRL(cm->crl, cert);
6694 #endif
6695 
6696 #ifndef NO_WOLFSSL_CM_VERIFY
6697     /* if verify callback has been set */
6698     if (cm->verifyCallback) {
6699         buffer certBuf;
6700     #ifdef WOLFSSL_SMALL_STACK
6701         ProcPeerCertArgs* args;
6702         args = (ProcPeerCertArgs*)XMALLOC(
6703             sizeof(ProcPeerCertArgs), cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
6704         if (args == NULL) {
6705             XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
6706             return MEMORY_E;
6707         }
6708     #else
6709         ProcPeerCertArgs  args[1];
6710     #endif
6711 
6712         certBuf.buffer = (byte*)buff;
6713         certBuf.length = (unsigned int)sz;
6714         XMEMSET(args, 0, sizeof(ProcPeerCertArgs));
6715 
6716         args->totalCerts = 1;
6717         args->certs = &certBuf;
6718         args->dCert = cert;
6719         args->dCertInit = 1;
6720 
6721         if (err_val != 0) {
6722             ret = err_val;
6723         }
6724         ret = DoVerifyCallback(cm, NULL, ret, args);
6725     #ifdef WOLFSSL_SMALL_STACK
6726         XFREE(args, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
6727     #endif
6728     }
6729 #else
6730     (void)err_val;
6731 #endif
6732 
6733     FreeDecodedCert(cert);
6734     FreeDer(&der);
6735 #ifdef WOLFSSL_SMALL_STACK
6736     XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
6737 #endif
6738 
6739     return ret == 0 ? WOLFSSL_SUCCESS : ret;
6740 }
6741 
6742 /* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER * cm,const byte * buff,long sz,int format)6743 int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
6744                                     long sz, int format)
6745 {
6746     return CM_VerifyBuffer_ex(cm, buff, sz, format, 0);
6747 }
6748 #endif /* !NO_WOLFSSL_CLIENT || !WOLFSSL_NO_CLIENT_AUTH */
6749 
6750 /* turn on OCSP if off and compiled in, set options */
wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER * cm,int options)6751 int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
6752 {
6753     int ret = WOLFSSL_SUCCESS;
6754 
6755     (void)options;
6756 
6757     WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
6758     if (cm == NULL)
6759         return BAD_FUNC_ARG;
6760 
6761     #ifdef HAVE_OCSP
6762         if (cm->ocsp == NULL) {
6763             cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
6764                                               DYNAMIC_TYPE_OCSP);
6765             if (cm->ocsp == NULL)
6766                 return MEMORY_E;
6767 
6768             if (InitOCSP(cm->ocsp, cm) != 0) {
6769                 WOLFSSL_MSG("Init OCSP failed");
6770                 FreeOCSP(cm->ocsp, 1);
6771                 cm->ocsp = NULL;
6772                 return WOLFSSL_FAILURE;
6773             }
6774         }
6775         cm->ocspEnabled = 1;
6776         if (options & WOLFSSL_OCSP_URL_OVERRIDE)
6777             cm->ocspUseOverrideURL = 1;
6778         if (options & WOLFSSL_OCSP_NO_NONCE)
6779             cm->ocspSendNonce = 0;
6780         else
6781             cm->ocspSendNonce = 1;
6782         if (options & WOLFSSL_OCSP_CHECKALL)
6783             cm->ocspCheckAll = 1;
6784         #ifndef WOLFSSL_USER_IO
6785             cm->ocspIOCb = EmbedOcspLookup;
6786             cm->ocspRespFreeCb = EmbedOcspRespFree;
6787             cm->ocspIOCtx = cm->heap;
6788         #endif /* WOLFSSL_USER_IO */
6789     #else
6790         ret = NOT_COMPILED_IN;
6791     #endif
6792 
6793     return ret;
6794 }
6795 
6796 
wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER * cm)6797 int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
6798 {
6799     WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
6800     if (cm == NULL)
6801         return BAD_FUNC_ARG;
6802 
6803     cm->ocspEnabled = 0;
6804 
6805     return WOLFSSL_SUCCESS;
6806 }
6807 
6808 /* turn on OCSP Stapling if off and compiled in, set options */
wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER * cm)6809 int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
6810 {
6811     int ret = WOLFSSL_SUCCESS;
6812 
6813     WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling");
6814 
6815     if (cm == NULL)
6816         return BAD_FUNC_ARG;
6817 
6818 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
6819  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
6820     #ifndef NO_WOLFSSL_SERVER
6821     if (cm->ocsp_stapling == NULL) {
6822         cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
6823                                                cm->heap, DYNAMIC_TYPE_OCSP);
6824         if (cm->ocsp_stapling == NULL)
6825             return MEMORY_E;
6826 
6827         if (InitOCSP(cm->ocsp_stapling, cm) != 0) {
6828             WOLFSSL_MSG("Init OCSP failed");
6829             FreeOCSP(cm->ocsp_stapling, 1);
6830             cm->ocsp_stapling = NULL;
6831             return WOLFSSL_FAILURE;
6832         }
6833     }
6834 
6835     #ifndef WOLFSSL_USER_IO
6836         cm->ocspIOCb = EmbedOcspLookup;
6837         cm->ocspRespFreeCb = EmbedOcspRespFree;
6838         cm->ocspIOCtx = cm->heap;
6839     #endif /* WOLFSSL_USER_IO */
6840     #endif /* NO_WOLFSSL_SERVER */
6841     cm->ocspStaplingEnabled = 1;
6842 #else
6843     ret = NOT_COMPILED_IN;
6844 #endif
6845 
6846     return ret;
6847 }
6848 
wolfSSL_CertManagerDisableOCSPStapling(WOLFSSL_CERT_MANAGER * cm)6849 int wolfSSL_CertManagerDisableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
6850 {
6851     int ret = WOLFSSL_SUCCESS;
6852 
6853     WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPStapling");
6854 
6855     if (cm == NULL)
6856         return BAD_FUNC_ARG;
6857 
6858 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
6859  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
6860     cm->ocspStaplingEnabled = 0;
6861 #else
6862     ret = NOT_COMPILED_IN;
6863 #endif
6864     return ret;
6865 }
6866 
6867 /* require OCSP stapling response */
wolfSSL_CertManagerEnableOCSPMustStaple(WOLFSSL_CERT_MANAGER * cm)6868 int wolfSSL_CertManagerEnableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm)
6869 {
6870     int ret;
6871 
6872     WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPMustStaple");
6873 
6874     if (cm == NULL)
6875         return BAD_FUNC_ARG;
6876 
6877 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
6878  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
6879     #ifndef NO_WOLFSSL_CLIENT
6880         cm->ocspMustStaple = 1;
6881     #endif
6882     ret = WOLFSSL_SUCCESS;
6883 #else
6884     ret = NOT_COMPILED_IN;
6885 #endif
6886 
6887     return ret;
6888 }
6889 
wolfSSL_CertManagerDisableOCSPMustStaple(WOLFSSL_CERT_MANAGER * cm)6890 int wolfSSL_CertManagerDisableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm)
6891 {
6892     int ret;
6893 
6894     WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPMustStaple");
6895 
6896     if (cm == NULL)
6897         return BAD_FUNC_ARG;
6898 
6899 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
6900  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
6901     #ifndef NO_WOLFSSL_CLIENT
6902         cm->ocspMustStaple = 0;
6903     #endif
6904     ret = WOLFSSL_SUCCESS;
6905 #else
6906     ret = NOT_COMPILED_IN;
6907 #endif
6908     return ret;
6909 }
6910 
6911 #ifdef HAVE_OCSP
6912 /* check CRL if enabled, WOLFSSL_SUCCESS  */
wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER * cm,byte * der,int sz)6913 int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
6914 {
6915     int ret;
6916 #ifdef WOLFSSL_SMALL_STACK
6917     DecodedCert* cert = NULL;
6918 #else
6919     DecodedCert  cert[1];
6920 #endif
6921 
6922     WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
6923 
6924     if (cm == NULL)
6925         return BAD_FUNC_ARG;
6926 
6927     if (cm->ocspEnabled == 0)
6928         return WOLFSSL_SUCCESS;
6929 
6930 #ifdef WOLFSSL_SMALL_STACK
6931     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap, DYNAMIC_TYPE_DCERT);
6932     if (cert == NULL)
6933         return MEMORY_E;
6934 #endif
6935 
6936     InitDecodedCert(cert, der, sz, NULL);
6937 
6938     if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm)) != 0) {
6939         WOLFSSL_MSG("ParseCert failed");
6940     }
6941     else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) {
6942         WOLFSSL_MSG("CheckCertOCSP failed");
6943     }
6944 
6945     FreeDecodedCert(cert);
6946 #ifdef WOLFSSL_SMALL_STACK
6947     XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
6948 #endif
6949 
6950     return ret == 0 ? WOLFSSL_SUCCESS : ret;
6951 }
6952 
wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER * cm,byte * response,int responseSz,buffer * responseBuffer,CertStatus * status,OcspEntry * entry,OcspRequest * ocspRequest)6953 WOLFSSL_API int wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER *cm,
6954                                                     byte *response, int responseSz, buffer *responseBuffer,
6955                                                     CertStatus *status, OcspEntry *entry, OcspRequest *ocspRequest)
6956 {
6957     int ret;
6958 
6959     WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSPResponse");
6960     if (cm == NULL || response == NULL)
6961         return BAD_FUNC_ARG;
6962     if (cm->ocspEnabled == 0)
6963         return WOLFSSL_SUCCESS;
6964 
6965     ret = CheckOcspResponse(cm->ocsp, response, responseSz, responseBuffer, status,
6966                         entry, ocspRequest);
6967 
6968     return ret == 0 ? WOLFSSL_SUCCESS : ret;
6969 }
6970 
wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER * cm,const char * url)6971 int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
6972                                           const char* url)
6973 {
6974     WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
6975     if (cm == NULL)
6976         return BAD_FUNC_ARG;
6977 
6978     XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
6979     if (url != NULL) {
6980         int urlSz = (int)XSTRLEN(url) + 1;
6981         cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, DYNAMIC_TYPE_URL);
6982         if (cm->ocspOverrideURL != NULL) {
6983             XMEMCPY(cm->ocspOverrideURL, url, urlSz);
6984         }
6985         else
6986             return MEMORY_E;
6987     }
6988     else
6989         cm->ocspOverrideURL = NULL;
6990 
6991     return WOLFSSL_SUCCESS;
6992 }
6993 
6994 
wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER * cm,CbOCSPIO ioCb,CbOCSPRespFree respFreeCb,void * ioCbCtx)6995 int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm,
6996                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
6997 {
6998     WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
6999     if (cm == NULL)
7000         return BAD_FUNC_ARG;
7001 
7002     cm->ocspIOCb = ioCb;
7003     cm->ocspRespFreeCb = respFreeCb;
7004     cm->ocspIOCtx = ioCbCtx;
7005 
7006     return WOLFSSL_SUCCESS;
7007 }
7008 
7009 
wolfSSL_EnableOCSP(WOLFSSL * ssl,int options)7010 int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
7011 {
7012     WOLFSSL_ENTER("wolfSSL_EnableOCSP");
7013     if (ssl)
7014         return wolfSSL_CertManagerEnableOCSP(SSL_CM(ssl), options);
7015     else
7016         return BAD_FUNC_ARG;
7017 }
7018 
wolfSSL_DisableOCSP(WOLFSSL * ssl)7019 int wolfSSL_DisableOCSP(WOLFSSL* ssl)
7020 {
7021     WOLFSSL_ENTER("wolfSSL_DisableOCSP");
7022     if (ssl)
7023         return wolfSSL_CertManagerDisableOCSP(SSL_CM(ssl));
7024     else
7025         return BAD_FUNC_ARG;
7026 }
7027 
7028 
wolfSSL_EnableOCSPStapling(WOLFSSL * ssl)7029 int wolfSSL_EnableOCSPStapling(WOLFSSL* ssl)
7030 {
7031     WOLFSSL_ENTER("wolfSSL_EnableOCSPStapling");
7032     if (ssl)
7033         return wolfSSL_CertManagerEnableOCSPStapling(SSL_CM(ssl));
7034     else
7035         return BAD_FUNC_ARG;
7036 }
7037 
wolfSSL_DisableOCSPStapling(WOLFSSL * ssl)7038 int wolfSSL_DisableOCSPStapling(WOLFSSL* ssl)
7039 {
7040     WOLFSSL_ENTER("wolfSSL_DisableOCSPStapling");
7041     if (ssl)
7042         return wolfSSL_CertManagerDisableOCSPStapling(SSL_CM(ssl));
7043     else
7044         return BAD_FUNC_ARG;
7045 }
7046 
wolfSSL_SetOCSP_OverrideURL(WOLFSSL * ssl,const char * url)7047 int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
7048 {
7049     WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
7050     if (ssl)
7051         return wolfSSL_CertManagerSetOCSPOverrideURL(SSL_CM(ssl), url);
7052     else
7053         return BAD_FUNC_ARG;
7054 }
7055 
7056 
wolfSSL_SetOCSP_Cb(WOLFSSL * ssl,CbOCSPIO ioCb,CbOCSPRespFree respFreeCb,void * ioCbCtx)7057 int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
7058                         CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
7059 {
7060     WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
7061     if (ssl) {
7062         ssl->ocspIOCtx = ioCbCtx; /* use SSL specific ioCbCtx */
7063         return wolfSSL_CertManagerSetOCSP_Cb(SSL_CM(ssl),
7064                                              ioCb, respFreeCb, NULL);
7065     }
7066     else
7067         return BAD_FUNC_ARG;
7068 }
7069 
7070 
wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX * ctx,int options)7071 int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
7072 {
7073     WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
7074     if (ctx)
7075         return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
7076     else
7077         return BAD_FUNC_ARG;
7078 }
7079 
7080 
wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX * ctx)7081 int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
7082 {
7083     WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
7084     if (ctx)
7085         return wolfSSL_CertManagerDisableOCSP(ctx->cm);
7086     else
7087         return BAD_FUNC_ARG;
7088 }
7089 
7090 
wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX * ctx,const char * url)7091 int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
7092 {
7093     WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
7094     if (ctx)
7095         return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
7096     else
7097         return BAD_FUNC_ARG;
7098 }
7099 
7100 
wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX * ctx,CbOCSPIO ioCb,CbOCSPRespFree respFreeCb,void * ioCbCtx)7101 int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
7102                            CbOCSPRespFree respFreeCb, void* ioCbCtx)
7103 {
7104     WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
7105     if (ctx)
7106         return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb,
7107                                              respFreeCb, ioCbCtx);
7108     else
7109         return BAD_FUNC_ARG;
7110 }
7111 
7112 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7113  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX * ctx)7114 int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
7115 {
7116     WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
7117     if (ctx)
7118         return wolfSSL_CertManagerEnableOCSPStapling(ctx->cm);
7119     else
7120         return BAD_FUNC_ARG;
7121 }
7122 
wolfSSL_CTX_DisableOCSPStapling(WOLFSSL_CTX * ctx)7123 int wolfSSL_CTX_DisableOCSPStapling(WOLFSSL_CTX* ctx)
7124 {
7125     WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSPStapling");
7126     if (ctx)
7127         return wolfSSL_CertManagerDisableOCSPStapling(ctx->cm);
7128     else
7129         return BAD_FUNC_ARG;
7130 }
7131 
wolfSSL_CTX_EnableOCSPMustStaple(WOLFSSL_CTX * ctx)7132 int wolfSSL_CTX_EnableOCSPMustStaple(WOLFSSL_CTX* ctx)
7133 {
7134     WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPMustStaple");
7135     if (ctx)
7136         return wolfSSL_CertManagerEnableOCSPMustStaple(ctx->cm);
7137     else
7138         return BAD_FUNC_ARG;
7139 }
7140 
wolfSSL_CTX_DisableOCSPMustStaple(WOLFSSL_CTX * ctx)7141 int wolfSSL_CTX_DisableOCSPMustStaple(WOLFSSL_CTX* ctx)
7142 {
7143     WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSPMustStaple");
7144     if (ctx)
7145         return wolfSSL_CertManagerDisableOCSPMustStaple(ctx->cm);
7146     else
7147         return BAD_FUNC_ARG;
7148 }
7149 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST || HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
7150 
7151 #endif /* HAVE_OCSP */
7152 
7153 /* macro to get verify settings for AddCA */
7154 #define GET_VERIFY_SETTING_CTX(ctx) \
7155     (ctx && ctx->verifyNone ? NO_VERIFY : VERIFY)
7156 #define GET_VERIFY_SETTING_SSL(ssl) \
7157     (ssl && ssl->options.verifyNone ? NO_VERIFY : VERIFY)
7158 
7159 #ifndef NO_FILESYSTEM
7160 
7161 /* process a file with name fname into ctx of format and type
7162    userChain specifies a user certificate chain to pass during handshake */
ProcessFile(WOLFSSL_CTX * ctx,const char * fname,int format,int type,WOLFSSL * ssl,int userChain,WOLFSSL_CRL * crl,int verify)7163 int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
7164                 WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl, int verify)
7165 {
7166 #ifdef WOLFSSL_SMALL_STACK
7167     byte   staticBuffer[1]; /* force heap usage */
7168 #else
7169     byte   staticBuffer[FILE_BUFFER_SIZE];
7170 #endif
7171     byte*  myBuffer = staticBuffer;
7172     int    dynamic = 0;
7173     int    ret;
7174     long   sz = 0;
7175     XFILE  file;
7176     void*  heapHint = wolfSSL_CTX_GetHeap(ctx, ssl);
7177 #ifndef NO_CODING
7178     const char* header = NULL;
7179     const char* footer = NULL;
7180 #endif
7181 
7182     (void)crl;
7183     (void)heapHint;
7184 
7185     if (fname == NULL) return WOLFSSL_BAD_FILE;
7186 
7187     file = XFOPEN(fname, "rb");
7188     if (file == XBADFILE) return WOLFSSL_BAD_FILE;
7189     if (XFSEEK(file, 0, XSEEK_END) != 0) {
7190         XFCLOSE(file);
7191         return WOLFSSL_BAD_FILE;
7192     }
7193     sz = XFTELL(file);
7194     XREWIND(file);
7195 
7196     if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
7197         WOLFSSL_MSG("ProcessFile file size error");
7198         XFCLOSE(file);
7199         return WOLFSSL_BAD_FILE;
7200     }
7201 
7202     if (sz > (long)sizeof(staticBuffer)) {
7203         WOLFSSL_MSG("Getting dynamic buffer");
7204         myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
7205         if (myBuffer == NULL) {
7206             XFCLOSE(file);
7207             return WOLFSSL_BAD_FILE;
7208         }
7209         dynamic = 1;
7210     }
7211 
7212     if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz)
7213         ret = WOLFSSL_BAD_FILE;
7214     else {
7215         /* Try to detect type by parsing cert header and footer */
7216         if (type == DETECT_CERT_TYPE) {
7217 #ifndef NO_CODING
7218             if (wc_PemGetHeaderFooter(CA_TYPE, &header, &footer) == 0 &&
7219                (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
7220                 type = CA_TYPE;
7221             }
7222 #ifdef HAVE_CRL
7223             else if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
7224                     (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
7225                 type = CRL_TYPE;
7226             }
7227 #endif
7228             else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
7229                     (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
7230                 type = CERT_TYPE;
7231             }
7232             else
7233 #endif
7234             {
7235                 WOLFSSL_MSG("Failed to detect certificate type");
7236                 if (dynamic)
7237                     XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
7238                 XFCLOSE(file);
7239                 return WOLFSSL_BAD_CERTTYPE;
7240             }
7241         }
7242         if ((type == CA_TYPE || type == TRUSTED_PEER_TYPE)
7243                                           && format == WOLFSSL_FILETYPE_PEM) {
7244             ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl,
7245                                      verify);
7246         }
7247 #ifdef HAVE_CRL
7248         else if (type == CRL_TYPE)
7249             ret = BufferLoadCRL(crl, myBuffer, sz, format, verify);
7250 #endif
7251         else
7252             ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
7253                                 userChain, verify);
7254     }
7255 
7256     XFCLOSE(file);
7257     if (dynamic)
7258         XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
7259 
7260     return ret;
7261 }
7262 
7263 /* loads file then loads each file in path, no c_rehash */
wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX * ctx,const char * file,const char * path,word32 flags)7264 int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file,
7265                                      const char* path, word32 flags)
7266 {
7267     int ret = WOLFSSL_SUCCESS;
7268 #ifndef NO_WOLFSSL_DIR
7269     int fileRet;
7270     int successCount = 0;
7271     int failCount = 0;
7272 #endif
7273     int verify;
7274 
7275     WOLFSSL_MSG("wolfSSL_CTX_load_verify_locations_ex");
7276 
7277     if (ctx == NULL || (file == NULL && path == NULL)) {
7278         return WOLFSSL_FAILURE;
7279     }
7280 
7281     verify = GET_VERIFY_SETTING_CTX(ctx);
7282     if (flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY)
7283         verify = VERIFY_SKIP_DATE;
7284 
7285     if (file) {
7286         ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CA_TYPE, NULL, 0,
7287                           NULL, verify);
7288 #ifndef NO_WOLFSSL_DIR
7289         if (ret == WOLFSSL_SUCCESS)
7290             successCount++;
7291 #endif
7292     }
7293 
7294     if (ret == WOLFSSL_SUCCESS && path) {
7295 #ifndef NO_WOLFSSL_DIR
7296         char* name = NULL;
7297     #ifdef WOLFSSL_SMALL_STACK
7298         ReadDirCtx* readCtx;
7299         readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
7300                                                        DYNAMIC_TYPE_DIRCTX);
7301         if (readCtx == NULL)
7302             return MEMORY_E;
7303     #else
7304         ReadDirCtx readCtx[1];
7305     #endif
7306 
7307         /* try to load each regular file in path */
7308         fileRet = wc_ReadDirFirst(readCtx, path, &name);
7309         while (fileRet == 0 && name) {
7310             WOLFSSL_MSG(name); /* log file name */
7311             ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, CA_TYPE,
7312                               NULL, 0, NULL, verify);
7313             if (ret != WOLFSSL_SUCCESS) {
7314                 /* handle flags for ignoring errors, skipping expired certs or
7315                    by PEM certificate header error */
7316                 if ( (flags & WOLFSSL_LOAD_FLAG_IGNORE_ERR) ||
7317                     ((flags & WOLFSSL_LOAD_FLAG_PEM_CA_ONLY) &&
7318                        (ret == ASN_NO_PEM_HEADER))) {
7319                     /* Do not fail here if a certificate fails to load,
7320                        continue to next file */
7321     #if defined(WOLFSSL_QT)
7322                     ret = WOLFSSL_SUCCESS;
7323     #endif
7324                 }
7325                 else {
7326                     WOLFSSL_ERROR(ret);
7327                     WOLFSSL_MSG("Load CA file failed, continuing");
7328                     failCount++;
7329                 }
7330             }
7331             else {
7332                 successCount++;
7333             }
7334             fileRet = wc_ReadDirNext(readCtx, path, &name);
7335         }
7336         wc_ReadDirClose(readCtx);
7337 
7338         /* pass directory read failure to response code */
7339         if (fileRet != WC_READDIR_NOFILE) {
7340             ret = fileRet;
7341     #if defined(WOLFSSL_QT)
7342             if (ret == BAD_PATH_ERROR &&
7343                 flags & WOLFSSL_LOAD_FLAG_IGNORE_BAD_PATH_ERR) {
7344                /* QSslSocket always loads certs in system folder
7345                 * when it is initialized.
7346                 * Compliant with OpenSSL when flag sets.
7347                 */
7348                 ret = WOLFSSL_SUCCESS;
7349             }
7350             else {
7351                 /* qssl socket wants to know errors. */
7352                 WOLFSSL_ERROR(ret);
7353             }
7354     #endif
7355         }
7356         /* report failure if no files were loaded or there were failures */
7357         else if (successCount == 0 || failCount > 0) {
7358             /* use existing error code if exists */
7359     #if defined(WOLFSSL_QT)
7360             /* compliant with OpenSSL when flag sets*/
7361             if (!(flags & WOLFSSL_LOAD_FLAG_IGNORE_ZEROFILE))
7362     #endif
7363             {
7364                 ret = WOLFSSL_FAILURE;
7365             }
7366         }
7367         else {
7368             ret = WOLFSSL_SUCCESS;
7369         }
7370 
7371     #ifdef WOLFSSL_SMALL_STACK
7372         XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_DIRCTX);
7373     #endif
7374 #else
7375         ret = NOT_COMPILED_IN;
7376         (void)flags;
7377 #endif
7378     }
7379 
7380     return ret;
7381 }
7382 
7383 WOLFSSL_ABI
wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX * ctx,const char * file,const char * path)7384 int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
7385                                      const char* path)
7386 {
7387     int ret = wolfSSL_CTX_load_verify_locations_ex(ctx, file, path,
7388         WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
7389 
7390     return WS_RETURN_CODE(ret,WOLFSSL_FAILURE);
7391 }
7392 
7393 
7394 #ifdef WOLFSSL_TRUST_PEER_CERT
7395 /* Used to specify a peer cert to match when connecting
7396     ctx : the ctx structure to load in peer cert
7397     file: the string name of cert file
7398     type: type of format such as PEM/DER
7399  */
wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX * ctx,const char * file,int type)7400 int wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX* ctx, const char* file, int type)
7401 {
7402     WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_cert");
7403 
7404     if (ctx == NULL || file == NULL) {
7405         return WOLFSSL_FAILURE;
7406     }
7407 
7408     return ProcessFile(ctx, file, type, TRUSTED_PEER_TYPE, NULL, 0, NULL,
7409                        GET_VERIFY_SETTING_CTX(ctx));
7410 }
7411 #endif /* WOLFSSL_TRUST_PEER_CERT */
7412 
7413 
7414 #if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
7415 /* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER * cm,const char * fname,int format)7416 int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
7417                              int format)
7418 {
7419     int    ret = WOLFSSL_FATAL_ERROR;
7420 #ifdef WOLFSSL_SMALL_STACK
7421     byte   staticBuffer[1]; /* force heap usage */
7422 #else
7423     byte   staticBuffer[FILE_BUFFER_SIZE];
7424 #endif
7425     byte*  myBuffer = staticBuffer;
7426     int    dynamic = 0;
7427     long   sz = 0;
7428     XFILE  file = XFOPEN(fname, "rb");
7429 
7430     WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
7431 
7432     if (file == XBADFILE) return WOLFSSL_BAD_FILE;
7433     if(XFSEEK(file, 0, XSEEK_END) != 0) {
7434         XFCLOSE(file);
7435         return WOLFSSL_BAD_FILE;
7436     }
7437     sz = XFTELL(file);
7438     XREWIND(file);
7439 
7440     if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
7441         WOLFSSL_MSG("CertManagerVerify file size error");
7442         XFCLOSE(file);
7443         return WOLFSSL_BAD_FILE;
7444     }
7445 
7446     if (sz > (long)sizeof(staticBuffer)) {
7447         WOLFSSL_MSG("Getting dynamic buffer");
7448         myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
7449         if (myBuffer == NULL) {
7450             XFCLOSE(file);
7451             return WOLFSSL_BAD_FILE;
7452         }
7453         dynamic = 1;
7454     }
7455 
7456     if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz)
7457         ret = WOLFSSL_BAD_FILE;
7458     else
7459         ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
7460 
7461     XFCLOSE(file);
7462     if (dynamic)
7463         XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
7464 
7465     return ret;
7466 }
7467 #endif
7468 
7469 /* like load verify locations, 1 for success, < 0 for error */
wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER * cm,const char * file,const char * path)7470 int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
7471                              const char* path)
7472 {
7473     int ret = WOLFSSL_FATAL_ERROR;
7474     WOLFSSL_CTX* tmp;
7475 
7476     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
7477 
7478     if (cm == NULL) {
7479         WOLFSSL_MSG("No CertManager error");
7480         return ret;
7481     }
7482     tmp = wolfSSL_CTX_new(cm_pick_method());
7483 
7484     if (tmp == NULL) {
7485         WOLFSSL_MSG("CTX new failed");
7486         return ret;
7487     }
7488 
7489     /* for tmp use */
7490     wolfSSL_CertManagerFree(tmp->cm);
7491     tmp->cm = cm;
7492 
7493     ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
7494 
7495     /* don't lose our good one */
7496     tmp->cm = NULL;
7497     wolfSSL_CTX_free(tmp);
7498 
7499     return ret;
7500 }
7501 
7502 
7503 #endif /* NO_FILESYSTEM */
7504 
7505 #ifdef HAVE_CRL
7506 
7507 /* check CRL if enabled, WOLFSSL_SUCCESS  */
wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER * cm,byte * der,int sz)7508 int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
7509 {
7510     int ret = 0;
7511 #ifdef WOLFSSL_SMALL_STACK
7512     DecodedCert* cert = NULL;
7513 #else
7514     DecodedCert  cert[1];
7515 #endif
7516 
7517     WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
7518 
7519     if (cm == NULL)
7520         return BAD_FUNC_ARG;
7521 
7522     if (cm->crlEnabled == 0)
7523         return WOLFSSL_SUCCESS;
7524 
7525 #ifdef WOLFSSL_SMALL_STACK
7526     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
7527     if (cert == NULL)
7528         return MEMORY_E;
7529 #endif
7530 
7531     InitDecodedCert(cert, der, sz, NULL);
7532 
7533     if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm)) != 0) {
7534         WOLFSSL_MSG("ParseCert failed");
7535     }
7536     else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
7537         WOLFSSL_MSG("CheckCertCRL failed");
7538     }
7539 
7540     FreeDecodedCert(cert);
7541 #ifdef WOLFSSL_SMALL_STACK
7542     XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
7543 #endif
7544 
7545     return ret == 0 ? WOLFSSL_SUCCESS : ret;
7546 }
7547 
7548 
wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER * cm,CbMissingCRL cb)7549 int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
7550 {
7551     WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
7552     if (cm == NULL)
7553         return BAD_FUNC_ARG;
7554 
7555     cm->cbMissingCRL = cb;
7556 
7557     return WOLFSSL_SUCCESS;
7558 }
7559 
7560 #ifdef HAVE_CRL_IO
wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER * cm,CbCrlIO cb)7561 int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, CbCrlIO cb)
7562 {
7563     if (cm == NULL)
7564         return BAD_FUNC_ARG;
7565 
7566     cm->crl->crlIOCb = cb;
7567 
7568     return WOLFSSL_SUCCESS;
7569 }
7570 #endif
7571 
7572 #ifndef NO_FILESYSTEM
wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER * cm,const char * path,int type,int monitor)7573 int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
7574                               int type, int monitor)
7575 {
7576     WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
7577     if (cm == NULL)
7578         return BAD_FUNC_ARG;
7579 
7580     if (cm->crl == NULL) {
7581         if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
7582             WOLFSSL_MSG("Enable CRL failed");
7583             return WOLFSSL_FATAL_ERROR;
7584         }
7585     }
7586 
7587     return LoadCRL(cm->crl, path, type, monitor);
7588 }
7589 #endif
7590 
wolfSSL_EnableCRL(WOLFSSL * ssl,int options)7591 int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
7592 {
7593     WOLFSSL_ENTER("wolfSSL_EnableCRL");
7594     if (ssl)
7595         return wolfSSL_CertManagerEnableCRL(SSL_CM(ssl), options);
7596     else
7597         return BAD_FUNC_ARG;
7598 }
7599 
7600 
wolfSSL_DisableCRL(WOLFSSL * ssl)7601 int wolfSSL_DisableCRL(WOLFSSL* ssl)
7602 {
7603     WOLFSSL_ENTER("wolfSSL_DisableCRL");
7604     if (ssl)
7605         return wolfSSL_CertManagerDisableCRL(SSL_CM(ssl));
7606     else
7607         return BAD_FUNC_ARG;
7608 }
7609 
7610 #ifndef NO_FILESYSTEM
wolfSSL_LoadCRL(WOLFSSL * ssl,const char * path,int type,int monitor)7611 int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
7612 {
7613     WOLFSSL_ENTER("wolfSSL_LoadCRL");
7614     if (ssl)
7615         return wolfSSL_CertManagerLoadCRL(SSL_CM(ssl), path, type, monitor);
7616     else
7617         return BAD_FUNC_ARG;
7618 }
7619 #endif
7620 
7621 
wolfSSL_SetCRL_Cb(WOLFSSL * ssl,CbMissingCRL cb)7622 int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
7623 {
7624     WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
7625     if (ssl)
7626         return wolfSSL_CertManagerSetCRL_Cb(SSL_CM(ssl), cb);
7627     else
7628         return BAD_FUNC_ARG;
7629 }
7630 
7631 #ifdef HAVE_CRL_IO
wolfSSL_SetCRL_IOCb(WOLFSSL * ssl,CbCrlIO cb)7632 int wolfSSL_SetCRL_IOCb(WOLFSSL* ssl, CbCrlIO cb)
7633 {
7634     WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
7635     if (ssl)
7636         return wolfSSL_CertManagerSetCRL_IOCb(SSL_CM(ssl), cb);
7637     else
7638         return BAD_FUNC_ARG;
7639 }
7640 #endif
7641 
wolfSSL_CTX_EnableCRL(WOLFSSL_CTX * ctx,int options)7642 int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
7643 {
7644     WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
7645     if (ctx)
7646         return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
7647     else
7648         return BAD_FUNC_ARG;
7649 }
7650 
7651 
wolfSSL_CTX_DisableCRL(WOLFSSL_CTX * ctx)7652 int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
7653 {
7654     WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
7655     if (ctx)
7656         return wolfSSL_CertManagerDisableCRL(ctx->cm);
7657     else
7658         return BAD_FUNC_ARG;
7659 }
7660 
7661 
7662 #ifndef NO_FILESYSTEM
wolfSSL_CTX_LoadCRL(WOLFSSL_CTX * ctx,const char * path,int type,int monitor)7663 int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path,
7664                         int type, int monitor)
7665 {
7666     WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
7667     if (ctx)
7668         return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
7669     else
7670         return BAD_FUNC_ARG;
7671 }
7672 #endif
7673 
7674 
wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX * ctx,CbMissingCRL cb)7675 int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
7676 {
7677     WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
7678     if (ctx)
7679         return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
7680     else
7681         return BAD_FUNC_ARG;
7682 }
7683 
7684 #ifdef HAVE_CRL_IO
wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX * ctx,CbCrlIO cb)7685 int wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX* ctx, CbCrlIO cb)
7686 {
7687     WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_IOCb");
7688     if (ctx)
7689         return wolfSSL_CertManagerSetCRL_IOCb(ctx->cm, cb);
7690     else
7691         return BAD_FUNC_ARG;
7692 }
7693 #endif
7694 
7695 
7696 #endif /* HAVE_CRL */
7697 
7698 
7699 #ifndef NO_FILESYSTEM
7700 
7701 
7702 #ifdef WOLFSSL_DER_LOAD
7703 
7704 /* Add format parameter to allow DER load of CA files */
wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX * ctx,const char * file,int format)7705 int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
7706                                           int format)
7707 {
7708     WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
7709     if (ctx == NULL || file == NULL)
7710         return WOLFSSL_FAILURE;
7711 
7712     if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL,
7713                     GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
7714         return WOLFSSL_SUCCESS;
7715     }
7716 
7717     return WOLFSSL_FAILURE;
7718 }
7719 
7720 #endif /* WOLFSSL_DER_LOAD */
7721 
7722 
7723 
7724 WOLFSSL_ABI
wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX * ctx,const char * file,int format)7725 int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
7726                                      int format)
7727 {
7728     WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
7729 
7730     if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL,
7731                     GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
7732         return WOLFSSL_SUCCESS;
7733     }
7734 
7735     return WOLFSSL_FAILURE;
7736 }
7737 
7738 
7739 WOLFSSL_ABI
wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX * ctx,const char * file,int format)7740 int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
7741                                     int format)
7742 {
7743     WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
7744 
7745     if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL,
7746                     GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
7747         return WOLFSSL_SUCCESS;
7748     }
7749 
7750     return WOLFSSL_FAILURE;
7751 }
7752 
7753 
7754 #endif /* NO_FILESYSTEM */
7755 
7756 
7757 /* Sets the max chain depth when verifying a certificate chain. Default depth
7758  * is set to MAX_CHAIN_DEPTH.
7759  *
7760  * ctx   WOLFSSL_CTX structure to set depth in
7761  * depth max depth
7762  */
wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX * ctx,int depth)7763 void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) {
7764     WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth");
7765 
7766     if (ctx == NULL || depth < 0 || depth > MAX_CHAIN_DEPTH) {
7767         WOLFSSL_MSG("Bad depth argument, too large or less than 0");
7768         return;
7769     }
7770 
7771     ctx->verifyDepth = (byte)depth;
7772 }
7773 
7774 
7775 /* get cert chaining depth using ssl struct */
wolfSSL_get_verify_depth(WOLFSSL * ssl)7776 long wolfSSL_get_verify_depth(WOLFSSL* ssl)
7777 {
7778     if(ssl == NULL) {
7779         return BAD_FUNC_ARG;
7780     }
7781 #ifndef OPENSSL_EXTRA
7782     return MAX_CHAIN_DEPTH;
7783 #else
7784     return ssl->options.verifyDepth;
7785 #endif
7786 }
7787 
7788 
7789 /* get cert chaining depth using ctx struct */
wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX * ctx)7790 long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
7791 {
7792     if (ctx == NULL) {
7793         return BAD_FUNC_ARG;
7794     }
7795 #ifndef OPENSSL_EXTRA
7796     return MAX_CHAIN_DEPTH;
7797 #else
7798     return ctx->verifyDepth;
7799 #endif
7800 }
7801 
7802 
7803 #ifndef NO_FILESYSTEM
7804 
7805 
7806 WOLFSSL_ABI
wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX * ctx,const char * file)7807 int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
7808 {
7809     /* process up to MAX_CHAIN_DEPTH plus subject cert */
7810     WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
7811 
7812     if (ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE, NULL, 1, NULL,
7813                     GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
7814         return WOLFSSL_SUCCESS;
7815     }
7816 
7817    return WOLFSSL_FAILURE;
7818 }
7819 
7820 
wolfSSL_CTX_use_certificate_chain_file_format(WOLFSSL_CTX * ctx,const char * file,int format)7821 int wolfSSL_CTX_use_certificate_chain_file_format(WOLFSSL_CTX* ctx,
7822                                                   const char* file, int format)
7823 {
7824     /* process up to MAX_CHAIN_DEPTH plus subject cert */
7825     WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file_format");
7826 
7827     if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 1, NULL,
7828                     GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
7829         return WOLFSSL_SUCCESS;
7830     }
7831 
7832    return WOLFSSL_FAILURE;
7833 }
7834 
7835 
7836 #ifndef NO_DH
7837 
7838 /* server Diffie-Hellman parameters */
wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX * ctx,WOLFSSL * ssl,const char * fname,int format)7839 static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
7840                                         const char* fname, int format)
7841 {
7842 #ifdef WOLFSSL_SMALL_STACK
7843     byte   staticBuffer[1]; /* force heap usage */
7844 #else
7845     byte   staticBuffer[FILE_BUFFER_SIZE];
7846 #endif
7847     byte*  myBuffer = staticBuffer;
7848     int    dynamic = 0;
7849     int    ret;
7850     long   sz = 0;
7851     XFILE  file;
7852 
7853     if (ctx == NULL || fname == NULL)
7854         return BAD_FUNC_ARG;
7855 
7856     file = XFOPEN(fname, "rb");
7857     if (file == XBADFILE) return WOLFSSL_BAD_FILE;
7858     if(XFSEEK(file, 0, XSEEK_END) != 0) {
7859         XFCLOSE(file);
7860         return WOLFSSL_BAD_FILE;
7861     }
7862     sz = XFTELL(file);
7863     XREWIND(file);
7864 
7865     if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
7866         WOLFSSL_MSG("SetTmpDH file size error");
7867         XFCLOSE(file);
7868         return WOLFSSL_BAD_FILE;
7869     }
7870 
7871     if (sz > (long)sizeof(staticBuffer)) {
7872         WOLFSSL_MSG("Getting dynamic buffer");
7873         myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
7874         if (myBuffer == NULL) {
7875             XFCLOSE(file);
7876             return WOLFSSL_BAD_FILE;
7877         }
7878         dynamic = 1;
7879     }
7880 
7881     if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz)
7882         ret = WOLFSSL_BAD_FILE;
7883     else {
7884         if (ssl)
7885             ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
7886         else
7887             ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
7888     }
7889 
7890     XFCLOSE(file);
7891     if (dynamic)
7892         XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
7893 
7894     return ret;
7895 }
7896 
7897 /* server Diffie-Hellman parameters */
wolfSSL_SetTmpDH_file(WOLFSSL * ssl,const char * fname,int format)7898 int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
7899 {
7900     if (ssl == NULL)
7901         return BAD_FUNC_ARG;
7902 
7903     return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
7904 }
7905 
7906 
7907 /* server Diffie-Hellman parameters */
wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX * ctx,const char * fname,int format)7908 int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
7909 {
7910     return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
7911 }
7912 
7913 #endif /* NO_DH */
7914 
7915 #endif /* NO_FILESYSTEM */
7916 
7917 #ifndef NO_CHECK_PRIVATE_KEY
7918 /* Check private against public in certificate for match
7919  *
7920  * ctx  WOLFSSL_CTX structure to check private key in
7921  *
7922  * Returns SSL_SUCCESS on good private key and SSL_FAILURE if miss matched. */
wolfSSL_CTX_check_private_key(const WOLFSSL_CTX * ctx)7923 int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
7924 {
7925 #ifdef WOLFSSL_SMALL_STACK
7926     DecodedCert* der = NULL;
7927 #else
7928     DecodedCert  der[1];
7929 #endif
7930     word32 size;
7931     byte*  buff;
7932     int    ret = WOLFSSL_FAILURE;
7933 
7934     WOLFSSL_ENTER("wolfSSL_CTX_check_private_key");
7935 
7936     if (ctx == NULL || ctx->certificate == NULL || ctx->privateKey == NULL) {
7937         return WOLFSSL_FAILURE;
7938     }
7939 
7940 #ifndef NO_CERTS
7941 #ifdef WOLFSSL_SMALL_STACK
7942     der = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
7943     if (der == NULL)
7944         return MEMORY_E;
7945 #endif
7946 
7947     size = ctx->certificate->length;
7948     buff = ctx->certificate->buffer;
7949     InitDecodedCert(der, buff, size, ctx->heap);
7950     if (ParseCertRelative(der, CERT_TYPE, NO_VERIFY, NULL) != 0) {
7951         FreeDecodedCert(der);
7952     #ifdef WOLFSSL_SMALL_STACK
7953         XFREE(der, NULL, DYNAMIC_TYPE_DCERT);
7954     #endif
7955         return WOLFSSL_FAILURE;
7956     }
7957 
7958     size = ctx->privateKey->length;
7959     buff = ctx->privateKey->buffer;
7960 #ifdef WOLF_CRYPTO_CB
7961     if (ctx->privateKeyDevId != INVALID_DEVID) {
7962         int type = 0;
7963         void *pkey = NULL;
7964 
7965     #ifndef NO_RSA
7966         if (der->keyOID == RSAk) {
7967             type = DYNAMIC_TYPE_RSA;
7968         }
7969     #endif
7970     #ifdef HAVE_ECC
7971         if (der->keyOID == ECDSAk) {
7972             type = DYNAMIC_TYPE_ECC;
7973         }
7974     #endif
7975         ret = CreateDevPrivateKey(&pkey, buff, size, type, ctx->privateKeyLabel,
7976                                   ctx->privateKeyId, ctx->heap,
7977                                   ctx->privateKeyDevId);
7978     #ifndef NO_RSA
7979         if (ret == 0 && der->keyOID == RSAk) {
7980             ret = wc_CryptoCb_RsaCheckPrivKey((RsaKey*)pkey, der->publicKey,
7981                                               der->pubKeySize);
7982             wc_FreeRsaKey((RsaKey*)pkey);
7983         }
7984     #endif
7985     #ifdef HAVE_ECC
7986         if (ret == 0 && der->keyOID == ECDSAk) {
7987             ret = wc_CryptoCb_EccCheckPrivKey((ecc_key*)pkey, der->publicKey,
7988                                               der->pubKeySize);
7989             wc_ecc_free((ecc_key*)pkey);
7990         }
7991     #endif
7992         if (pkey != NULL) {
7993             XFREE(pkey, ctx->heap, type);
7994         }
7995         if (ret != CRYPTOCB_UNAVAILABLE) {
7996             if (ret == 0) {
7997                 ret = WOLFSSL_SUCCESS;
7998             }
7999             else {
8000                 ret = WOLFSSL_FAILURE;
8001             }
8002         }
8003     }
8004     else {
8005         /* fall through if unavailable */
8006         ret = CRYPTOCB_UNAVAILABLE;
8007     }
8008 
8009     if (ret == CRYPTOCB_UNAVAILABLE)
8010 #endif
8011     {
8012         ret = wc_CheckPrivateKeyCert(buff, size, der);
8013         if (ret == 1) {
8014             ret = WOLFSSL_SUCCESS;
8015         }
8016         else {
8017             ret = WOLFSSL_FAILURE;
8018         }
8019     }
8020     FreeDecodedCert(der);
8021 #ifdef WOLFSSL_SMALL_STACK
8022     XFREE(der, NULL, DYNAMIC_TYPE_DCERT);
8023 #endif
8024 
8025     return ret;
8026 #else
8027     WOLFSSL_MSG("NO_CERTS is defined, can not check private key");
8028     return WOLFSSL_FAILURE;
8029 #endif
8030 }
8031 #endif /* !NO_CHECK_PRIVATE_KEY */
8032 
8033 #ifdef OPENSSL_ALL
8034 /**
8035  * Return the private key of the WOLFSSL_CTX struct
8036  * @return WOLFSSL_EVP_PKEY* The caller doesn *NOT*` free the returned object.
8037  */
wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX * ctx)8038 WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx)
8039 {
8040     const unsigned char *key;
8041     int type;
8042 
8043     WOLFSSL_ENTER("wolfSSL_CTX_get0_privatekey");
8044 
8045     if (ctx == NULL || ctx->privateKey == NULL ||
8046             ctx->privateKey->buffer == NULL) {
8047         WOLFSSL_MSG("Bad parameter or key not set");
8048         return NULL;
8049     }
8050 
8051     switch (ctx->privateKeyType) {
8052 #ifndef NO_RSA
8053         case rsa_sa_algo:
8054             type = EVP_PKEY_RSA;
8055             break;
8056 #endif
8057 #ifdef HAVE_ECC
8058         case ecc_dsa_sa_algo:
8059             type = EVP_PKEY_EC;
8060             break;
8061 #endif
8062         default:
8063             /* Other key types not supported either as ssl private keys
8064              * or in the EVP layer */
8065             WOLFSSL_MSG("Unsupported key type");
8066             return NULL;
8067     }
8068 
8069     key = ctx->privateKey->buffer;
8070 
8071     if (ctx->privateKeyPKey != NULL)
8072         return ctx->privateKeyPKey;
8073     else
8074         return wolfSSL_d2i_PrivateKey(type,
8075                 (WOLFSSL_EVP_PKEY**)&ctx->privateKeyPKey, &key,
8076                 (long)ctx->privateKey->length);
8077 }
8078 #endif
8079 
8080 #ifdef OPENSSL_EXTRA
8081 
wolfSSL_d2i_PKCS8_PKEY(WOLFSSL_PKCS8_PRIV_KEY_INFO ** pkey,const unsigned char ** keyBuf,long keyLen)8082 WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY(
8083     WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey, const unsigned char** keyBuf, long keyLen)
8084 {
8085     WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8 = NULL;
8086 #ifdef WOLFSSL_PEM_TO_DER
8087     int ret;
8088     DerBuffer* der = NULL;
8089 
8090     if (keyBuf == NULL || *keyBuf == NULL || keyLen <= 0) {
8091         WOLFSSL_MSG("Bad key PEM/DER args");
8092         return NULL;
8093     }
8094 
8095     ret = PemToDer(*keyBuf, keyLen, PRIVATEKEY_TYPE, &der, NULL, NULL, NULL);
8096     if (ret < 0) {
8097         WOLFSSL_MSG("Not PEM format");
8098         ret = AllocDer(&der, (word32)keyLen, PRIVATEKEY_TYPE, NULL);
8099         if (ret == 0) {
8100             XMEMCPY(der->buffer, *keyBuf, keyLen);
8101         }
8102     }
8103 
8104     if (ret == 0) {
8105         /* Verify this is PKCS8 Key */
8106         word32 inOutIdx = 0;
8107         word32 algId;
8108         ret = ToTraditionalInline_ex(der->buffer, &inOutIdx, der->length, &algId);
8109         if (ret >= 0) {
8110             ret = 0; /* good DER */
8111         }
8112     }
8113 
8114     if (ret == 0) {
8115         pkcs8 = wolfSSL_EVP_PKEY_new();
8116         if (pkcs8 == NULL)
8117             ret = MEMORY_E;
8118     }
8119     if (ret == 0) {
8120         pkcs8->pkey.ptr = (char*)XMALLOC(der->length, NULL,
8121             DYNAMIC_TYPE_PUBLIC_KEY);
8122         if (pkcs8->pkey.ptr == NULL)
8123             ret = MEMORY_E;
8124     }
8125     if (ret == 0) {
8126         XMEMCPY(pkcs8->pkey.ptr, der->buffer, der->length);
8127         pkcs8->pkey_sz = der->length;
8128     }
8129 
8130     FreeDer(&der);
8131     if (ret != 0) {
8132         wolfSSL_EVP_PKEY_free(pkcs8);
8133         pkcs8 = NULL;
8134     }
8135     if (pkey != NULL) {
8136         *pkey = pkcs8;
8137     }
8138 
8139 #else
8140     (void)bio;
8141     (void)pkey;
8142 #endif /* WOLFSSL_PEM_TO_DER */
8143 
8144     return pkcs8;
8145 }
8146 
8147 
8148 #ifndef NO_BIO
8149 /* put SSL type in extra for now, not very common */
8150 
8151 /* Converts a DER format key read from "bio" to a PKCS8 structure.
8152  *
8153  * bio  input bio to read DER from
8154  * pkey If not NULL then this pointer will be overwritten with a new PKCS8
8155  *      structure.
8156  *
8157  * returns a WOLFSSL_PKCS8_PRIV_KEY_INFO pointer on success and NULL in fail
8158  *         case.
8159  */
wolfSSL_d2i_PKCS8_PKEY_bio(WOLFSSL_BIO * bio,WOLFSSL_PKCS8_PRIV_KEY_INFO ** pkey)8160 WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY_bio(WOLFSSL_BIO* bio,
8161         WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey)
8162 {
8163     WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8 = NULL;
8164 #ifdef WOLFSSL_PEM_TO_DER
8165     unsigned char* mem = NULL;
8166     int memSz;
8167 
8168     WOLFSSL_ENTER("wolfSSL_d2i_PKCS8_PKEY_bio");
8169 
8170     if (bio == NULL) {
8171         return NULL;
8172     }
8173 
8174     if ((memSz = wolfSSL_BIO_get_mem_data(bio, &mem)) < 0) {
8175         return NULL;
8176     }
8177 
8178     pkcs8 = wolfSSL_d2i_PKCS8_PKEY(pkey, (const unsigned char**)&mem, memSz);
8179 #else
8180     (void)bio;
8181     (void)pkey;
8182 #endif /* WOLFSSL_PEM_TO_DER */
8183 
8184     return pkcs8;
8185 }
8186 
8187 
8188 /* expecting DER format public key
8189  *
8190  * bio  input bio to read DER from
8191  * out  If not NULL then this pointer will be overwritten with a new
8192  * WOLFSSL_EVP_PKEY pointer
8193  *
8194  * returns a WOLFSSL_EVP_PKEY pointer on success and NULL in fail case.
8195  */
wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO * bio,WOLFSSL_EVP_PKEY ** out)8196 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio,
8197                                          WOLFSSL_EVP_PKEY** out)
8198 {
8199     unsigned char* mem;
8200     long memSz;
8201     WOLFSSL_EVP_PKEY* pkey = NULL;
8202 
8203     WOLFSSL_ENTER("wolfSSL_d2i_PUBKEY_bio()");
8204 
8205     if (bio == NULL) {
8206         return NULL;
8207     }
8208     (void)out;
8209 
8210     memSz = wolfSSL_BIO_get_len(bio);
8211     if (memSz <= 0) {
8212         return NULL;
8213     }
8214 
8215     mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
8216     if (mem == NULL) {
8217         return NULL;
8218     }
8219 
8220     if (wolfSSL_BIO_read(bio, mem, (int)memSz) == memSz) {
8221         pkey = wolfSSL_d2i_PUBKEY(NULL, (const unsigned char**)&mem, memSz);
8222         if (out != NULL && pkey != NULL) {
8223             *out = pkey;
8224         }
8225     }
8226 
8227     XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
8228     return pkey;
8229 }
8230 
8231 #endif /* !NO_BIO */
8232 
d2iGenericKey(WOLFSSL_EVP_PKEY ** out,const unsigned char ** in,long inSz,int priv)8233 static WOLFSSL_EVP_PKEY* d2iGenericKey(WOLFSSL_EVP_PKEY** out,
8234                                  const unsigned char** in, long inSz, int priv)
8235 {
8236 
8237     WOLFSSL_EVP_PKEY* pkey = NULL;
8238     const unsigned char* mem;
8239     long memSz = inSz;
8240 
8241     WOLFSSL_ENTER("d2iGenericKey");
8242 
8243     if (in == NULL || *in == NULL || inSz < 0) {
8244         WOLFSSL_MSG("Bad argument");
8245         return NULL;
8246     }
8247     mem = *in;
8248 
8249     #if !defined(NO_RSA)
8250     {
8251         word32 keyIdx = 0;
8252         int isRsaKey;
8253     #ifdef WOLFSSL_SMALL_STACK
8254         RsaKey *rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
8255         if (rsa == NULL)
8256             return NULL;
8257     #else
8258         RsaKey rsa[1];
8259     #endif
8260         XMEMSET(rsa, 0, sizeof(RsaKey));
8261 
8262         /* test if RSA key */
8263         if (priv)
8264             isRsaKey = wc_InitRsaKey(rsa, NULL) == 0 &&
8265                 wc_RsaPrivateKeyDecode(mem, &keyIdx, rsa, (word32)memSz) == 0;
8266         else
8267             isRsaKey = wc_InitRsaKey(rsa, NULL) == 0 &&
8268                 wc_RsaPublicKeyDecode(mem, &keyIdx, rsa, (word32)memSz) == 0;
8269         wc_FreeRsaKey(rsa);
8270     #ifdef WOLFSSL_SMALL_STACK
8271         XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
8272     #endif
8273 
8274         if (isRsaKey) {
8275             pkey = wolfSSL_EVP_PKEY_new();
8276             if (pkey != NULL) {
8277                 pkey->pkey_sz = keyIdx;
8278                 pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
8279                         priv ? DYNAMIC_TYPE_PRIVATE_KEY :
8280                                DYNAMIC_TYPE_PUBLIC_KEY);
8281                 if (pkey->pkey.ptr == NULL) {
8282                     wolfSSL_EVP_PKEY_free(pkey);
8283                     return NULL;
8284                 }
8285                 XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
8286                 pkey->type = EVP_PKEY_RSA;
8287                 if (out != NULL) {
8288                     *out = pkey;
8289                 }
8290 
8291                 pkey->ownRsa = 1;
8292                 pkey->rsa = wolfSSL_RSA_new();
8293                 if (pkey->rsa == NULL) {
8294                     wolfSSL_EVP_PKEY_free(pkey);
8295                     return NULL;
8296                 }
8297 
8298                 if (wolfSSL_RSA_LoadDer_ex(pkey->rsa,
8299                         (const unsigned char*)pkey->pkey.ptr,
8300                         pkey->pkey_sz, priv ? WOLFSSL_RSA_LOAD_PRIVATE
8301                                             : WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
8302                     wolfSSL_EVP_PKEY_free(pkey);
8303                     return NULL;
8304                 }
8305 
8306                 return pkey;
8307             }
8308             else {
8309                 WOLFSSL_MSG("RSA wolfSSL_EVP_PKEY_new error");
8310             }
8311         }
8312     }
8313     #endif /* NO_RSA */
8314 
8315     #ifdef HAVE_ECC
8316     {
8317         word32  keyIdx = 0;
8318         int     isEccKey;
8319     #ifdef WOLFSSL_SMALL_STACK
8320         ecc_key *ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
8321         if (ecc == NULL)
8322             return NULL;
8323     #else
8324         ecc_key ecc[1];
8325     #endif
8326         XMEMSET(ecc, 0, sizeof(ecc_key));
8327 
8328         if (priv)
8329             isEccKey = wc_ecc_init(ecc) == 0 &&
8330                 wc_EccPrivateKeyDecode(mem, &keyIdx, ecc, (word32)memSz) == 0;
8331         else
8332             isEccKey = wc_ecc_init(ecc) == 0 &&
8333                 wc_EccPublicKeyDecode(mem, &keyIdx, ecc, (word32)memSz) == 0;
8334         wc_ecc_free(ecc);
8335     #ifdef WOLFSSL_SMALL_STACK
8336         XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
8337     #endif
8338 
8339         if (isEccKey) {
8340             pkey = wolfSSL_EVP_PKEY_new();
8341             if (pkey != NULL) {
8342                 pkey->pkey_sz = keyIdx;
8343                 pkey->pkey.ptr = (char*)XMALLOC(keyIdx, NULL,
8344                         priv ? DYNAMIC_TYPE_PRIVATE_KEY :
8345                                DYNAMIC_TYPE_PUBLIC_KEY);
8346                 if (pkey->pkey.ptr == NULL) {
8347                     wolfSSL_EVP_PKEY_free(pkey);
8348                     return NULL;
8349                 }
8350                 XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
8351                 pkey->type = EVP_PKEY_EC;
8352                 if (out != NULL) {
8353                     *out = pkey;
8354                 }
8355 
8356                 pkey->ownEcc = 1;
8357                 pkey->ecc = wolfSSL_EC_KEY_new();
8358                 if (pkey->ecc == NULL) {
8359                     wolfSSL_EVP_PKEY_free(pkey);
8360                     return NULL;
8361                 }
8362 
8363                 if (wolfSSL_EC_KEY_LoadDer_ex(pkey->ecc,
8364                         (const unsigned char*)pkey->pkey.ptr,
8365                         pkey->pkey_sz, priv ? WOLFSSL_RSA_LOAD_PRIVATE
8366                                             : WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
8367                     wolfSSL_EVP_PKEY_free(pkey);
8368                     return NULL;
8369                 }
8370 
8371                 return pkey;
8372             }
8373             else {
8374                 WOLFSSL_MSG("ECC wolfSSL_EVP_PKEY_new error");
8375             }
8376         }
8377     }
8378     #endif /* HAVE_ECC */
8379 
8380     #if !defined(NO_DSA)
8381     {
8382         word32 keyIdx = 0;
8383         int     isDsaKey;
8384     #ifdef WOLFSSL_SMALL_STACK
8385         DsaKey *dsa = (DsaKey*)XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
8386         if (dsa == NULL)
8387             return NULL;
8388     #else
8389         DsaKey dsa[1];
8390     #endif
8391         XMEMSET(dsa, 0, sizeof(DsaKey));
8392 
8393         if (priv)
8394             isDsaKey = wc_InitDsaKey(dsa) == 0 &&
8395                 wc_DsaPrivateKeyDecode(mem, &keyIdx, dsa, (word32)memSz) == 0;
8396         else
8397             isDsaKey = wc_InitDsaKey(dsa) == 0 &&
8398                 wc_DsaPublicKeyDecode(mem, &keyIdx, dsa, (word32)memSz) == 0;
8399         wc_FreeDsaKey(dsa);
8400     #ifdef WOLFSSL_SMALL_STACK
8401         XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
8402     #endif
8403 
8404         /* test if DSA key */
8405         if (isDsaKey) {
8406             pkey = wolfSSL_EVP_PKEY_new();
8407 
8408             if (pkey != NULL) {
8409                 pkey->pkey_sz = keyIdx;
8410                 pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
8411                         priv ? DYNAMIC_TYPE_PRIVATE_KEY :
8412                                DYNAMIC_TYPE_PUBLIC_KEY);
8413                 if (pkey->pkey.ptr == NULL) {
8414                     wolfSSL_EVP_PKEY_free(pkey);
8415                     return NULL;
8416                 }
8417                 XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
8418                 pkey->type = EVP_PKEY_DSA;
8419                 if (out != NULL) {
8420                     *out = pkey;
8421                 }
8422 
8423                 pkey->ownDsa = 1;
8424                 pkey->dsa = wolfSSL_DSA_new();
8425                 if (pkey->dsa == NULL) {
8426                     wolfSSL_EVP_PKEY_free(pkey);
8427                     return NULL;
8428                 }
8429 
8430                 if (wolfSSL_DSA_LoadDer_ex(pkey->dsa,
8431                         (const unsigned char*)pkey->pkey.ptr,
8432                         pkey->pkey_sz, priv ? WOLFSSL_RSA_LOAD_PRIVATE
8433                                             : WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
8434                     wolfSSL_EVP_PKEY_free(pkey);
8435                     return NULL;
8436                 }
8437 
8438                 return pkey;
8439             }
8440             else {
8441                 WOLFSSL_MSG("DSA wolfSSL_EVP_PKEY_new error");
8442             }
8443         }
8444     }
8445     #endif /* NO_DSA */
8446 
8447     #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
8448     #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
8449         (HAVE_FIPS_VERSION > 2))
8450     {
8451         int isDhKey;
8452         word32 keyIdx = 0;
8453     #ifdef WOLFSSL_SMALL_STACK
8454         DhKey *dh = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
8455         if (dh == NULL)
8456             return NULL;
8457     #else
8458         DhKey dh[1];
8459     #endif
8460         XMEMSET(dh, 0, sizeof(DhKey));
8461 
8462         isDhKey = wc_InitDhKey(dh) == 0 &&
8463                   wc_DhKeyDecode(mem, &keyIdx, dh, (word32)memSz) == 0;
8464         wc_FreeDhKey(dh);
8465     #ifdef WOLFSSL_SMALL_STACK
8466         XFREE(dh, NULL, DYNAMIC_TYPE_DH);
8467     #endif
8468 
8469         /* test if DH key */
8470         if (isDhKey) {
8471             pkey = wolfSSL_EVP_PKEY_new();
8472 
8473             if (pkey != NULL) {
8474                 pkey->pkey_sz = (int)memSz;
8475                 pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
8476                         priv ? DYNAMIC_TYPE_PRIVATE_KEY :
8477                                DYNAMIC_TYPE_PUBLIC_KEY);
8478                 if (pkey->pkey.ptr == NULL) {
8479                     wolfSSL_EVP_PKEY_free(pkey);
8480                     return NULL;
8481                 }
8482                 XMEMCPY(pkey->pkey.ptr, mem, memSz);
8483                 pkey->type = EVP_PKEY_DH;
8484                 if (out != NULL) {
8485                     *out = pkey;
8486                 }
8487 
8488                 pkey->ownDh = 1;
8489                 pkey->dh = wolfSSL_DH_new();
8490                 if (pkey->dh == NULL) {
8491                     wolfSSL_EVP_PKEY_free(pkey);
8492                     return NULL;
8493                 }
8494 
8495                 if (wolfSSL_DH_LoadDer(pkey->dh,
8496                             (const unsigned char*)pkey->pkey.ptr,
8497                             pkey->pkey_sz) != WOLFSSL_SUCCESS) {
8498                     wolfSSL_EVP_PKEY_free(pkey);
8499                     return NULL;
8500                 }
8501 
8502                 return pkey;
8503             }
8504             else {
8505                 WOLFSSL_MSG("DH wolfSSL_EVP_PKEY_new error");
8506             }
8507         }
8508     }
8509     #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
8510     #endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
8511 
8512     #if !defined(NO_DH) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_DH_EXTRA)
8513     #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
8514             (HAVE_FIPS_VERSION > 2))
8515     {
8516         DhKey   dh;
8517         word32  keyIdx = 0;
8518         DhKey*  key = NULL;
8519         int ret;
8520         int elements;
8521         /* test if DH-public key */
8522         if (wc_InitDhKey(&dh) != 0)
8523             return NULL;
8524 
8525         ret = wc_DhKeyDecode(mem, &keyIdx, &dh, (word32)memSz);
8526         wc_FreeDhKey(&dh);
8527 
8528         if (ret == 0) {
8529             pkey = wolfSSL_EVP_PKEY_new();
8530             if (pkey != NULL) {
8531                 pkey->type     = EVP_PKEY_DH;
8532                 pkey->pkey_sz  = (int)memSz;
8533                 pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
8534                         priv ? DYNAMIC_TYPE_PRIVATE_KEY :
8535                                DYNAMIC_TYPE_PUBLIC_KEY);
8536                 if (pkey->pkey.ptr == NULL) {
8537                     wolfSSL_EVP_PKEY_free(pkey);
8538                     return NULL;
8539                 }
8540                 XMEMCPY(pkey->pkey.ptr, mem, memSz);
8541                 if (out != NULL) {
8542                     *out = pkey;
8543                 }
8544                 pkey->ownDh = 1;
8545                 pkey->dh = wolfSSL_DH_new();
8546                 if (pkey->dh == NULL) {
8547                     wolfSSL_EVP_PKEY_free(pkey);
8548                     return NULL;
8549                 }
8550 
8551                 key = (DhKey*)pkey->dh->internal;
8552 
8553                 keyIdx = 0;
8554                 if (wc_DhKeyDecode(mem, &keyIdx, key, (word32)memSz) == 0)
8555                 {
8556                     elements = ELEMENT_P | ELEMENT_G | ELEMENT_Q | ELEMENT_PUB;
8557                     if (priv)
8558                         elements |= ELEMENT_PRV;
8559                     if(SetDhExternal_ex(pkey->dh, elements)
8560                             == WOLFSSL_SUCCESS ) {
8561                         return pkey;
8562                     }
8563                 }
8564                 else {
8565                     wolfSSL_EVP_PKEY_free(pkey);
8566                     return NULL;
8567                 }
8568             }
8569         }
8570     }
8571     #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
8572     #endif /* !NO_DH &&  OPENSSL_EXTRA && WOLFSSL_DH_EXTRA */
8573 
8574     #ifdef HAVE_PQC
8575     {
8576         int isFalcon = 0;
8577     #ifdef WOLFSSL_SMALL_STACK
8578         falcon_key *falcon = (falcon_key *)MALLOC(sizeof(falcon_key), NULL,
8579                                                   DYNAMIC_TYPE_FALCON);
8580         if (falcon == NULL) {
8581             return NULL;
8582         }
8583     #else
8584         falcon_key falcon[1];
8585     #endif
8586 
8587         if (wc_falcon_init(falcon) == 0) {
8588             /* test if Falcon key */
8589             if (priv) {
8590                 /* Try level 1 */
8591                 isFalcon = wc_falcon_set_level(falcon, 1) == 0 &&
8592                            wc_falcon_import_private_only(mem, (word32)memSz,
8593                                                          falcon) == 0;
8594                 if (!isFalcon) {
8595                     /* Try level 5 */
8596                     isFalcon = wc_falcon_set_level(falcon, 5) == 0 &&
8597                                wc_falcon_import_private_only(mem, (word32)memSz,
8598                                                              falcon) == 0;
8599                 }
8600             } else {
8601                 /* Try level 1 */
8602                 isFalcon = wc_falcon_set_level(falcon, 1) == 0 &&
8603                            wc_falcon_import_public(mem, (word32)memSz, falcon)
8604                            == 0;
8605 
8606                 if (!isFalcon) {
8607                     /* Try level 5 */
8608                     isFalcon = wc_falcon_set_level(falcon, 5) == 0 &&
8609                                wc_falcon_import_public(mem, (word32)memSz,
8610                                                        falcon) == 0;
8611                 }
8612             }
8613             wc_falcon_free(falcon);
8614         }
8615 
8616     #ifdef WOLFSSL_SMALL_STACK
8617         XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
8618     #endif
8619         if (isFalcon) {
8620             /* Create a fake Falcon EVP_PKEY. In the future, we might integrate
8621              * Falcon into the compatibility layer. */
8622             pkey = wolfSSL_EVP_PKEY_new();
8623             if (pkey == NULL) {
8624                 WOLFSSL_MSG("Falcon wolfSSL_EVP_PKEY_new error");
8625                 return NULL;
8626             }
8627             pkey->type = EVP_PKEY_FALCON;
8628             pkey->pkey.ptr = NULL;
8629             pkey->pkey_sz = 0;
8630             return pkey;
8631         }
8632 
8633     }
8634     #endif /* HAVE_PQC */
8635 
8636     if (pkey == NULL) {
8637         WOLFSSL_MSG("wolfSSL_d2i_PUBKEY couldn't determine key type");
8638     }
8639 
8640     return pkey;
8641 
8642 }
8643 
8644 
8645 /* Converts a DER encoded public key to a WOLFSSL_EVP_PKEY structure.
8646  *
8647  * out  pointer to new WOLFSSL_EVP_PKEY structure. Can be NULL
8648  * in   DER buffer to convert
8649  * inSz size of in buffer
8650  *
8651  * returns a pointer to a new WOLFSSL_EVP_PKEY structure on success and NULL
8652  *         on fail
8653  */
wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY ** out,const unsigned char ** in,long inSz)8654 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out,
8655                                      const unsigned char** in, long inSz)
8656 {
8657     WOLFSSL_ENTER("wolfSSL_d2i_PUBKEY");
8658     return d2iGenericKey(out, in, inSz, 0);
8659 }
8660 
8661 /* helper function to get raw pointer to DER buffer from WOLFSSL_EVP_PKEY */
wolfSSL_EVP_PKEY_get_der(const WOLFSSL_EVP_PKEY * key,unsigned char ** der)8662 static int wolfSSL_EVP_PKEY_get_der(const WOLFSSL_EVP_PKEY* key, unsigned char** der)
8663 {
8664     unsigned char* pt;
8665     int sz;
8666     word16 pkcs8HeaderSz;
8667 
8668     if (!key || !key->pkey_sz)
8669         return WOLFSSL_FATAL_ERROR;
8670 
8671     /* return the key without PKCS8 for compatibility */
8672     /* if pkcs8HeaderSz is invalid, use 0 and return all of pkey */
8673     pkcs8HeaderSz = 0;
8674     if (key->pkey_sz > key->pkcs8HeaderSz)
8675         pkcs8HeaderSz = key->pkcs8HeaderSz;
8676     sz = key->pkey_sz - pkcs8HeaderSz;
8677     if (der) {
8678         pt = (unsigned char*)key->pkey.ptr;
8679         if (*der) {
8680             /* since this function signature has no size value passed in it is
8681              * assumed that the user has allocated a large enough buffer */
8682             XMEMCPY(*der, pt + pkcs8HeaderSz, sz);
8683             *der += sz;
8684         }
8685         else {
8686             *der = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL);
8687             if (*der == NULL) {
8688                 return WOLFSSL_FATAL_ERROR;
8689             }
8690             XMEMCPY(*der, pt + pkcs8HeaderSz, sz);
8691         }
8692     }
8693     return sz;
8694 }
8695 
wolfSSL_i2d_PUBKEY(const WOLFSSL_EVP_PKEY * key,unsigned char ** der)8696 int wolfSSL_i2d_PUBKEY(const WOLFSSL_EVP_PKEY *key, unsigned char **der)
8697 {
8698     return wolfSSL_EVP_PKEY_get_der(key, der);
8699 }
8700 
_d2i_PublicKey(int type,WOLFSSL_EVP_PKEY ** out,const unsigned char ** in,long inSz,int priv)8701 static WOLFSSL_EVP_PKEY* _d2i_PublicKey(int type, WOLFSSL_EVP_PKEY** out,
8702     const unsigned char **in, long inSz, int priv)
8703 {
8704     int ret = 0;
8705     word32 idx = 0, algId;
8706     word16 pkcs8HeaderSz = 0;
8707     WOLFSSL_EVP_PKEY* local;
8708     int opt;
8709 
8710     if (in == NULL || inSz < 0) {
8711         WOLFSSL_MSG("Bad argument");
8712         return NULL;
8713     }
8714 
8715     if (priv == 1) {
8716         /* Check if input buffer has PKCS8 header. In the case that it does not
8717          * have a PKCS8 header then do not error out. */
8718         if ((ret = ToTraditionalInline_ex((const byte*)(*in), &idx,
8719                                           (word32)inSz, &algId)) > 0) {
8720             WOLFSSL_MSG("Found PKCS8 header");
8721             pkcs8HeaderSz = (word16)idx;
8722 
8723             if ((type == EVP_PKEY_RSA && algId != RSAk) ||
8724                 (type == EVP_PKEY_EC && algId != ECDSAk) ||
8725                 (type == EVP_PKEY_DSA && algId != DSAk) ||
8726                 (type == EVP_PKEY_DH && algId != DHk)) {
8727                 WOLFSSL_MSG("PKCS8 does not match EVP key type");
8728                 return NULL;
8729             }
8730 
8731             (void)idx; /* not used */
8732         }
8733         else {
8734             if (ret != ASN_PARSE_E) {
8735                 WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 "
8736                     "header");
8737                 return NULL;
8738             }
8739         }
8740     }
8741 
8742     if (out != NULL && *out != NULL) {
8743         wolfSSL_EVP_PKEY_free(*out);
8744         *out = NULL;
8745     }
8746     local = wolfSSL_EVP_PKEY_new();
8747     if (local == NULL) {
8748         return NULL;
8749     }
8750 
8751     local->type     = type;
8752     local->pkey_sz  = (int)inSz;
8753     local->pkcs8HeaderSz = pkcs8HeaderSz;
8754     local->pkey.ptr = (char*)XMALLOC(inSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
8755     if (local->pkey.ptr == NULL) {
8756         wolfSSL_EVP_PKEY_free(local);
8757         local = NULL;
8758         return NULL;
8759     }
8760     else {
8761         XMEMCPY(local->pkey.ptr, *in, inSz);
8762     }
8763 
8764     switch (type) {
8765 #ifndef NO_RSA
8766         case EVP_PKEY_RSA:
8767             local->ownRsa = 1;
8768             local->rsa = wolfSSL_RSA_new();
8769             if (local->rsa == NULL) {
8770                 wolfSSL_EVP_PKEY_free(local);
8771                 return NULL;
8772             }
8773             opt = priv ? WOLFSSL_RSA_LOAD_PRIVATE : WOLFSSL_RSA_LOAD_PUBLIC;
8774             if (wolfSSL_RSA_LoadDer_ex(local->rsa,
8775                       (const unsigned char*)local->pkey.ptr, local->pkey_sz,
8776                       opt) != WOLFSSL_SUCCESS) {
8777                 wolfSSL_EVP_PKEY_free(local);
8778                 return NULL;
8779             }
8780             break;
8781 #endif /* NO_RSA */
8782 #ifdef HAVE_ECC
8783         case EVP_PKEY_EC:
8784             local->ownEcc = 1;
8785             local->ecc = wolfSSL_EC_KEY_new();
8786             if (local->ecc == NULL) {
8787                 wolfSSL_EVP_PKEY_free(local);
8788                 return NULL;
8789             }
8790             opt = priv ? WOLFSSL_EC_KEY_LOAD_PRIVATE :
8791                          WOLFSSL_EC_KEY_LOAD_PUBLIC;
8792             if (wolfSSL_EC_KEY_LoadDer_ex(local->ecc,
8793                       (const unsigned char*)local->pkey.ptr, local->pkey_sz,
8794                       opt)
8795                       != WOLFSSL_SUCCESS) {
8796                 wolfSSL_EVP_PKEY_free(local);
8797                 return NULL;
8798             }
8799             break;
8800 #endif /* HAVE_ECC */
8801 #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)
8802 #ifndef NO_DSA
8803         case EVP_PKEY_DSA:
8804             local->ownDsa = 1;
8805             local->dsa = wolfSSL_DSA_new();
8806             if (local->dsa == NULL) {
8807                 wolfSSL_EVP_PKEY_free(local);
8808                 return NULL;
8809             }
8810             opt = priv ? WOLFSSL_DSA_LOAD_PRIVATE : WOLFSSL_DSA_LOAD_PUBLIC;
8811             if (wolfSSL_DSA_LoadDer_ex(local->dsa,
8812                     (const unsigned char*)local->pkey.ptr, local->pkey_sz,
8813                     opt)
8814                     != WOLFSSL_SUCCESS) {
8815                 wolfSSL_EVP_PKEY_free(local);
8816                 return NULL;
8817             }
8818             break;
8819 #endif /* NO_DSA */
8820 #ifndef NO_DH
8821 #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
8822         case EVP_PKEY_DH:
8823             local->ownDh = 1;
8824             local->dh = wolfSSL_DH_new();
8825             if (local->dh == NULL) {
8826                 wolfSSL_EVP_PKEY_free(local);
8827                 return NULL;
8828             }
8829             if (wolfSSL_DH_LoadDer(local->dh,
8830                       (const unsigned char*)local->pkey.ptr, local->pkey_sz)
8831                       != WOLFSSL_SUCCESS) {
8832                 wolfSSL_EVP_PKEY_free(local);
8833                 return NULL;
8834             }
8835             break;
8836 #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
8837 #endif /* HAVE_DH */
8838 #endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_OPENSSH */
8839         default:
8840             WOLFSSL_MSG("Unsupported key type");
8841             wolfSSL_EVP_PKEY_free(local);
8842             return NULL;
8843     }
8844 
8845     /* advance pointer with success */
8846     if (local != NULL) {
8847         if (local->pkey_sz <= (int)inSz) {
8848             *in += local->pkey_sz;
8849         }
8850 
8851         if (out != NULL) {
8852             *out = local;
8853         }
8854     }
8855 
8856     return local;
8857 }
8858 
wolfSSL_d2i_PublicKey(int type,WOLFSSL_EVP_PKEY ** out,const unsigned char ** in,long inSz)8859 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PublicKey(int type, WOLFSSL_EVP_PKEY** out,
8860         const unsigned char **in, long inSz)
8861 {
8862     WOLFSSL_ENTER("wolfSSL_d2i_PublicKey");
8863 
8864     return _d2i_PublicKey(type, out, in, inSz, 0);
8865 }
8866 /* Reads in a DER format key. If PKCS8 headers are found they are stripped off.
8867  *
8868  * type  type of key
8869  * out   newly created WOLFSSL_EVP_PKEY structure
8870  * in    pointer to input key DER
8871  * inSz  size of in buffer
8872  *
8873  * On success a non null pointer is returned and the pointer in is advanced the
8874  * same number of bytes read.
8875  */
wolfSSL_d2i_PrivateKey(int type,WOLFSSL_EVP_PKEY ** out,const unsigned char ** in,long inSz)8876 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
8877         const unsigned char **in, long inSz)
8878 {
8879     WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey");
8880 
8881     return _d2i_PublicKey(type, out, in, inSz, 1);
8882 }
8883 
8884 #ifdef WOLF_CRYPTO_CB
8885 /* Create an EVP structure for use with crypto callbacks */
wolfSSL_d2i_PrivateKey_id(int type,WOLFSSL_EVP_PKEY ** out,void * heap,int devId)8886 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_id(int type, WOLFSSL_EVP_PKEY** out,
8887     void* heap, int devId)
8888 {
8889     WOLFSSL_EVP_PKEY* local;
8890 
8891     if (out != NULL && *out != NULL) {
8892         wolfSSL_EVP_PKEY_free(*out);
8893         *out = NULL;
8894     }
8895 
8896     local = wolfSSL_EVP_PKEY_new_ex(heap);
8897     if (local == NULL) {
8898         return NULL;
8899     }
8900 
8901     local->type     = type;
8902     local->pkey_sz  = 0;
8903     local->pkcs8HeaderSz = 0;
8904 
8905     switch (type) {
8906 #ifndef NO_RSA
8907         case EVP_PKEY_RSA:
8908         {
8909             RsaKey* key;
8910             local->ownRsa = 1;
8911             local->rsa = wolfSSL_RSA_new_ex(heap, devId);
8912             if (local->rsa == NULL) {
8913                 wolfSSL_EVP_PKEY_free(local);
8914                 return NULL;
8915             }
8916             key = (RsaKey*)local->rsa->internal;
8917             key->devId = devId;
8918             local->rsa->inSet = 1;
8919             break;
8920         }
8921 #endif /* !NO_RSA */
8922 #ifdef HAVE_ECC
8923         case EVP_PKEY_EC:
8924         {
8925             ecc_key* key;
8926             local->ownEcc = 1;
8927             local->ecc = wolfSSL_EC_KEY_new_ex(heap, devId);
8928             if (local->ecc == NULL) {
8929                 wolfSSL_EVP_PKEY_free(local);
8930                 return NULL;
8931             }
8932             key = (ecc_key*)local->ecc->internal;
8933             key->devId = devId;
8934             key->type = ECC_PRIVATEKEY;
8935             /* key is required to have a key size / curve set, although
8936              * actual one used is determined by devId callback function */
8937             wc_ecc_set_curve(key, ECDHE_SIZE, ECC_CURVE_DEF);
8938 
8939             local->ecc->inSet = 1;
8940             break;
8941         }
8942 #endif /* HAVE_ECC */
8943         default:
8944             WOLFSSL_MSG("Unsupported private key id type");
8945             wolfSSL_EVP_PKEY_free(local);
8946             return NULL;
8947     }
8948 
8949     if (local != NULL && out != NULL) {
8950         *out = local;
8951     }
8952 
8953     return local;
8954 }
8955 #endif /* WOLF_CRYPTO_CB */
8956 
8957 #ifndef NO_CERTS
8958 
8959 #ifndef NO_CHECK_PRIVATE_KEY
wolfSSL_check_private_key(const WOLFSSL * ssl)8960 int wolfSSL_check_private_key(const WOLFSSL* ssl)
8961 {
8962     DecodedCert der;
8963     word32 size;
8964     byte*  buff;
8965     int    ret;
8966 
8967     if (ssl == NULL) {
8968         return WOLFSSL_FAILURE;
8969     }
8970 
8971     size = ssl->buffers.certificate->length;
8972     buff = ssl->buffers.certificate->buffer;
8973     InitDecodedCert(&der, buff, size, ssl->heap);
8974 #ifdef HAVE_PK_CALLBACKS
8975     ret = InitSigPkCb((WOLFSSL*)ssl, &der.sigCtx);
8976     if (ret != 0) {
8977         FreeDecodedCert(&der);
8978         return ret;
8979     }
8980 #endif
8981 
8982     if (ParseCertRelative(&der, CERT_TYPE, NO_VERIFY, NULL) != 0) {
8983         FreeDecodedCert(&der);
8984         return WOLFSSL_FAILURE;
8985     }
8986 
8987     size = ssl->buffers.key->length;
8988     buff = ssl->buffers.key->buffer;
8989 #ifdef WOLF_CRYPTO_CB
8990     if (ssl->buffers.keyDevId != INVALID_DEVID) {
8991         int type = 0;
8992         void *pkey = NULL;
8993 
8994     #ifndef NO_RSA
8995         if (der.keyOID == RSAk) {
8996             type = DYNAMIC_TYPE_RSA;
8997         }
8998     #endif
8999     #ifdef HAVE_ECC
9000         if (der.keyOID == ECDSAk) {
9001             type = DYNAMIC_TYPE_ECC;
9002         }
9003     #endif
9004         ret = CreateDevPrivateKey(&pkey, buff, size, type,
9005                                   ssl->buffers.keyLabel,
9006                                   ssl->buffers.keyId, ssl->heap,
9007                                   ssl->buffers.keyDevId);
9008     #ifndef NO_RSA
9009         if (ret == 0 && der.keyOID == RSAk) {
9010             ret = wc_CryptoCb_RsaCheckPrivKey((RsaKey*)pkey, der.publicKey,
9011                                               der.pubKeySize);
9012             if (ret == 0)
9013                 ret = WOLFSSL_SUCCESS;
9014             wc_FreeRsaKey((RsaKey*)pkey);
9015         }
9016     #endif
9017     #ifdef HAVE_ECC
9018         if (ret == 0 && der.keyOID == ECDSAk) {
9019             ret = wc_CryptoCb_EccCheckPrivKey((ecc_key*)pkey, der.publicKey,
9020                                               der.pubKeySize);
9021             if (ret == 0)
9022                 ret = WOLFSSL_SUCCESS;
9023             wc_ecc_free((ecc_key*)pkey);
9024         }
9025     #endif
9026         if (pkey != NULL) {
9027             XFREE(pkey, ssl->heap, type);
9028         }
9029     }
9030     else {
9031         /* fall through if unavailable */
9032         ret = CRYPTOCB_UNAVAILABLE;
9033     }
9034 
9035     if (ret == CRYPTOCB_UNAVAILABLE)
9036 #endif
9037         ret  = wc_CheckPrivateKeyCert(buff, size, &der);
9038     FreeDecodedCert(&der);
9039     return ret;
9040 }
9041 #endif /* !NO_CHECK_PRIVATE_KEY */
9042 
9043 #if defined(OPENSSL_ALL)
wolfSSL_X509_get_extension_flags(WOLFSSL_X509 * x509)9044 unsigned int wolfSSL_X509_get_extension_flags(WOLFSSL_X509* x509)
9045 {
9046     unsigned int flags = 0;
9047 
9048     WOLFSSL_ENTER("wolfSSL_X509_get_extension_flags");
9049 
9050     if (x509 != NULL) {
9051         if (x509->keyUsageSet) {
9052             flags |= EXFLAG_KUSAGE;
9053         }
9054         if (x509->extKeyUsageSrc != NULL) {
9055             flags |= EXFLAG_XKUSAGE;
9056         }
9057     }
9058 
9059     WOLFSSL_LEAVE("wolfSSL_X509_get_extension_flags", flags);
9060 
9061     return flags;
9062 }
9063 
wolfSSL_X509_get_key_usage(WOLFSSL_X509 * x509)9064 unsigned int wolfSSL_X509_get_key_usage(WOLFSSL_X509* x509)
9065 {
9066     unsigned int ret = 0;
9067 
9068     WOLFSSL_ENTER("wolfSSL_X509_get_key_usage");
9069 
9070     if (x509 == NULL) {
9071         WOLFSSL_MSG("x509 is NULL");
9072     }
9073     else {
9074         if (x509->keyUsageSet) {
9075             ret = wolfSSL_X509_get_keyUsage(x509);
9076         }
9077         else {
9078             ret = (unsigned int)-1;
9079         }
9080     }
9081 
9082     WOLFSSL_LEAVE("wolfSSL_X509_get_key_usage", ret);
9083 
9084     return ret;
9085 }
9086 
wolfSSL_X509_get_extended_key_usage(WOLFSSL_X509 * x509)9087 unsigned int wolfSSL_X509_get_extended_key_usage(WOLFSSL_X509* x509)
9088 {
9089     int ret = 0;
9090 
9091     WOLFSSL_ENTER("wolfSSL_X509_get_extended_key_usage");
9092 
9093     if (x509 != NULL) {
9094         if (x509->extKeyUsage & EXTKEYUSE_OCSP_SIGN)
9095             ret |= XKU_OCSP_SIGN;
9096         if (x509->extKeyUsage & EXTKEYUSE_TIMESTAMP)
9097             ret |= XKU_TIMESTAMP;
9098         if (x509->extKeyUsage & EXTKEYUSE_EMAILPROT)
9099             ret |= XKU_SMIME;
9100         if (x509->extKeyUsage & EXTKEYUSE_CODESIGN)
9101             ret |= XKU_CODE_SIGN;
9102         if (x509->extKeyUsage & EXTKEYUSE_CLIENT_AUTH)
9103             ret |= XKU_SSL_CLIENT;
9104         if (x509->extKeyUsage & EXTKEYUSE_SERVER_AUTH)
9105             ret |= XKU_SSL_SERVER;
9106         if (x509->extKeyUsage & EXTKEYUSE_ANY)
9107             ret |= XKU_ANYEKU;
9108     }
9109 
9110     WOLFSSL_LEAVE("wolfSSL_X509_get_extended_key_usage", ret);
9111 
9112     return (unsigned int)ret;
9113 }
9114 
9115 /* Returns the number of X509V3 extensions in X509 object, or 0 on failure */
wolfSSL_X509_get_ext_count(const WOLFSSL_X509 * passedCert)9116 int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
9117 {
9118     int extCount = 0;
9119     int length = 0;
9120     int outSz = 0;
9121     const byte* rawCert;
9122     int sz = 0;
9123     word32 idx = 0;
9124     DecodedCert cert;
9125     const byte* input;
9126 
9127     WOLFSSL_ENTER("wolfSSL_X509_get_ext_count()");
9128     if (passedCert == NULL) {
9129         WOLFSSL_MSG("\tNot passed a certificate");
9130         return WOLFSSL_FAILURE;
9131     }
9132 
9133     rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)passedCert, &outSz);
9134     if (rawCert == NULL) {
9135         WOLFSSL_MSG("\tpassedCert has no internal DerBuffer set.");
9136         return WOLFSSL_FAILURE;
9137     }
9138     InitDecodedCert(&cert, rawCert, (word32)outSz, 0);
9139 
9140     if (ParseCert(&cert,
9141 #ifdef WOLFSSL_CERT_REQ
9142             passedCert->isCSR ? CERTREQ_TYPE :
9143 #endif
9144                     CA_TYPE,
9145             NO_VERIFY, NULL) < 0) {
9146         WOLFSSL_MSG("\tCertificate parsing failed");
9147         FreeDecodedCert(&cert);
9148         return WOLFSSL_FAILURE;
9149     }
9150 
9151     input = cert.extensions;
9152     sz = cert.extensionsSz;
9153 
9154     if (input == NULL || sz == 0) {
9155         WOLFSSL_MSG("\tsz or input NULL error");
9156         FreeDecodedCert(&cert);
9157         return WOLFSSL_FAILURE;
9158     }
9159 
9160 #ifdef WOLFSSL_CERT_REQ
9161     if (!passedCert->isCSR)
9162 #endif
9163     {
9164         if (input[idx++] != ASN_EXTENSIONS) {
9165             WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
9166             FreeDecodedCert(&cert);
9167             return WOLFSSL_FAILURE;
9168         }
9169 
9170         if (GetLength(input, &idx, &length, sz) < 0) {
9171             WOLFSSL_MSG("\tfail: invalid length");
9172             FreeDecodedCert(&cert);
9173             return WOLFSSL_FAILURE;
9174         }
9175     }
9176 
9177     if (GetSequence(input, &idx, &length, sz) < 0) {
9178         WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
9179         FreeDecodedCert(&cert);
9180         return WOLFSSL_FAILURE;
9181     }
9182 
9183     while (idx < (word32)sz) {
9184         if (GetSequence(input, &idx, &length, sz) < 0) {
9185             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
9186             FreeDecodedCert(&cert);
9187             return WOLFSSL_FAILURE;
9188         }
9189         idx += length;
9190         extCount++;
9191     }
9192     FreeDecodedCert(&cert);
9193     return extCount;
9194 }
9195 
9196 /* Creates and returns pointer to a new X509_EXTENSION object in memory */
wolfSSL_X509_EXTENSION_new(void)9197 WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void)
9198 {
9199     WOLFSSL_X509_EXTENSION* newExt;
9200 
9201     WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_new");
9202 
9203     newExt = (WOLFSSL_X509_EXTENSION*)XMALLOC(sizeof(WOLFSSL_X509_EXTENSION),
9204               NULL, DYNAMIC_TYPE_X509_EXT);
9205     if (newExt == NULL)
9206         return NULL;
9207     XMEMSET(newExt, 0, sizeof(WOLFSSL_X509_EXTENSION));
9208 
9209     return newExt;
9210 }
9211 
wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION * x)9212 void wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION* x)
9213 {
9214     WOLFSSL_ASN1_STRING asn1;
9215     WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_free");
9216     if (x == NULL)
9217         return;
9218 
9219     if (x->obj != NULL)
9220         wolfSSL_ASN1_OBJECT_free(x->obj);
9221 
9222     asn1 = x->value;
9223     if (asn1.length > 0 && asn1.data != NULL && asn1.isDynamic)
9224         XFREE(asn1.data, NULL, DYNAMIC_TYPE_OPENSSL);
9225 
9226     wolfSSL_sk_pop_free(x->ext_sk, NULL);
9227 
9228     XFREE(x, NULL, DYNAMIC_TYPE_X509_EXT);
9229 }
9230 
wolfSSL_X509_EXTENSION_dup(WOLFSSL_X509_EXTENSION * src)9231 WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_dup(WOLFSSL_X509_EXTENSION* src)
9232 {
9233     WOLFSSL_X509_EXTENSION* ret = NULL;
9234     int err = 0;
9235 
9236     WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_dup");
9237 
9238     if (src == NULL) {
9239         err = 1;
9240     }
9241 
9242     if (err == 0) {
9243         ret = wolfSSL_X509_EXTENSION_new();
9244         if (ret == NULL) {
9245             err = 1;
9246         }
9247     }
9248     if (err == 0 && src->obj != NULL) {
9249         ret->obj = wolfSSL_ASN1_OBJECT_dup(src->obj);
9250         if (ret->obj == NULL) {
9251             err = 1;
9252         }
9253     }
9254     if (err == 0) {
9255         ret->crit = src->crit;
9256         if (wolfSSL_ASN1_STRING_copy(&ret->value, &src->value) !=
9257                 WOLFSSL_SUCCESS) {
9258             err = 1;
9259         }
9260     }
9261 
9262     if (err == 1 && ret != NULL) {
9263         wolfSSL_X509_EXTENSION_free(ret);
9264         ret = NULL;
9265     }
9266 
9267     return ret;
9268 }
9269 
9270 /* Creates and returns a new WOLFSSL_X509_EXTENSION stack. */
wolfSSL_sk_new_x509_ext(void)9271 WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void)
9272 {
9273     WOLFSSL_STACK* sk;
9274     WOLFSSL_ENTER("wolfSSL_sk_new_x509_ext");
9275 
9276     sk = wolfSSL_sk_new_null();
9277     if (sk) {
9278         sk->type = STACK_TYPE_X509_EXT;
9279     }
9280     return sk;
9281 }
9282 
9283 /* return 1 on success 0 on fail */
wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK * sk,WOLFSSL_X509_EXTENSION * ext)9284 int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,WOLFSSL_X509_EXTENSION* ext)
9285 {
9286     WOLFSSL_STACK* node;
9287 
9288     WOLFSSL_ENTER("wolfSSL_sk_X509_EXTENSION_push");
9289 
9290     if (sk == NULL || ext == NULL) {
9291         return WOLFSSL_FAILURE;
9292     }
9293 
9294     /* no previous values in stack */
9295     if (sk->data.ext == NULL) {
9296         sk->data.ext = ext;
9297         sk->num += 1;
9298         return WOLFSSL_SUCCESS;
9299     }
9300 
9301     /* stack already has value(s) create a new node and add more */
9302     node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
9303                                                              DYNAMIC_TYPE_X509);
9304     if (node == NULL) {
9305         WOLFSSL_MSG("Memory error");
9306         return WOLFSSL_FAILURE;
9307     }
9308     XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
9309 
9310     /* push new obj onto head of stack */
9311     node->data.ext  = sk->data.ext;
9312     node->next      = sk->next;
9313     node->type      = sk->type;
9314     sk->next        = node;
9315     sk->data.ext    = ext;
9316     sk->num        += 1;
9317 
9318     return WOLFSSL_SUCCESS;
9319 }
9320 
9321 /* Free the structure for X509_EXTENSION stack
9322  *
9323  * sk  stack to free nodes in
9324  */
wolfSSL_sk_X509_EXTENSION_free(WOLFSSL_STACK * sk)9325 void wolfSSL_sk_X509_EXTENSION_free(WOLFSSL_STACK* sk)
9326 {
9327     WOLFSSL_STACK* node;
9328 
9329     WOLFSSL_ENTER("wolfSSL_sk_X509_EXTENSION_free");
9330 
9331     if (sk == NULL) {
9332         return;
9333     }
9334 
9335     /* parse through stack freeing each node */
9336     node = sk->next;
9337     while ((node != NULL) && (sk->num > 1)) {
9338         WOLFSSL_STACK* tmp = node;
9339         node = node->next;
9340 
9341         wolfSSL_X509_EXTENSION_free(tmp->data.ext);
9342         XFREE(tmp, NULL, DYNAMIC_TYPE_X509);
9343         sk->num -= 1;
9344     }
9345 
9346     /* free head of stack */
9347     if (sk->num == 1) {
9348         wolfSSL_X509_EXTENSION_free(sk->data.ext);
9349     }
9350     XFREE(sk, NULL, DYNAMIC_TYPE_X509);
9351 }
9352 
wolfSSL_ASN1_BIT_STRING_set_bit(WOLFSSL_ASN1_BIT_STRING * str,int pos,int val)9353 int wolfSSL_ASN1_BIT_STRING_set_bit(WOLFSSL_ASN1_BIT_STRING* str, int pos,
9354     int val)
9355 {
9356     int bytes_cnt, bit;
9357     byte* temp;
9358 
9359     if (!str || (val != 0 && val != 1) || pos < 0) {
9360         return WOLFSSL_FAILURE;
9361     }
9362 
9363     bytes_cnt = pos/8;
9364     bit = 1<<(7-(pos%8));
9365 
9366     if (bytes_cnt+1 > str->length) {
9367         if (!(temp = (byte*)XREALLOC(str->data, bytes_cnt+1, NULL,
9368                 DYNAMIC_TYPE_OPENSSL))) {
9369             return WOLFSSL_FAILURE;
9370         }
9371         XMEMSET(temp+str->length, 0, bytes_cnt+1 - str->length);
9372         str->data = temp;
9373         str->length = bytes_cnt+1;
9374     }
9375 
9376     str->data[bytes_cnt] &= ~bit;
9377     str->data[bytes_cnt] |= val ? bit : 0;
9378 
9379     return WOLFSSL_SUCCESS;
9380 }
9381 
generateExtStack(const WOLFSSL_X509 * x)9382 static WOLFSSL_STACK* generateExtStack(const WOLFSSL_X509 *x)
9383 {
9384     int numOfExt, i;
9385     WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x;
9386     WOLFSSL_STACK* ret;
9387     WOLFSSL_STACK* tmp;
9388 
9389     if (!x509) {
9390         WOLFSSL_MSG("Bad parameter");
9391         return NULL;
9392     }
9393 
9394     /* Save x509->ext_sk */
9395     tmp = x509->ext_sk;
9396     x509->ext_sk = NULL;
9397     numOfExt = wolfSSL_X509_get_ext_count(x509);
9398 
9399     for (i = 0; i < numOfExt; i++) {
9400         /* Build the extension stack */
9401         (void)wolfSSL_X509_set_ext(x509, i);
9402     }
9403 
9404     /* Restore */
9405     ret = x509->ext_sk;
9406     x509->ext_sk = tmp;
9407     return ret;
9408 }
9409 
9410 /**
9411  * @param x Certificate to extract extensions from
9412  * @return STACK_OF(X509_EXTENSION)*
9413  */
wolfSSL_X509_get0_extensions(const WOLFSSL_X509 * x)9414 const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x)
9415 {
9416     int numOfExt;
9417     WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x;
9418     WOLFSSL_ENTER("wolfSSL_X509_get0_extensions");
9419 
9420     if (!x509) {
9421         WOLFSSL_MSG("Bad parameter");
9422         return NULL;
9423     }
9424 
9425     numOfExt = wolfSSL_X509_get_ext_count(x509);
9426 
9427     if (numOfExt != wolfSSL_sk_num(x509->ext_sk_full)) {
9428         wolfSSL_sk_pop_free(x509->ext_sk_full, NULL);
9429         x509->ext_sk_full = generateExtStack(x);
9430     }
9431 
9432     return x509->ext_sk_full;
9433 }
9434 
9435 /**
9436  * Caller is responsible for freeing the returned stack.
9437  */
wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 * x)9438 const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 *x)
9439 {
9440     return generateExtStack(x);
9441 }
9442 
9443 /* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509.
9444  *
9445  * x509   : The X509 structure to look for the extension.
9446  * loc    : Location of the extension. If the extension is found at the given
9447  * location, a new X509_EXTENSION structure is populated with extension-specific
9448  * data based on the extension type.
9449 
9450  * Returns NULL on error or pointer to X509_EXTENSION structure containing the
9451  * extension. The returned X509_EXTENSION should not be free'd by caller.
9452  * The returned X509_EXTENSION is pushed onto a stack inside the x509 argument.
9453  * This is later free'd when x509 is free'd.
9454  *
9455  * NOTE: for unknown extension NIDs, a X509_EXTENSION is populated with the
9456  * extension oid as the ASN1_OBJECT (QT compatibility)
9457  */
wolfSSL_X509_get_ext(const WOLFSSL_X509 * x509,int loc)9458 WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x509, int loc)
9459 {
9460     WOLFSSL_X509_EXTENSION* ext = NULL;
9461     WOLFSSL_ENTER("wolfSSL_X509_get_ext");
9462     if (x509 == NULL)
9463         return NULL;
9464 
9465    ext = wolfSSL_X509_set_ext((WOLFSSL_X509*) x509, loc);
9466    return ext;
9467 }
9468 
wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 * x,const WOLFSSL_ASN1_OBJECT * obj,int lastpos)9469 int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x,
9470         const WOLFSSL_ASN1_OBJECT *obj, int lastpos)
9471 {
9472     const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION) *sk;
9473 
9474     if (!x || !obj) {
9475         WOLFSSL_MSG("Bad parameter");
9476         return -1;
9477     }
9478 
9479     sk = wolfSSL_X509_get0_extensions(x);
9480     if (!sk) {
9481         WOLFSSL_MSG("No extensions");
9482         return -1;
9483     }
9484     lastpos++;
9485     if (lastpos < 0)
9486         lastpos = 0;
9487     for (; lastpos < wolfSSL_sk_num(sk); lastpos++)
9488         if (wolfSSL_OBJ_cmp((WOLFSSL_ASN1_OBJECT*)wolfSSL_sk_value(sk,
9489                         lastpos), obj) == 0)
9490             return lastpos;
9491     return -1;
9492 }
9493 
9494 /* Pushes a new X509_EXTENSION* ext onto the stack inside WOLFSSL_X509* x509.
9495  * This is currently a helper function for wolfSSL_X509_get_ext
9496  * Caller does not free the returned WOLFSSL_X509_EXTENSION*
9497  */
wolfSSL_X509_set_ext(WOLFSSL_X509 * x509,int loc)9498 WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
9499 {
9500     int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
9501     int objSz = 0, isSet = 0;
9502     const byte* rawCert;
9503     const byte* input;
9504     byte* oidBuf;
9505     word32 oid, idx = 0, tmpIdx = 0, nid;
9506     WOLFSSL_X509_EXTENSION* ext = NULL;
9507     WOLFSSL_ASN1_INTEGER* a;
9508     WOLFSSL_STACK* sk;
9509     DecodedCert cert;
9510 
9511     WOLFSSL_ENTER("wolfSSL_X509_set_ext");
9512 
9513     if(x509 == NULL){
9514         WOLFSSL_MSG("\tNot passed a certificate");
9515         return NULL;
9516     }
9517 
9518     if(loc <0 || (loc > wolfSSL_X509_get_ext_count(x509))){
9519         WOLFSSL_MSG("\tBad location argument");
9520         return NULL;
9521     }
9522 
9523     ext = wolfSSL_X509_EXTENSION_new();
9524     if (ext == NULL) {
9525         WOLFSSL_MSG("\tX509_EXTENSION_new() failed");
9526         return NULL;
9527     }
9528 
9529     rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
9530     if (rawCert == NULL) {
9531         WOLFSSL_MSG("\tX509_get_der() failed");
9532         wolfSSL_X509_EXTENSION_free(ext);
9533         return NULL;
9534     }
9535 
9536     InitDecodedCert( &cert, rawCert, (word32)outSz, 0);
9537 
9538     if (ParseCert(&cert,
9539 #ifdef WOLFSSL_CERT_REQ
9540             x509->isCSR ? CERTREQ_TYPE :
9541 #endif
9542                     CA_TYPE,
9543             NO_VERIFY, NULL) < 0) {
9544         WOLFSSL_MSG("\tCertificate parsing failed");
9545         wolfSSL_X509_EXTENSION_free(ext);
9546         FreeDecodedCert(&cert);
9547         return NULL;
9548     }
9549 
9550     input = cert.extensions;
9551     sz = cert.extensionsSz;
9552 
9553     if (input == NULL || sz == 0) {
9554         WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
9555         wolfSSL_X509_EXTENSION_free(ext);
9556         FreeDecodedCert(&cert);
9557         return NULL;
9558     }
9559 
9560 #ifdef WOLFSSL_CERT_REQ
9561     if (!x509->isCSR)
9562 #endif
9563     {
9564         if (input[idx++] != ASN_EXTENSIONS) {
9565             WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
9566             wolfSSL_X509_EXTENSION_free(ext);
9567             FreeDecodedCert(&cert);
9568             return NULL;
9569         }
9570 
9571         if (GetLength(input, &idx, &length, sz) < 0) {
9572             WOLFSSL_MSG("\tfail: invalid length");
9573             wolfSSL_X509_EXTENSION_free(ext);
9574             FreeDecodedCert(&cert);
9575             return NULL;
9576         }
9577     }
9578 
9579     if (GetSequence(input, &idx, &length, sz) < 0) {
9580         WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
9581         wolfSSL_X509_EXTENSION_free(ext);
9582         FreeDecodedCert(&cert);
9583         return NULL;
9584     }
9585 
9586     while (idx < (word32)sz) {
9587         oid = 0;
9588 
9589         if (GetSequence(input, &idx, &length, sz) < 0) {
9590             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
9591             wolfSSL_X509_EXTENSION_free(ext);
9592             FreeDecodedCert(&cert);
9593             return NULL;
9594         }
9595 
9596         tmpIdx = idx;
9597         ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz);
9598         if (ret < 0) {
9599             WOLFSSL_MSG("\tfail: OBJECT ID");
9600             wolfSSL_X509_EXTENSION_free(ext);
9601             FreeDecodedCert(&cert);
9602             return NULL;
9603         }
9604         idx = tmpIdx;
9605         nid = (word32)oid2nid(oid, oidCertExtType);
9606 
9607         /* Continue while loop until extCount == loc or idx > sz */
9608         if (extCount != loc) {
9609             idx += length;
9610             extCount++;
9611             continue;
9612         }
9613         /* extCount == loc. Now get the extension. */
9614         /* Check if extension has been set */
9615         isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509, nid);
9616         ext->obj = wolfSSL_OBJ_nid2obj(nid);
9617         if (ext->obj == NULL) {
9618             WOLFSSL_MSG("\tfail: Invalid OBJECT");
9619             wolfSSL_X509_EXTENSION_free(ext);
9620             FreeDecodedCert(&cert);
9621             return NULL;
9622         }
9623         ext->obj->nid = nid;
9624 
9625         switch (oid) {
9626             case BASIC_CA_OID:
9627                 if (!isSet)
9628                     break;
9629                 /* Set pathlength */
9630                 a = wolfSSL_ASN1_INTEGER_new();
9631                 if (a == NULL) {
9632                     wolfSSL_X509_EXTENSION_free(ext);
9633                     FreeDecodedCert(&cert);
9634                     return NULL;
9635                 }
9636                 a->length = x509->pathLength;
9637 
9638                 /* Save ASN1_INTEGER in x509 extension */
9639                 ext->obj->pathlen = a;
9640 
9641                 ext->obj->ca = x509->isCa;
9642                 ext->crit = x509->basicConstCrit;
9643                 break;
9644 
9645             case AUTH_INFO_OID:
9646                 if (!isSet)
9647                     break;
9648 
9649                 /* Create a stack to hold both the caIssuer and ocsp objects
9650                     in X509_EXTENSION structure */
9651                 sk = wolfSSL_sk_new_asn1_obj();
9652                 if (sk == NULL) {
9653                     WOLFSSL_MSG("Failed to malloc stack");
9654                     wolfSSL_X509_EXTENSION_free(ext);
9655                     FreeDecodedCert(&cert);
9656                     return NULL;
9657                 }
9658 
9659                 /* Add CaIssuers object to stack */
9660                 if (x509->authInfoCaIssuer != NULL &&
9661                     x509->authInfoCaIssuerSz > 0)
9662                 {
9663                     WOLFSSL_ASN1_OBJECT* obj;
9664                     obj = wolfSSL_ASN1_OBJECT_new();
9665                     if (obj == NULL) {
9666                         WOLFSSL_MSG("Error creating ASN1 object");
9667                         wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
9668                         wolfSSL_X509_EXTENSION_free(ext);
9669                         FreeDecodedCert(&cert);
9670                         return NULL;
9671                     }
9672                     obj->obj = (byte*)x509->authInfoCaIssuer;
9673                     obj->objSz = x509->authInfoCaIssuerSz;
9674                     obj->grp = oidCertAuthInfoType;
9675                     obj->nid = NID_ad_ca_issuers;
9676 
9677                     ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj);
9678                     if (ret != WOLFSSL_SUCCESS) {
9679                         WOLFSSL_MSG("Error pushing ASN1 object onto stack");
9680                         wolfSSL_ASN1_OBJECT_free(obj);
9681                         wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
9682                         wolfSSL_X509_EXTENSION_free(ext);
9683                         FreeDecodedCert(&cert);
9684                         return NULL;
9685                     }
9686                 }
9687 
9688                 /* Add OCSP object to stack */
9689                 if (x509->authInfo != NULL &&
9690                     x509->authInfoSz > 0)
9691                 {
9692                     WOLFSSL_ASN1_OBJECT* obj;
9693                     obj = wolfSSL_ASN1_OBJECT_new();
9694                     if (obj == NULL) {
9695                         WOLFSSL_MSG("Error creating ASN1 object");
9696                         wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
9697                         wolfSSL_X509_EXTENSION_free(ext);
9698                         FreeDecodedCert(&cert);
9699                         return NULL;
9700                     }
9701                     obj->obj = x509->authInfo;
9702                     obj->objSz = x509->authInfoSz;
9703                     obj->grp = oidCertAuthInfoType;
9704                     obj->nid = NID_ad_OCSP;
9705 
9706                     ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj);
9707                     if (ret != WOLFSSL_SUCCESS) {
9708                         WOLFSSL_MSG("Error pushing ASN1 object onto stack");
9709                         wolfSSL_ASN1_OBJECT_free(obj);
9710                         wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
9711                         wolfSSL_X509_EXTENSION_free(ext);
9712                         FreeDecodedCert(&cert);
9713                         return NULL;
9714                     }
9715                 }
9716                 ext->ext_sk = sk;
9717                 ext->crit = x509->authInfoCrit;
9718                 break;
9719 
9720             case AUTH_KEY_OID:
9721                 if (!isSet)
9722                     break;
9723 
9724                 ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->authKeyId,
9725                                         x509->authKeyIdSz);
9726                 if (ret != WOLFSSL_SUCCESS) {
9727                     WOLFSSL_MSG("ASN1_STRING_set() failed");
9728                     wolfSSL_X509_EXTENSION_free(ext);
9729                     FreeDecodedCert(&cert);
9730                     return NULL;
9731                 }
9732                 ext->crit = x509->authKeyIdCrit;
9733                 break;
9734 
9735             case SUBJ_KEY_OID:
9736                 if (!isSet)
9737                     break;
9738 
9739                 ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->subjKeyId,
9740                                         x509->subjKeyIdSz);
9741                 if (ret != WOLFSSL_SUCCESS) {
9742                     WOLFSSL_MSG("ASN1_STRING_set() failed");
9743                     wolfSSL_X509_EXTENSION_free(ext);
9744                     FreeDecodedCert(&cert);
9745                     return NULL;
9746                 }
9747                 ext->crit = x509->subjKeyIdCrit;
9748                 break;
9749 
9750             case CERT_POLICY_OID:
9751                 if (!isSet)
9752                     break;
9753                 ext->crit = x509->certPolicyCrit;
9754                 break;
9755 
9756             case KEY_USAGE_OID:
9757                 if (!isSet)
9758                     break;
9759 
9760                 ret = wolfSSL_ASN1_STRING_set(&ext->value,
9761                                   (byte*)&(x509->keyUsage), sizeof(word16));
9762                 if (ret != WOLFSSL_SUCCESS) {
9763                     WOLFSSL_MSG("ASN1_STRING_set() failed");
9764                     wolfSSL_X509_EXTENSION_free(ext);
9765                     FreeDecodedCert(&cert);
9766                     return NULL;
9767                 }
9768                 ext->crit = x509->keyUsageCrit;
9769                 break;
9770 
9771             case EXT_KEY_USAGE_OID:
9772                 if (!isSet)
9773                     break;
9774                 ext->crit = x509->keyUsageCrit;
9775                 break;
9776 
9777             case CRL_DIST_OID:
9778                 if (!isSet)
9779                     break;
9780                 ext->crit = x509->CRLdistCrit;
9781                 break;
9782 
9783             case ALT_NAMES_OID:
9784             {
9785                 WOLFSSL_GENERAL_NAME* gn = NULL;
9786                 DNS_entry* dns = NULL;
9787                 if (!isSet)
9788                     break;
9789 
9790             #ifdef OPENSSL_ALL
9791                 ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->subjAltNameSrc,
9792                           x509->subjAltNameSz);
9793                 if (ret != WOLFSSL_SUCCESS) {
9794                     WOLFSSL_MSG("ASN1_STRING_set() failed");
9795                     wolfSSL_X509_EXTENSION_free(ext);
9796                     FreeDecodedCert(&cert);
9797                     return NULL;
9798                 }
9799             #endif
9800 
9801                 sk = (WOLFSSL_GENERAL_NAMES*)XMALLOC(
9802                           sizeof(WOLFSSL_GENERAL_NAMES), NULL,
9803                           DYNAMIC_TYPE_ASN1);
9804                 if (sk == NULL) {
9805                     wolfSSL_X509_EXTENSION_free(ext);
9806                     FreeDecodedCert(&cert);
9807                     return NULL;
9808                 }
9809                 XMEMSET(sk, 0, sizeof(WOLFSSL_GENERAL_NAMES));
9810                 sk->type = STACK_TYPE_GEN_NAME;
9811 
9812                 if (x509->subjAltNameSet && x509->altNames != NULL) {
9813                     /* alt names are DNS_entry structs */
9814                     dns = x509->altNames;
9815                     /* Currently only support GEN_DNS type */
9816                     while (dns != NULL) {
9817                         gn = wolfSSL_GENERAL_NAME_new();
9818                         if (gn == NULL) {
9819                             WOLFSSL_MSG("Error creating GENERAL_NAME");
9820                             wolfSSL_X509_EXTENSION_free(ext);
9821                             FreeDecodedCert(&cert);
9822                             wolfSSL_sk_pop_free(sk, NULL);
9823                             return NULL;
9824                         }
9825 
9826                         gn->type = dns->type;
9827                         gn->d.ia5->length = dns->len;
9828                         if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
9829                                     gn->d.ia5->length) != WOLFSSL_SUCCESS) {
9830                             WOLFSSL_MSG("ASN1_STRING_set failed");
9831                             wolfSSL_X509_EXTENSION_free(ext);
9832                             FreeDecodedCert(&cert);
9833                             wolfSSL_GENERAL_NAME_free(gn);
9834                             wolfSSL_sk_pop_free(sk, NULL);
9835                             return NULL;
9836                         }
9837 
9838                         dns = dns->next;
9839                         /* last dns in list add at end of function */
9840                         if (dns != NULL) {
9841                             if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) !=
9842                                                           WOLFSSL_SUCCESS) {
9843                                 WOLFSSL_MSG("Error pushing onto stack");
9844                                 wolfSSL_X509_EXTENSION_free(ext);
9845                                 FreeDecodedCert(&cert);
9846                                 wolfSSL_GENERAL_NAME_free(gn);
9847                                 wolfSSL_sk_pop_free(sk, NULL);
9848                                 return NULL;
9849                             }
9850                         }
9851                     }
9852                     if (wolfSSL_sk_GENERAL_NAME_push(sk,gn) !=
9853                                                           WOLFSSL_SUCCESS) {
9854                         WOLFSSL_MSG("Error pushing onto stack");
9855                         wolfSSL_X509_EXTENSION_free(ext);
9856                         FreeDecodedCert(&cert);
9857                         wolfSSL_GENERAL_NAME_free(gn);
9858                         wolfSSL_sk_pop_free(sk, NULL);
9859                         return NULL;
9860                     }
9861                 }
9862                 ext->ext_sk = sk;
9863                 ext->crit = x509->subjAltNameCrit;
9864                 break;
9865             }
9866 
9867             default:
9868                 WOLFSSL_MSG("Unknown extension type found, parsing OID");
9869                 /* If the extension type is not recognized/supported,
9870                     set the ASN1_OBJECT in the extension with the
9871                     parsed oid for access in later function calls */
9872 
9873                 /* Get OID from input */
9874                 if (GetASNObjectId(input, &idx, &length, sz) != 0) {
9875                     WOLFSSL_MSG("Failed to Get ASN Object Id");
9876                     wolfSSL_X509_EXTENSION_free(ext);
9877                     FreeDecodedCert(&cert);
9878                     return NULL;
9879                 }
9880                 oidBuf = (byte*)XMALLOC(length+1+MAX_LENGTH_SZ, NULL,
9881                                     DYNAMIC_TYPE_TMP_BUFFER);
9882                 if (oidBuf == NULL) {
9883                     WOLFSSL_MSG("Failed to malloc tmp buffer");
9884                     wolfSSL_X509_EXTENSION_free(ext);
9885                     FreeDecodedCert(&cert);
9886                     return NULL;
9887                 }
9888                 oidBuf[0] = ASN_OBJECT_ID;
9889                 objSz++;
9890                 objSz += SetLength(length, oidBuf + 1);
9891                 objSz += length;
9892 
9893                 /* Set object size and reallocate space in object buffer */
9894                 ext->obj->objSz = objSz;
9895                 if(((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
9896                    (ext->obj->obj == NULL)) {
9897                         ext->obj->obj =(byte*)XREALLOC((byte*)ext->obj->obj,
9898                                              ext->obj->objSz,
9899                                              NULL,DYNAMIC_TYPE_ASN1);
9900                     if (ext->obj->obj == NULL) {
9901                         wolfSSL_ASN1_OBJECT_free(ext->obj);
9902                         wolfSSL_X509_EXTENSION_free(ext);
9903                         FreeDecodedCert(&cert);
9904                         XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9905                         return NULL;
9906                     }
9907                     ext->obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
9908                 } else {
9909                     ext->obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
9910                 }
9911                 /* Get OID from input and copy to ASN1_OBJECT buffer */
9912                 XMEMCPY(oidBuf+2, input+idx, length);
9913                 XMEMCPY((byte*)ext->obj->obj, oidBuf, ext->obj->objSz);
9914                 XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9915                 oidBuf = NULL;
9916                 ext->obj->grp = oidCertExtType;
9917                 ext->crit = 0;
9918 
9919                 /* Get extension data and copy as ASN1_STRING */
9920                 tmpIdx = idx + length;
9921                 if ((tmpIdx >= (word32)sz) || (input[tmpIdx++] != ASN_OCTET_STRING)) {
9922                     WOLFSSL_MSG("Error decoding unknown extension data");
9923                     wolfSSL_ASN1_OBJECT_free(ext->obj);
9924                     wolfSSL_X509_EXTENSION_free(ext);
9925                     FreeDecodedCert(&cert);
9926                     return NULL;
9927                 }
9928 
9929                 if (GetLength(input, &tmpIdx, &length, sz) <= 0) {
9930                     WOLFSSL_MSG("Error: Invalid Input Length.");
9931                     wolfSSL_ASN1_OBJECT_free(ext->obj);
9932                     wolfSSL_X509_EXTENSION_free(ext);
9933                     FreeDecodedCert(&cert);
9934                     return NULL;
9935                 }
9936                 ext->value.data = (char*)XMALLOC(length, NULL, DYNAMIC_TYPE_ASN1);
9937                 ext->value.isDynamic = 1;
9938                 if (ext->value.data == NULL) {
9939                     WOLFSSL_MSG("Failed to malloc ASN1_STRING data");
9940                     wolfSSL_X509_EXTENSION_free(ext);
9941                     FreeDecodedCert(&cert);
9942                     return NULL;
9943                 }
9944                 XMEMCPY(ext->value.data,input+tmpIdx,length);
9945                 ext->value.length = length;
9946         } /* switch(oid) */
9947 
9948         break; /* Got the Extension. Now exit while loop. */
9949 
9950     } /* while(idx < sz) */
9951 
9952     /* Store the new extension in a stack inside x509
9953      * The extensions on the stack are free'd internally when FreeX509 is called
9954      */
9955     if (x509->ext_sk == NULL)
9956         x509->ext_sk = wolfSSL_sk_new_x509_ext();
9957     if (x509->ext_sk != NULL)
9958         wolfSSL_sk_X509_EXTENSION_push(x509->ext_sk, ext);
9959 
9960     FreeDecodedCert(&cert);
9961     return ext;
9962 }
9963 
9964 /**
9965  * @param str String to copy
9966  * @param buf Output buffer. If this contains a pointer then it is free'd
9967  *            with the DYNAMIC_TYPE_X509_EXT hint.
9968  * @param len Output length
9969  * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
9970  */
asn1_string_copy_to_buffer(WOLFSSL_ASN1_STRING * str,byte ** buf,word32 * len,void * heap)9971 static int asn1_string_copy_to_buffer(WOLFSSL_ASN1_STRING* str, byte** buf,
9972         word32* len, void* heap) {
9973     if (!str || !buf || !len) {
9974         return WOLFSSL_FAILURE;
9975     }
9976     if (str->data && str->length > 0) {
9977         if (*buf)
9978             XFREE(*buf, heap, DYNAMIC_TYPE_X509_EXT);
9979         *len = 0;
9980         *buf = (byte*)XMALLOC(str->length, heap,
9981                 DYNAMIC_TYPE_X509_EXT);
9982         if (!*buf) {
9983             WOLFSSL_MSG("malloc error");
9984             return WOLFSSL_FAILURE;
9985         }
9986         *len = str->length;
9987         XMEMCPY(*buf, str->data, str->length);
9988     }
9989 
9990     (void)heap;
9991     return WOLFSSL_SUCCESS;
9992 }
9993 
wolfSSL_X509_add_ext(WOLFSSL_X509 * x509,WOLFSSL_X509_EXTENSION * ext,int loc)9994 int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int loc)
9995 {
9996     WOLFSSL_ENTER("wolfSSL_X509_add_ext");
9997 
9998     if (!x509 || !ext || !ext->obj || loc >= 0) {
9999         WOLFSSL_MSG("Bad parameter");
10000         return WOLFSSL_FAILURE;
10001     }
10002 
10003     switch (ext->obj->type) {
10004     case NID_authority_key_identifier:
10005         if (x509->authKeyIdSrc != NULL) {
10006             /* If authKeyId points into authKeyIdSrc then free it and
10007              * revert to old functionality */
10008             XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
10009             x509->authKeyIdSrc = NULL;
10010             x509->authKeyId = NULL;
10011         }
10012         if (asn1_string_copy_to_buffer(&ext->value, &x509->authKeyId,
10013                 &x509->authKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
10014             WOLFSSL_MSG("asn1_string_copy_to_buffer error");
10015             return WOLFSSL_FAILURE;
10016         }
10017         x509->authKeyIdCrit = ext->crit;
10018         break;
10019     case NID_subject_key_identifier:
10020         if (asn1_string_copy_to_buffer(&ext->value, &x509->subjKeyId,
10021                 &x509->subjKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
10022             WOLFSSL_MSG("asn1_string_copy_to_buffer error");
10023             return WOLFSSL_FAILURE;
10024         }
10025         x509->subjKeyIdCrit = ext->crit;
10026         break;
10027     case NID_subject_alt_name:
10028     {
10029         WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk;
10030         while (gns) {
10031             WOLFSSL_GENERAL_NAME* gn = gns->data.gn;
10032             if (!gn || !gn->d.ia5 ||
10033                 wolfSSL_X509_add_altname_ex(x509, gn->d.ia5->data,
10034                     gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) {
10035                 WOLFSSL_MSG("Subject alternative name missing extension");
10036                 return WOLFSSL_FAILURE;
10037             }
10038             gns = gns->next;
10039         }
10040         x509->subjAltNameSet = 1;
10041         x509->subjAltNameCrit = ext->crit;
10042         break;
10043     }
10044     case NID_key_usage:
10045         if (ext && ext->value.data &&
10046                 ext->value.length == sizeof(word16)) {
10047             x509->keyUsage = *(word16*)ext->value.data;
10048             x509->keyUsageCrit = ext->crit;
10049             x509->keyUsageSet = 1;
10050         }
10051         break;
10052     case NID_basic_constraints:
10053         if (ext->obj) {
10054             x509->isCa = ext->obj->ca;
10055             x509->basicConstCrit = ext->crit;
10056             if (ext->obj->pathlen)
10057                 x509->pathLength = ext->obj->pathlen->length;
10058             x509->basicConstSet = 1;
10059         }
10060         break;
10061     default:
10062         WOLFSSL_MSG("Unsupported extension to add");
10063         return WOLFSSL_FAILURE;
10064     }
10065 
10066     return WOLFSSL_SUCCESS;
10067 }
10068 
10069 #ifndef NO_BIO
10070 /* Return 0 on success and 1 on failure. Copies ext data to bio, using indent
10071  *  to pad the output. flag is ignored. */
wolfSSL_X509V3_EXT_print(WOLFSSL_BIO * out,WOLFSSL_X509_EXTENSION * ext,unsigned long flag,int indent)10072 int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext,
10073         unsigned long flag, int indent)
10074 {
10075     ASN1_OBJECT* obj;
10076     ASN1_STRING* str;
10077     int nid;
10078     const int sz = CTC_NAME_SIZE*2;
10079     int rc = WOLFSSL_FAILURE;
10080     char tmp[CTC_NAME_SIZE*2 + 1] = {0};
10081     WOLFSSL_ENTER("wolfSSL_X509V3_EXT_print");
10082 
10083     if ((out == NULL) || (ext == NULL)) {
10084         WOLFSSL_MSG("NULL parameter error");
10085         return rc;
10086     }
10087 
10088     obj = wolfSSL_X509_EXTENSION_get_object(ext);
10089     if (obj == NULL) {
10090         WOLFSSL_MSG("Error getting ASN1_OBJECT from X509_EXTENSION");
10091         return rc;
10092     }
10093 
10094     str = wolfSSL_X509_EXTENSION_get_data(ext);
10095     if (str == NULL) {
10096         WOLFSSL_MSG("Error getting ASN1_STRING from X509_EXTENSION");
10097         return rc;
10098     }
10099 
10100     /* Print extension based on the type */
10101     nid = wolfSSL_OBJ_obj2nid(obj);
10102     switch (nid) {
10103         case BASIC_CA_OID:
10104         {
10105             char isCa[] = "TRUE";
10106             char notCa[] = "FALSE";
10107             XSNPRINTF(tmp, sz, "%*sCA:%s", indent, "",
10108                                                     obj->ca ? isCa : notCa);
10109             break;
10110         }
10111         case ALT_NAMES_OID:
10112         {
10113             WOLFSSL_STACK* sk;
10114             char* val;
10115             int len;
10116             tmp[0] = '\0'; /* Make sure tmp is null-terminated */
10117 
10118             sk = ext->ext_sk;
10119             while (sk != NULL) {
10120                 if (sk->type == STACK_TYPE_GEN_NAME && sk->data.gn) {
10121                     /* str is GENERAL_NAME for subject alternative name ext */
10122                     str = sk->data.gn->d.ia5;
10123                     len = str->length + 2; /* + 2 for NULL char and "," */
10124                     if (len > sz) {
10125                         WOLFSSL_MSG("len greater than buffer size");
10126                         return rc;
10127                     }
10128 
10129                     val = (char*)XMALLOC(len + indent, NULL,
10130                                                        DYNAMIC_TYPE_TMP_BUFFER);
10131                     if (val == NULL) {
10132                         WOLFSSL_MSG("Memory error");
10133                         return rc;
10134                     }
10135                     if (sk->next)
10136                         XSNPRINTF(val, len, "%*s%s,", indent, "", str->strData);
10137                     else
10138                         XSNPRINTF(val, len, "%*s%s", indent, "", str->strData);
10139 
10140                     XSTRNCAT(tmp, val, len);
10141                     XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10142                 }
10143                 sk = sk->next;
10144             }
10145             break;
10146         }
10147         case AUTH_KEY_OID:
10148         case SUBJ_KEY_OID:
10149         {
10150             char* asn1str;
10151             asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str);
10152             XSNPRINTF(tmp, sz, "%*s%s", indent, "", asn1str);
10153             XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10154             break;
10155         }
10156         case AUTH_INFO_OID:
10157         case CERT_POLICY_OID:
10158         case CRL_DIST_OID:
10159         case KEY_USAGE_OID:
10160             WOLFSSL_MSG("X509V3_EXT_print not yet implemented for ext type");
10161             break;
10162 
10163         default:
10164             XSNPRINTF(tmp, sz, "%*s%s", indent, "", str->strData);
10165     }
10166 
10167     if (wolfSSL_BIO_write(out, tmp, (int)XSTRLEN(tmp)) == (int)XSTRLEN(tmp)) {
10168         rc = WOLFSSL_SUCCESS;
10169     }
10170     (void) flag;
10171 
10172     return rc;
10173 }
10174 #endif /* !NO_BIO */
10175 
10176 #ifndef NO_WOLFSSL_STUB
wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF * conf,WOLFSSL_X509V3_CTX * ctx,const char * section,WOLFSSL_X509 * cert)10177 int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_CTX *ctx,
10178         const char *section, WOLFSSL_X509 *cert)
10179 {
10180     WOLFSSL_ENTER("wolfSSL_X509V3_EXT_add_nconf");
10181     WOLFSSL_STUB("wolfSSL_X509V3_EXT_add_nconf");
10182     (void)conf;
10183     (void)ctx;
10184     (void)section;
10185     (void)cert;
10186     return WOLFSSL_SUCCESS;
10187 }
10188 #endif
10189 
10190 /* Returns crit flag in X509_EXTENSION object */
wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION * ex)10191 int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex)
10192 {
10193     WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_critical");
10194     if (ex == NULL)
10195         return BAD_FUNC_ARG;
10196     return ex->crit;
10197 }
10198 
10199 /* Sets if the extension is critical
10200  * returns WOLFSSL_SUCCESS on success
10201  */
wolfSSL_X509_EXTENSION_set_critical(WOLFSSL_X509_EXTENSION * ex,int crit)10202 int wolfSSL_X509_EXTENSION_set_critical(WOLFSSL_X509_EXTENSION* ex, int crit)
10203 {
10204     WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_critical");
10205     if (ex == NULL)
10206         return WOLFSSL_FAILURE;
10207     ex->crit = crit;
10208     return WOLFSSL_SUCCESS;
10209 }
10210 
10211 /* Creates v3_ext_method for a given X509v3 extension
10212  *
10213  * ex   : The X509_EXTENSION used to create v3_ext_method. If the extension is
10214  * not NULL, get the NID of the extension object and populate the
10215  * extension type-specific X509V3_EXT_* function(s) in v3_ext_method.
10216  *
10217  * Returns NULL on error or pointer to the v3_ext_method populated with extension
10218  * type-specific X509V3_EXT_* function(s).
10219  *
10220  * NOTE: NID_subject_key_identifier is currently the only extension implementing
10221  * the X509V3_EXT_* functions, as it is the only type called directly by QT. The
10222  * other extension types return a pointer to a v3_ext_method struct that contains
10223  * only the NID.
10224  */
wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION * ex)10225 const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
10226 {
10227     int nid;
10228     WOLFSSL_v3_ext_method method;
10229 
10230     WOLFSSL_ENTER("wolfSSL_X509V3_EXT_get");
10231     if ((ex == NULL) || (ex->obj == NULL)) {
10232         WOLFSSL_MSG("Passed an invalid X509_EXTENSION*");
10233         return NULL;
10234     }
10235     /* Initialize method to 0 */
10236     XMEMSET(&method, 0, sizeof(struct WOLFSSL_v3_ext_method));
10237 
10238     nid = ex->obj->nid;
10239     if (nid <= 0) {
10240         WOLFSSL_MSG("Failed to get nid from passed extension object");
10241         return NULL;
10242     }
10243     XMEMSET(&method, 0, sizeof(WOLFSSL_v3_ext_method));
10244     switch (nid) {
10245         case NID_basic_constraints:
10246             break;
10247         case NID_subject_key_identifier:
10248             method.i2s = (X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
10249             break;
10250         case NID_subject_alt_name:
10251             WOLFSSL_MSG("i2v function not yet implemented for Subject Alternative Name");
10252             break;
10253         case NID_key_usage:
10254             WOLFSSL_MSG("i2v function not yet implemented for Key Usage");
10255             break;
10256         case NID_authority_key_identifier:
10257             WOLFSSL_MSG("i2v function not yet implemented for Auth Key Id");
10258             break;
10259         case NID_info_access:
10260             WOLFSSL_MSG("i2v function not yet implemented for Info Access");
10261             break;
10262         case NID_ext_key_usage:
10263             WOLFSSL_MSG("i2v function not yet implemented for Ext Key Usage");
10264             break;
10265         case NID_certificate_policies:
10266             WOLFSSL_MSG("r2i function not yet implemented for Cert Policies");
10267             break;
10268         case NID_crl_distribution_points:
10269             WOLFSSL_MSG("r2i function not yet implemented for CRL Dist Points");
10270             break;
10271         default:
10272             /* If extension type is unknown, return NULL -- QT makes call to
10273                 X509_EXTENSION_get_data() if there is no v3_ext_method */
10274             WOLFSSL_MSG("X509V3_EXT_get(): Unknown extension type found");
10275             return NULL;
10276     }
10277 
10278     method.ext_nid = nid;
10279     ex->ext_method = method;
10280 
10281     return (const WOLFSSL_v3_ext_method*)&ex->ext_method;
10282 }
10283 
10284 /* Parses and returns an x509v3 extension internal structure.
10285  *
10286  * ext   : The X509_EXTENSION for parsing internal structure. If extension is
10287  * not NULL, get the NID of the extension object and create a new
10288  * extension-specific internal structure based on the extension type.
10289  *
10290  * Returns NULL on error or if NID is not found, otherwise returns a pointer to
10291  * the extension type-specific X509_EXTENSION internal structure.
10292  * Return is expected to be free'd by caller.
10293  */
wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION * ext)10294 void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
10295 {
10296     const WOLFSSL_v3_ext_method* method;
10297     int ret;
10298     WOLFSSL_ASN1_OBJECT* object;
10299     WOLFSSL_BASIC_CONSTRAINTS* bc;
10300     WOLFSSL_AUTHORITY_KEYID* akey;
10301     WOLFSSL_ASN1_STRING* asn1String, *newString;
10302     WOLFSSL_AUTHORITY_INFO_ACCESS* aia;
10303     WOLFSSL_STACK* sk;
10304 
10305     WOLFSSL_ENTER("wolfSSL_X509V3_EXT_d2i");
10306 
10307     if(ext == NULL) {
10308         WOLFSSL_MSG("Bad function Argument");
10309         return NULL;
10310     }
10311 
10312     /* extract extension info */
10313     method = wolfSSL_X509V3_EXT_get(ext);
10314     if (method == NULL) {
10315         WOLFSSL_MSG("wolfSSL_X509V3_EXT_get error");
10316         return NULL;
10317     }
10318     object = wolfSSL_X509_EXTENSION_get_object(ext);
10319     if (object == NULL) {
10320         WOLFSSL_MSG("X509_EXTENSION_get_object failed");
10321         return NULL;
10322     }
10323 
10324     /* Return pointer to proper internal structure based on NID */
10325     switch (object->type) {
10326         /* basicConstraints */
10327         case (NID_basic_constraints):
10328             WOLFSSL_MSG("basicConstraints");
10329             /* Allocate new BASIC_CONSTRAINTS structure */
10330             bc = wolfSSL_BASIC_CONSTRAINTS_new();
10331             if (bc == NULL) {
10332                 WOLFSSL_MSG("Failed to malloc basic constraints");
10333                 return NULL;
10334             }
10335             /* Copy pathlen and CA into BASIC_CONSTRAINTS from object */
10336             bc->ca = object->ca;
10337             if (object->pathlen->length > 0) {
10338                 bc->pathlen = wolfSSL_ASN1_INTEGER_dup(object->pathlen);
10339                 if (bc->pathlen == NULL) {
10340                     WOLFSSL_MSG("Failed to duplicate ASN1_INTEGER");
10341                     wolfSSL_BASIC_CONSTRAINTS_free(bc);
10342                     return NULL;
10343                 }
10344             }
10345             else
10346                 bc->pathlen = NULL;
10347             return bc;
10348 
10349         /* subjectKeyIdentifier */
10350         case (NID_subject_key_identifier):
10351             WOLFSSL_MSG("subjectKeyIdentifier");
10352             asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
10353             if (asn1String == NULL) {
10354                 WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
10355                 return NULL;
10356             }
10357             newString = wolfSSL_ASN1_STRING_new();
10358             if (newString == NULL) {
10359                 WOLFSSL_MSG("Failed to malloc ASN1_STRING");
10360                 return NULL;
10361             }
10362             ret = wolfSSL_ASN1_STRING_set(newString, asn1String->data,
10363                                                             asn1String->length);
10364             if (ret != WOLFSSL_SUCCESS) {
10365                 WOLFSSL_MSG("ASN1_STRING_set() failed");
10366                 wolfSSL_ASN1_STRING_free(newString);
10367                 return NULL;
10368             };
10369             newString->type = asn1String->type;
10370             return newString;
10371 
10372         /* authorityKeyIdentifier */
10373         case (NID_authority_key_identifier):
10374             WOLFSSL_MSG("AuthorityKeyIdentifier");
10375 
10376             akey = (WOLFSSL_AUTHORITY_KEYID*)
10377                     XMALLOC(sizeof(WOLFSSL_AUTHORITY_KEYID), NULL,
10378                     DYNAMIC_TYPE_X509_EXT);
10379             if (akey == NULL) {
10380                 WOLFSSL_MSG("Failed to malloc authority key id");
10381                 return NULL;
10382             }
10383 
10384             XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
10385 
10386             akey->keyid = wolfSSL_ASN1_STRING_new();
10387             if (akey->keyid == NULL) {
10388                 WOLFSSL_MSG("ASN1_STRING_new() failed");
10389                 wolfSSL_AUTHORITY_KEYID_free(akey);
10390                 return NULL;
10391             }
10392 
10393             asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
10394             if (asn1String == NULL) {
10395                 WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
10396                 wolfSSL_AUTHORITY_KEYID_free(akey);
10397                 return NULL;
10398             }
10399 
10400             ret = wolfSSL_ASN1_STRING_set(akey->keyid, asn1String->data,
10401                                                             asn1String->length);
10402             if (ret != WOLFSSL_SUCCESS) {
10403                 WOLFSSL_MSG("ASN1_STRING_set() failed");
10404                 wolfSSL_AUTHORITY_KEYID_free(akey);
10405                 return NULL;
10406             };
10407             akey->keyid->type   = asn1String->type;
10408 
10409             /* For now, set issuer and serial to NULL. This may need to be
10410                 updated for future use */
10411             akey->issuer = NULL;
10412             akey->serial = NULL;
10413             return akey;
10414 
10415         /* keyUsage */
10416         case (NID_key_usage):
10417             WOLFSSL_MSG("keyUsage");
10418             /* This may need to be updated for future use. The i2v method for
10419                 keyUsage is not currently set. For now, return the ASN1_STRING
10420                 representation of KeyUsage bit string */
10421             asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
10422             if (asn1String == NULL) {
10423                 WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
10424                 return NULL;
10425             }
10426             newString = wolfSSL_ASN1_STRING_new();
10427             if (newString == NULL) {
10428                 WOLFSSL_MSG("Failed to malloc ASN1_STRING");
10429                 return NULL;
10430             }
10431             ret = wolfSSL_ASN1_STRING_set(newString, asn1String->data,
10432                                                             asn1String->length);
10433             if (ret != WOLFSSL_SUCCESS) {
10434                 WOLFSSL_MSG("ASN1_STRING_set() failed");
10435                 wolfSSL_ASN1_STRING_free(newString);
10436                 return NULL;
10437             };
10438             newString->type = asn1String->type;
10439             return newString;
10440 
10441         /* extKeyUsage */
10442         case (NID_ext_key_usage):
10443             WOLFSSL_MSG("extKeyUsage not supported yet");
10444             return NULL;
10445 
10446         /* certificatePolicies */
10447         case (NID_certificate_policies):
10448             WOLFSSL_MSG("certificatePolicies not supported yet");
10449             return NULL;
10450 
10451         /* cRLDistributionPoints */
10452         case (NID_crl_distribution_points):
10453             WOLFSSL_MSG("cRLDistributionPoints not supported yet");
10454             return NULL;
10455 
10456         /* authorityInfoAccess */
10457         case (NID_info_access):
10458             WOLFSSL_MSG("AuthorityInfoAccess");
10459 
10460             sk = ext->ext_sk;
10461             if (sk == NULL) {
10462                 WOLFSSL_MSG("ACCESS_DESCRIPTION stack NULL");
10463                 return NULL;
10464             }
10465 
10466             /* AUTHORITY_INFO_ACCESS is a stack of ACCESS_DESCRIPTION entries */
10467             aia = wolfSSL_sk_new_null();
10468             if (aia == NULL) {
10469                 WOLFSSL_MSG("Failed to malloc AUTHORITY_INFO_ACCESS");
10470                 return NULL;
10471             }
10472             aia->type = STACK_TYPE_ACCESS_DESCRIPTION;
10473 
10474             while (sk) {
10475                 WOLFSSL_ACCESS_DESCRIPTION* ad;
10476                 WOLFSSL_ASN1_OBJECT* aiaEntry;
10477 
10478                 if (sk->type != STACK_TYPE_OBJ) {
10479                     sk = sk->next;
10480                     continue;
10481                 }
10482 
10483                 aiaEntry = sk->data.obj;
10484 
10485                 /* ACCESS_DESCRIPTION has two members, method and location.
10486                 Method: ASN1_OBJECT as either AIA_OCSP_OID or AIA_CA_ISSUER_OID
10487                 Location: GENERAL_NAME structure containing the URI. */
10488 
10489                 ad = (WOLFSSL_ACCESS_DESCRIPTION*)
10490                         XMALLOC(sizeof(WOLFSSL_ACCESS_DESCRIPTION), NULL,
10491                         DYNAMIC_TYPE_X509_EXT);
10492                 if (ad == NULL) {
10493                     WOLFSSL_MSG("Failed to malloc ACCESS_DESCRIPTION");
10494                     XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
10495                     return NULL;
10496                 }
10497                 XMEMSET(ad, 0, sizeof(WOLFSSL_ACCESS_DESCRIPTION));
10498 
10499                 /* Create new ASN1_OBJECT from oid */
10500                 ad->method = wolfSSL_OBJ_nid2obj(aiaEntry->nid);
10501                 if (ad->method == NULL) {
10502                     WOLFSSL_MSG("OBJ_nid2obj() failed");
10503                     XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
10504                     XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
10505                     return NULL;
10506                 }
10507 
10508                 /* Allocate memory for GENERAL NAME */
10509                 ad->location = wolfSSL_GENERAL_NAME_new();
10510                 if (ad->location == NULL) {
10511                     WOLFSSL_MSG("Failed to malloc GENERAL_NAME");
10512                     wolfSSL_ASN1_OBJECT_free(ad->method);
10513                     XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
10514                     XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
10515                     return NULL;
10516                 }
10517 
10518                 ret = wolfSSL_GENERAL_NAME_set_type(ad->location, GEN_URI);
10519                 if (ret != WOLFSSL_SUCCESS) {
10520                     wolfSSL_ASN1_OBJECT_free(ad->method);
10521                     XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
10522                     wolfSSL_GENERAL_NAME_free(ad->location);
10523                     XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
10524                     return NULL;
10525                 }
10526 
10527                 /* Set the URI in GENERAL_NAME */
10528                 ret = wolfSSL_ASN1_STRING_set(
10529                                     ad->location->d.uniformResourceIdentifier,
10530                                     aiaEntry->obj, aiaEntry->objSz);
10531                 if (ret != WOLFSSL_SUCCESS) {
10532                     WOLFSSL_MSG("ASN1_STRING_set() failed");
10533                     wolfSSL_ASN1_OBJECT_free(ad->method);
10534                     XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
10535                     wolfSSL_GENERAL_NAME_free(ad->location);
10536                     XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
10537                     return NULL;
10538                 }
10539                 /* Push to AUTHORITY_INFO_ACCESS stack */
10540                 ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(aia, ad);
10541                 if (ret != WOLFSSL_SUCCESS) {
10542                     WOLFSSL_MSG("Error pushing ASN1 AD onto stack");
10543                     wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL);
10544                     wolfSSL_ASN1_OBJECT_free(ad->method);
10545                     wolfSSL_GENERAL_NAME_free(ad->location);
10546                     XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT);
10547                     XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
10548                     return NULL;
10549                 }
10550 
10551                 sk = sk->next;
10552             }
10553             return aia;
10554 
10555         default:
10556             WOLFSSL_MSG("Extension NID not in table, returning NULL");
10557             break;
10558     }
10559     return NULL;
10560 }
10561 
10562 /* Looks for the extension matching the passed in nid
10563  *
10564  * x509 : certificate to get parse through for extension.
10565  * nid : Extension OID to be found.
10566  * lastPos : Start search from extension after lastPos.
10567  *           Set to -1 to search from index 0.
10568  * return >= 0 If successful the extension index is returned.
10569  * return -1 If extension is not found or error is encountered.
10570  */
wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509 * x509,int nid,int lastPos)10571 int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
10572 {
10573     int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
10574     int isSet = 0, found = 0, loc;
10575     const byte* rawCert;
10576     const byte* input;
10577     word32 oid, idx = 0, tmpIdx = 0, foundNID;
10578     DecodedCert cert;
10579 
10580     WOLFSSL_ENTER("wolfSSL_X509_get_ext_by_NID");
10581 
10582     if(x509 == NULL){
10583         WOLFSSL_MSG("\tNot passed a certificate");
10584         return WOLFSSL_FATAL_ERROR;
10585     }
10586 
10587     if(lastPos < -1 || (lastPos > (wolfSSL_X509_get_ext_count(x509) - 1))){
10588         WOLFSSL_MSG("\tBad location argument");
10589         return WOLFSSL_FATAL_ERROR;
10590     }
10591 
10592     loc = lastPos + 1;
10593 
10594     rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
10595     if (rawCert == NULL) {
10596         WOLFSSL_MSG("\tX509_get_der() failed");
10597         return WOLFSSL_FATAL_ERROR;
10598     }
10599 
10600     InitDecodedCert( &cert, rawCert, (word32)outSz, 0);
10601 
10602     if (ParseCert(&cert,
10603 #ifdef WOLFSSL_CERT_REQ
10604             x509->isCSR ? CERTREQ_TYPE :
10605 #endif
10606             CA_TYPE,
10607             NO_VERIFY, NULL) < 0) {
10608         WOLFSSL_MSG("\tCertificate parsing failed");
10609         FreeDecodedCert(&cert);
10610         return WOLFSSL_FATAL_ERROR;
10611     }
10612 
10613     input = cert.extensions;
10614     sz = cert.extensionsSz;
10615 
10616     if (input == NULL || sz == 0) {
10617         WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
10618         FreeDecodedCert(&cert);
10619         return WOLFSSL_FATAL_ERROR;
10620     }
10621 
10622 #ifdef WOLFSSL_CERT_REQ
10623     if (!x509->isCSR)
10624 #endif
10625     {
10626         if (input[idx++] != ASN_EXTENSIONS) {
10627             WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
10628             FreeDecodedCert(&cert);
10629             return WOLFSSL_FATAL_ERROR;
10630         }
10631 
10632         if (GetLength(input, &idx, &length, sz) < 0) {
10633             WOLFSSL_MSG("\tfail: invalid length");
10634             FreeDecodedCert(&cert);
10635             return WOLFSSL_FATAL_ERROR;
10636         }
10637     }
10638 
10639     if (GetSequence(input, &idx, &length, sz) < 0) {
10640         WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
10641         FreeDecodedCert(&cert);
10642         return WOLFSSL_FATAL_ERROR;
10643     }
10644 
10645     while (idx < (word32)sz) {
10646         oid = 0;
10647 
10648         if (GetSequence(input, &idx, &length, sz) < 0) {
10649             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
10650             FreeDecodedCert(&cert);
10651             return WOLFSSL_FATAL_ERROR;
10652         }
10653 
10654         tmpIdx = idx;
10655         ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz);
10656         if (ret < 0) {
10657             WOLFSSL_MSG("\tfail: OBJECT ID");
10658             FreeDecodedCert(&cert);
10659             return WOLFSSL_FATAL_ERROR;
10660         }
10661         idx = tmpIdx;
10662         foundNID = (word32)oid2nid(oid, oidCertExtType);
10663 
10664         if (extCount >= loc) {
10665             /* extCount >= loc. Now check if extension has been set */
10666             isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509, foundNID);
10667 
10668             if (isSet && ((word32)nid == foundNID)) {
10669                 found = 1;
10670                 break;
10671             }
10672         }
10673 
10674         idx += length;
10675         extCount++;
10676     } /* while(idx < sz) */
10677 
10678     FreeDecodedCert(&cert);
10679 
10680     return found ? extCount : WOLFSSL_FATAL_ERROR;
10681 }
10682 
10683 
10684 #endif /* OPENSSL_ALL */
10685 
10686 #endif /* !NO_CERTS */
10687 #endif /* OPENSSL_EXTRA */
10688 
10689 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
wolfSSL_ASN1_BIT_STRING_new(void)10690 WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void)
10691 {
10692     WOLFSSL_ASN1_BIT_STRING* str;
10693 
10694     str = (WOLFSSL_ASN1_BIT_STRING*)XMALLOC(sizeof(WOLFSSL_ASN1_BIT_STRING),
10695                                                   NULL, DYNAMIC_TYPE_OPENSSL);
10696     if (str) {
10697         XMEMSET(str, 0, sizeof(WOLFSSL_ASN1_BIT_STRING));
10698     }
10699     return str;
10700 }
10701 
wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING * str)10702 void wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING* str)
10703 {
10704     if (str) {
10705         if (str->data) {
10706             XFREE(str->data, NULL, DYNAMIC_TYPE_OPENSSL);
10707             str->data = NULL;
10708         }
10709         XFREE(str, NULL, DYNAMIC_TYPE_OPENSSL);
10710     }
10711 }
10712 
wolfSSL_ASN1_BIT_STRING_get_bit(const WOLFSSL_ASN1_BIT_STRING * str,int i)10713 int wolfSSL_ASN1_BIT_STRING_get_bit(const WOLFSSL_ASN1_BIT_STRING* str, int i)
10714 {
10715     if (!str || !str->data || str->length <= (i/8) || i < 0) {
10716         return WOLFSSL_FAILURE;
10717     }
10718 
10719     return (str->data[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
10720 }
10721 
10722 /* Looks for the extension matching the passed in nid
10723  *
10724  * c   : if not null then is set to status value -2 if multiple occurrences
10725  *       of the extension are found, -1 if not found, 0 if found and not
10726  *       critical, and 1 if found and critical.
10727  * nid : Extension OID to be found.
10728  * idx : if NULL return first extension found match, otherwise start search at
10729  *       idx location and set idx to the location of extension returned.
10730  * returns NULL or a pointer to an WOLFSSL_ASN1_BIT_STRING (for KEY_USAGE_OID)
10731  * or WOLFSSL_STACK (for other)
10732  * holding extension structure
10733  *
10734  * NOTE code for decoding extensions is in asn.c DecodeCertExtensions --
10735  * use already decoded extension in this function to avoid decoding twice.
10736  * Currently we do not make use of idx since getting pre decoded extensions.
10737  */
wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509 * x509,int nid,int * c,int * idx)10738 void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
10739     int* idx)
10740 {
10741     void* ret = NULL;
10742     WOLFSSL_STACK* sk = NULL;
10743     WOLFSSL_ASN1_OBJECT* obj = NULL;
10744     WOLFSSL_GENERAL_NAME* gn = NULL;
10745     WOLFSSL_DIST_POINT* dp = NULL;
10746     WOLFSSL_BASIC_CONSTRAINTS* bc = NULL;
10747 
10748     WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i");
10749 
10750     if (x509 == NULL) {
10751         return NULL;
10752     }
10753 
10754     if (c != NULL) {
10755         *c = -1; /* default to not found */
10756     }
10757 
10758     switch (nid) {
10759         case BASIC_CA_OID:
10760             if (x509->basicConstSet) {
10761                 WOLFSSL_ASN1_INTEGER* a;
10762 
10763                 bc = wolfSSL_BASIC_CONSTRAINTS_new();
10764                 if (!bc) {
10765                     WOLFSSL_MSG("wolfSSL_BASIC_CONSTRAINTS_new error");
10766                     return NULL;
10767                 }
10768 
10769                 a = wolfSSL_ASN1_INTEGER_new();
10770                 if (!a) {
10771                     WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
10772                     wolfSSL_BASIC_CONSTRAINTS_free(bc);
10773                     return NULL;
10774                 }
10775                 a->length = x509->pathLength;
10776 
10777 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
10778         defined(WOLFSSL_APACHE_HTTPD)
10779                 bc->ca = x509->isCa;
10780 #endif
10781                 bc->pathlen = a;
10782                 if (c != NULL) {
10783                     *c = x509->basicConstCrit;
10784                 }
10785             }
10786             else {
10787                 WOLFSSL_MSG("No Basic Constraint set");
10788             }
10789             return bc;
10790 
10791         case ALT_NAMES_OID:
10792         {
10793             DNS_entry* dns = NULL;
10794 
10795             if (x509->subjAltNameSet && x509->altNames != NULL) {
10796                 /* Malloc GENERAL_NAME stack */
10797                 sk = wolfSSL_sk_new_null();
10798                 if (sk == NULL)
10799                     return NULL;
10800                 sk->type = STACK_TYPE_GEN_NAME;
10801 
10802                 /* alt names are DNS_entry structs */
10803                 if (c != NULL) {
10804                     if (x509->altNames->next != NULL) {
10805                         *c = -2; /* more then one found */
10806                     }
10807                     else {
10808                         *c = x509->subjAltNameCrit;
10809                     }
10810                 }
10811 
10812                 dns = x509->altNames;
10813                 /* Currently only support GEN_DNS type */
10814                 while (dns != NULL) {
10815                     gn = wolfSSL_GENERAL_NAME_new();
10816                     if (gn == NULL) {
10817                         WOLFSSL_MSG("Error creating GENERAL_NAME");
10818                         goto err;
10819                     }
10820 
10821                     gn->type = dns->type;
10822                     switch (gn->type) {
10823                         case ASN_DIR_TYPE:
10824                             {
10825                                 int localIdx = 0;
10826                                 unsigned char* n = (unsigned char*)XMALLOC(
10827                                         dns->len + MAX_SEQ_SZ, x509->heap,
10828                                         DYNAMIC_TYPE_TMP_BUFFER);
10829                                 if (n == NULL) {
10830                                     goto err;
10831                                 }
10832 
10833                                 localIdx += SetSequence(dns->len, n);
10834                                 XMEMCPY(n + localIdx, dns->name, dns->len);
10835                                 gn->d.dirn =  wolfSSL_d2i_X509_NAME(NULL, &n,
10836                                         dns->len + localIdx);
10837                                 XFREE(n, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
10838                                 if (gn->d.dirn == NULL) {
10839                                     WOLFSSL_MSG("Convert altDirName to X509 "
10840                                             "NAME failed");
10841                                     goto err;
10842                                 }
10843                             }
10844                             break;
10845 
10846                         default:
10847                             if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
10848                                     dns->len) != WOLFSSL_SUCCESS) {
10849                                 WOLFSSL_MSG("ASN1_STRING_set failed");
10850                                 goto err;
10851                             }
10852                     }
10853 
10854                     dns = dns->next;
10855                     if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) !=
10856                                                       WOLFSSL_SUCCESS) {
10857                         WOLFSSL_MSG("Error pushing ASN1 object onto stack");
10858                         goto err;
10859                     }
10860                     /* null so that it doesn't get pushed again after switch */
10861                     gn = NULL;
10862                 }
10863             }
10864             else {
10865                 WOLFSSL_MSG("No Alt Names set");
10866             }
10867 
10868             break;
10869         }
10870 
10871         case CRL_DIST_OID:
10872             if (x509->CRLdistSet && x509->CRLInfo != NULL) {
10873                 if (c != NULL) {
10874                     *c = x509->CRLdistCrit;
10875                 }
10876 
10877                 sk = wolfSSL_sk_new_null();
10878                 if (sk == NULL) {
10879                     return NULL;
10880                 }
10881                 sk->type = STACK_TYPE_DIST_POINT;
10882 
10883                 gn = wolfSSL_GENERAL_NAME_new();
10884                 if (gn == NULL) {
10885                     WOLFSSL_MSG("Error creating GENERAL_NAME");
10886                     goto err;
10887                 }
10888 
10889                 if (wolfSSL_GENERAL_NAME_set_type(gn, GEN_URI) !=
10890                         WOLFSSL_SUCCESS) {
10891                     WOLFSSL_MSG("Error setting GENERAL_NAME type");
10892                     goto err;
10893                 }
10894 
10895                 if (wolfSSL_ASN1_STRING_set(gn->d.uniformResourceIdentifier,
10896                         x509->CRLInfo, x509->CRLInfoSz) != WOLFSSL_SUCCESS) {
10897                     WOLFSSL_MSG("ASN1_STRING_set failed");
10898                     goto err;
10899                 }
10900 
10901                 /* wolfSSL only decodes one dist point */
10902                 dp = wolfSSL_DIST_POINT_new();
10903                 if (dp == NULL) {
10904                     WOLFSSL_MSG("Error creating DIST_POINT");
10905                     goto err;
10906                 }
10907 
10908                 /* push GENERAL_NAME onto fullname stack */
10909                 if (wolfSSL_sk_GENERAL_NAME_push(dp->distpoint->name.fullname,
10910                                                  gn) != WOLFSSL_SUCCESS) {
10911                     WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
10912                     goto err;
10913                 }
10914 
10915                 /* push DIST_POINT onto stack */
10916                 if (wolfSSL_sk_DIST_POINT_push(sk, dp) != WOLFSSL_SUCCESS) {
10917                     WOLFSSL_MSG("Error pushing DIST_POINT onto stack");
10918                     goto err;
10919                 }
10920 
10921                 gn = NULL;
10922                 dp = NULL;
10923 
10924             }
10925             else {
10926                 WOLFSSL_MSG("No CRL dist set");
10927             }
10928 
10929             break;
10930 
10931         case AUTH_INFO_OID:
10932             if (x509->authInfoSet && x509->authInfo != NULL) {
10933                 if (c != NULL) {
10934                     *c = x509->authInfoCrit;
10935                 }
10936                 obj = wolfSSL_ASN1_OBJECT_new();
10937                 if (obj == NULL) {
10938                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
10939                     return NULL;
10940                 }
10941                 obj->type  = AUTH_INFO_OID;
10942                 obj->grp   = oidCertExtType;
10943                 obj->obj   = x509->authInfo;
10944                 obj->objSz = x509->authInfoSz;
10945             }
10946             else {
10947                 WOLFSSL_MSG("No Auth Info set");
10948             }
10949             break;
10950 
10951         case AUTH_KEY_OID:
10952             if (x509->authKeyIdSet) {
10953                 WOLFSSL_AUTHORITY_KEYID* akey = wolfSSL_AUTHORITY_KEYID_new();
10954                 if (!akey) {
10955                     WOLFSSL_MSG("Issue creating WOLFSSL_AUTHORITY_KEYID struct");
10956                     return NULL;
10957                 }
10958 
10959                 if (c != NULL) {
10960                     *c = x509->authKeyIdCrit;
10961                 }
10962                 obj = wolfSSL_ASN1_OBJECT_new();
10963                 if (obj == NULL) {
10964                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
10965                     wolfSSL_AUTHORITY_KEYID_free(akey);
10966                     return NULL;
10967                 }
10968                 obj->type  = AUTH_KEY_OID;
10969                 obj->grp   = oidCertExtType;
10970                 obj->obj   = x509->authKeyId;
10971                 obj->objSz = x509->authKeyIdSz;
10972                 akey->issuer = obj;
10973                 return akey;
10974             }
10975             else {
10976                 WOLFSSL_MSG("No Auth Key set");
10977             }
10978             break;
10979 
10980         case SUBJ_KEY_OID:
10981             if (x509->subjKeyIdSet) {
10982                 if (c != NULL) {
10983                     *c = x509->subjKeyIdCrit;
10984                 }
10985                 obj = wolfSSL_ASN1_OBJECT_new();
10986                 if (obj == NULL) {
10987                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
10988                     return NULL;
10989                 }
10990                 obj->type  = SUBJ_KEY_OID;
10991                 obj->grp   = oidCertExtType;
10992                 obj->obj   = x509->subjKeyId;
10993                 obj->objSz = x509->subjKeyIdSz;
10994             }
10995             else {
10996                 WOLFSSL_MSG("No Subject Key set");
10997             }
10998             break;
10999 
11000         case CERT_POLICY_OID:
11001         {
11002         #ifdef WOLFSSL_CERT_EXT
11003             int i;
11004 
11005             if (x509->certPoliciesNb > 0) {
11006                 if (c != NULL) {
11007                     if (x509->certPoliciesNb > 1) {
11008                         *c = -2;
11009                     }
11010                     else {
11011                         *c = 0;
11012                     }
11013                 }
11014 
11015                 sk = wolfSSL_sk_new_asn1_obj();
11016                 if (sk == NULL) {
11017                     return NULL;
11018                 }
11019 
11020                 for (i = 0; i < x509->certPoliciesNb - 1; i++) {
11021                     obj = wolfSSL_ASN1_OBJECT_new();
11022                     if (obj == NULL) {
11023                         WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
11024                         wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
11025                         return NULL;
11026                     }
11027                     obj->type  = CERT_POLICY_OID;
11028                     obj->grp   = oidCertExtType;
11029                     obj->obj   = (byte*)(x509->certPolicies[i]);
11030                     obj->objSz = MAX_CERTPOL_SZ;
11031                     if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj)
11032                                                            != WOLFSSL_SUCCESS) {
11033                         WOLFSSL_MSG("Error pushing ASN1 object onto stack");
11034                         wolfSSL_ASN1_OBJECT_free(obj);
11035                         wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
11036                         sk = NULL;
11037                     }
11038                 }
11039                 obj = wolfSSL_ASN1_OBJECT_new();
11040                 if (obj == NULL) {
11041                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
11042                     wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
11043                     return NULL;
11044                 }
11045                 obj->type  = CERT_POLICY_OID;
11046                 obj->grp   = oidCertExtType;
11047                 obj->obj   = (byte*)(x509->certPolicies[i]);
11048                 obj->objSz = MAX_CERTPOL_SZ;
11049             }
11050             else {
11051                 WOLFSSL_MSG("No Cert Policy set");
11052             }
11053         #elif defined(WOLFSSL_SEP)
11054             if (x509->certPolicySet) {
11055                 if (c != NULL) {
11056                     *c = x509->certPolicyCrit;
11057                 }
11058                 obj = wolfSSL_ASN1_OBJECT_new();
11059                 if (obj == NULL) {
11060                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
11061                     return NULL;
11062                 }
11063                 obj->type  = CERT_POLICY_OID;
11064                 obj->grp   = oidCertExtType;
11065             }
11066             else {
11067                 WOLFSSL_MSG("No Cert Policy set");
11068             }
11069         #else
11070             WOLFSSL_MSG("wolfSSL not built with WOLFSSL_SEP or WOLFSSL_CERT_EXT");
11071         #endif
11072             break;
11073         }
11074         case KEY_USAGE_OID:
11075         {
11076             WOLFSSL_ASN1_STRING* asn1str = NULL;
11077             if (x509->keyUsageSet) {
11078                 if (c != NULL) {
11079                     *c = x509->keyUsageCrit;
11080                 }
11081 
11082                 asn1str = wolfSSL_ASN1_STRING_new();
11083                 if (asn1str == NULL) {
11084                     WOLFSSL_MSG("Failed to malloc ASN1_STRING");
11085                     return NULL;
11086                 }
11087 
11088                 if (wolfSSL_ASN1_STRING_set(asn1str, &x509->keyUsage,
11089                         sizeof(word16)) != WOLFSSL_SUCCESS) {
11090                     WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
11091                     wolfSSL_ASN1_STRING_free(asn1str);
11092                     return NULL;
11093                 }
11094 
11095                 asn1str->type = KEY_USAGE_OID;
11096             }
11097             else {
11098                 WOLFSSL_MSG("No Key Usage set");
11099             }
11100             /* don't add stack of and return bit string directly */
11101             return asn1str;
11102         }
11103         case INHIBIT_ANY_OID:
11104             WOLFSSL_MSG("INHIBIT ANY extension not supported");
11105             break;
11106 
11107         case EXT_KEY_USAGE_OID:
11108             if (x509->extKeyUsageSrc != NULL) {
11109                 if (c != NULL) {
11110                     if (x509->extKeyUsageCount > 1) {
11111                         *c = -2;
11112                     }
11113                     else {
11114                         *c = x509->extKeyUsageCrit;
11115                     }
11116                 }
11117                 obj = wolfSSL_ASN1_OBJECT_new();
11118                 if (obj == NULL) {
11119                     WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
11120                     return NULL;
11121                 }
11122                 obj->type  = EXT_KEY_USAGE_OID;
11123                 obj->grp   = oidCertExtType;
11124                 obj->obj   = x509->extKeyUsageSrc;
11125                 obj->objSz = x509->extKeyUsageSz;
11126             }
11127             else {
11128                 WOLFSSL_MSG("No Extended Key Usage set");
11129             }
11130             break;
11131 
11132         case NAME_CONS_OID:
11133             WOLFSSL_MSG("Name Constraint OID extension not supported");
11134             break;
11135 
11136         case PRIV_KEY_USAGE_PERIOD_OID:
11137             WOLFSSL_MSG("Private Key Usage Period extension not supported");
11138             break;
11139 
11140         case SUBJECT_INFO_ACCESS:
11141             WOLFSSL_MSG("Subject Info Access extension not supported");
11142             break;
11143 
11144         case POLICY_MAP_OID:
11145             WOLFSSL_MSG("Policy Map extension not supported");
11146             break;
11147 
11148         case POLICY_CONST_OID:
11149             WOLFSSL_MSG("Policy Constraint extension not supported");
11150             break;
11151 
11152         case ISSUE_ALT_NAMES_OID:
11153             WOLFSSL_MSG("Issue Alt Names extension not supported");
11154             break;
11155 
11156         case TLS_FEATURE_OID:
11157             WOLFSSL_MSG("TLS Feature extension not supported");
11158             break;
11159 
11160         default:
11161             WOLFSSL_MSG("Unsupported/Unknown extension OID");
11162     }
11163 
11164     /* make sure stack of is allocated */
11165     if ((obj || gn) && sk == NULL) {
11166         sk = wolfSSL_sk_new_asn1_obj();
11167         if (sk == NULL) {
11168             goto err;
11169         }
11170     }
11171     if (obj) {
11172         if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) != WOLFSSL_SUCCESS) {
11173             WOLFSSL_MSG("Error pushing ASN1_OBJECT object onto "
11174                         "stack.");
11175             goto err;
11176         }
11177     }
11178 
11179     ret = sk;
11180 
11181     (void)idx;
11182 
11183     return ret;
11184 
11185 err:
11186     if (obj) {
11187         wolfSSL_ASN1_OBJECT_free(obj);
11188     }
11189     if (gn) {
11190         wolfSSL_GENERAL_NAME_free(gn);
11191     }
11192     if (dp) {
11193         wolfSSL_DIST_POINT_free(dp);
11194     }
11195     if (sk) {
11196         wolfSSL_sk_free(sk);
11197     }
11198     return NULL;
11199 }
11200 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
11201 
11202 #ifdef OPENSSL_EXTRA
11203 #ifndef NO_CERTS
wolfSSL_X509_add_altname_ex(WOLFSSL_X509 * x509,const char * name,word32 nameSz,int type)11204 int wolfSSL_X509_add_altname_ex(WOLFSSL_X509* x509, const char* name,
11205         word32 nameSz, int type)
11206 {
11207     DNS_entry* newAltName = NULL;
11208     char* nameCopy = NULL;
11209 
11210     if (x509 == NULL)
11211         return WOLFSSL_FAILURE;
11212 
11213     if ((name == NULL) || (nameSz == 0))
11214         return WOLFSSL_SUCCESS;
11215 
11216     newAltName = AltNameNew(x509->heap);
11217     if (newAltName == NULL)
11218         return WOLFSSL_FAILURE;
11219 
11220     nameCopy = (char*)XMALLOC(nameSz + 1, x509->heap, DYNAMIC_TYPE_ALTNAME);
11221     if (nameCopy == NULL) {
11222         XFREE(newAltName, x509->heap, DYNAMIC_TYPE_ALTNAME);
11223         return WOLFSSL_FAILURE;
11224     }
11225 
11226     XMEMCPY(nameCopy, name, nameSz);
11227 
11228     nameCopy[nameSz] = '\0';
11229 
11230     newAltName->next = x509->altNames;
11231     newAltName->type = type;
11232     newAltName->len = nameSz;
11233     newAltName->name = nameCopy;
11234     x509->altNames = newAltName;
11235 
11236     return WOLFSSL_SUCCESS;
11237 }
11238 
wolfSSL_X509_add_altname(WOLFSSL_X509 * x509,const char * name,int type)11239 int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
11240 {
11241     word32 nameSz;
11242 
11243     if (name == NULL)
11244         return WOLFSSL_SUCCESS;
11245 
11246     nameSz = (word32)XSTRLEN(name);
11247     if (nameSz == 0)
11248         return WOLFSSL_SUCCESS;
11249 
11250     if (type == ASN_IP_TYPE) {
11251         WOLFSSL_MSG("Type not supported, use wolfSSL_X509_add_altname_ex");
11252         return WOLFSSL_FAILURE;
11253     }
11254 
11255     return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type);
11256 }
11257 
11258 #ifndef NO_WOLFSSL_STUB
wolfSSL_X509_delete_ext(WOLFSSL_X509 * x509,int loc)11259 WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc)
11260 {
11261     WOLFSSL_STUB("wolfSSL_X509_delete_ext");
11262     (void)x509;
11263     (void)loc;
11264     return NULL;
11265 }
11266 
11267 /* currently LHASH is not implemented (and not needed for Apache port) */
wolfSSL_X509V3_EXT_conf_nid(WOLF_LHASH_OF (CONF_VALUE)* conf,WOLFSSL_X509V3_CTX * ctx,int nid,char * value)11268 WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_conf_nid(
11269         WOLF_LHASH_OF(CONF_VALUE)* conf, WOLFSSL_X509V3_CTX* ctx, int nid,
11270         char* value)
11271 {
11272     WOLFSSL_STUB("wolfSSL_X509V3_EXT_conf_nid");
11273 
11274     if (conf != NULL) {
11275         WOLFSSL_MSG("Handling LHASH not implemented yet");
11276         return NULL;
11277     }
11278 
11279     (void)conf;
11280     (void)ctx;
11281     (void)nid;
11282     (void)value;
11283     return NULL;
11284 }
11285 
wolfSSL_X509V3_set_ctx_nodb(WOLFSSL_X509V3_CTX * ctx)11286 void wolfSSL_X509V3_set_ctx_nodb(WOLFSSL_X509V3_CTX* ctx)
11287 {
11288     WOLFSSL_STUB("wolfSSL_X509V3_set_ctx_nodb");
11289     (void)ctx;
11290 }
11291 #endif /* !NO_WOLFSSL_STUB */
11292 
11293 #ifdef OPENSSL_ALL
createExtFromStr(int nid,const char * value)11294 static WOLFSSL_X509_EXTENSION* createExtFromStr(int nid, const char *value) {
11295     WOLFSSL_X509_EXTENSION* ext = wolfSSL_X509_EXTENSION_new();
11296 
11297     if (ext == NULL) {
11298         WOLFSSL_MSG("memory error");
11299         return NULL;
11300     }
11301 
11302     if (value == NULL)
11303         return NULL;
11304 
11305     switch (nid) {
11306         case NID_subject_key_identifier:
11307         case NID_authority_key_identifier:
11308             if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
11309                     != WOLFSSL_SUCCESS) {
11310                 WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
11311                 goto err_cleanup;
11312             }
11313             ext->value.type = CTC_UTF8;
11314             break;
11315         case NID_subject_alt_name:
11316         {
11317             WOLFSSL_GENERAL_NAMES* gns = wolfSSL_sk_new_null();
11318             WOLFSSL_GENERAL_NAME* gn;
11319             if (gns == NULL) {
11320                 WOLFSSL_MSG("wolfSSL_sk_new_null error");
11321                 goto err_cleanup;
11322             }
11323             ext->ext_sk = gns; /* wolfSSL_X509_EXTENSION_free will handle
11324                                 * free'ing gns */
11325             gns->type = STACK_TYPE_GEN_NAME;
11326             gn = wolfSSL_GENERAL_NAME_new();
11327             if (gn == NULL) {
11328                 WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
11329                 goto err_cleanup;
11330             }
11331             if (wolfSSL_sk_GENERAL_NAME_push(gns, gn) != WOLFSSL_SUCCESS) {
11332                 WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
11333                 wolfSSL_GENERAL_NAME_free(gn);
11334                 goto err_cleanup;
11335             }
11336             if (wolfSSL_ASN1_STRING_set(gn->d.ia5, value, -1)
11337                     != WOLFSSL_SUCCESS) {
11338                 WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
11339                 goto err_cleanup;
11340             }
11341             gn->type = ASN_DNS_TYPE;
11342             break;
11343         }
11344         case NID_key_usage:
11345             if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
11346                     != WOLFSSL_SUCCESS) {
11347                 WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
11348                 goto err_cleanup;
11349             }
11350             ext->value.type = KEY_USAGE_OID;
11351             break;
11352         default:
11353             WOLFSSL_MSG("invalid or unsupported NID");
11354             goto err_cleanup;
11355     }
11356     return ext;
11357 err_cleanup:
11358     wolfSSL_X509_EXTENSION_free(ext);
11359     return NULL;
11360 }
11361 
11362 /**
11363  * Create a WOLFSSL_X509_EXTENSION from the input arguments.
11364  * @param conf  Not used
11365  * @param ctx   Not used
11366  * @param nid   Interprets the value parameter as the x509 extension that
11367  *              corresponds to this NID.
11368  * @param value A NULL terminated string that is taken as the value of the
11369  *              newly created extension object.
11370  * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
11371  */
wolfSSL_X509V3_EXT_nconf_nid(WOLFSSL_CONF * conf,WOLFSSL_X509V3_CTX * ctx,int nid,const char * value)11372 WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf_nid(WOLFSSL_CONF* conf,
11373         WOLFSSL_X509V3_CTX *ctx, int nid, const char *value)
11374 {
11375     WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf_nid");
11376 
11377     if (value == NULL) {
11378         WOLFSSL_MSG("value NULL parameter");
11379         return NULL;
11380     }
11381 
11382     if (conf != NULL || ctx != NULL) {
11383         WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf_nid does not handle either "
11384                     "conf or ctx parameters");
11385     }
11386 
11387     return createExtFromStr(nid, value);
11388 }
11389 
11390 /**
11391  * Create a WOLFSSL_X509_EXTENSION from the input arguments.
11392  * @param conf  Not used
11393  * @param ctx   Not used
11394  * @param sName The textual representation of the NID that the value parameter
11395  *              should be interpreted as.
11396  * @param value A NULL terminated string that is taken as the value of the
11397  *              newly created extension object.
11398  * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
11399  */
wolfSSL_X509V3_EXT_nconf(WOLFSSL_CONF * conf,WOLFSSL_X509V3_CTX * ctx,const char * sName,const char * value)11400 WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf(WOLFSSL_CONF *conf,
11401         WOLFSSL_X509V3_CTX *ctx, const char *sName, const char *value)
11402 {
11403     const WOLFSSL_ObjectInfo* info = wolfssl_object_info;
11404     size_t i;
11405 
11406     WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf");
11407 
11408     if (value == NULL) {
11409         WOLFSSL_MSG("value NULL parameter");
11410         return NULL;
11411     }
11412 
11413     if (conf != NULL || ctx != NULL) {
11414         WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf does not handle either "
11415                     "conf or ctx parameters");
11416     }
11417 
11418     for (i = 0; i < wolfssl_object_info_sz; i++, info++) {
11419         if (XSTRCMP(info->sName, sName) == 0)
11420             return createExtFromStr(info->nid, value);
11421     }
11422 
11423     WOLFSSL_MSG("value didn't match any known NID");
11424     return NULL;
11425 }
11426 
wolfSSL_X509V3_EXT_METHOD_populate(WOLFSSL_v3_ext_method * method,int nid)11427 static void wolfSSL_X509V3_EXT_METHOD_populate(WOLFSSL_v3_ext_method *method,
11428                                                int nid)
11429 {
11430     if (!method)
11431         return;
11432 
11433     WOLFSSL_ENTER("wolfSSL_X509V3_EXT_METHOD_populate");
11434     switch (nid) {
11435     case NID_subject_key_identifier:
11436         method->i2s = (X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
11437         FALL_THROUGH;
11438     case NID_authority_key_identifier:
11439     case NID_key_usage:
11440     case NID_certificate_policies:
11441     case NID_policy_mappings:
11442     case NID_subject_alt_name:
11443     case NID_issuer_alt_name:
11444     case NID_basic_constraints:
11445     case NID_name_constraints:
11446     case NID_policy_constraints:
11447     case NID_ext_key_usage:
11448     case NID_crl_distribution_points:
11449     case NID_inhibit_any_policy:
11450     case NID_info_access:
11451         WOLFSSL_MSG("Nothing to populate for current NID");
11452         break;
11453     default:
11454         WOLFSSL_MSG("Unknown or unsupported NID");
11455         break;
11456     }
11457 
11458     return;
11459 }
11460 
11461 /**
11462  * @param nid One of the NID_* constants defined in asn.h
11463  * @param crit
11464  * @param data This data is copied to the returned extension.
11465  * @return
11466  */
wolfSSL_X509V3_EXT_i2d(int nid,int crit,void * data)11467 WOLFSSL_X509_EXTENSION *wolfSSL_X509V3_EXT_i2d(int nid, int crit,
11468                                                void *data)
11469 {
11470     WOLFSSL_X509_EXTENSION *ext = NULL;
11471     WOLFSSL_ASN1_STRING* asn1str = NULL;
11472 
11473     WOLFSSL_ENTER("wolfSSL_X509V3_EXT_i2d");
11474 
11475     if (!data) {
11476         return NULL;
11477     }
11478 
11479     if (!(ext = wolfSSL_X509_EXTENSION_new())) {
11480         return NULL;
11481     }
11482 
11483     wolfSSL_X509V3_EXT_METHOD_populate(&ext->ext_method, nid);
11484 
11485     switch (nid) {
11486     case NID_subject_key_identifier:
11487         /* WOLFSSL_ASN1_STRING */
11488     case NID_key_usage:
11489         /* WOLFSSL_ASN1_STRING */
11490     {
11491         asn1str = (WOLFSSL_ASN1_STRING*)data;
11492         ext->value = *asn1str;
11493         if (asn1str->isDynamic) {
11494             ext->value.data = (char*)XMALLOC(asn1str->length, NULL,
11495                                              DYNAMIC_TYPE_OPENSSL);
11496             if (!ext->value.data) {
11497                 WOLFSSL_MSG("malloc failed");
11498                 /* Zero so that no existing memory is freed */
11499                 XMEMSET(&ext->value, 0, sizeof(WOLFSSL_ASN1_STRING));
11500                 goto err_cleanup;
11501             }
11502             XMEMCPY(ext->value.data, asn1str->data, asn1str->length);
11503         }
11504         else {
11505             ext->value.data = ext->value.strData;
11506         }
11507 
11508         if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
11509             WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
11510             goto err_cleanup;
11511         }
11512 
11513         break;
11514     }
11515     case NID_subject_alt_name:
11516         /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
11517     case NID_issuer_alt_name:
11518         /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
11519     case NID_ext_key_usage:
11520         /* typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE */
11521     case NID_info_access:
11522         /* typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS */
11523     {
11524         WOLFSSL_STACK* sk = (WOLFSSL_STACK*)data;
11525 
11526         if (ext->ext_sk) {
11527             wolfSSL_sk_pop_free(ext->ext_sk, NULL);
11528         }
11529 
11530         if (!(ext->ext_sk = wolfSSL_sk_dup(sk))) {
11531             WOLFSSL_MSG("wolfSSL_sk_dup failed");
11532             goto err_cleanup;
11533         }
11534         break;
11535     }
11536     case NID_basic_constraints:
11537     {
11538         /* WOLFSSL_BASIC_CONSTRAINTS */
11539         WOLFSSL_BASIC_CONSTRAINTS* bc = (WOLFSSL_BASIC_CONSTRAINTS*)data;
11540 
11541         if (!(ext->obj = wolfSSL_ASN1_OBJECT_new())) {
11542             WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
11543             goto err_cleanup;
11544         }
11545 
11546         ext->obj->ca = bc->ca;
11547         if (bc->pathlen) {
11548             ext->obj->pathlen = wolfSSL_ASN1_INTEGER_dup(bc->pathlen);
11549             if (!ext->obj->pathlen) {
11550                 WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_dup failed");
11551                 goto err_cleanup;
11552             }
11553         }
11554         break;
11555     }
11556     case NID_authority_key_identifier:
11557     {
11558         /* AUTHORITY_KEYID */
11559         WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)data;
11560 
11561         if (akey->keyid) {
11562             if (wolfSSL_ASN1_STRING_set(&ext->value, akey->keyid->data,
11563                                     akey->keyid->length) != WOLFSSL_SUCCESS) {
11564                 WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
11565                 goto err_cleanup;
11566             }
11567             ext->value.type = akey->keyid->type;
11568 
11569             if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
11570                 WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
11571                 goto err_cleanup;
11572             }
11573 
11574         }
11575         else if (akey->issuer) {
11576             ext->obj = wolfSSL_ASN1_OBJECT_dup(akey->issuer);
11577             if (!ext->obj) {
11578                 WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup failed");
11579                 goto err_cleanup;
11580             }
11581         }
11582         else {
11583             WOLFSSL_MSG("NID_authority_key_identifier empty data");
11584             goto err_cleanup;
11585         }
11586         break;
11587     }
11588     case NID_inhibit_any_policy:
11589         /* ASN1_INTEGER */
11590     case NID_certificate_policies:
11591         /* STACK_OF(POLICYINFO) */
11592     case NID_policy_mappings:
11593         /* STACK_OF(POLICY_MAPPING) */
11594     case NID_name_constraints:
11595         /* NAME_CONSTRAINTS */
11596     case NID_policy_constraints:
11597         /* POLICY_CONSTRAINTS */
11598     case NID_crl_distribution_points:
11599         /* typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS */
11600     default:
11601         WOLFSSL_MSG("Unknown or unsupported NID");
11602         break;
11603     }
11604 
11605     ext->crit = crit;
11606 
11607     return ext;
11608 err_cleanup:
11609     if (ext) {
11610         wolfSSL_X509_EXTENSION_free(ext);
11611     }
11612     if (asn1str) {
11613         wolfSSL_ASN1_STRING_free(asn1str);
11614     }
11615     return NULL;
11616 }
11617 
11618 /* Returns pointer to ASN1_OBJECT from an X509_EXTENSION object */
wolfSSL_X509_EXTENSION_get_object(WOLFSSL_X509_EXTENSION * ext)11619 WOLFSSL_ASN1_OBJECT* wolfSSL_X509_EXTENSION_get_object \
11620     (WOLFSSL_X509_EXTENSION* ext)
11621 {
11622     WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_object");
11623     if(ext == NULL)
11624         return NULL;
11625     return ext->obj;
11626 }
11627 
11628 
11629 /**
11630  * duplicates the 'obj' input and sets it into the 'ext' structure
11631  * returns WOLFSSL_SUCCESS on success
11632  */
wolfSSL_X509_EXTENSION_set_object(WOLFSSL_X509_EXTENSION * ext,const WOLFSSL_ASN1_OBJECT * obj)11633 int wolfSSL_X509_EXTENSION_set_object(WOLFSSL_X509_EXTENSION* ext,
11634         const WOLFSSL_ASN1_OBJECT* obj)
11635 {
11636     WOLFSSL_ASN1_OBJECT *current;
11637 
11638     WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_object");
11639     if (ext == NULL)
11640         return WOLFSSL_FAILURE;
11641 
11642     current = wolfSSL_X509_EXTENSION_get_object(ext);
11643     if (current != NULL) {
11644         wolfSSL_ASN1_OBJECT_free(current);
11645     }
11646     ext->obj = wolfSSL_ASN1_OBJECT_dup((WOLFSSL_ASN1_OBJECT*)obj);
11647     return WOLFSSL_SUCCESS;
11648 }
11649 #endif /* OPENSSL_ALL */
11650 
11651 /* Returns pointer to ASN1_STRING in X509_EXTENSION object */
wolfSSL_X509_EXTENSION_get_data(WOLFSSL_X509_EXTENSION * ext)11652 WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(WOLFSSL_X509_EXTENSION* ext)
11653 {
11654     WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_data");
11655     if (ext == NULL)
11656         return NULL;
11657     return &ext->value;
11658 }
11659 
11660 
11661 /**
11662  * Creates a duplicate of input 'data' and sets it into 'ext' structure
11663  * returns WOLFSSL_SUCCESS on success
11664  */
wolfSSL_X509_EXTENSION_set_data(WOLFSSL_X509_EXTENSION * ext,WOLFSSL_ASN1_STRING * data)11665 int wolfSSL_X509_EXTENSION_set_data(WOLFSSL_X509_EXTENSION* ext,
11666         WOLFSSL_ASN1_STRING* data)
11667 {
11668     WOLFSSL_ASN1_STRING* current;
11669 
11670     if (ext == NULL || data == NULL)
11671         return WOLFSSL_FAILURE;
11672 
11673     current = wolfSSL_X509_EXTENSION_get_data(ext);
11674     if (current->length > 0 && current->data != NULL && current->isDynamic) {
11675         XFREE(current->data, NULL, DYNAMIC_TYPE_OPENSSL);
11676     }
11677 
11678     return wolfSSL_ASN1_STRING_copy(&ext->value, data);
11679 }
11680 
11681 #if !defined(NO_PWDBASED)
wolfSSL_X509_digest(const WOLFSSL_X509 * x509,const WOLFSSL_EVP_MD * digest,unsigned char * buf,unsigned int * len)11682 int wolfSSL_X509_digest(const WOLFSSL_X509* x509, const WOLFSSL_EVP_MD* digest,
11683         unsigned char* buf, unsigned int* len)
11684 {
11685     int ret;
11686 
11687     WOLFSSL_ENTER("wolfSSL_X509_digest");
11688 
11689     if (x509 == NULL || digest == NULL) {
11690         WOLFSSL_MSG("Null argument found");
11691         return WOLFSSL_FAILURE;
11692     }
11693 
11694     if (x509->derCert == NULL) {
11695         WOLFSSL_MSG("No DER certificate stored in X509");
11696         return WOLFSSL_FAILURE;
11697     }
11698 
11699     ret = wolfSSL_EVP_Digest(x509->derCert->buffer, x509->derCert->length, buf,
11700                               len, digest, NULL);
11701     WOLFSSL_LEAVE("wolfSSL_X509_digest", ret);
11702     return ret;
11703 }
11704 
wolfSSL_X509_pubkey_digest(const WOLFSSL_X509 * x509,const WOLFSSL_EVP_MD * digest,unsigned char * buf,unsigned int * len)11705 int wolfSSL_X509_pubkey_digest(const WOLFSSL_X509 *x509,
11706         const WOLFSSL_EVP_MD *digest, unsigned char* buf, unsigned int* len)
11707 {
11708     int ret;
11709 
11710     WOLFSSL_ENTER("wolfSSL_X509_pubkey_digest");
11711 
11712     if (x509 == NULL || digest == NULL) {
11713         WOLFSSL_MSG("Null argument found");
11714         return WOLFSSL_FAILURE;
11715     }
11716 
11717     if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
11718         WOLFSSL_MSG("No DER public key stored in X509");
11719         return WOLFSSL_FAILURE;
11720     }
11721 
11722     ret = wolfSSL_EVP_Digest(x509->pubKey.buffer, x509->pubKey.length, buf,
11723                               len, digest, NULL);
11724     WOLFSSL_LEAVE("wolfSSL_X509_pubkey_digest", ret);
11725     return ret;
11726 }
11727 #endif
11728 
wolfSSL_use_PrivateKey(WOLFSSL * ssl,WOLFSSL_EVP_PKEY * pkey)11729 int wolfSSL_use_PrivateKey(WOLFSSL* ssl, WOLFSSL_EVP_PKEY* pkey)
11730 {
11731     WOLFSSL_ENTER("wolfSSL_use_PrivateKey");
11732     if (ssl == NULL || pkey == NULL ) {
11733         return WOLFSSL_FAILURE;
11734     }
11735 
11736     return wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)pkey->pkey.ptr,
11737                                          pkey->pkey_sz, WOLFSSL_FILETYPE_ASN1);
11738 }
11739 
11740 
wolfSSL_use_PrivateKey_ASN1(int pri,WOLFSSL * ssl,const unsigned char * der,long derSz)11741 int wolfSSL_use_PrivateKey_ASN1(int pri, WOLFSSL* ssl, const unsigned char* der,
11742                                 long derSz)
11743 {
11744     WOLFSSL_ENTER("wolfSSL_use_PrivateKey_ASN1");
11745     if (ssl == NULL || der == NULL ) {
11746         return WOLFSSL_FAILURE;
11747     }
11748 
11749     (void)pri; /* type of private key */
11750     return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, WOLFSSL_FILETYPE_ASN1);
11751 }
11752 /******************************************************************************
11753 * wolfSSL_CTX_use_PrivateKey_ASN1 - loads a private key buffer into the SSL ctx
11754 *
11755 * RETURNS:
11756 * returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
11757 */
11758 
wolfSSL_CTX_use_PrivateKey_ASN1(int pri,WOLFSSL_CTX * ctx,unsigned char * der,long derSz)11759 int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx,
11760                                             unsigned char* der, long derSz)
11761 {
11762     WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_ASN1");
11763     if (ctx == NULL || der == NULL ) {
11764         return WOLFSSL_FAILURE;
11765     }
11766 
11767     (void)pri; /* type of private key */
11768     return wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz, WOLFSSL_FILETYPE_ASN1);
11769 }
11770 
11771 
11772 #ifndef NO_RSA
wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL * ssl,unsigned char * der,long derSz)11773 int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, long derSz)
11774 {
11775     WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_ASN1");
11776     if (ssl == NULL || der == NULL ) {
11777         return WOLFSSL_FAILURE;
11778     }
11779 
11780     return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, WOLFSSL_FILETYPE_ASN1);
11781 }
11782 #endif
11783 
wolfSSL_use_certificate(WOLFSSL * ssl,WOLFSSL_X509 * x509)11784 int wolfSSL_use_certificate(WOLFSSL* ssl, WOLFSSL_X509* x509)
11785 {
11786     long idx;
11787 
11788     WOLFSSL_ENTER("wolfSSL_use_certificate");
11789     if (x509 != NULL && ssl != NULL && x509->derCert != NULL) {
11790         if (ProcessBuffer(NULL, x509->derCert->buffer, x509->derCert->length,
11791                           WOLFSSL_FILETYPE_ASN1, CERT_TYPE, ssl, &idx, 0,
11792                           GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
11793             return WOLFSSL_SUCCESS;
11794         }
11795     }
11796 
11797     (void)idx;
11798     return WOLFSSL_FAILURE;
11799 }
11800 
11801 #endif /* NO_CERTS */
11802 
11803 #endif /* OPENSSL_EXTRA */
11804 
11805 #ifndef NO_CERTS
wolfSSL_use_certificate_ASN1(WOLFSSL * ssl,const unsigned char * der,int derSz)11806 int wolfSSL_use_certificate_ASN1(WOLFSSL* ssl, const unsigned char* der,
11807                                  int derSz)
11808 {
11809     long idx;
11810 
11811     WOLFSSL_ENTER("wolfSSL_use_certificate_ASN1");
11812     if (der != NULL && ssl != NULL) {
11813         if (ProcessBuffer(NULL, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
11814                 ssl, &idx, 0, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
11815             return WOLFSSL_SUCCESS;
11816         }
11817     }
11818 
11819     (void)idx;
11820     return WOLFSSL_FAILURE;
11821 }
11822 
11823 #ifndef NO_FILESYSTEM
11824 
11825 WOLFSSL_ABI
wolfSSL_use_certificate_file(WOLFSSL * ssl,const char * file,int format)11826 int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
11827 {
11828     WOLFSSL_ENTER("wolfSSL_use_certificate_file");
11829 
11830     if (ssl == NULL) {
11831         return BAD_FUNC_ARG;
11832     }
11833 
11834     if (ProcessFile(ssl->ctx, file, format, CERT_TYPE,
11835                 ssl, 0, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
11836         return WOLFSSL_SUCCESS;
11837     }
11838 
11839     return WOLFSSL_FAILURE;
11840 }
11841 
11842 
11843 WOLFSSL_ABI
wolfSSL_use_PrivateKey_file(WOLFSSL * ssl,const char * file,int format)11844 int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
11845 {
11846     WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
11847 
11848     if (ssl == NULL) {
11849         return BAD_FUNC_ARG;
11850     }
11851 
11852     if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE,
11853                 ssl, 0, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
11854         return WOLFSSL_SUCCESS;
11855     }
11856 
11857     return WOLFSSL_FAILURE;
11858 }
11859 
11860 
11861 WOLFSSL_ABI
wolfSSL_use_certificate_chain_file(WOLFSSL * ssl,const char * file)11862 int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
11863 {
11864     /* process up to MAX_CHAIN_DEPTH plus subject cert */
11865     WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
11866 
11867     if (ssl == NULL) {
11868         return BAD_FUNC_ARG;
11869     }
11870 
11871     if (ProcessFile(ssl->ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE,
11872                ssl, 1, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
11873         return WOLFSSL_SUCCESS;
11874     }
11875 
11876    return WOLFSSL_FAILURE;
11877 }
11878 
wolfSSL_use_certificate_chain_file_format(WOLFSSL * ssl,const char * file,int format)11879 int wolfSSL_use_certificate_chain_file_format(WOLFSSL* ssl, const char* file,
11880                                               int format)
11881 {
11882     /* process up to MAX_CHAIN_DEPTH plus subject cert */
11883     WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file_format");
11884 
11885     if (ssl == NULL) {
11886         return BAD_FUNC_ARG;
11887     }
11888 
11889     if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 1,
11890                     NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
11891         return WOLFSSL_SUCCESS;
11892     }
11893     return WOLFSSL_FAILURE;
11894 }
11895 
11896 #endif /* !NO_FILESYSTEM */
11897 #endif /* !NO_CERTS */
11898 
11899 #ifdef HAVE_ECC
11900 
11901 /* Set Temp CTX EC-DHE size in octets, can be 14 - 66 (112 - 521 bit) */
wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX * ctx,word16 sz)11902 int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
11903 {
11904     if (ctx == NULL)
11905         return BAD_FUNC_ARG;
11906 
11907     /* if 0 then get from loaded private key */
11908     if (sz == 0) {
11909         /* applies only to ECDSA */
11910         if (ctx->privateKeyType != ecc_dsa_sa_algo)
11911             return WOLFSSL_SUCCESS;
11912 
11913         if (ctx->privateKeySz == 0) {
11914             WOLFSSL_MSG("Must set private key/cert first");
11915             return BAD_FUNC_ARG;
11916         }
11917 
11918         sz = (word16)ctx->privateKeySz;
11919     }
11920 
11921     /* check size */
11922     if (sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
11923         return BAD_FUNC_ARG;
11924 
11925     ctx->eccTempKeySz = sz;
11926 
11927     return WOLFSSL_SUCCESS;
11928 }
11929 
11930 
11931 /* Set Temp SSL EC-DHE size in octets, can be 14 - 66 (112 - 521 bit) */
wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL * ssl,word16 sz)11932 int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
11933 {
11934     if (ssl == NULL)
11935         return BAD_FUNC_ARG;
11936 
11937     /* check size */
11938     if (sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
11939         return BAD_FUNC_ARG;
11940 
11941     ssl->eccTempKeySz = sz;
11942 
11943     return WOLFSSL_SUCCESS;
11944 }
11945 
11946 #endif /* HAVE_ECC */
11947 
11948 
11949 #ifdef OPENSSL_EXTRA
11950 
11951 #ifndef NO_FILESYSTEM
wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX * ctx,const char * file,int format)11952 int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
11953                                    int format)
11954 {
11955     WOLFSSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
11956 
11957     return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
11958 }
11959 
11960 
wolfSSL_use_RSAPrivateKey_file(WOLFSSL * ssl,const char * file,int format)11961 int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
11962 {
11963     WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
11964 
11965     return wolfSSL_use_PrivateKey_file(ssl, file, format);
11966 }
11967 #endif /* NO_FILESYSTEM */
11968 
11969 
11970 /* Copies the master secret over to out buffer. If outSz is 0 returns the size
11971  * of master secret.
11972  *
11973  * ses : a session from completed TLS/SSL handshake
11974  * out : buffer to hold copy of master secret
11975  * outSz : size of out buffer
11976  * returns : number of bytes copied into out buffer on success
11977  *           less then or equal to 0 is considered a failure case
11978  */
wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION * ses,unsigned char * out,int outSz)11979 int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses,
11980         unsigned char* out, int outSz)
11981 {
11982     int size;
11983 
11984     if (outSz == 0) {
11985         return SECRET_LEN;
11986     }
11987 
11988     if (ses == NULL || out == NULL || outSz < 0) {
11989         return 0;
11990     }
11991 
11992     if (outSz > SECRET_LEN) {
11993         size = SECRET_LEN;
11994     }
11995     else {
11996         size = outSz;
11997     }
11998 
11999     XMEMCPY(out, ses->masterSecret, size);
12000     return size;
12001 }
12002 
12003 
wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION * ses)12004 int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses)
12005 {
12006     (void)ses;
12007     return SECRET_LEN;
12008 }
12009 
12010 #endif /* OPENSSL_EXTRA */
12011 
12012 WOLFSSL_ABI
wolfSSL_CTX_set_verify(WOLFSSL_CTX * ctx,int mode,VerifyCallback vc)12013 void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
12014 {
12015     WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
12016     if (ctx == NULL)
12017         return;
12018 
12019     ctx->verifyPeer     = 0;
12020     ctx->verifyNone     = 0;
12021     ctx->failNoCert     = 0;
12022     ctx->failNoCertxPSK = 0;
12023 #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
12024     ctx->verifyPostHandshake = 0;
12025 #endif
12026 
12027     if (mode != WOLFSSL_VERIFY_DEFAULT) {
12028         if (mode == WOLFSSL_VERIFY_NONE) {
12029             ctx->verifyNone = 1;
12030         }
12031         else {
12032             if (mode & WOLFSSL_VERIFY_PEER) {
12033                 ctx->verifyPeer = 1;
12034             }
12035             if (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) {
12036                 ctx->failNoCertxPSK = 1;
12037             }
12038             if (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
12039                 ctx->failNoCert = 1;
12040             }
12041 #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
12042             if (mode & WOLFSSL_VERIFY_POST_HANDSHAKE) {
12043                 ctx->verifyPostHandshake = 1;
12044             }
12045 #endif
12046         }
12047     }
12048 
12049     ctx->verifyCallback = vc;
12050 }
12051 
12052 #ifdef OPENSSL_ALL
wolfSSL_CTX_set_cert_verify_callback(WOLFSSL_CTX * ctx,CertVerifyCallback cb,void * arg)12053 void wolfSSL_CTX_set_cert_verify_callback(WOLFSSL_CTX* ctx,
12054     CertVerifyCallback cb, void* arg)
12055 {
12056     WOLFSSL_ENTER("SSL_CTX_set_cert_verify_callback");
12057     if (ctx == NULL)
12058         return;
12059 
12060     ctx->verifyCertCb = cb;
12061     ctx->verifyCertCbArg = arg;
12062 }
12063 #endif
12064 
12065 
wolfSSL_set_verify(WOLFSSL * ssl,int mode,VerifyCallback vc)12066 void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
12067 {
12068     WOLFSSL_ENTER("wolfSSL_set_verify");
12069     if (ssl == NULL)
12070         return;
12071 
12072     /* Special case for verifyNone since WOLFSSL_VERIFY_NONE == 0  */
12073     ssl->options.verifyNone     =  mode == WOLFSSL_VERIFY_NONE;
12074     ssl->options.verifyPeer     = (mode & WOLFSSL_VERIFY_PEER)
12075                                         == WOLFSSL_VERIFY_PEER;
12076     ssl->options.failNoCert     = (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT)
12077                                         == WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
12078     ssl->options.failNoCertxPSK = (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK)
12079                                         == WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
12080 #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
12081     ssl->options.verifyPostHandshake = (mode & WOLFSSL_VERIFY_POST_HANDSHAKE)
12082                                         == WOLFSSL_VERIFY_POST_HANDSHAKE;
12083 #endif
12084 
12085     ssl->verifyCallback = vc;
12086 }
12087 
wolfSSL_set_verify_result(WOLFSSL * ssl,long v)12088 void wolfSSL_set_verify_result(WOLFSSL *ssl, long v)
12089 {
12090     WOLFSSL_ENTER("wolfSSL_set_verify_result");
12091 
12092     if (ssl == NULL)
12093         return;
12094 
12095 #ifdef OPENSSL_ALL
12096     ssl->verifyCallbackResult = v;
12097 #else
12098     (void)v;
12099     WOLFSSL_STUB("wolfSSL_set_verify_result");
12100 #endif
12101 }
12102 
12103 #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
12104     defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
12105 /* For TLS v1.3 send handshake messages after handshake completes. */
12106 /* Returns 1=WOLFSSL_SUCCESS or 0=WOLFSSL_FAILURE */
wolfSSL_verify_client_post_handshake(WOLFSSL * ssl)12107 int wolfSSL_verify_client_post_handshake(WOLFSSL* ssl)
12108 {
12109     int ret = wolfSSL_request_certificate(ssl);
12110     if (ret != WOLFSSL_SUCCESS) {
12111         if (!IsAtLeastTLSv1_3(ssl->version)) {
12112             /* specific error of wrong version expected */
12113             WOLFSSL_ERROR(UNSUPPORTED_PROTO_VERSION);
12114 
12115         }
12116         else {
12117             WOLFSSL_ERROR(ret); /* log the error in the error queue */
12118         }
12119     }
12120     return (ret == WOLFSSL_SUCCESS) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
12121 }
12122 
wolfSSL_CTX_set_post_handshake_auth(WOLFSSL_CTX * ctx,int val)12123 int wolfSSL_CTX_set_post_handshake_auth(WOLFSSL_CTX* ctx, int val)
12124 {
12125     int ret = wolfSSL_CTX_allow_post_handshake_auth(ctx);
12126     if (ret == 0) {
12127         ctx->postHandshakeAuth = (val != 0);
12128     }
12129     return (ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
12130 }
wolfSSL_set_post_handshake_auth(WOLFSSL * ssl,int val)12131 int wolfSSL_set_post_handshake_auth(WOLFSSL* ssl, int val)
12132 {
12133     int ret = wolfSSL_allow_post_handshake_auth(ssl);
12134     if (ret == 0) {
12135         ssl->options.postHandshakeAuth = (val != 0);
12136     }
12137     return (ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
12138 }
12139 #endif /* OPENSSL_EXTRA && !NO_CERTS && WOLFSSL_TLS13 && WOLFSSL_POST_HANDSHAKE_AUTH */
12140 
12141 /* store user ctx for verify callback */
wolfSSL_SetCertCbCtx(WOLFSSL * ssl,void * ctx)12142 void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
12143 {
12144     WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
12145     if (ssl)
12146         ssl->verifyCbCtx = ctx;
12147 }
12148 
12149 
12150 /* store context CA Cache addition callback */
wolfSSL_CTX_SetCACb(WOLFSSL_CTX * ctx,CallbackCACache cb)12151 void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
12152 {
12153     if (ctx && ctx->cm)
12154         ctx->cm->caCacheCallback = cb;
12155 }
12156 
12157 
12158 #if defined(PERSIST_CERT_CACHE)
12159 
12160 #if !defined(NO_FILESYSTEM)
12161 
12162 /* Persist cert cache to file */
wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX * ctx,const char * fname)12163 int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
12164 {
12165     WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
12166 
12167     if (ctx == NULL || fname == NULL)
12168         return BAD_FUNC_ARG;
12169 
12170     return CM_SaveCertCache(ctx->cm, fname);
12171 }
12172 
12173 
12174 /* Persist cert cache from file */
wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX * ctx,const char * fname)12175 int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
12176 {
12177     WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
12178 
12179     if (ctx == NULL || fname == NULL)
12180         return BAD_FUNC_ARG;
12181 
12182     return CM_RestoreCertCache(ctx->cm, fname);
12183 }
12184 
12185 #endif /* NO_FILESYSTEM */
12186 
12187 /* Persist cert cache to memory */
wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX * ctx,void * mem,int sz,int * used)12188 int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem,
12189                                    int sz, int* used)
12190 {
12191     WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
12192 
12193     if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
12194         return BAD_FUNC_ARG;
12195 
12196     return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
12197 }
12198 
12199 
12200 /* Restore cert cache from memory */
wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX * ctx,const void * mem,int sz)12201 int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
12202 {
12203     WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
12204 
12205     if (ctx == NULL || mem == NULL || sz <= 0)
12206         return BAD_FUNC_ARG;
12207 
12208     return CM_MemRestoreCertCache(ctx->cm, mem, sz);
12209 }
12210 
12211 
12212 /* get how big the the cert cache save buffer needs to be */
wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX * ctx)12213 int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
12214 {
12215     WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
12216 
12217     if (ctx == NULL)
12218         return BAD_FUNC_ARG;
12219 
12220     return CM_GetCertCacheMemSize(ctx->cm);
12221 }
12222 
12223 #endif /* PERSIST_CERT_CACHE */
12224 #endif /* !NO_CERTS */
12225 
12226 
12227 #ifndef NO_SESSION_CACHE
12228 
12229 WOLFSSL_ABI
wolfSSL_get_session(WOLFSSL * ssl)12230 WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
12231 {
12232     WOLFSSL_ENTER("SSL_get_session");
12233     if (ssl)
12234         return GetSession(ssl, NULL, 1);
12235 
12236     return NULL;
12237 }
12238 
12239 /* The get1 version requires caller to call SSL_SESSION_free */
wolfSSL_get1_session(WOLFSSL * ssl)12240 WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)
12241 {
12242     WOLFSSL_SESSION* sess = NULL;
12243     if (ssl != NULL) {
12244         sess = GetSessionRef(ssl);
12245         if (sess != NULL) {
12246             /* wolfSSL_get_session returns either static cache or ref. If ref then
12247             * increase reference counter */
12248             /* increase reference count if allocated session */
12249         #ifdef ENABLE_CLIENT_SESSION_REF
12250             if (sess->type == WOLFSSL_SESSION_TYPE_REF) {
12251                 sess->refCount++;
12252             }
12253         #endif
12254         }
12255     }
12256     return sess;
12257 }
12258 
12259 
12260 /*
12261  * Sets the session object to use when establishing a TLS/SSL session using
12262  * the ssl object. Therefore, this function must be called before
12263  * wolfSSL_connect. The session object to use can be obtained in a previous
12264  * TLS/SSL connection using wolfSSL_get_session.
12265  *
12266  * This function rejects the session if it has been expired when this function
12267  * is called. Note that this expiration check is wolfSSL specific and differs
12268  * from OpenSSL return code behavior.
12269  *
12270  * By default, wolfSSL_set_session returns WOLFSSL_SUCCESS on successfully
12271  * setting the session, WOLFSSL_FAILURE on failure due to the session cache
12272  * being disabled, or the session has expired.
12273  *
12274  * To match OpenSSL return code behavior when session is expired, define
12275  * OPENSSL_EXTRA and WOLFSSL_ERROR_CODE_OPENSSL. This behavior will return
12276  * WOLFSSL_SUCCESS even when the session is expired and rejected.
12277  */
12278 WOLFSSL_ABI
wolfSSL_set_session(WOLFSSL * ssl,WOLFSSL_SESSION * session)12279 int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session)
12280 {
12281     WOLFSSL_ENTER("SSL_set_session");
12282     if (session)
12283         return SetSession(ssl, session);
12284 
12285     return WOLFSSL_FAILURE;
12286 }
12287 
12288 
12289 #ifndef NO_CLIENT_CACHE
12290 
12291 /* Associate client session with serverID, find existing or store for saving
12292    if newSession flag on, don't reuse existing session
12293    WOLFSSL_SUCCESS on ok */
wolfSSL_SetServerID(WOLFSSL * ssl,const byte * id,int len,int newSession)12294 int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
12295 {
12296     WOLFSSL_SESSION* session = NULL;
12297 
12298     WOLFSSL_ENTER("wolfSSL_SetServerID");
12299 
12300     if (ssl == NULL || id == NULL || len <= 0)
12301         return BAD_FUNC_ARG;
12302 
12303     if (newSession == 0) {
12304         session = GetSessionClient(ssl, id, len);
12305         if (session) {
12306             if (SetSession(ssl, session) != WOLFSSL_SUCCESS) {
12307             #ifdef HAVE_EXT_CACHE
12308                 FreeSession(session);
12309             #endif
12310                 WOLFSSL_MSG("SetSession failed");
12311                 session = NULL;
12312             }
12313         }
12314     }
12315 
12316     if (session == NULL) {
12317         WOLFSSL_MSG("Valid ServerID not cached already");
12318 
12319         ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
12320         XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
12321     }
12322 #ifdef HAVE_EXT_CACHE
12323     else {
12324         FreeSession(session);
12325     }
12326 #endif
12327 
12328     return WOLFSSL_SUCCESS;
12329 }
12330 
12331 #endif /* !NO_CLIENT_CACHE */
12332 
12333 #if defined(PERSIST_SESSION_CACHE)
12334 
12335 /* for persistence, if changes to layout need to increment and modify
12336    save_session_cache() and restore_session_cache and memory versions too */
12337 #define WOLFSSL_CACHE_VERSION 2
12338 
12339 /* Session Cache Header information */
12340 typedef struct {
12341     int version;     /* cache layout version id */
12342     int rows;        /* session rows */
12343     int columns;     /* session columns */
12344     int sessionSz;   /* sizeof WOLFSSL_SESSION */
12345 } cache_header_t;
12346 
12347 /* current persistence layout is:
12348 
12349    1) cache_header_t
12350    2) SessionCache
12351    3) ClientCache
12352 
12353    update WOLFSSL_CACHE_VERSION if change layout for the following
12354    PERSISTENT_SESSION_CACHE functions
12355 */
12356 
12357 
12358 /* get how big the the session cache save buffer needs to be */
wolfSSL_get_session_cache_memsize(void)12359 int wolfSSL_get_session_cache_memsize(void)
12360 {
12361     int sz  = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
12362 #ifndef NO_CLIENT_CACHE
12363     sz += (int)(sizeof(ClientCache));
12364 #endif
12365     return sz;
12366 }
12367 
12368 
12369 /* Persist session cache to memory */
wolfSSL_memsave_session_cache(void * mem,int sz)12370 int wolfSSL_memsave_session_cache(void* mem, int sz)
12371 {
12372     int i;
12373     cache_header_t cache_header;
12374     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
12375 #ifndef NO_CLIENT_CACHE
12376     ClientRow*     clRow;
12377 #endif
12378 
12379     WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
12380 
12381     if (sz < wolfSSL_get_session_cache_memsize()) {
12382         WOLFSSL_MSG("Memory buffer too small");
12383         return BUFFER_E;
12384     }
12385 
12386     cache_header.version   = WOLFSSL_CACHE_VERSION;
12387     cache_header.rows      = SESSION_ROWS;
12388     cache_header.columns   = SESSIONS_PER_ROW;
12389     cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
12390     XMEMCPY(mem, &cache_header, sizeof(cache_header));
12391 
12392 #ifndef ENABLE_SESSION_CACHE_ROW_LOCK
12393     if (wc_LockMutex(&session_mutex) != 0) {
12394         WOLFSSL_MSG("Session cache mutex lock failed");
12395         return BAD_MUTEX_E;
12396     }
12397 #endif
12398     for (i = 0; i < cache_header.rows; ++i) {
12399     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
12400         if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
12401             WOLFSSL_MSG("Session row cache mutex lock failed");
12402             return BAD_MUTEX_E;
12403         }
12404     #endif
12405 
12406         XMEMCPY(row++, &SessionCache[i], SIZEOF_SESSION_ROW);
12407     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
12408         SESSION_ROW_UNLOCK(&SessionCache[i]);
12409     #endif
12410     }
12411 #ifndef ENABLE_SESSION_CACHE_ROW_LOCK
12412     wc_UnLockMutex(&session_mutex);
12413 #endif
12414 
12415 #ifndef NO_CLIENT_CACHE
12416     if (wc_LockMutex(&clisession_mutex) != 0) {
12417         WOLFSSL_MSG("Client cache mutex lock failed");
12418         return BAD_MUTEX_E;
12419     }
12420 
12421     clRow = (ClientRow*)row;
12422     for (i = 0; i < cache_header.rows; ++i) {
12423         XMEMCPY(clRow++, ClientCache + i, sizeof(ClientRow));
12424     }
12425     wc_UnLockMutex(&clisession_mutex);
12426 #endif
12427 
12428     WOLFSSL_LEAVE("wolfSSL_memsave_session_cache", WOLFSSL_SUCCESS);
12429 
12430     return WOLFSSL_SUCCESS;
12431 }
12432 
12433 
12434 /* Restore the persistent session cache from memory */
wolfSSL_memrestore_session_cache(const void * mem,int sz)12435 int wolfSSL_memrestore_session_cache(const void* mem, int sz)
12436 {
12437     int    i;
12438     cache_header_t cache_header;
12439     SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
12440 #ifndef NO_CLIENT_CACHE
12441     ClientRow*     clRow;
12442 #endif
12443 
12444     WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
12445 
12446     if (sz < wolfSSL_get_session_cache_memsize()) {
12447         WOLFSSL_MSG("Memory buffer too small");
12448         return BUFFER_E;
12449     }
12450 
12451     XMEMCPY(&cache_header, mem, sizeof(cache_header));
12452     if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
12453         cache_header.rows      != SESSION_ROWS ||
12454         cache_header.columns   != SESSIONS_PER_ROW ||
12455         cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
12456 
12457         WOLFSSL_MSG("Session cache header match failed");
12458         return CACHE_MATCH_ERROR;
12459     }
12460 
12461 #ifndef ENABLE_SESSION_CACHE_ROW_LOCK
12462     if (wc_LockMutex(&session_mutex) != 0) {
12463         WOLFSSL_MSG("Session cache mutex lock failed");
12464         return BAD_MUTEX_E;
12465     }
12466 #endif
12467     for (i = 0; i < cache_header.rows; ++i) {
12468     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
12469         if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
12470             WOLFSSL_MSG("Session row cache mutex lock failed");
12471             return BAD_MUTEX_E;
12472         }
12473     #endif
12474 
12475         XMEMCPY(&SessionCache[i], row++, SIZEOF_SESSION_ROW);
12476     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
12477         SESSION_ROW_UNLOCK(&SessionCache[i]);
12478     #endif
12479     }
12480 #ifndef ENABLE_SESSION_CACHE_ROW_LOCK
12481     wc_UnLockMutex(&session_mutex);
12482 #endif
12483 
12484 #ifndef NO_CLIENT_CACHE
12485     if (wc_LockMutex(&clisession_mutex) != 0) {
12486         WOLFSSL_MSG("Client cache mutex lock failed");
12487         return BAD_MUTEX_E;
12488     }
12489 
12490     clRow = (ClientRow*)row;
12491     for (i = 0; i < cache_header.rows; ++i) {
12492         XMEMCPY(ClientCache + i, clRow++, sizeof(ClientRow));
12493     }
12494     wc_UnLockMutex(&clisession_mutex);
12495 #endif
12496 
12497     WOLFSSL_LEAVE("wolfSSL_memrestore_session_cache", WOLFSSL_SUCCESS);
12498 
12499     return WOLFSSL_SUCCESS;
12500 }
12501 
12502 #if !defined(NO_FILESYSTEM)
12503 
12504 /* Persist session cache to file */
12505 /* doesn't use memsave because of additional memory use */
wolfSSL_save_session_cache(const char * fname)12506 int wolfSSL_save_session_cache(const char *fname)
12507 {
12508     XFILE  file;
12509     int    ret;
12510     int    rc = WOLFSSL_SUCCESS;
12511     int    i;
12512     cache_header_t cache_header;
12513 
12514     WOLFSSL_ENTER("wolfSSL_save_session_cache");
12515 
12516     file = XFOPEN(fname, "w+b");
12517     if (file == XBADFILE) {
12518         WOLFSSL_MSG("Couldn't open session cache save file");
12519         return WOLFSSL_BAD_FILE;
12520     }
12521     cache_header.version   = WOLFSSL_CACHE_VERSION;
12522     cache_header.rows      = SESSION_ROWS;
12523     cache_header.columns   = SESSIONS_PER_ROW;
12524     cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
12525 
12526     /* cache header */
12527     ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
12528     if (ret != 1) {
12529         WOLFSSL_MSG("Session cache header file write failed");
12530         XFCLOSE(file);
12531         return FWRITE_ERROR;
12532     }
12533 
12534 #ifndef ENABLE_SESSION_CACHE_ROW_LOCK
12535     if (wc_LockMutex(&session_mutex) != 0) {
12536         WOLFSSL_MSG("Session cache mutex lock failed");
12537         XFCLOSE(file);
12538         return BAD_MUTEX_E;
12539     }
12540 #endif
12541     /* session cache */
12542     for (i = 0; i < cache_header.rows; ++i) {
12543     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
12544         if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
12545             WOLFSSL_MSG("Session row cache mutex lock failed");
12546             XFCLOSE(file);
12547             return BAD_MUTEX_E;
12548         }
12549     #endif
12550 
12551         ret = (int)XFWRITE(&SessionCache[i], SIZEOF_SESSION_ROW, 1, file);
12552     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
12553         SESSION_ROW_UNLOCK(&SessionCache[i]);
12554     #endif
12555         if (ret != 1) {
12556             WOLFSSL_MSG("Session cache member file write failed");
12557             rc = FWRITE_ERROR;
12558             break;
12559         }
12560     }
12561 #ifndef ENABLE_SESSION_CACHE_ROW_LOCK
12562     wc_UnLockMutex(&session_mutex);
12563 #endif
12564 
12565 #ifndef NO_CLIENT_CACHE
12566     /* client cache */
12567     if (wc_LockMutex(&clisession_mutex) != 0) {
12568         WOLFSSL_MSG("Client cache mutex lock failed");
12569         XFCLOSE(file);
12570         return BAD_MUTEX_E;
12571     }
12572 
12573     for (i = 0; i < cache_header.rows; ++i) {
12574         ret = (int)XFWRITE(ClientCache + i, sizeof(ClientRow), 1, file);
12575         if (ret != 1) {
12576             WOLFSSL_MSG("Client cache member file write failed");
12577             rc = FWRITE_ERROR;
12578             break;
12579         }
12580     }
12581     wc_UnLockMutex(&clisession_mutex);
12582 #endif /* !NO_CLIENT_CACHE */
12583 
12584     XFCLOSE(file);
12585     WOLFSSL_LEAVE("wolfSSL_save_session_cache", rc);
12586 
12587     return rc;
12588 }
12589 
12590 
12591 /* Restore the persistent session cache from file */
12592 /* doesn't use memstore because of additional memory use */
wolfSSL_restore_session_cache(const char * fname)12593 int wolfSSL_restore_session_cache(const char *fname)
12594 {
12595     XFILE  file;
12596     int    rc = WOLFSSL_SUCCESS;
12597     int    ret;
12598     int    i;
12599     cache_header_t cache_header;
12600 
12601     WOLFSSL_ENTER("wolfSSL_restore_session_cache");
12602 
12603     file = XFOPEN(fname, "rb");
12604     if (file == XBADFILE) {
12605         WOLFSSL_MSG("Couldn't open session cache save file");
12606         return WOLFSSL_BAD_FILE;
12607     }
12608     /* cache header */
12609     ret = (int)XFREAD(&cache_header, sizeof(cache_header), 1, file);
12610     if (ret != 1) {
12611         WOLFSSL_MSG("Session cache header file read failed");
12612         XFCLOSE(file);
12613         return FREAD_ERROR;
12614     }
12615     if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
12616         cache_header.rows      != SESSION_ROWS ||
12617         cache_header.columns   != SESSIONS_PER_ROW ||
12618         cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
12619 
12620         WOLFSSL_MSG("Session cache header match failed");
12621         XFCLOSE(file);
12622         return CACHE_MATCH_ERROR;
12623     }
12624 
12625 #ifndef ENABLE_SESSION_CACHE_ROW_LOCK
12626     if (wc_LockMutex(&session_mutex) != 0) {
12627         WOLFSSL_MSG("Session cache mutex lock failed");
12628         XFCLOSE(file);
12629         return BAD_MUTEX_E;
12630     }
12631 #endif
12632     /* session cache */
12633     for (i = 0; i < cache_header.rows; ++i) {
12634     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
12635         if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
12636             WOLFSSL_MSG("Session row cache mutex lock failed");
12637             XFCLOSE(file);
12638             return BAD_MUTEX_E;
12639         }
12640     #endif
12641 
12642         ret = (int)XFREAD(&SessionCache[i], SIZEOF_SESSION_ROW, 1, file);
12643     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
12644         SESSION_ROW_UNLOCK(&SessionCache[i]);
12645     #endif
12646         if (ret != 1) {
12647             WOLFSSL_MSG("Session cache member file read failed");
12648             XMEMSET(SessionCache, 0, sizeof SessionCache);
12649             rc = FREAD_ERROR;
12650             break;
12651         }
12652     }
12653 #ifndef ENABLE_SESSION_CACHE_ROW_LOCK
12654     wc_UnLockMutex(&session_mutex);
12655 #endif
12656 
12657 #ifndef NO_CLIENT_CACHE
12658     /* client cache */
12659     if (wc_LockMutex(&clisession_mutex) != 0) {
12660         WOLFSSL_MSG("Client cache mutex lock failed");
12661         XFCLOSE(file);
12662         return BAD_MUTEX_E;
12663     }
12664     for (i = 0; i < cache_header.rows; ++i) {
12665         ret = (int)XFREAD(ClientCache + i, sizeof(ClientRow), 1, file);
12666         if (ret != 1) {
12667             WOLFSSL_MSG("Client cache member file read failed");
12668             XMEMSET(ClientCache, 0, sizeof ClientCache);
12669             rc = FREAD_ERROR;
12670             break;
12671         }
12672     }
12673     wc_UnLockMutex(&clisession_mutex);
12674 #endif /* !NO_CLIENT_CACHE */
12675 
12676     XFCLOSE(file);
12677     WOLFSSL_LEAVE("wolfSSL_restore_session_cache", rc);
12678 
12679     return rc;
12680 }
12681 
12682 #endif /* !NO_FILESYSTEM */
12683 #endif /* PERSIST_SESSION_CACHE */
12684 #endif /* NO_SESSION_CACHE */
12685 
12686 
wolfSSL_load_error_strings(void)12687 void wolfSSL_load_error_strings(void)
12688 {
12689     /* compatibility only */
12690 }
12691 
12692 
wolfSSL_library_init(void)12693 int wolfSSL_library_init(void)
12694 {
12695     WOLFSSL_ENTER("SSL_library_init");
12696     if (wolfSSL_Init() == WOLFSSL_SUCCESS)
12697         return WOLFSSL_SUCCESS;
12698     else
12699         return WOLFSSL_FATAL_ERROR;
12700 }
12701 
12702 
12703 #ifdef HAVE_SECRET_CALLBACK
12704 
wolfSSL_set_session_secret_cb(WOLFSSL * ssl,SessionSecretCb cb,void * ctx)12705 int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
12706 {
12707     WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
12708     if (ssl == NULL)
12709         return WOLFSSL_FATAL_ERROR;
12710 
12711     ssl->sessionSecretCb = cb;
12712     ssl->sessionSecretCtx = ctx;
12713     /* If using a pre-set key, assume session resumption. */
12714     ssl->session.sessionIDSz = 0;
12715     ssl->options.resuming = 1;
12716 
12717     return WOLFSSL_SUCCESS;
12718 }
12719 
12720 #endif
12721 
12722 
12723 #ifndef NO_SESSION_CACHE
12724 
12725 /* on by default if built in but allow user to turn off */
12726 WOLFSSL_ABI
wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX * ctx,long mode)12727 long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
12728 {
12729     WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
12730 
12731     if (ctx == NULL)
12732         return WOLFSSL_FAILURE;
12733 
12734     if (mode == WOLFSSL_SESS_CACHE_OFF)
12735         ctx->sessionCacheOff = 1;
12736 
12737     if ((mode & WOLFSSL_SESS_CACHE_NO_AUTO_CLEAR) != 0)
12738         ctx->sessionCacheFlushOff = 1;
12739 
12740 #ifdef HAVE_EXT_CACHE
12741     if ((mode & WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE) != 0)
12742         ctx->internalCacheOff = 1;
12743 #endif
12744 
12745     return WOLFSSL_SUCCESS;
12746 }
12747 
12748 #endif /* NO_SESSION_CACHE */
12749 
12750 
12751 #if !defined(NO_CERTS)
12752 #if defined(PERSIST_CERT_CACHE)
12753 
12754 
12755 #define WOLFSSL_CACHE_CERT_VERSION 1
12756 
12757 typedef struct {
12758     int version;                 /* cache cert layout version id */
12759     int rows;                    /* hash table rows, CA_TABLE_SIZE */
12760     int columns[CA_TABLE_SIZE];  /* columns per row on list */
12761     int signerSz;                /* sizeof Signer object */
12762 } CertCacheHeader;
12763 
12764 /* current cert persistence layout is:
12765 
12766    1) CertCacheHeader
12767    2) caTable
12768 
12769    update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
12770    PERSIST_CERT_CACHE functions
12771 */
12772 
12773 
12774 /* Return memory needed to persist this signer, have lock */
GetSignerMemory(Signer * signer)12775 static WC_INLINE int GetSignerMemory(Signer* signer)
12776 {
12777     int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
12778            + sizeof(signer->nameLen)    + sizeof(signer->subjectNameHash);
12779 
12780 #if !defined(NO_SKID)
12781         sz += (int)sizeof(signer->subjectKeyIdHash);
12782 #endif
12783 
12784     /* add dynamic bytes needed */
12785     sz += signer->pubKeySize;
12786     sz += signer->nameLen;
12787 
12788     return sz;
12789 }
12790 
12791 
12792 /* Return memory needed to persist this row, have lock */
GetCertCacheRowMemory(Signer * row)12793 static WC_INLINE int GetCertCacheRowMemory(Signer* row)
12794 {
12795     int sz = 0;
12796 
12797     while (row) {
12798         sz += GetSignerMemory(row);
12799         row = row->next;
12800     }
12801 
12802     return sz;
12803 }
12804 
12805 
12806 /* get the size of persist cert cache, have lock */
GetCertCacheMemSize(WOLFSSL_CERT_MANAGER * cm)12807 static WC_INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
12808 {
12809     int sz;
12810     int i;
12811 
12812     sz = sizeof(CertCacheHeader);
12813 
12814     for (i = 0; i < CA_TABLE_SIZE; i++)
12815         sz += GetCertCacheRowMemory(cm->caTable[i]);
12816 
12817     return sz;
12818 }
12819 
12820 
12821 /* Store cert cache header columns with number of items per list, have lock */
SetCertHeaderColumns(WOLFSSL_CERT_MANAGER * cm,int * columns)12822 static WC_INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns)
12823 {
12824     int     i;
12825     Signer* row;
12826 
12827     for (i = 0; i < CA_TABLE_SIZE; i++) {
12828         int count = 0;
12829         row = cm->caTable[i];
12830 
12831         while (row) {
12832             ++count;
12833             row = row->next;
12834         }
12835         columns[i] = count;
12836     }
12837 }
12838 
12839 
12840 /* Restore whole cert row from memory, have lock, return bytes consumed,
12841    < 0 on error, have lock */
RestoreCertRow(WOLFSSL_CERT_MANAGER * cm,byte * current,int row,int listSz,const byte * end)12842 static WC_INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current,
12843                                  int row, int listSz, const byte* end)
12844 {
12845     int idx = 0;
12846 
12847     if (listSz < 0) {
12848         WOLFSSL_MSG("Row header corrupted, negative value");
12849         return PARSE_ERROR;
12850     }
12851 
12852     while (listSz) {
12853         Signer* signer;
12854         byte*   publicKey;
12855         byte*   start = current + idx;  /* for end checks on this signer */
12856         int     minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
12857                       sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
12858         #ifndef NO_SKID
12859                 minSz += (int)sizeof(signer->subjectKeyIdHash);
12860         #endif
12861 
12862         if (start + minSz > end) {
12863             WOLFSSL_MSG("Would overread restore buffer");
12864             return BUFFER_E;
12865         }
12866         signer = MakeSigner(cm->heap);
12867         if (signer == NULL)
12868             return MEMORY_E;
12869 
12870         /* pubKeySize */
12871         XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
12872         idx += (int)sizeof(signer->pubKeySize);
12873 
12874         /* keyOID */
12875         XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
12876         idx += (int)sizeof(signer->keyOID);
12877 
12878         /* publicKey */
12879         if (start + minSz + signer->pubKeySize > end) {
12880             WOLFSSL_MSG("Would overread restore buffer");
12881             FreeSigner(signer, cm->heap);
12882             return BUFFER_E;
12883         }
12884         publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
12885                                    DYNAMIC_TYPE_KEY);
12886         if (publicKey == NULL) {
12887             FreeSigner(signer, cm->heap);
12888             return MEMORY_E;
12889         }
12890 
12891         XMEMCPY(publicKey, current + idx, signer->pubKeySize);
12892         signer->publicKey = publicKey;
12893         idx += signer->pubKeySize;
12894 
12895         /* nameLen */
12896         XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
12897         idx += (int)sizeof(signer->nameLen);
12898 
12899         /* name */
12900         if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
12901             WOLFSSL_MSG("Would overread restore buffer");
12902             FreeSigner(signer, cm->heap);
12903             return BUFFER_E;
12904         }
12905         signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
12906                                       DYNAMIC_TYPE_SUBJECT_CN);
12907         if (signer->name == NULL) {
12908             FreeSigner(signer, cm->heap);
12909             return MEMORY_E;
12910         }
12911 
12912         XMEMCPY(signer->name, current + idx, signer->nameLen);
12913         idx += signer->nameLen;
12914 
12915         /* subjectNameHash */
12916         XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
12917         idx += SIGNER_DIGEST_SIZE;
12918 
12919         #ifndef NO_SKID
12920             /* subjectKeyIdHash */
12921             XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
12922             idx += SIGNER_DIGEST_SIZE;
12923         #endif
12924 
12925         signer->next = cm->caTable[row];
12926         cm->caTable[row] = signer;
12927 
12928         --listSz;
12929     }
12930 
12931     return idx;
12932 }
12933 
12934 
12935 /* Store whole cert row into memory, have lock, return bytes added */
StoreCertRow(WOLFSSL_CERT_MANAGER * cm,byte * current,int row)12936 static WC_INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row)
12937 {
12938     int     added  = 0;
12939     Signer* list   = cm->caTable[row];
12940 
12941     while (list) {
12942         XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
12943         added += (int)sizeof(list->pubKeySize);
12944 
12945         XMEMCPY(current + added, &list->keyOID,     sizeof(list->keyOID));
12946         added += (int)sizeof(list->keyOID);
12947 
12948         XMEMCPY(current + added, list->publicKey, list->pubKeySize);
12949         added += list->pubKeySize;
12950 
12951         XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
12952         added += (int)sizeof(list->nameLen);
12953 
12954         XMEMCPY(current + added, list->name, list->nameLen);
12955         added += list->nameLen;
12956 
12957         XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
12958         added += SIGNER_DIGEST_SIZE;
12959 
12960         #ifndef NO_SKID
12961             XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
12962             added += SIGNER_DIGEST_SIZE;
12963         #endif
12964 
12965         list = list->next;
12966     }
12967 
12968     return added;
12969 }
12970 
12971 
12972 /* Persist cert cache to memory, have lock */
DoMemSaveCertCache(WOLFSSL_CERT_MANAGER * cm,void * mem,int sz)12973 static WC_INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm,
12974                                      void* mem, int sz)
12975 {
12976     int realSz;
12977     int ret = WOLFSSL_SUCCESS;
12978     int i;
12979 
12980     WOLFSSL_ENTER("DoMemSaveCertCache");
12981 
12982     realSz = GetCertCacheMemSize(cm);
12983     if (realSz > sz) {
12984         WOLFSSL_MSG("Mem output buffer too small");
12985         ret = BUFFER_E;
12986     }
12987     else {
12988         byte*           current;
12989         CertCacheHeader hdr;
12990 
12991         hdr.version  = WOLFSSL_CACHE_CERT_VERSION;
12992         hdr.rows     = CA_TABLE_SIZE;
12993         SetCertHeaderColumns(cm, hdr.columns);
12994         hdr.signerSz = (int)sizeof(Signer);
12995 
12996         XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
12997         current = (byte*)mem + sizeof(CertCacheHeader);
12998 
12999         for (i = 0; i < CA_TABLE_SIZE; ++i)
13000             current += StoreCertRow(cm, current, i);
13001     }
13002 
13003     return ret;
13004 }
13005 
13006 
13007 #if !defined(NO_FILESYSTEM)
13008 
13009 /* Persist cert cache to file */
CM_SaveCertCache(WOLFSSL_CERT_MANAGER * cm,const char * fname)13010 int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
13011 {
13012     XFILE file;
13013     int   rc = WOLFSSL_SUCCESS;
13014     int   memSz;
13015     byte* mem;
13016 
13017     WOLFSSL_ENTER("CM_SaveCertCache");
13018 
13019     file = XFOPEN(fname, "w+b");
13020     if (file == XBADFILE) {
13021        WOLFSSL_MSG("Couldn't open cert cache save file");
13022        return WOLFSSL_BAD_FILE;
13023     }
13024 
13025     if (wc_LockMutex(&cm->caLock) != 0) {
13026         WOLFSSL_MSG("wc_LockMutex on caLock failed");
13027         XFCLOSE(file);
13028         return BAD_MUTEX_E;
13029     }
13030 
13031     memSz = GetCertCacheMemSize(cm);
13032     mem   = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
13033     if (mem == NULL) {
13034         WOLFSSL_MSG("Alloc for tmp buffer failed");
13035         rc = MEMORY_E;
13036     } else {
13037         rc = DoMemSaveCertCache(cm, mem, memSz);
13038         if (rc == WOLFSSL_SUCCESS) {
13039             int ret = (int)XFWRITE(mem, memSz, 1, file);
13040             if (ret != 1) {
13041                 WOLFSSL_MSG("Cert cache file write failed");
13042                 rc = FWRITE_ERROR;
13043             }
13044         }
13045         XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
13046     }
13047 
13048     wc_UnLockMutex(&cm->caLock);
13049     XFCLOSE(file);
13050 
13051     return rc;
13052 }
13053 
13054 
13055 /* Restore cert cache from file */
CM_RestoreCertCache(WOLFSSL_CERT_MANAGER * cm,const char * fname)13056 int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
13057 {
13058     XFILE file;
13059     int   rc = WOLFSSL_SUCCESS;
13060     int   ret;
13061     int   memSz;
13062     byte* mem;
13063 
13064     WOLFSSL_ENTER("CM_RestoreCertCache");
13065 
13066     file = XFOPEN(fname, "rb");
13067     if (file == XBADFILE) {
13068        WOLFSSL_MSG("Couldn't open cert cache save file");
13069        return WOLFSSL_BAD_FILE;
13070     }
13071 
13072     if(XFSEEK(file, 0, XSEEK_END) != 0) {
13073         XFCLOSE(file);
13074         return WOLFSSL_BAD_FILE;
13075     }
13076     memSz = (int)XFTELL(file);
13077     XREWIND(file);
13078 
13079     if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz <= 0) {
13080         WOLFSSL_MSG("CM_RestoreCertCache file size error");
13081         XFCLOSE(file);
13082         return WOLFSSL_BAD_FILE;
13083     }
13084 
13085     mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
13086     if (mem == NULL) {
13087         WOLFSSL_MSG("Alloc for tmp buffer failed");
13088         XFCLOSE(file);
13089         return MEMORY_E;
13090     }
13091 
13092     ret = (int)XFREAD(mem, memSz, 1, file);
13093     if (ret != 1) {
13094         WOLFSSL_MSG("Cert file read error");
13095         rc = FREAD_ERROR;
13096     } else {
13097         rc = CM_MemRestoreCertCache(cm, mem, memSz);
13098         if (rc != WOLFSSL_SUCCESS) {
13099             WOLFSSL_MSG("Mem restore cert cache failed");
13100         }
13101     }
13102 
13103     XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
13104     XFCLOSE(file);
13105 
13106     return rc;
13107 }
13108 
13109 #endif /* NO_FILESYSTEM */
13110 
13111 
13112 /* Persist cert cache to memory */
CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER * cm,void * mem,int sz,int * used)13113 int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
13114 {
13115     int ret = WOLFSSL_SUCCESS;
13116 
13117     WOLFSSL_ENTER("CM_MemSaveCertCache");
13118 
13119     if (wc_LockMutex(&cm->caLock) != 0) {
13120         WOLFSSL_MSG("wc_LockMutex on caLock failed");
13121         return BAD_MUTEX_E;
13122     }
13123 
13124     ret = DoMemSaveCertCache(cm, mem, sz);
13125     if (ret == WOLFSSL_SUCCESS)
13126         *used  = GetCertCacheMemSize(cm);
13127 
13128     wc_UnLockMutex(&cm->caLock);
13129 
13130     return ret;
13131 }
13132 
13133 
13134 /* Restore cert cache from memory */
CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER * cm,const void * mem,int sz)13135 int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
13136 {
13137     int ret = WOLFSSL_SUCCESS;
13138     int i;
13139     CertCacheHeader* hdr = (CertCacheHeader*)mem;
13140     byte*            current = (byte*)mem + sizeof(CertCacheHeader);
13141     byte*            end     = (byte*)mem + sz;  /* don't go over */
13142 
13143     WOLFSSL_ENTER("CM_MemRestoreCertCache");
13144 
13145     if (current > end) {
13146         WOLFSSL_MSG("Cert Cache Memory buffer too small");
13147         return BUFFER_E;
13148     }
13149 
13150     if (hdr->version  != WOLFSSL_CACHE_CERT_VERSION ||
13151         hdr->rows     != CA_TABLE_SIZE ||
13152         hdr->signerSz != (int)sizeof(Signer)) {
13153 
13154         WOLFSSL_MSG("Cert Cache Memory header mismatch");
13155         return CACHE_MATCH_ERROR;
13156     }
13157 
13158     if (wc_LockMutex(&cm->caLock) != 0) {
13159         WOLFSSL_MSG("wc_LockMutex on caLock failed");
13160         return BAD_MUTEX_E;
13161     }
13162 
13163     FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
13164 
13165     for (i = 0; i < CA_TABLE_SIZE; ++i) {
13166         int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
13167         if (added < 0) {
13168             WOLFSSL_MSG("RestoreCertRow error");
13169             ret = added;
13170             break;
13171         }
13172         current += added;
13173     }
13174 
13175     wc_UnLockMutex(&cm->caLock);
13176 
13177     return ret;
13178 }
13179 
13180 
13181 /* get how big the the cert cache save buffer needs to be */
CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER * cm)13182 int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
13183 {
13184     int sz;
13185 
13186     WOLFSSL_ENTER("CM_GetCertCacheMemSize");
13187 
13188     if (wc_LockMutex(&cm->caLock) != 0) {
13189         WOLFSSL_MSG("wc_LockMutex on caLock failed");
13190         return BAD_MUTEX_E;
13191     }
13192 
13193     sz = GetCertCacheMemSize(cm);
13194 
13195     wc_UnLockMutex(&cm->caLock);
13196 
13197     return sz;
13198 }
13199 
13200 #endif /* PERSIST_CERT_CACHE */
13201 #endif /* NO_CERTS */
13202 
13203 #ifdef OPENSSL_EXTRA
13204 
13205 
13206 /* removes all cipher suites from the list that contain "toRemove"
13207  * returns the new list size on success
13208  */
wolfSSL_remove_ciphers(char * list,int sz,const char * toRemove)13209 static int wolfSSL_remove_ciphers(char* list, int sz, const char* toRemove)
13210 {
13211     int idx = 0;
13212     char* next = (char*)list;
13213     int totalSz = sz;
13214 
13215     if (list == NULL) {
13216         return 0;
13217     }
13218 
13219     do {
13220         char*  current = next;
13221         char   name[MAX_SUITE_NAME + 1];
13222         word32 length;
13223 
13224         next   = XSTRSTR(next, ":");
13225         length = min(sizeof(name), !next ? (word32)XSTRLEN(current) /* last */
13226                                          : (word32)(next - current));
13227 
13228         XSTRNCPY(name, current, length);
13229         name[(length == sizeof(name)) ? length - 1 : length] = 0;
13230 
13231         if (XSTRSTR(name, toRemove)) {
13232             XMEMMOVE(list + idx, list + idx + length, totalSz - (idx + length));
13233             totalSz -= length;
13234             list[totalSz] = '\0';
13235             next = current;
13236         }
13237         else {
13238             idx += length;
13239         }
13240     } while (next++); /* ++ needed to skip ':' */
13241 
13242     return totalSz;
13243 }
13244 /*
13245  * build enabled cipher list w/ TLS13 or w/o TLS13 suites
13246  * @param ctx    a pointer to WOLFSSL_CTX structure
13247  * @param suites currently enabled suites
13248  * @param onlytlsv13suites flag whether correcting w/ TLS13 suites
13249  *                         or w/o TLS13 suties
13250  * @param list   suites list that user wants to update
13251  * @return suites list on success, otherwise NULL
13252  */
buildEnabledCipherList(WOLFSSL_CTX * ctx,Suites * suites,int tls13Only,const char * list)13253 static char* buildEnabledCipherList(WOLFSSL_CTX* ctx, Suites* suites,
13254            int tls13Only, const char* list)
13255 {
13256     word32 idx = 0;
13257     word32 listsz = 0;
13258     word32 len = 0;
13259     word32 ianasz = 0;
13260     const char* enabledcs = NULL;
13261     char* locallist = NULL;
13262     char* head = NULL;
13263     byte cipherSuite0;
13264     byte cipherSuite;
13265 
13266     /* sanity check */
13267     if (ctx == NULL || suites == NULL || list == NULL)
13268         return NULL;
13269 
13270     if (!suites->setSuites)
13271         return NULL;
13272 
13273     listsz = (word32)XSTRLEN(list);
13274 
13275     /* calculate necessary buffer length */
13276     for(idx = 0; idx < suites->suiteSz; idx++) {
13277 
13278         cipherSuite0 = suites->suites[idx];
13279         cipherSuite  = suites->suites[++idx];
13280 
13281         if (tls13Only && cipherSuite0 == TLS13_BYTE) {
13282             enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
13283         }
13284         else if (!tls13Only && cipherSuite0 != TLS13_BYTE) {
13285             enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
13286         }
13287         else
13288             continue;
13289 
13290         if (XSTRNCMP(enabledcs, "None", XSTRLEN(enabledcs)) != 0) {
13291             len += (word32)XSTRLEN(enabledcs) + 2;
13292         }
13293     }
13294 
13295     len += listsz + 2;
13296 
13297     /* build string */
13298     if (len > (listsz + 2)) {
13299         locallist = (char*)XMALLOC(len, ctx->heap,
13300                                            DYNAMIC_TYPE_TMP_BUFFER);
13301         /* sanity check */
13302         if (!locallist)
13303             return NULL;
13304 
13305         XMEMSET(locallist, 0, len);
13306 
13307         head = locallist;
13308 
13309         if (!tls13Only)
13310         {
13311             /* always tls13 suites in the head position */
13312             XSTRNCPY(locallist, list, len);
13313             locallist += listsz;
13314             *locallist++ = ':';
13315             *locallist = 0;
13316             len -= listsz + 1;
13317         }
13318 
13319         for(idx = 0; idx < suites->suiteSz; idx++) {
13320             cipherSuite0 = suites->suites[idx];
13321             cipherSuite  = suites->suites[++idx];
13322 
13323             if (tls13Only && cipherSuite0 == TLS13_BYTE) {
13324                 enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
13325             }
13326             else if (!tls13Only && cipherSuite0 != TLS13_BYTE) {
13327                 enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
13328             }
13329             else
13330                 continue;
13331 
13332             ianasz = (int)XSTRLEN(enabledcs);
13333             if (ianasz + 1 < len) {
13334                 XSTRNCPY(locallist, enabledcs, len);
13335                 locallist += ianasz;
13336 
13337                 *locallist++ = ':';
13338                 *locallist = 0;
13339                 len -= ianasz + 1;
13340             }
13341             else{
13342                 XFREE(locallist, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13343                 return NULL;
13344             }
13345         }
13346 
13347         if (tls13Only) {
13348             XSTRNCPY(locallist, list, len);
13349             locallist += listsz;
13350             *locallist = 0;
13351         }
13352 
13353         return head;
13354     }
13355     else
13356         return NULL;
13357 }
13358 
13359 /*
13360  * check if the list has TLS13 and pre-TLS13 suites
13361  * @param list cipher suite list that user want to set
13362  * @return mixed: 0, only pre-TLS13: 1, only TLS13: 2
13363  */
CheckcipherList(const char * list)13364 static int CheckcipherList(const char* list)
13365 {
13366     int ret;
13367     int findTLSv13Suites = 0;
13368     int findbeforeSuites = 0;
13369     byte cipherSuite0;
13370     byte cipherSuite1;
13371     int flags;
13372     char* next = (char*)list;
13373 
13374     do {
13375         char*  current = next;
13376         char   name[MAX_SUITE_NAME + 1];
13377         word32 length = MAX_SUITE_NAME;
13378         word32 current_length;
13379 
13380         next   = XSTRSTR(next, ":");
13381 
13382         current_length = (!next) ? (word32)XSTRLEN(current)
13383                                  : (word32)(next - current);
13384 
13385         if (current_length < length) {
13386             length = current_length;
13387         }
13388         XSTRNCPY(name, current, length);
13389         name[length] = 0;
13390 
13391         ret = wolfSSL_get_cipher_suite_from_name(name, &cipherSuite0,
13392                                                         &cipherSuite1, &flags);
13393         if (ret == 0) {
13394             if (cipherSuite0 == TLS13_BYTE) {
13395                 /* TLSv13 suite */
13396                 findTLSv13Suites = 1;
13397                 break;
13398             }
13399             else {
13400                 findbeforeSuites = 1;
13401                 break;
13402             }
13403         }
13404         if (findTLSv13Suites == 1 && findbeforeSuites == 1) {
13405             /* list has mixed suites */
13406             return 0;
13407         }
13408     }  while (next++); /* ++ needed to skip ':' */
13409 
13410     if (findTLSv13Suites == 0 && findbeforeSuites == 1) {
13411         return 1;/* only before TLSv13 suites */
13412     }
13413     else if (findTLSv13Suites == 1 && findbeforeSuites == 0) {
13414         return 2;/* only TLSv13 suties */
13415     }
13416     else {
13417         return 0;/* handle as mixed */
13418     }
13419 }
13420 
13421 /* parse some bulk lists like !eNULL / !aNULL
13422  *
13423  * returns WOLFSSL_SUCCESS on success and sets the cipher suite list
13424  */
wolfSSL_parse_cipher_list(WOLFSSL_CTX * ctx,Suites * suites,const char * list)13425 static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, Suites* suites,
13426         const char* list)
13427 {
13428     int       ret          = 0;
13429     const int suiteSz      = GetCipherNamesSize();
13430     char*     next         = (char*)list;
13431     const CipherSuiteInfo* names = GetCipherNames();
13432     char*     localList    = NULL;
13433     int sz = 0;
13434     int listattribute = 0;
13435     char*     buildcipherList = NULL;
13436     int tls13Only = 0;
13437 
13438     if (suites == NULL || list == NULL) {
13439         WOLFSSL_MSG("NULL argument");
13440         return WOLFSSL_FAILURE;
13441     }
13442 
13443     /* does list contain eNULL or aNULL? */
13444     if (XSTRSTR(list, "aNULL") || XSTRSTR(list, "eNULL")) {
13445         do {
13446             char*  current = next;
13447             char   name[MAX_SUITE_NAME + 1];
13448             int    i;
13449             word32 length = MAX_SUITE_NAME;
13450             word32 current_length;
13451 
13452             next   = XSTRSTR(next, ":");
13453 
13454             current_length = (!next) ? (word32)XSTRLEN(current)
13455                                      : (word32)(next - current);
13456 
13457             if (current_length < length) {
13458                 length = current_length;
13459             }
13460             XSTRNCPY(name, current, length);
13461             name[length] = 0;
13462 
13463             /* check for "not" case */
13464             if (name[0] == '!' && suiteSz > 0) {
13465                 /* populate list with all suites if not already created */
13466                 if (localList == NULL) {
13467                     for (i = 0; i < suiteSz; i++) {
13468                         sz += (int)XSTRLEN(names[i].name) + 2;
13469                     }
13470                     localList = (char*)XMALLOC(sz, ctx->heap,
13471                                                        DYNAMIC_TYPE_TMP_BUFFER);
13472                     if (localList == NULL) {
13473                         return WOLFSSL_FAILURE;
13474                     }
13475                     wolfSSL_get_ciphers(localList, sz);
13476                     sz = (int)XSTRLEN(localList);
13477                 }
13478 
13479                 if (XSTRSTR(name, "eNULL")) {
13480                     wolfSSL_remove_ciphers(localList, sz, "-NULL");
13481                 }
13482             }
13483         }
13484         while (next++); /* ++ needed to skip ':' */
13485 
13486         ret = SetCipherList(ctx, suites, localList);
13487         XFREE(localList, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13488         return (ret)? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
13489     }
13490     else {
13491 
13492         listattribute = CheckcipherList(list);
13493 
13494         if (listattribute == 0) {
13495            /* list has mixed(pre-TLSv13 and TLSv13) suites
13496             * update cipher suites the same as before
13497             */
13498             return (SetCipherList(ctx, suites, list)) ? WOLFSSL_SUCCESS :
13499             WOLFSSL_FAILURE;
13500         }
13501         else if (listattribute == 1) {
13502            /* list has only pre-TLSv13 suites.
13503             * Only update before TLSv13 suites.
13504             */
13505             tls13Only = 1;
13506         }
13507         else if (listattribute == 2) {
13508            /* list has only TLSv13 suites. Only update TLv13 suites
13509             * simulate set_ciphersuites() compatibility layer API
13510             */
13511             tls13Only = 0;
13512         }
13513 
13514         buildcipherList = buildEnabledCipherList(ctx, ctx->suites,
13515                                                 tls13Only, list);
13516 
13517         if (buildcipherList) {
13518             ret = SetCipherList(ctx, suites, buildcipherList);
13519             XFREE(buildcipherList, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13520         }
13521         else {
13522             ret = SetCipherList(ctx, suites, list);
13523         }
13524 
13525         return ret;
13526     }
13527 }
13528 
13529 #endif
13530 
13531 
wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX * ctx,const char * list)13532 int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
13533 {
13534     WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
13535 
13536     if (ctx == NULL)
13537         return WOLFSSL_FAILURE;
13538 
13539     /* alloc/init on demand only */
13540     if (ctx->suites == NULL) {
13541         ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
13542                                        DYNAMIC_TYPE_SUITES);
13543         if (ctx->suites == NULL) {
13544             WOLFSSL_MSG("Memory alloc for Suites failed");
13545             return WOLFSSL_FAILURE;
13546         }
13547         XMEMSET(ctx->suites, 0, sizeof(Suites));
13548     }
13549 
13550 #ifdef OPENSSL_EXTRA
13551     return wolfSSL_parse_cipher_list(ctx, ctx->suites, list);
13552 #else
13553     return (SetCipherList(ctx, ctx->suites, list)) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
13554 #endif
13555 }
13556 
13557 
wolfSSL_set_cipher_list(WOLFSSL * ssl,const char * list)13558 int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
13559 {
13560     WOLFSSL_ENTER("wolfSSL_set_cipher_list");
13561 #ifdef SINGLE_THREADED
13562     if (ssl->ctx->suites == ssl->suites) {
13563         ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
13564                                        DYNAMIC_TYPE_SUITES);
13565         if (ssl->suites == NULL) {
13566             WOLFSSL_MSG("Suites Memory error");
13567             return MEMORY_E;
13568         }
13569         *ssl->suites = *ssl->ctx->suites;
13570         ssl->options.ownSuites = 1;
13571     }
13572 #endif
13573 
13574 #ifdef OPENSSL_EXTRA
13575     return wolfSSL_parse_cipher_list(ssl->ctx, ssl->suites, list);
13576 #else
13577     return (SetCipherList(ssl->ctx, ssl->suites, list)) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
13578 #endif
13579 }
13580 
13581 #ifdef HAVE_KEYING_MATERIAL
13582 
13583 #define TLS_PRF_LABEL_CLIENT_FINISHED     "client finished"
13584 #define TLS_PRF_LABEL_SERVER_FINISHED     "server finished"
13585 #define TLS_PRF_LABEL_MASTER_SECRET       "master secret"
13586 #define TLS_PRF_LABEL_EXT_MASTER_SECRET   "extended master secret"
13587 #define TLS_PRF_LABEL_KEY_EXPANSION       "key expansion"
13588 
13589 static const struct ForbiddenLabels {
13590     const char* label;
13591     size_t labelLen;
13592 } forbiddenLabels[] = {
13593     {TLS_PRF_LABEL_CLIENT_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_CLIENT_FINISHED)},
13594     {TLS_PRF_LABEL_SERVER_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_SERVER_FINISHED)},
13595     {TLS_PRF_LABEL_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_MASTER_SECRET)},
13596     {TLS_PRF_LABEL_EXT_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_EXT_MASTER_SECRET)},
13597     {TLS_PRF_LABEL_KEY_EXPANSION, XSTR_SIZEOF(TLS_PRF_LABEL_KEY_EXPANSION)},
13598     {NULL, 0},
13599 };
13600 
13601 /**
13602  * Implement RFC 5705
13603  * TLS 1.3 uses a different exporter definition (section 7.5 of RFC 8446)
13604  * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
13605  */
wolfSSL_export_keying_material(WOLFSSL * ssl,unsigned char * out,size_t outLen,const char * label,size_t labelLen,const unsigned char * context,size_t contextLen,int use_context)13606 int wolfSSL_export_keying_material(WOLFSSL *ssl,
13607         unsigned char *out, size_t outLen,
13608         const char *label, size_t labelLen,
13609         const unsigned char *context, size_t contextLen,
13610         int use_context)
13611 {
13612     byte*  seed = NULL;
13613     word32 seedLen;
13614     const struct ForbiddenLabels* fl;
13615 
13616     WOLFSSL_ENTER("wolfSSL_export_keying_material");
13617 
13618     if (ssl == NULL || out == NULL || label == NULL ||
13619             (use_context && contextLen && context == NULL)) {
13620         WOLFSSL_MSG("Bad argument");
13621         return WOLFSSL_FAILURE;
13622     }
13623 
13624     /* clientRandom + serverRandom
13625      * OR
13626      * clientRandom + serverRandom + ctx len encoding + ctx */
13627     seedLen = !use_context ? (word32)SEED_LEN :
13628                              (word32)SEED_LEN + 2 + (word32)contextLen;
13629 
13630     if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
13631         WOLFSSL_MSG("To export keying material wolfSSL needs to keep handshake "
13632                     "data. Call wolfSSL_KeepArrays before attempting to "
13633                     "export keyid material.");
13634         return WOLFSSL_FAILURE;
13635     }
13636 
13637     /* check forbidden labels */
13638     for (fl = &forbiddenLabels[0]; fl->label != NULL; fl++) {
13639         if (labelLen >= fl->labelLen &&
13640                 XMEMCMP(label, fl->label, fl->labelLen) == 0) {
13641             WOLFSSL_MSG("Forbidden label");
13642             return WOLFSSL_FAILURE;
13643         }
13644     }
13645 
13646 #ifdef WOLFSSL_TLS13
13647     if (IsAtLeastTLSv1_3(ssl->version)) {
13648         /* Path for TLS 1.3 */
13649         if (!use_context) {
13650             contextLen = 0;
13651             context = (byte*)""; /* Give valid pointer for 0 length memcpy */
13652         }
13653 
13654         if (Tls13_Exporter(ssl, out, (word32)outLen, label, labelLen,
13655                 context, contextLen) != 0) {
13656             WOLFSSL_MSG("Tls13_Exporter error");
13657             return WOLFSSL_FAILURE;
13658         }
13659         return WOLFSSL_SUCCESS;
13660     }
13661 #endif
13662 
13663     /* Path for <=TLS 1.2 */
13664     seed = (byte*)XMALLOC(seedLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13665     if (seed == NULL) {
13666         WOLFSSL_MSG("malloc error");
13667         return WOLFSSL_FAILURE;
13668     }
13669 
13670     XMEMCPY(seed,           ssl->arrays->clientRandom, RAN_LEN);
13671     XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
13672 
13673     if (use_context) {
13674         /* Encode len in big endian */
13675         seed[SEED_LEN    ] = (contextLen >> 8) & 0xFF;
13676         seed[SEED_LEN + 1] = (contextLen) & 0xFF;
13677         if (contextLen) {
13678             /* 0 length context is allowed */
13679             XMEMCPY(seed + SEED_LEN + 2, context, contextLen);
13680         }
13681     }
13682 
13683     PRIVATE_KEY_UNLOCK();
13684     if (wc_PRF_TLS(out, (word32)outLen, ssl->arrays->masterSecret, SECRET_LEN,
13685             (byte*)label, (word32)labelLen, seed, seedLen, IsAtLeastTLSv1_2(ssl),
13686             ssl->specs.mac_algorithm, ssl->heap, ssl->devId) != 0) {
13687         WOLFSSL_MSG("wc_PRF_TLS error");
13688         PRIVATE_KEY_LOCK();
13689         XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13690         return WOLFSSL_FAILURE;
13691     }
13692     PRIVATE_KEY_LOCK();
13693 
13694     XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13695     return WOLFSSL_SUCCESS;
13696 }
13697 #endif /* HAVE_KEYING_MATERIAL */
13698 
wolfSSL_dtls_get_using_nonblock(WOLFSSL * ssl)13699 int wolfSSL_dtls_get_using_nonblock(WOLFSSL* ssl)
13700 {
13701     int useNb = 0;
13702 
13703     if (ssl == NULL)
13704         return WOLFSSL_FAILURE;
13705 
13706     WOLFSSL_ENTER("wolfSSL_dtls_get_using_nonblock");
13707     if (ssl->options.dtls) {
13708 #ifdef WOLFSSL_DTLS
13709         useNb = ssl->options.dtlsUseNonblock;
13710 #endif
13711     }
13712     else {
13713         WOLFSSL_MSG("wolfSSL_dtls_get_using_nonblock() is "
13714                     "DEPRECATED for non-DTLS use.");
13715     }
13716     return useNb;
13717 }
13718 
13719 
13720 #ifndef WOLFSSL_LEANPSK
13721 
wolfSSL_dtls_set_using_nonblock(WOLFSSL * ssl,int nonblock)13722 void wolfSSL_dtls_set_using_nonblock(WOLFSSL* ssl, int nonblock)
13723 {
13724     (void)nonblock;
13725 
13726     WOLFSSL_ENTER("wolfSSL_dtls_set_using_nonblock");
13727 
13728     if (ssl == NULL)
13729         return;
13730 
13731     if (ssl->options.dtls) {
13732 #ifdef WOLFSSL_DTLS
13733         ssl->options.dtlsUseNonblock = (nonblock != 0);
13734 #endif
13735     }
13736     else {
13737         WOLFSSL_MSG("wolfSSL_dtls_set_using_nonblock() is "
13738                     "DEPRECATED for non-DTLS use.");
13739     }
13740 }
13741 
13742 
13743 #ifdef WOLFSSL_DTLS
13744 
wolfSSL_dtls_get_current_timeout(WOLFSSL * ssl)13745 int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
13746 {
13747     int timeout = 0;
13748     if (ssl)
13749         timeout = ssl->dtls_timeout;
13750 
13751     WOLFSSL_LEAVE("wolfSSL_dtls_get_current_timeout()", timeout);
13752     return timeout;
13753 }
13754 
wolfSSL_DTLSv1_get_timeout(WOLFSSL * ssl,WOLFSSL_TIMEVAL * timeleft)13755 int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, WOLFSSL_TIMEVAL* timeleft)
13756 {
13757     if (ssl && timeleft) {
13758         XMEMSET(timeleft, 0, sizeof(WOLFSSL_TIMEVAL));
13759         timeleft->tv_sec = ssl->dtls_timeout;
13760     }
13761     return 0;
13762 }
13763 
13764 #ifndef NO_WOLFSSL_STUB
wolfSSL_DTLSv1_handle_timeout(WOLFSSL * ssl)13765 int wolfSSL_DTLSv1_handle_timeout(WOLFSSL* ssl)
13766 {
13767     WOLFSSL_STUB("SSL_DTLSv1_handle_timeout");
13768     (void)ssl;
13769     return 0;
13770 }
13771 #endif
13772 
13773 #ifndef NO_WOLFSSL_STUB
wolfSSL_DTLSv1_set_initial_timeout_duration(WOLFSSL * ssl,word32 duration_ms)13774 void wolfSSL_DTLSv1_set_initial_timeout_duration(WOLFSSL* ssl, word32 duration_ms)
13775 {
13776     WOLFSSL_STUB("SSL_DTLSv1_set_initial_timeout_duration");
13777     (void)ssl;
13778     (void)duration_ms;
13779 }
13780 #endif
13781 
13782 /* user may need to alter init dtls recv timeout, WOLFSSL_SUCCESS on ok */
wolfSSL_dtls_set_timeout_init(WOLFSSL * ssl,int timeout)13783 int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
13784 {
13785     if (ssl == NULL || timeout < 0)
13786         return BAD_FUNC_ARG;
13787 
13788     if (timeout > ssl->dtls_timeout_max) {
13789         WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
13790         return BAD_FUNC_ARG;
13791     }
13792 
13793     ssl->dtls_timeout_init = timeout;
13794     ssl->dtls_timeout = timeout;
13795 
13796     return WOLFSSL_SUCCESS;
13797 }
13798 
13799 
13800 /* user may need to alter max dtls recv timeout, WOLFSSL_SUCCESS on ok */
wolfSSL_dtls_set_timeout_max(WOLFSSL * ssl,int timeout)13801 int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
13802 {
13803     if (ssl == NULL || timeout < 0)
13804         return BAD_FUNC_ARG;
13805 
13806     if (timeout < ssl->dtls_timeout_init) {
13807         WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
13808         return BAD_FUNC_ARG;
13809     }
13810 
13811     ssl->dtls_timeout_max = timeout;
13812 
13813     return WOLFSSL_SUCCESS;
13814 }
13815 
13816 
wolfSSL_dtls_got_timeout(WOLFSSL * ssl)13817 int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
13818 {
13819     int result = WOLFSSL_SUCCESS;
13820     WOLFSSL_ENTER("wolfSSL_dtls_got_timeout()");
13821 
13822     if (ssl == NULL)
13823         return WOLFSSL_FATAL_ERROR;
13824 
13825     if ((IsSCR(ssl) || !ssl->options.handShakeDone)) {
13826         if (DtlsMsgPoolTimeout(ssl) < 0){
13827             ssl->error = SOCKET_ERROR_E;
13828             WOLFSSL_ERROR(ssl->error);
13829             result = WOLFSSL_FATAL_ERROR;
13830         }
13831         else if ((result = DtlsMsgPoolSend(ssl, 0)) < 0)  {
13832             ssl->error = result;
13833             WOLFSSL_ERROR(result);
13834             result = WOLFSSL_FATAL_ERROR;
13835         }
13836         else {
13837             /* Reset return value to success */
13838             result = WOLFSSL_SUCCESS;
13839         }
13840     }
13841 
13842     WOLFSSL_LEAVE("wolfSSL_dtls_got_timeout()", result);
13843     return result;
13844 }
13845 
13846 
13847 /* retransmit all the saves messages, WOLFSSL_SUCCESS on ok */
wolfSSL_dtls_retransmit(WOLFSSL * ssl)13848 int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
13849 {
13850     WOLFSSL_ENTER("wolfSSL_dtls_retransmit()");
13851 
13852     if (ssl == NULL)
13853         return WOLFSSL_FATAL_ERROR;
13854 
13855     if (!ssl->options.handShakeDone) {
13856         int result = DtlsMsgPoolSend(ssl, 0);
13857         if (result < 0) {
13858             ssl->error = result;
13859             WOLFSSL_ERROR(result);
13860             return WOLFSSL_FATAL_ERROR;
13861         }
13862     }
13863 
13864     return 0;
13865 }
13866 
13867 #endif /* DTLS */
13868 #endif /* LEANPSK */
13869 
13870 
13871 #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
13872 
13873 /* Not an SSL function, return 0 for success, error code otherwise */
13874 /* Prereq: ssl's RNG needs to be initialized. */
wolfSSL_DTLS_SetCookieSecret(WOLFSSL * ssl,const byte * secret,word32 secretSz)13875 int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
13876                                  const byte* secret, word32 secretSz)
13877 {
13878     int ret = 0;
13879 
13880     WOLFSSL_ENTER("wolfSSL_DTLS_SetCookieSecret");
13881 
13882     if (ssl == NULL) {
13883         WOLFSSL_MSG("need a SSL object");
13884         return BAD_FUNC_ARG;
13885     }
13886 
13887     if (secret != NULL && secretSz == 0) {
13888         WOLFSSL_MSG("can't have a new secret without a size");
13889         return BAD_FUNC_ARG;
13890     }
13891 
13892     /* If secretSz is 0, use the default size. */
13893     if (secretSz == 0)
13894         secretSz = COOKIE_SECRET_SZ;
13895 
13896     if (secretSz != ssl->buffers.dtlsCookieSecret.length) {
13897         byte* newSecret;
13898 
13899         if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
13900             ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
13901                       ssl->buffers.dtlsCookieSecret.length);
13902             XFREE(ssl->buffers.dtlsCookieSecret.buffer,
13903                   ssl->heap, DYNAMIC_TYPE_NONE);
13904         }
13905 
13906         newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
13907         if (newSecret == NULL) {
13908             ssl->buffers.dtlsCookieSecret.buffer = NULL;
13909             ssl->buffers.dtlsCookieSecret.length = 0;
13910             WOLFSSL_MSG("couldn't allocate new cookie secret");
13911             return MEMORY_ERROR;
13912         }
13913         ssl->buffers.dtlsCookieSecret.buffer = newSecret;
13914         ssl->buffers.dtlsCookieSecret.length = secretSz;
13915     }
13916 
13917     /* If the supplied secret is NULL, randomly generate a new secret. */
13918     if (secret == NULL) {
13919         ret = wc_RNG_GenerateBlock(ssl->rng,
13920                              ssl->buffers.dtlsCookieSecret.buffer, secretSz);
13921     }
13922     else
13923         XMEMCPY(ssl->buffers.dtlsCookieSecret.buffer, secret, secretSz);
13924 
13925     WOLFSSL_LEAVE("wolfSSL_DTLS_SetCookieSecret", 0);
13926     return ret;
13927 }
13928 
13929 #endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
13930 
13931 
13932 /* EITHER SIDE METHODS */
13933 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
wolfSSLv23_method(void)13934     WOLFSSL_METHOD* wolfSSLv23_method(void)
13935     {
13936         return wolfSSLv23_method_ex(NULL);
13937     }
wolfSSLv23_method_ex(void * heap)13938     WOLFSSL_METHOD* wolfSSLv23_method_ex(void* heap)
13939     {
13940         WOLFSSL_METHOD* m = NULL;
13941         WOLFSSL_ENTER("SSLv23_method");
13942     #if !defined(NO_WOLFSSL_CLIENT)
13943         m = wolfSSLv23_client_method_ex(heap);
13944     #elif !defined(NO_WOLFSSL_SERVER)
13945         m = wolfSSLv23_server_method_ex(heap);
13946     #endif
13947         if (m != NULL) {
13948             m->side = WOLFSSL_NEITHER_END;
13949         }
13950 
13951         return m;
13952     }
13953 
13954     #ifdef WOLFSSL_ALLOW_SSLV3
wolfSSLv3_method(void)13955     WOLFSSL_METHOD* wolfSSLv3_method(void)
13956     {
13957         return wolfSSLv3_method_ex(NULL);
13958     }
wolfSSLv3_method_ex(void * heap)13959     WOLFSSL_METHOD* wolfSSLv3_method_ex(void* heap)
13960     {
13961         WOLFSSL_METHOD* m = NULL;
13962         WOLFSSL_ENTER("SSLv3_method");
13963     #if !defined(NO_WOLFSSL_CLIENT)
13964         m = wolfSSLv3_client_method_ex(heap);
13965     #elif !defined(NO_WOLFSSL_SERVER)
13966         m = wolfSSLv3_server_method_ex(heap);
13967     #endif
13968         if (m != NULL) {
13969             m->side = WOLFSSL_NEITHER_END;
13970         }
13971 
13972         return m;
13973     }
13974     #endif
13975 #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
13976 
13977 /* client only parts */
13978 #ifndef NO_WOLFSSL_CLIENT
13979 
13980     #ifdef OPENSSL_EXTRA
wolfSSLv2_client_method(void)13981     WOLFSSL_METHOD* wolfSSLv2_client_method(void)
13982     {
13983         WOLFSSL_STUB("wolfSSLv2_client_method");
13984         return NULL;
13985     }
13986     #endif
13987 
13988     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
wolfSSLv3_client_method(void)13989     WOLFSSL_METHOD* wolfSSLv3_client_method(void)
13990     {
13991         return wolfSSLv3_client_method_ex(NULL);
13992     }
wolfSSLv3_client_method_ex(void * heap)13993     WOLFSSL_METHOD* wolfSSLv3_client_method_ex(void* heap)
13994     {
13995         WOLFSSL_METHOD* method =
13996                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
13997                                                      heap, DYNAMIC_TYPE_METHOD);
13998         (void)heap;
13999         WOLFSSL_ENTER("SSLv3_client_method_ex");
14000         if (method)
14001             InitSSL_Method(method, MakeSSLv3());
14002         return method;
14003     }
14004     #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
14005 
14006 
wolfSSLv23_client_method(void)14007     WOLFSSL_METHOD* wolfSSLv23_client_method(void)
14008     {
14009         return wolfSSLv23_client_method_ex(NULL);
14010     }
wolfSSLv23_client_method_ex(void * heap)14011     WOLFSSL_METHOD* wolfSSLv23_client_method_ex(void* heap)
14012     {
14013         WOLFSSL_METHOD* method =
14014                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
14015                                                      heap, DYNAMIC_TYPE_METHOD);
14016         (void)heap;
14017         WOLFSSL_ENTER("SSLv23_client_method_ex");
14018         if (method) {
14019     #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
14020         #if defined(WOLFSSL_TLS13)
14021             InitSSL_Method(method, MakeTLSv1_3());
14022         #elif !defined(WOLFSSL_NO_TLS12)
14023             InitSSL_Method(method, MakeTLSv1_2());
14024         #elif !defined(NO_OLD_TLS)
14025             InitSSL_Method(method, MakeTLSv1_1());
14026         #endif
14027     #else
14028         #ifndef NO_OLD_TLS
14029             InitSSL_Method(method, MakeTLSv1_1());
14030         #endif
14031     #endif
14032     #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
14033             method->downgrade = 1;
14034     #endif
14035         }
14036         return method;
14037     }
14038 
14039 
14040     #if defined(WOLFSSL_DTLS) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS) || \
14041         defined(WOLFSSL_ALLOW_SSLV3)
14042     /* If SCTP is not enabled returns the state of the dtls option.
14043      * If SCTP is enabled returns dtls && !sctp. */
IsDtlsNotSctpMode(WOLFSSL * ssl)14044     static WC_INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
14045     {
14046         int result = ssl->options.dtls;
14047 
14048         if (result) {
14049         #ifdef WOLFSSL_SCTP
14050             result = !ssl->options.dtlsSctp;
14051         #endif
14052         }
14053 
14054         return result;
14055     }
14056     #endif /* WOLFSSL_DTLS || !WOLFSSL_NO_TLS12 || !NO_OLD_TLS */
14057 
14058 
14059     /* please see note at top of README if you get an error from connect */
14060     WOLFSSL_ABI
wolfSSL_connect(WOLFSSL * ssl)14061     int wolfSSL_connect(WOLFSSL* ssl)
14062     {
14063     #if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13))
14064         int neededState;
14065     #endif
14066 
14067         WOLFSSL_ENTER("SSL_connect()");
14068 
14069         #ifdef HAVE_ERRNO_H
14070             errno = 0;
14071         #endif
14072 
14073         if (ssl == NULL)
14074             return BAD_FUNC_ARG;
14075 
14076     #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
14077         if (ssl->options.side == WOLFSSL_NEITHER_END) {
14078             ssl->error = InitSSL_Side(ssl, WOLFSSL_CLIENT_END);
14079             if (ssl->error != WOLFSSL_SUCCESS) {
14080                 WOLFSSL_ERROR(ssl->error);
14081                 return WOLFSSL_FATAL_ERROR;
14082             }
14083             ssl->error = 0; /* expected to be zero here */
14084         }
14085 
14086     #ifdef OPENSSL_EXTRA
14087         if (ssl->CBIS != NULL) {
14088             ssl->CBIS(ssl, SSL_ST_CONNECT, WOLFSSL_SUCCESS);
14089             ssl->cbmode = SSL_CB_WRITE;
14090         }
14091     #endif
14092     #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
14093 
14094     #if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
14095         return wolfSSL_connect_TLSv13(ssl);
14096     #else
14097         #ifdef WOLFSSL_TLS13
14098         if (ssl->options.tls1_3)
14099             return wolfSSL_connect_TLSv13(ssl);
14100         #endif
14101 
14102 #ifdef WOLFSSL_WOLFSENTRY_HOOKS
14103         if (ssl->ConnectFilter) {
14104             wolfSSL_netfilter_decision_t res;
14105             if ((ssl->ConnectFilter(ssl, ssl->ConnectFilter_arg, &res) ==
14106                  WOLFSSL_SUCCESS) &&
14107                 (res == WOLFSSL_NETFILTER_REJECT)) {
14108                 WOLFSSL_ERROR(ssl->error = SOCKET_FILTERED_E);
14109                 return WOLFSSL_FATAL_ERROR;
14110             }
14111         }
14112 #endif /* WOLFSSL_WOLFSENTRY_HOOKS */
14113 
14114         if (ssl->options.side != WOLFSSL_CLIENT_END) {
14115             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
14116             return WOLFSSL_FATAL_ERROR;
14117         }
14118 
14119         #ifdef WOLFSSL_DTLS
14120         if (ssl->version.major == DTLS_MAJOR) {
14121             ssl->options.dtls   = 1;
14122             ssl->options.tls    = 1;
14123             ssl->options.tls1_1 = 1;
14124         }
14125         #endif
14126 
14127         if (ssl->buffers.outputBuffer.length > 0
14128         #ifdef WOLFSSL_ASYNC_CRYPT
14129             /* do not send buffered or advance state if last error was an
14130                 async pending operation */
14131             && ssl->error != WC_PENDING_E
14132         #endif
14133         ) {
14134             if ( (ssl->error = SendBuffered(ssl)) == 0) {
14135                 /* fragOffset is non-zero when sending fragments. On the last
14136                  * fragment, fragOffset is zero again, and the state can be
14137                  * advanced. */
14138                 if (ssl->fragOffset == 0) {
14139                     ssl->options.connectState++;
14140                     WOLFSSL_MSG("connect state: "
14141                                 "Advanced from last buffered fragment send");
14142                 }
14143                 else {
14144                     WOLFSSL_MSG("connect state: "
14145                                 "Not advanced, more fragments to send");
14146                 }
14147             }
14148             else {
14149                 WOLFSSL_ERROR(ssl->error);
14150                 return WOLFSSL_FATAL_ERROR;
14151             }
14152         }
14153 
14154         switch (ssl->options.connectState) {
14155 
14156         case CONNECT_BEGIN :
14157             /* always send client hello first */
14158             if ( (ssl->error = SendClientHello(ssl)) != 0) {
14159                 WOLFSSL_ERROR(ssl->error);
14160                 return WOLFSSL_FATAL_ERROR;
14161             }
14162             ssl->options.connectState = CLIENT_HELLO_SENT;
14163             WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
14164             FALL_THROUGH;
14165 
14166         case CLIENT_HELLO_SENT :
14167             neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
14168                                           SERVER_HELLODONE_COMPLETE;
14169             #ifdef WOLFSSL_DTLS
14170                 /* In DTLS, when resuming, we can go straight to FINISHED,
14171                  * or do a cookie exchange and then skip to FINISHED, assume
14172                  * we need the cookie exchange first. */
14173                 if (IsDtlsNotSctpMode(ssl))
14174                     neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
14175             #endif
14176             /* get response */
14177             while (ssl->options.serverState < neededState) {
14178                 #ifdef WOLFSSL_TLS13
14179                     if (ssl->options.tls1_3)
14180                         return wolfSSL_connect_TLSv13(ssl);
14181                 #endif
14182                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
14183                     WOLFSSL_ERROR(ssl->error);
14184                     return WOLFSSL_FATAL_ERROR;
14185                 }
14186                 /* if resumption failed, reset needed state */
14187                 else if (neededState == SERVER_FINISHED_COMPLETE)
14188                     if (!ssl->options.resuming) {
14189                         if (!IsDtlsNotSctpMode(ssl))
14190                             neededState = SERVER_HELLODONE_COMPLETE;
14191                         else
14192                             neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
14193                     }
14194             }
14195 
14196             ssl->options.connectState = HELLO_AGAIN;
14197             WOLFSSL_MSG("connect state: HELLO_AGAIN");
14198             FALL_THROUGH;
14199 
14200         case HELLO_AGAIN :
14201             if (ssl->options.certOnly)
14202                 return WOLFSSL_SUCCESS;
14203 
14204         #ifdef WOLFSSL_TLS13
14205             if (ssl->options.tls1_3)
14206                 return wolfSSL_connect_TLSv13(ssl);
14207         #endif
14208 
14209             #ifdef WOLFSSL_DTLS
14210             if (ssl->options.serverState ==
14211                     SERVER_HELLOVERIFYREQUEST_COMPLETE) {
14212                 if (IsDtlsNotSctpMode(ssl)) {
14213                     /* re-init hashes, exclude first hello and verify request */
14214                     if ((ssl->error = InitHandshakeHashes(ssl)) != 0) {
14215                         WOLFSSL_ERROR(ssl->error);
14216                         return WOLFSSL_FATAL_ERROR;
14217                     }
14218                     if ( (ssl->error = SendClientHello(ssl)) != 0) {
14219                         WOLFSSL_ERROR(ssl->error);
14220                         return WOLFSSL_FATAL_ERROR;
14221                     }
14222                 }
14223             }
14224             #endif
14225 
14226             ssl->options.connectState = HELLO_AGAIN_REPLY;
14227             WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
14228             FALL_THROUGH;
14229 
14230         case HELLO_AGAIN_REPLY :
14231             #ifdef WOLFSSL_DTLS
14232                 if (IsDtlsNotSctpMode(ssl)) {
14233                     neededState = ssl->options.resuming ?
14234                            SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
14235 
14236                     /* get response */
14237                     while (ssl->options.serverState < neededState) {
14238                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
14239                             WOLFSSL_ERROR(ssl->error);
14240                             return WOLFSSL_FATAL_ERROR;
14241                         }
14242                         /* if resumption failed, reset needed state */
14243                         if (neededState == SERVER_FINISHED_COMPLETE) {
14244                             if (!ssl->options.resuming)
14245                                 neededState = SERVER_HELLODONE_COMPLETE;
14246                         }
14247                     }
14248                 }
14249             #endif
14250 
14251             ssl->options.connectState = FIRST_REPLY_DONE;
14252             WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
14253             FALL_THROUGH;
14254 
14255         case FIRST_REPLY_DONE :
14256             #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
14257                 #ifdef WOLFSSL_TLS13
14258                     if (ssl->options.tls1_3)
14259                         return wolfSSL_connect_TLSv13(ssl);
14260                 #endif
14261                 if (ssl->options.sendVerify) {
14262                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
14263                     #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
14264                         ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
14265                     #endif
14266                         WOLFSSL_ERROR(ssl->error);
14267                         return WOLFSSL_FATAL_ERROR;
14268                     }
14269                     WOLFSSL_MSG("sent: certificate");
14270                 }
14271 
14272             #endif
14273             ssl->options.connectState = FIRST_REPLY_FIRST;
14274             WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
14275             FALL_THROUGH;
14276 
14277         case FIRST_REPLY_FIRST :
14278         #ifdef WOLFSSL_TLS13
14279             if (ssl->options.tls1_3)
14280                 return wolfSSL_connect_TLSv13(ssl);
14281         #endif
14282             if (!ssl->options.resuming) {
14283                 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
14284                 #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
14285                     ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
14286                 #endif
14287                     WOLFSSL_ERROR(ssl->error);
14288                     return WOLFSSL_FATAL_ERROR;
14289                 }
14290                 WOLFSSL_MSG("sent: client key exchange");
14291             }
14292 
14293             ssl->options.connectState = FIRST_REPLY_SECOND;
14294             WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
14295             FALL_THROUGH;
14296 
14297     #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
14298         case FIRST_REPLY_SECOND :
14299             #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
14300                 if (ssl->options.sendVerify) {
14301                     if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
14302                     #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
14303                         ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
14304                     #endif
14305                         WOLFSSL_ERROR(ssl->error);
14306                         return WOLFSSL_FATAL_ERROR;
14307                     }
14308                     WOLFSSL_MSG("sent: certificate verify");
14309                 }
14310             #endif /* !NO_CERTS && !WOLFSSL_NO_CLIENT_AUTH */
14311             ssl->options.connectState = FIRST_REPLY_THIRD;
14312             WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
14313             FALL_THROUGH;
14314 
14315         case FIRST_REPLY_THIRD :
14316             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
14317             #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
14318                 ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
14319             #endif
14320                 WOLFSSL_ERROR(ssl->error);
14321                 return WOLFSSL_FATAL_ERROR;
14322             }
14323             WOLFSSL_MSG("sent: change cipher spec");
14324             ssl->options.connectState = FIRST_REPLY_FOURTH;
14325             WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
14326             FALL_THROUGH;
14327 
14328         case FIRST_REPLY_FOURTH :
14329             if ( (ssl->error = SendFinished(ssl)) != 0) {
14330             #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
14331                 ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
14332             #endif
14333                 WOLFSSL_ERROR(ssl->error);
14334                 return WOLFSSL_FATAL_ERROR;
14335             }
14336             WOLFSSL_MSG("sent: finished");
14337             ssl->options.connectState = FINISHED_DONE;
14338             WOLFSSL_MSG("connect state: FINISHED_DONE");
14339             FALL_THROUGH;
14340 
14341         case FINISHED_DONE :
14342             /* get response */
14343             while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
14344                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
14345                     WOLFSSL_ERROR(ssl->error);
14346                     return WOLFSSL_FATAL_ERROR;
14347                 }
14348 
14349             ssl->options.connectState = SECOND_REPLY_DONE;
14350             WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
14351             FALL_THROUGH;
14352 
14353         case SECOND_REPLY_DONE:
14354         #ifndef NO_HANDSHAKE_DONE_CB
14355             if (ssl->hsDoneCb) {
14356                 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
14357                 if (cbret < 0) {
14358                     ssl->error = cbret;
14359                     WOLFSSL_MSG("HandShake Done Cb don't continue error");
14360                     return WOLFSSL_FATAL_ERROR;
14361                 }
14362             }
14363         #endif /* NO_HANDSHAKE_DONE_CB */
14364 
14365             if (!ssl->options.dtls) {
14366                 if (!ssl->options.keepResources) {
14367                     FreeHandshakeResources(ssl);
14368                 }
14369             }
14370         #ifdef WOLFSSL_DTLS
14371             else {
14372                 ssl->options.dtlsHsRetain = 1;
14373             }
14374         #endif /* WOLFSSL_DTLS */
14375 
14376         #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION)
14377             /* This may be necessary in async so that we don't try to
14378              * renegotiate again */
14379             if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
14380                 ssl->secure_renegotiation->startScr = 0;
14381             }
14382         #endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */
14383 
14384             WOLFSSL_LEAVE("SSL_connect()", WOLFSSL_SUCCESS);
14385             return WOLFSSL_SUCCESS;
14386     #endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS */
14387 
14388         default:
14389             WOLFSSL_MSG("Unknown connect state ERROR");
14390             return WOLFSSL_FATAL_ERROR; /* unknown connect state */
14391         }
14392     #endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS || !WOLFSSL_TLS13 */
14393     }
14394 
14395 #endif /* NO_WOLFSSL_CLIENT */
14396 
14397 
14398 /* server only parts */
14399 #ifndef NO_WOLFSSL_SERVER
14400 
14401     #ifdef OPENSSL_EXTRA
wolfSSLv2_server_method(void)14402     WOLFSSL_METHOD* wolfSSLv2_server_method(void)
14403     {
14404         WOLFSSL_STUB("wolfSSLv2_server_method");
14405         return 0;
14406     }
14407     #endif
14408 
14409     #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
wolfSSLv3_server_method(void)14410     WOLFSSL_METHOD* wolfSSLv3_server_method(void)
14411     {
14412         return wolfSSLv3_server_method_ex(NULL);
14413     }
wolfSSLv3_server_method_ex(void * heap)14414     WOLFSSL_METHOD* wolfSSLv3_server_method_ex(void* heap)
14415     {
14416         WOLFSSL_METHOD* method =
14417                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
14418                                                      heap, DYNAMIC_TYPE_METHOD);
14419         (void)heap;
14420         WOLFSSL_ENTER("SSLv3_server_method_ex");
14421         if (method) {
14422             InitSSL_Method(method, MakeSSLv3());
14423             method->side = WOLFSSL_SERVER_END;
14424         }
14425         return method;
14426     }
14427     #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
14428 
wolfSSLv23_server_method(void)14429     WOLFSSL_METHOD* wolfSSLv23_server_method(void)
14430     {
14431         return wolfSSLv23_server_method_ex(NULL);
14432     }
14433 
wolfSSLv23_server_method_ex(void * heap)14434     WOLFSSL_METHOD* wolfSSLv23_server_method_ex(void* heap)
14435     {
14436         WOLFSSL_METHOD* method =
14437                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
14438                                                      heap, DYNAMIC_TYPE_METHOD);
14439         (void)heap;
14440         WOLFSSL_ENTER("SSLv23_server_method_ex");
14441         if (method) {
14442     #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
14443         #ifdef WOLFSSL_TLS13
14444             InitSSL_Method(method, MakeTLSv1_3());
14445         #elif !defined(WOLFSSL_NO_TLS12)
14446             InitSSL_Method(method, MakeTLSv1_2());
14447         #elif !defined(NO_OLD_TLS)
14448             InitSSL_Method(method, MakeTLSv1_1());
14449         #endif
14450     #else
14451         #ifndef NO_OLD_TLS
14452             InitSSL_Method(method, MakeTLSv1_1());
14453         #else
14454             #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
14455         #endif
14456     #endif
14457     #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
14458             method->downgrade = 1;
14459     #endif
14460             method->side      = WOLFSSL_SERVER_END;
14461         }
14462         return method;
14463     }
14464 
14465 
14466     WOLFSSL_ABI
wolfSSL_accept(WOLFSSL * ssl)14467     int wolfSSL_accept(WOLFSSL* ssl)
14468     {
14469 #if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13))
14470         word16 havePSK = 0;
14471         word16 haveAnon = 0;
14472         word16 haveMcast = 0;
14473 #endif
14474 
14475         if (ssl == NULL)
14476             return WOLFSSL_FATAL_ERROR;
14477 
14478     #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
14479         if (ssl->options.side == WOLFSSL_NEITHER_END) {
14480             WOLFSSL_MSG("Setting WOLFSSL_SSL to be server side");
14481             ssl->error = InitSSL_Side(ssl, WOLFSSL_SERVER_END);
14482             if (ssl->error != WOLFSSL_SUCCESS) {
14483                 WOLFSSL_ERROR(ssl->error);
14484                 return WOLFSSL_FATAL_ERROR;
14485             }
14486             ssl->error = 0; /* expected to be zero here */
14487         }
14488     #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
14489 
14490 #if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
14491         return wolfSSL_accept_TLSv13(ssl);
14492 #else
14493     #ifdef WOLFSSL_TLS13
14494         if (ssl->options.tls1_3)
14495             return wolfSSL_accept_TLSv13(ssl);
14496     #endif
14497         WOLFSSL_ENTER("SSL_accept()");
14498 
14499 #ifdef WOLFSSL_WOLFSENTRY_HOOKS
14500         if (ssl->AcceptFilter) {
14501             wolfSSL_netfilter_decision_t res;
14502             if ((ssl->AcceptFilter(ssl, ssl->AcceptFilter_arg, &res) ==
14503                  WOLFSSL_SUCCESS) &&
14504                 (res == WOLFSSL_NETFILTER_REJECT)) {
14505                 WOLFSSL_ERROR(ssl->error = SOCKET_FILTERED_E);
14506                 return WOLFSSL_FATAL_ERROR;
14507             }
14508         }
14509 #endif /* WOLFSSL_WOLFSENTRY_HOOKS */
14510 
14511         #ifdef HAVE_ERRNO_H
14512             errno = 0;
14513         #endif
14514 
14515         #ifndef NO_PSK
14516             havePSK = ssl->options.havePSK;
14517         #endif
14518         (void)havePSK;
14519 
14520         #ifdef HAVE_ANON
14521             haveAnon = ssl->options.haveAnon;
14522         #endif
14523         (void)haveAnon;
14524 
14525         #ifdef WOLFSSL_MULTICAST
14526             haveMcast = ssl->options.haveMcast;
14527         #endif
14528         (void)haveMcast;
14529 
14530         if (ssl->options.side != WOLFSSL_SERVER_END) {
14531             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
14532             return WOLFSSL_FATAL_ERROR;
14533         }
14534 
14535     #ifndef NO_CERTS
14536         /* in case used set_accept_state after init */
14537         /* allow no private key if using PK callbacks and CB is set */
14538         if (!havePSK && !haveAnon && !haveMcast) {
14539         #ifdef OPENSSL_EXTRA
14540             if (ssl->ctx->certSetupCb != NULL) {
14541                 WOLFSSL_MSG("CertSetupCb set. server cert and "
14542                             "key not checked");
14543             }
14544             else
14545         #endif
14546             {
14547                 if (!ssl->buffers.certificate ||
14548                     !ssl->buffers.certificate->buffer) {
14549 
14550                     WOLFSSL_MSG("accept error: server cert required");
14551                     ssl->error = NO_PRIVATE_KEY;
14552                     WOLFSSL_ERROR(ssl->error);
14553                     return WOLFSSL_FATAL_ERROR;
14554                 }
14555 
14556             #ifdef HAVE_PK_CALLBACKS
14557                 if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) {
14558                     WOLFSSL_MSG("Using PK for server private key");
14559                 }
14560                 else
14561             #endif
14562                 if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
14563                     WOLFSSL_MSG("accept error: server key required");
14564                     ssl->error = NO_PRIVATE_KEY;
14565                     WOLFSSL_ERROR(ssl->error);
14566                     return WOLFSSL_FATAL_ERROR;
14567                 }
14568             }
14569         }
14570     #endif
14571 
14572     #ifdef WOLFSSL_DTLS
14573         if (ssl->version.major == DTLS_MAJOR) {
14574             ssl->options.dtls   = 1;
14575             ssl->options.tls    = 1;
14576             ssl->options.tls1_1 = 1;
14577         }
14578     #endif
14579 
14580         if (ssl->buffers.outputBuffer.length > 0
14581         #ifdef WOLFSSL_ASYNC_CRYPT
14582             /* do not send buffered or advance state if last error was an
14583                 async pending operation */
14584             && ssl->error != WC_PENDING_E
14585         #endif
14586         ) {
14587             if ( (ssl->error = SendBuffered(ssl)) == 0) {
14588                 /* fragOffset is non-zero when sending fragments. On the last
14589                  * fragment, fragOffset is zero again, and the state can be
14590                  * advanced. */
14591                 if (ssl->fragOffset == 0) {
14592                     ssl->options.acceptState++;
14593                     WOLFSSL_MSG("accept state: "
14594                                 "Advanced from last buffered fragment send");
14595                 }
14596                 else {
14597                     WOLFSSL_MSG("accept state: "
14598                                 "Not advanced, more fragments to send");
14599                 }
14600             }
14601             else {
14602                 WOLFSSL_ERROR(ssl->error);
14603                 return WOLFSSL_FATAL_ERROR;
14604             }
14605         }
14606 
14607         switch (ssl->options.acceptState) {
14608 
14609         case ACCEPT_BEGIN :
14610 #ifdef HAVE_SECURE_RENEGOTIATION
14611         case ACCEPT_BEGIN_RENEG:
14612 #endif
14613             /* get response */
14614             while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
14615                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
14616                     WOLFSSL_ERROR(ssl->error);
14617                     return WOLFSSL_FATAL_ERROR;
14618                 }
14619 #ifdef WOLFSSL_TLS13
14620             ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
14621             WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
14622             FALL_THROUGH;
14623 
14624         case ACCEPT_CLIENT_HELLO_DONE :
14625             if (ssl->options.tls1_3) {
14626                 return wolfSSL_accept_TLSv13(ssl);
14627             }
14628 #endif
14629             ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
14630             WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
14631             FALL_THROUGH;
14632 
14633         case ACCEPT_FIRST_REPLY_DONE :
14634             if ( (ssl->error = SendServerHello(ssl)) != 0) {
14635                 WOLFSSL_ERROR(ssl->error);
14636                 return WOLFSSL_FATAL_ERROR;
14637             }
14638             ssl->options.acceptState = SERVER_HELLO_SENT;
14639             WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
14640             FALL_THROUGH;
14641 
14642         case SERVER_HELLO_SENT :
14643         #ifdef WOLFSSL_TLS13
14644             if (ssl->options.tls1_3) {
14645                 return wolfSSL_accept_TLSv13(ssl);
14646             }
14647         #endif
14648             #ifndef NO_CERTS
14649                 if (!ssl->options.resuming)
14650                     if ( (ssl->error = SendCertificate(ssl)) != 0) {
14651                         WOLFSSL_ERROR(ssl->error);
14652                         return WOLFSSL_FATAL_ERROR;
14653                     }
14654             #endif
14655             ssl->options.acceptState = CERT_SENT;
14656             WOLFSSL_MSG("accept state CERT_SENT");
14657             FALL_THROUGH;
14658 
14659         case CERT_SENT :
14660             #ifndef NO_CERTS
14661             if (!ssl->options.resuming)
14662                 if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
14663                     WOLFSSL_ERROR(ssl->error);
14664                     return WOLFSSL_FATAL_ERROR;
14665                 }
14666             #endif
14667             ssl->options.acceptState = CERT_STATUS_SENT;
14668             WOLFSSL_MSG("accept state CERT_STATUS_SENT");
14669             FALL_THROUGH;
14670 
14671         case CERT_STATUS_SENT :
14672         #ifdef WOLFSSL_TLS13
14673             if (ssl->options.tls1_3) {
14674                 return wolfSSL_accept_TLSv13(ssl);
14675             }
14676         #endif
14677             if (!ssl->options.resuming)
14678                 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
14679                     WOLFSSL_ERROR(ssl->error);
14680                     return WOLFSSL_FATAL_ERROR;
14681                 }
14682             ssl->options.acceptState = KEY_EXCHANGE_SENT;
14683             WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
14684             FALL_THROUGH;
14685 
14686         case KEY_EXCHANGE_SENT :
14687             #ifndef NO_CERTS
14688                 if (!ssl->options.resuming) {
14689                     if (ssl->options.verifyPeer) {
14690                         if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
14691                             WOLFSSL_ERROR(ssl->error);
14692                             return WOLFSSL_FATAL_ERROR;
14693                         }
14694                     }
14695                 }
14696             #endif
14697             ssl->options.acceptState = CERT_REQ_SENT;
14698             WOLFSSL_MSG("accept state CERT_REQ_SENT");
14699             FALL_THROUGH;
14700 
14701         case CERT_REQ_SENT :
14702             if (!ssl->options.resuming)
14703                 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
14704                     WOLFSSL_ERROR(ssl->error);
14705                     return WOLFSSL_FATAL_ERROR;
14706                 }
14707             ssl->options.acceptState = SERVER_HELLO_DONE;
14708             WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
14709             FALL_THROUGH;
14710 
14711         case SERVER_HELLO_DONE :
14712             if (!ssl->options.resuming) {
14713                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
14714                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
14715                         WOLFSSL_ERROR(ssl->error);
14716                         return WOLFSSL_FATAL_ERROR;
14717                     }
14718             }
14719             ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
14720             WOLFSSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
14721             FALL_THROUGH;
14722 
14723         case ACCEPT_SECOND_REPLY_DONE :
14724 #ifdef HAVE_SESSION_TICKET
14725             if (ssl->options.createTicket && !ssl->options.noTicketTls12) {
14726                 if ( (ssl->error = SendTicket(ssl)) != 0) {
14727                     WOLFSSL_ERROR(ssl->error);
14728                     return WOLFSSL_FATAL_ERROR;
14729                 }
14730             }
14731 #endif /* HAVE_SESSION_TICKET */
14732             ssl->options.acceptState = TICKET_SENT;
14733             WOLFSSL_MSG("accept state  TICKET_SENT");
14734             FALL_THROUGH;
14735 
14736         case TICKET_SENT:
14737             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
14738                 WOLFSSL_ERROR(ssl->error);
14739                 return WOLFSSL_FATAL_ERROR;
14740             }
14741             ssl->options.acceptState = CHANGE_CIPHER_SENT;
14742             WOLFSSL_MSG("accept state  CHANGE_CIPHER_SENT");
14743             FALL_THROUGH;
14744 
14745         case CHANGE_CIPHER_SENT :
14746             if ( (ssl->error = SendFinished(ssl)) != 0) {
14747                 WOLFSSL_ERROR(ssl->error);
14748                 return WOLFSSL_FATAL_ERROR;
14749             }
14750 
14751             ssl->options.acceptState = ACCEPT_FINISHED_DONE;
14752             WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
14753             FALL_THROUGH;
14754 
14755         case ACCEPT_FINISHED_DONE :
14756             if (ssl->options.resuming)
14757                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
14758                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
14759                         WOLFSSL_ERROR(ssl->error);
14760                         return WOLFSSL_FATAL_ERROR;
14761                     }
14762 
14763             ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
14764             WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
14765             FALL_THROUGH;
14766 
14767         case ACCEPT_THIRD_REPLY_DONE :
14768 #ifndef NO_HANDSHAKE_DONE_CB
14769             if (ssl->hsDoneCb) {
14770                 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
14771                 if (cbret < 0) {
14772                     ssl->error = cbret;
14773                     WOLFSSL_MSG("HandShake Done Cb don't continue error");
14774                     return WOLFSSL_FATAL_ERROR;
14775                 }
14776             }
14777 #endif /* NO_HANDSHAKE_DONE_CB */
14778 
14779             if (!ssl->options.dtls) {
14780                 if (!ssl->options.keepResources) {
14781                     FreeHandshakeResources(ssl);
14782                 }
14783             }
14784 #ifdef WOLFSSL_DTLS
14785             else {
14786                 ssl->options.dtlsHsRetain = 1;
14787             }
14788 #endif /* WOLFSSL_DTLS */
14789 
14790 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION)
14791             /* This may be necessary in async so that we don't try to
14792              * renegotiate again */
14793             if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
14794                 ssl->secure_renegotiation->startScr = 0;
14795             }
14796 #endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */
14797 
14798 #if defined(WOLFSSL_SESSION_EXPORT) && defined(WOLFSSL_DTLS)
14799             if (ssl->dtls_export) {
14800                 if ((ssl->error = wolfSSL_send_session(ssl)) != 0) {
14801                     WOLFSSL_MSG("Export DTLS session error");
14802                     WOLFSSL_ERROR(ssl->error);
14803                     return WOLFSSL_FATAL_ERROR;
14804                 }
14805             }
14806 #endif
14807 
14808             WOLFSSL_LEAVE("SSL_accept()", WOLFSSL_SUCCESS);
14809             return WOLFSSL_SUCCESS;
14810 
14811         default :
14812             WOLFSSL_MSG("Unknown accept state ERROR");
14813             return WOLFSSL_FATAL_ERROR;
14814         }
14815 #endif /* !WOLFSSL_NO_TLS12 */
14816     }
14817 
14818 #endif /* NO_WOLFSSL_SERVER */
14819 
14820 
14821 #ifndef NO_HANDSHAKE_DONE_CB
14822 
wolfSSL_SetHsDoneCb(WOLFSSL * ssl,HandShakeDoneCb cb,void * user_ctx)14823 int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
14824 {
14825     WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
14826 
14827     if (ssl == NULL)
14828         return BAD_FUNC_ARG;
14829 
14830     ssl->hsDoneCb  = cb;
14831     ssl->hsDoneCtx = user_ctx;
14832 
14833 
14834     return WOLFSSL_SUCCESS;
14835 }
14836 
14837 #endif /* NO_HANDSHAKE_DONE_CB */
14838 
14839 WOLFSSL_ABI
wolfSSL_Cleanup(void)14840 int wolfSSL_Cleanup(void)
14841 {
14842     int ret = WOLFSSL_SUCCESS; /* Only the first error will be returned */
14843     int release = 0;
14844 #if !defined(NO_SESSION_CACHE) && defined(ENABLE_SESSION_CACHE_ROW_LOCK)
14845     int i;
14846 #endif
14847 
14848     WOLFSSL_ENTER("wolfSSL_Cleanup");
14849 
14850     if (initRefCount == 0)
14851         return ret;  /* possibly no init yet, but not failure either way */
14852 
14853     if ((count_mutex_valid == 1) && (wc_LockMutex(&count_mutex) != 0)) {
14854         WOLFSSL_MSG("Bad Lock Mutex count");
14855         ret = BAD_MUTEX_E;
14856     }
14857 
14858     release = initRefCount-- == 1;
14859     if (initRefCount < 0)
14860         initRefCount = 0;
14861 
14862     if (count_mutex_valid == 1) {
14863         wc_UnLockMutex(&count_mutex);
14864     }
14865 
14866     if (!release)
14867         return ret;
14868 
14869 #ifdef OPENSSL_EXTRA
14870     if (bn_one) {
14871         wolfSSL_BN_free(bn_one);
14872         bn_one = NULL;
14873     }
14874 #endif
14875 
14876 #ifndef NO_SESSION_CACHE
14877     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
14878     for (i = 0; i < SESSION_ROWS; ++i) {
14879         if ((SessionCache[i].mutex_valid == 1) &&
14880             (wc_FreeMutex(&SessionCache[i].row_mutex) != 0)) {
14881             if (ret == WOLFSSL_SUCCESS)
14882                 ret = BAD_MUTEX_E;
14883         }
14884         SessionCache[i].mutex_valid = 0;
14885     }
14886     #else
14887     if ((session_mutex_valid == 1) && (wc_FreeMutex(&session_mutex) != 0)) {
14888         if (ret == WOLFSSL_SUCCESS)
14889             ret = BAD_MUTEX_E;
14890     }
14891     session_mutex_valid = 0;
14892     #endif
14893     #ifndef NO_CLIENT_CACHE
14894     if ((clisession_mutex_valid == 1) &&
14895         (wc_FreeMutex(&clisession_mutex) != 0)) {
14896         if (ret == WOLFSSL_SUCCESS)
14897             ret = BAD_MUTEX_E;
14898     }
14899     clisession_mutex_valid = 0;
14900     #endif
14901 #endif /* !NO_SESSION_CACHE */
14902 
14903     if ((count_mutex_valid == 1) && (wc_FreeMutex(&count_mutex) != 0)) {
14904         if (ret == WOLFSSL_SUCCESS)
14905             ret = BAD_MUTEX_E;
14906     }
14907     count_mutex_valid = 0;
14908 
14909 #ifdef OPENSSL_EXTRA
14910     wolfSSL_RAND_Cleanup();
14911 #endif
14912 
14913     if (wolfCrypt_Cleanup() != 0) {
14914         WOLFSSL_MSG("Error with wolfCrypt_Cleanup call");
14915         if (ret == WOLFSSL_SUCCESS)
14916             ret = WC_CLEANUP_E;
14917     }
14918 
14919 #if defined(HAVE_FIPS_VERSION) && ((HAVE_FIPS_VERSION > 5) || ((HAVE_FIPS_VERSION == 5) && (HAVE_FIPS_VERSION_MINOR >= 1)))
14920     if (wolfCrypt_SetPrivateKeyReadEnable_fips(0, WC_KEYTYPE_ALL) < 0) {
14921         if (ret == WOLFSSL_SUCCESS)
14922             ret = WC_CLEANUP_E;
14923     }
14924 #endif
14925 
14926 #ifdef HAVE_GLOBAL_RNG
14927     if ((globalRNGMutex_valid == 1) && (wc_FreeMutex(&globalRNGMutex) != 0)) {
14928         if (ret == WOLFSSL_SUCCESS)
14929             ret = BAD_MUTEX_E;
14930     }
14931     globalRNGMutex_valid = 0;
14932 #endif
14933     return ret;
14934 }
14935 
14936 
GetSessionPtr(const WOLFSSL_SESSION * s)14937 static WC_INLINE WOLFSSL_SESSION* GetSessionPtr(const WOLFSSL_SESSION* s)
14938 {
14939 #ifdef ENABLE_CLIENT_SESSION_REF
14940     if (s && s->type == WOLFSSL_SESSION_TYPE_REF) {
14941         s = (const WOLFSSL_SESSION*)s->refPtr;
14942     }
14943 #endif
14944     return (WOLFSSL_SESSION*)s;
14945 }
14946 
14947 #ifndef NO_SESSION_CACHE
14948 
14949 /* some session IDs aren't random after all, let's make them random */
HashSession(const byte * sessionID,word32 len,int * error)14950 static WC_INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
14951 {
14952     byte digest[WC_MAX_DIGEST_SIZE];
14953 
14954 #ifndef NO_MD5
14955     *error =  wc_Md5Hash(sessionID, len, digest);
14956 #elif !defined(NO_SHA)
14957     *error =  wc_ShaHash(sessionID, len, digest);
14958 #elif !defined(NO_SHA256)
14959     *error =  wc_Sha256Hash(sessionID, len, digest);
14960 #else
14961     #error "We need a digest to hash the session IDs"
14962 #endif
14963 
14964     return *error == 0 ? MakeWordFromHash(digest) : 0; /* 0 on failure */
14965 }
14966 
14967 
14968 WOLFSSL_ABI
wolfSSL_flush_sessions(WOLFSSL_CTX * ctx,long tm)14969 void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
14970 {
14971     /* static table now, no flushing needed */
14972     (void)ctx;
14973     (void)tm;
14974 }
14975 
14976 
14977 /* set ssl session timeout in seconds */
14978 WOLFSSL_ABI
wolfSSL_set_timeout(WOLFSSL * ssl,unsigned int to)14979 int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
14980 {
14981     if (ssl == NULL)
14982         return BAD_FUNC_ARG;
14983 
14984     if (to == 0)
14985         to = WOLFSSL_SESSION_TIMEOUT;
14986     ssl->timeout = to;
14987 
14988     return WOLFSSL_SUCCESS;
14989 }
14990 
14991 
14992 /**
14993  * Sets ctx session timeout in seconds.
14994  * The timeout value set here should be reflected in the
14995  * "session ticket lifetime hint" if this API works in the openssl compat-layer.
14996  * Therefore wolfSSL_CTX_set_TicketHint is called internally.
14997  * Arguments:
14998  *  - ctx  WOLFSSL_CTX object which the timeout is set to
14999  *  - to   timeout value in second
15000  * Returns:
15001  *  WOLFSSL_SUCCESS on success, BAD_FUNC_ARG on failure.
15002  *  When WOLFSSL_ERROR_CODE_OPENSSL is defined, returns previous timeout value
15003  *  on success, BAD_FUNC_ARG on failure.
15004  */
15005 WOLFSSL_ABI
wolfSSL_CTX_set_timeout(WOLFSSL_CTX * ctx,unsigned int to)15006 int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
15007 {
15008     #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
15009     word32 prev_timeout;
15010     #endif
15011 
15012     int ret = WOLFSSL_SUCCESS;
15013     (void)ret;
15014 
15015     if (ctx == NULL)
15016         ret = BAD_FUNC_ARG;
15017 
15018     if (ret == WOLFSSL_SUCCESS) {
15019     #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
15020         prev_timeout = ctx->timeout;
15021     #endif
15022         if (to == 0) {
15023             ctx->timeout = WOLFSSL_SESSION_TIMEOUT;
15024         }
15025         else {
15026             ctx->timeout = to;
15027         }
15028     }
15029 #if defined(OPENSSL_EXTRA) && defined(HAVE_SESSION_TICKET) && \
15030    !defined(NO_WOLFSSL_SERVER)
15031     if (ret == WOLFSSL_SUCCESS) {
15032         if (to == 0) {
15033             ret = wolfSSL_CTX_set_TicketHint(ctx, SESSION_TICKET_HINT_DEFAULT);
15034         }
15035         else {
15036             ret = wolfSSL_CTX_set_TicketHint(ctx, to);
15037         }
15038     }
15039 #endif /* OPENSSL_EXTRA && HAVE_SESSION_TICKET && !NO_WOLFSSL_SERVER */
15040 
15041 #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
15042     if (ret == WOLFSSL_SUCCESS) {
15043         return prev_timeout;
15044     }
15045     else {
15046         return ret;
15047     }
15048 #else
15049     return ret;
15050 #endif /* WOLFSSL_ERROR_CODE_OPENSSL */
15051 }
15052 
15053 
15054 #ifndef NO_CLIENT_CACHE
15055 
15056 /* Get Session from Client cache based on id/len, return NULL on failure */
GetSessionClient(WOLFSSL * ssl,const byte * id,int len)15057 WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
15058 {
15059     WOLFSSL_SESSION* ret = NULL;
15060     word32          row;
15061     int             idx;
15062     int             count;
15063     int             error = 0;
15064     ClientSession*  clSess;
15065 
15066     WOLFSSL_ENTER("GetSessionClient");
15067 
15068     if (ssl->ctx->sessionCacheOff)
15069         return NULL;
15070 
15071     if (ssl->options.side == WOLFSSL_SERVER_END)
15072         return NULL;
15073 
15074     len = min(SERVER_ID_LEN, (word32)len);
15075 
15076 #ifdef HAVE_EXT_CACHE
15077     if (ssl->ctx->get_sess_cb != NULL) {
15078         int copy = 0;
15079         ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, len, &copy);
15080         if (ret != NULL)
15081             return ret;
15082     }
15083 
15084     if (ssl->ctx->internalCacheOff)
15085         return NULL;
15086 #endif
15087 
15088     row = HashSession(id, len, &error) % SESSION_ROWS;
15089     if (error != 0) {
15090         WOLFSSL_MSG("Hash session failed");
15091         return NULL;
15092     }
15093 
15094     if (wc_LockMutex(&clisession_mutex) != 0) {
15095         WOLFSSL_MSG("Client cache mutex lock failed");
15096         return NULL;
15097     }
15098 
15099     /* start from most recently used */
15100     count = min((word32)ClientCache[row].totalCount, SESSIONS_PER_ROW);
15101     idx = ClientCache[row].nextIdx - 1;
15102     if (idx < 0 || idx >= SESSIONS_PER_ROW) {
15103         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
15104     }
15105     clSess = ClientCache[row].Clients;
15106 
15107     for (; count > 0; --count) {
15108         WOLFSSL_SESSION* current;
15109         SessionRow* sessRow;
15110 
15111         if (clSess[idx].serverRow >= SESSION_ROWS) {
15112             WOLFSSL_MSG("Client cache serverRow invalid");
15113             break;
15114         }
15115 
15116         /* lock row */
15117         sessRow = &SessionCache[clSess[idx].serverRow];
15118         if (SESSION_ROW_LOCK(sessRow) != 0) {
15119             WOLFSSL_MSG("Session cache row lock failure");
15120             break;
15121         }
15122 
15123         current = &sessRow->Sessions[clSess[idx].serverIdx];
15124         if (XMEMCMP(current->serverID, id, len) == 0) {
15125             WOLFSSL_MSG("Found a serverid match for client");
15126             if (LowResTimer() < (current->bornOn + current->timeout)) {
15127                 WOLFSSL_MSG("Session valid");
15128                 ret = current;
15129                 SESSION_ROW_UNLOCK(sessRow);
15130                 break;
15131             } else {
15132                 WOLFSSL_MSG("Session timed out");  /* could have more for id */
15133             }
15134         } else {
15135             WOLFSSL_MSG("ServerID not a match from client table");
15136         }
15137         SESSION_ROW_UNLOCK(sessRow);
15138 
15139         idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1;
15140     }
15141 
15142     wc_UnLockMutex(&clisession_mutex);
15143 
15144     return ret;
15145 }
15146 
15147 #endif /* !NO_CLIENT_CACHE */
15148 
15149 /* Restore the master secret and session information for certificates.
15150  *
15151  * ssl                  The SSL/TLS object.
15152  * session              The cached session to restore.
15153  * masterSecret         The master secret from the cached session.
15154  * restoreSessionCerts  Restoring session certificates is required.
15155  */
RestoreSession(WOLFSSL * ssl,WOLFSSL_SESSION * session,byte * masterSecret,byte restoreSessionCerts)15156 static WC_INLINE void RestoreSession(WOLFSSL* ssl, WOLFSSL_SESSION* session,
15157         byte* masterSecret, byte restoreSessionCerts)
15158 {
15159     (void)ssl;
15160     (void)restoreSessionCerts;
15161 
15162     if (masterSecret)
15163         XMEMCPY(masterSecret, session->masterSecret, SECRET_LEN);
15164 #ifdef SESSION_CERTS
15165     /* If set, we should copy the session certs into the ssl object
15166      * from the session we are returning so we can resume */
15167     if (restoreSessionCerts) {
15168         ssl->session.chain        = session->chain;
15169         ssl->session.version      = session->version;
15170     #ifdef NO_RESUME_SUITE_CHECK
15171         ssl->session.cipherSuite0 = session->cipherSuite0;
15172         ssl->session.cipherSuite  = session->cipherSuite;
15173     #endif
15174     }
15175 #endif /* SESSION_CERTS */
15176 #if !defined(NO_RESUME_SUITE_CHECK) || \
15177                         (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
15178     ssl->session.cipherSuite0 = session->cipherSuite0;
15179     ssl->session.cipherSuite  = session->cipherSuite;
15180 #endif
15181 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15182     ssl->peerVerifyRet = (unsigned long)session->peerVerifyRet;
15183 #endif
15184 }
15185 
SslSessionCacheOff(const WOLFSSL * ssl,const WOLFSSL_SESSION * session)15186 static int SslSessionCacheOff(const WOLFSSL* ssl, const WOLFSSL_SESSION* session)
15187 {
15188     (void)session;
15189     return ssl->options.sessionCacheOff
15190     #if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_FORCE_CACHE_ON_TICKET)
15191                 && session->ticketLen == 0
15192     #endif
15193     #ifdef OPENSSL_EXTRA
15194                 && ssl->options.side != WOLFSSL_CLIENT_END
15195     #endif
15196                 ;
15197 }
15198 
GetSession(WOLFSSL * ssl,byte * masterSecret,byte restoreSessionCerts)15199 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
15200         byte restoreSessionCerts)
15201 {
15202     WOLFSSL_SESSION* ret = NULL;
15203     const byte*  id = NULL;
15204     word32       row;
15205     int          idx;
15206     int          count;
15207     int          error = 0;
15208     SessionRow*  sessRow;
15209 
15210     (void)restoreSessionCerts;
15211 
15212     if (SslSessionCacheOff(ssl, &ssl->session))
15213         return NULL;
15214 
15215     if (ssl->options.haveSessionId == 0)
15216         return NULL;
15217 
15218 #ifdef HAVE_SESSION_TICKET
15219     if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
15220         return NULL;
15221 #endif
15222 
15223     if (!ssl->options.tls1_3 && ssl->arrays != NULL)
15224         id = ssl->arrays->sessionID;
15225     else
15226         id = ssl->session.sessionID;
15227 
15228 #ifdef HAVE_EXT_CACHE
15229     if (ssl->ctx->get_sess_cb != NULL) {
15230         int copy = 0;
15231         /* Attempt to retrieve the session from the external cache. */
15232         ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, ID_LEN, &copy);
15233         if (ret != NULL) {
15234             RestoreSession(ssl, ret, masterSecret, restoreSessionCerts);
15235             return ret;
15236         }
15237     }
15238 
15239     if (ssl->ctx->internalCacheOff)
15240         return NULL;
15241 #endif
15242 
15243     row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
15244     if (error != 0) {
15245         WOLFSSL_MSG("Hash session failed");
15246         return NULL;
15247     }
15248 
15249     /* lock row */
15250     sessRow = &SessionCache[row];
15251     if (SESSION_ROW_LOCK(sessRow) != 0) {
15252         WOLFSSL_MSG("Session cache row lock failure");
15253         return NULL;
15254     }
15255 
15256     /* start from most recently used */
15257     count = min((word32)sessRow->totalCount, SESSIONS_PER_ROW);
15258     idx = sessRow->nextIdx - 1;
15259     if (idx < 0 || idx >= SESSIONS_PER_ROW) {
15260         idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
15261     }
15262 
15263     for (; count > 0; --count) {
15264         WOLFSSL_SESSION* current;
15265 
15266         current = &sessRow->Sessions[idx];
15267         if (XMEMCMP(current->sessionID, id, ID_LEN) == 0 &&
15268                 current->side == ssl->options.side) {
15269             WOLFSSL_MSG("Found a session match");
15270             if (LowResTimer() < (current->bornOn + current->timeout)) {
15271                 WOLFSSL_MSG("Session valid");
15272                 ret = current;
15273 
15274                 RestoreSession(ssl, ret, masterSecret, restoreSessionCerts);
15275             } else {
15276                 WOLFSSL_MSG("Session timed out");
15277             }
15278             break;  /* no more sessionIDs whether valid or not that match */
15279         } else {
15280             WOLFSSL_MSG("SessionID not a match at this idx");
15281         }
15282 
15283         idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1;
15284     }
15285 
15286     SESSION_ROW_UNLOCK(sessRow);
15287 
15288     return ret;
15289 }
15290 
SetSession(WOLFSSL * ssl,WOLFSSL_SESSION * session)15291 int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
15292 {
15293     int ret = WOLFSSL_SUCCESS, row = -1;
15294 #ifdef HAVE_SESSION_TICKET
15295     int   ticLenAlloc;
15296     byte *ticBuff = NULL;
15297 #endif
15298 #ifdef ENABLE_CLIENT_SESSION_REF
15299     WOLFSSL_SESSION* ref = NULL;
15300 #endif
15301 
15302     if (ssl == NULL || session == NULL || SslSessionCacheOff(ssl, session)) {
15303         return WOLFSSL_FAILURE;
15304     }
15305 
15306     row = session->cacheRow;
15307 #ifdef ENABLE_CLIENT_SESSION_REF
15308     if (session->type == WOLFSSL_SESSION_TYPE_REF) {
15309         if (session->refPtr == NULL) {
15310             WOLFSSL_MSG("Invalid session reference");
15311             ret = WOLFSSL_FAILURE;
15312         }
15313         if (ret == WOLFSSL_SUCCESS) {
15314             int error = 0;
15315             ref = session; /* keep copy of ref for later */
15316             session = (WOLFSSL_SESSION*)session->refPtr;
15317             row = HashSession(ref->sessionID, ID_LEN, &error) % SESSION_ROWS;
15318             if (error != 0) {
15319                 WOLFSSL_MSG("Hash session failed");
15320                 ret = WOLFSSL_FAILURE;
15321             }
15322         }
15323     }
15324 #endif
15325 
15326     if (row < 0 || row >= SESSION_ROWS) {
15327         return BAD_FUNC_ARG;
15328     }
15329 
15330     /* lock session cache row */
15331     if (SESSION_ROW_LOCK(&SessionCache[row]) != 0) {
15332         return BAD_MUTEX_E;
15333     }
15334 
15335 #ifdef ENABLE_CLIENT_SESSION_REF
15336     /* verify if ID matches session cache entry */
15337     if (ref != NULL &&
15338             XMEMCMP(ref->sessionID, session->sessionID, ID_LEN) != 0) {
15339         WOLFSSL_MSG("Session cache reference not longer valid");
15340         ret = WOLFSSL_FAILURE;
15341     }
15342 #endif
15343 
15344 #ifdef HAVE_SESSION_TICKET
15345     /* cache the old dynamic buffer and try to reuse or free later */
15346     ticLenAlloc = ssl->session.ticketLenAlloc;
15347     if (ticLenAlloc > 0) {
15348         ticBuff = ssl->session.ticket;
15349     }
15350 #endif
15351 
15352     /* copy session structure */
15353     XMEMCPY(&ssl->session, session, sizeof(WOLFSSL_SESSION));
15354     ssl->session.type = WOLFSSL_SESSION_TYPE_SSL;
15355     ssl->session.masterSecret = ssl->session._masterSecret;
15356 #ifndef NO_CLIENT_CACHE
15357     ssl->session.serverID = ssl->session._serverID;
15358 #endif
15359 #ifdef OPENSSL_EXTRA
15360     ssl->session.sessionCtx = ssl->session._sessionCtx;
15361 #endif
15362 
15363 #ifdef HAVE_SESSION_TICKET
15364     /* try and use existing buffer */
15365     if (ssl->session.ticketLenAlloc > 0 && ticBuff != NULL &&
15366                                        ticLenAlloc >= ssl->session.ticketLen) {
15367         XMEMCPY(ticBuff, session->ticket, ssl->session.ticketLen);
15368         ssl->session.ticket = ticBuff;
15369         ssl->session.ticketLenAlloc = ticLenAlloc;
15370         ticBuff = NULL; /* don't free later after unlock */
15371     }
15372     else {
15373         /* Default ticket to non dynamic */
15374         ssl->session.ticket = ssl->session._staticTicket;
15375         ssl->session.ticketLenAlloc = 0;
15376     }
15377 #endif
15378 
15379     SESSION_ROW_UNLOCK(&SessionCache[row]);
15380 
15381 #ifdef HAVE_SESSION_TICKET
15382     if (ret == WOLFSSL_SUCCESS) {
15383         if (ticBuff != NULL) {
15384             /* free old ticket buffer */
15385             XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
15386         }
15387         /* allocate new one */
15388         ticBuff = (byte*)XMALLOC(ssl->session.ticketLen, ssl->heap,
15389                                  DYNAMIC_TYPE_SESSION_TICK);
15390         if (ticBuff != NULL) {
15391             XMEMSET(ticBuff, 0, ssl->session.ticketLen);
15392             ssl->session.ticketLenAlloc = (word16)ssl->session.ticketLen;
15393             ssl->session.ticket = ticBuff;
15394         }
15395         else {
15396             ret = MEMORY_ERROR;
15397         }
15398         if (ret == WOLFSSL_SUCCESS && SESSION_ROW_LOCK(&SessionCache[row]) != 0) {
15399             ret = BAD_MUTEX_E;
15400         }
15401         if (ret == WOLFSSL_SUCCESS && session->ticketLen != ssl->session.ticketLen) {
15402             /* Another thread modified the ssl->session ticket during alloc.
15403              * Treat as error, since ticket different than when copy requested */
15404             ret = VAR_STATE_CHANGE_E;
15405         }
15406         if (ret == WOLFSSL_SUCCESS) {
15407             XMEMCPY(ssl->session.ticket, session->ticket, ssl->session.ticketLen);
15408         }
15409         if (ret != BAD_MUTEX_E) {
15410             SESSION_ROW_UNLOCK(&SessionCache[row]);
15411         }
15412     }
15413 #endif
15414 
15415     if (ret != WOLFSSL_SUCCESS) {
15416     #ifdef HAVE_SESSION_TICKET
15417         /* cleanup */
15418         if (ssl->session.ticket != ssl->session._staticTicket) {
15419             XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
15420         }
15421         ssl->session.ticket = ssl->session._staticTicket;
15422         ssl->session.ticketLenAlloc = 0;
15423     #endif
15424         return ret;
15425     }
15426     session = NULL; /* invalidate the provided session, only use ssl->session */
15427 
15428 #ifdef OPENSSL_EXTRA
15429     /* check for application context id */
15430     if (ssl->sessionCtxSz > 0) {
15431         if (XMEMCMP(ssl->sessionCtx, ssl->session.sessionCtx, ssl->sessionCtxSz)) {
15432             /* context id did not match! */
15433             WOLFSSL_MSG("Session context did not match");
15434             return WOLFSSL_FAILURE;
15435         }
15436     }
15437 #endif /* OPENSSL_EXTRA */
15438 
15439     if (LowResTimer() < (ssl->session.bornOn + ssl->session.timeout)) {
15440         ssl->options.resuming = 1;
15441 
15442 #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
15443                                defined(HAVE_SESSION_TICKET))
15444         ssl->version              = ssl->session.version;
15445 #endif
15446 #if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
15447                         (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
15448         ssl->options.cipherSuite0 = ssl->session.cipherSuite0;
15449         ssl->options.cipherSuite  = ssl->session.cipherSuite;
15450 #endif
15451         ret = WOLFSSL_SUCCESS;
15452     }
15453     else {
15454 #if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL)
15455         WOLFSSL_MSG("Session is expired but return success for \
15456                               OpenSSL compatibility");
15457         ret = WOLFSSL_SUCCESS;
15458 #else
15459         ret = WOLFSSL_FAILURE;  /* session timed out */
15460 #endif /* OPENSSL_EXTRA && WOLFSSL_ERROR_CODE_OPENSSL */
15461     }
15462     return ret;
15463 }
15464 
15465 
15466 #ifdef WOLFSSL_SESSION_STATS
15467 static int get_locked_session_stats(word32* active, word32* total,
15468                                     word32* peak);
15469 #endif
15470 
AddSession(WOLFSSL * ssl)15471 int AddSession(WOLFSSL* ssl)
15472 {
15473     word32 row = 0;
15474     word32 idx = 0;
15475     int    error = 0;
15476     const byte* id = NULL;
15477 #ifdef HAVE_SESSION_TICKET
15478     byte*  ticBuff = NULL;
15479     int    ticLen  = 0;
15480 #endif
15481     WOLFSSL_SESSION* session;
15482     int i;
15483     int overwrite = 0;
15484 #ifdef HAVE_EXT_CACHE
15485     int cbRet = 0;
15486 #endif
15487     SessionRow* sessRow = NULL;
15488 
15489     if (SslSessionCacheOff(ssl, &ssl->session))
15490         return 0;
15491 
15492     if (ssl->options.haveSessionId == 0)
15493         return 0;
15494 
15495 #ifdef HAVE_SESSION_TICKET
15496     if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
15497         return 0;
15498 #endif
15499 
15500     if (!ssl->options.tls1_3 && ssl->arrays != NULL)
15501         id = ssl->arrays->sessionID;
15502     else
15503         id = ssl->session.sessionID;
15504 
15505     if (id == NULL) {
15506         return BAD_FUNC_ARG;
15507     }
15508 
15509 #ifdef HAVE_SESSION_TICKET
15510     ticLen = ssl->session.ticketLen;
15511     /* Alloc Memory here so if Malloc fails can exit outside of lock */
15512     if (ticLen > SESSION_TICKET_LEN) {
15513         ticBuff = (byte*)XMALLOC(ticLen, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
15514         if (ticBuff == NULL) {
15515             return MEMORY_E;
15516         }
15517     }
15518 #endif
15519 
15520 #ifdef HAVE_EXT_CACHE
15521     if (ssl->options.internalCacheOff) {
15522         /* Create a new session object to be stored. */
15523         session = wolfSSL_SESSION_new();
15524         if (session == NULL) {
15525         #ifdef HAVE_SESSION_TICKET
15526             XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
15527         #endif
15528             return MEMORY_E;
15529         }
15530     }
15531     else
15532 #endif
15533     {
15534         /* Use the session object in the cache for external cache if required */
15535         row = HashSession(id, ID_LEN, &error) % SESSION_ROWS;
15536         if (error != 0) {
15537             WOLFSSL_MSG("Hash session failed");
15538         #ifdef HAVE_SESSION_TICKET
15539             XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
15540         #endif
15541             return error;
15542         }
15543 
15544         sessRow = &SessionCache[row];
15545         if (SESSION_ROW_LOCK(sessRow) != 0) {
15546         #ifdef HAVE_SESSION_TICKET
15547             XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
15548         #endif
15549             return BAD_MUTEX_E;
15550         }
15551 
15552         for (i=0; i<SESSIONS_PER_ROW; i++) {
15553             if (XMEMCMP(id,
15554                     sessRow->Sessions[i].sessionID, ID_LEN) == 0 &&
15555                     sessRow->Sessions[i].side == ssl->options.side) {
15556                 WOLFSSL_MSG("Session already exists. Overwriting.");
15557                 overwrite = 1;
15558                 idx = i;
15559                 break;
15560             }
15561         }
15562 
15563         if (!overwrite) {
15564             idx = sessRow->nextIdx++;
15565         }
15566 #ifdef SESSION_INDEX
15567         ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
15568 #endif
15569         session = &sessRow->Sessions[idx];
15570     }
15571 
15572     session->type = WOLFSSL_SESSION_TYPE_CACHE;
15573     session->cacheRow = row;
15574     session->side = (byte)ssl->options.side;
15575     session->heap = ssl->heap;
15576     session->masterSecret = session->_masterSecret;
15577 #ifndef NO_CLIENT_CACHE
15578     session->serverID = session->_serverID;
15579 #endif
15580 #ifdef OPENSSL_EXTRA
15581     session->sessionCtx = session->_sessionCtx;
15582 #endif
15583 
15584 #ifdef WOLFSSL_TLS13
15585     if (ssl->options.tls1_3) {
15586         XMEMCPY(session->masterSecret, ssl->session.masterSecret, SECRET_LEN);
15587         session->sessionIDSz = ID_LEN;
15588     }
15589     else
15590 #endif
15591     if (ssl->arrays != NULL) {
15592         XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN);
15593         session->sessionIDSz = ssl->arrays->sessionIDSz;
15594     }
15595     XMEMCPY(session->sessionID, id, ID_LEN);
15596     session->haveEMS = ssl->options.haveEMS;
15597 
15598 #ifdef OPENSSL_EXTRA
15599     /* If using compatibility layer then check for and copy over session context
15600      * id. */
15601     if (ssl->sessionCtxSz > 0 && ssl->sessionCtxSz < ID_LEN) {
15602         XMEMCPY(session->sessionCtx, ssl->sessionCtx, ssl->sessionCtxSz);
15603         session->sessionCtxSz = ssl->sessionCtxSz;
15604     }
15605 #endif
15606 
15607     session->timeout = ssl->timeout;
15608     session->bornOn  = LowResTimer();
15609 
15610 #ifdef HAVE_SESSION_TICKET
15611     /* Check if another thread modified ticket since alloc */
15612     if ((word16)ticLen != ssl->session.ticketLen) {
15613         error = VAR_STATE_CHANGE_E;
15614     }
15615     if (error == 0) {
15616         /* Cleanup cache row's old Dynamic buff if exists */
15617         if (session->ticketLenAlloc > 0) {
15618             XFREE(session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
15619             session->ticket = NULL;
15620         }
15621 
15622         /* If too large to store in static buffer, use dyn buffer */
15623         if (ticLen > SESSION_TICKET_LEN) {
15624             session->ticket = ticBuff;
15625             session->ticketLenAlloc = (word16)ticLen;
15626         }
15627         else {
15628             session->ticket = session->_staticTicket;
15629             session->ticketLenAlloc = 0;
15630         }
15631 
15632         session->ticketLen = (word16)ticLen;
15633         XMEMCPY(session->ticket, ssl->session.ticket, ticLen);
15634     }
15635     else { /* cleanup, reset state */
15636         session->ticket    = session->_staticTicket;
15637         session->ticketLenAlloc = 0;
15638         session->ticketLen = 0;
15639         if (ticBuff) {
15640             XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
15641             ticBuff = NULL;
15642         }
15643     }
15644 #endif
15645 
15646 #ifdef SESSION_CERTS
15647     if (error == 0) {
15648         if (!overwrite || ssl->session.chain.count > 0) {
15649             /* If we are overwriting and no certs present in ssl->session.chain
15650              * then keep the old chain. */
15651             session->chain.count = ssl->session.chain.count;
15652             XMEMCPY(session->chain.certs, ssl->session.chain.certs,
15653                     sizeof(x509_buffer) * session->chain.count);
15654         }
15655     }
15656 #endif /* SESSION_CERTS */
15657 #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
15658                                defined(HAVE_SESSION_TICKET))
15659     if (error == 0) {
15660         session->version      = ssl->version;
15661     }
15662 #endif /* SESSION_CERTS || (WOLFSSL_TLS13 & HAVE_SESSION_TICKET) */
15663 #if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
15664                         (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
15665     if (error == 0) {
15666         session->cipherSuite0 = ssl->options.cipherSuite0;
15667         session->cipherSuite  = ssl->options.cipherSuite;
15668     }
15669 #endif
15670 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15671     if (error == 0) {
15672         session->peerVerifyRet = (byte)ssl->peerVerifyRet;
15673     }
15674 #endif
15675 #if defined(WOLFSSL_TLS13)
15676     if (error == 0) {
15677         session->namedGroup     = ssl->session.namedGroup;
15678     }
15679 #endif
15680 #if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
15681     if (error == 0) {
15682         session->ticketSeen     = ssl->session.ticketSeen;
15683         session->ticketAdd      = ssl->session.ticketAdd;
15684         XMEMCPY(&session->ticketNonce, &ssl->session.ticketNonce,
15685                                                            sizeof(TicketNonce));
15686     #ifdef WOLFSSL_EARLY_DATA
15687         session->maxEarlyDataSz = ssl->session.maxEarlyDataSz;
15688     #endif
15689     }
15690 #endif /* WOLFSSL_TLS13 && HAVE_SESSION_TICKET */
15691 
15692     if (error == 0 && sessRow != NULL) {
15693         sessRow->totalCount++;
15694         if (sessRow->nextIdx == SESSIONS_PER_ROW) {
15695             sessRow->nextIdx = 0;
15696         }
15697     }
15698 
15699 #ifndef NO_CLIENT_CACHE
15700     if (error == 0) {
15701         if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->session.idLen) {
15702             word32 clientRow, clientIdx;
15703 
15704             WOLFSSL_MSG("Adding client cache entry");
15705 
15706             session->idLen = ssl->session.idLen;
15707             XMEMCPY(session->serverID, ssl->session.serverID,
15708                     ssl->session.idLen);
15709 
15710             if (sessRow != NULL) {
15711                 clientRow = HashSession(ssl->session.serverID,
15712                         ssl->session.idLen, &error) % SESSION_ROWS;
15713                 if (error == 0 && wc_LockMutex(&clisession_mutex) == 0) {
15714                     clientIdx = ClientCache[clientRow].nextIdx++;
15715                     ClientCache[clientRow].Clients[clientIdx].serverRow =
15716                                                                     (word16)row;
15717                     ClientCache[clientRow].Clients[clientIdx].serverIdx =
15718                                                                     (word16)idx;
15719                     ClientCache[clientRow].totalCount++;
15720                     if (ClientCache[clientRow].nextIdx == SESSIONS_PER_ROW) {
15721                         ClientCache[clientRow].nextIdx = 0;
15722                     }
15723 
15724                     wc_UnLockMutex(&clisession_mutex);
15725                 }
15726                 else {
15727                     WOLFSSL_MSG("Hash session failed");
15728                 }
15729             }
15730         }
15731         else {
15732             session->idLen = 0;
15733         }
15734     }
15735 #endif /* !NO_CLIENT_CACHE */
15736 
15737     if (sessRow != NULL) {
15738         SESSION_ROW_UNLOCK(sessRow);
15739 
15740     #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
15741         if (error == 0) {
15742             word32 active = 0;
15743 
15744             error = get_locked_session_stats(&active, NULL, NULL);
15745             if (error == WOLFSSL_SUCCESS) {
15746                 error = 0;  /* back to this function ok */
15747 
15748                 if (PeakSessions < active) {
15749                     PeakSessions = active;
15750                 }
15751             }
15752         }
15753     #endif /* WOLFSSL_SESSION_STATS && WOLFSSL_PEAK_SESSIONS */
15754     }
15755 
15756 #ifdef HAVE_EXT_CACHE
15757     if (error == 0 && ssl->ctx->new_sess_cb != NULL) {
15758         cbRet = ssl->ctx->new_sess_cb(ssl, session);
15759     }
15760     if (ssl->options.internalCacheOff && cbRet == 0) {
15761         FreeSession(session);
15762     }
15763 #endif
15764 
15765     return error;
15766 }
15767 
15768 
15769 #ifdef SESSION_INDEX
15770 
wolfSSL_GetSessionIndex(WOLFSSL * ssl)15771 int wolfSSL_GetSessionIndex(WOLFSSL* ssl)
15772 {
15773     WOLFSSL_ENTER("wolfSSL_GetSessionIndex");
15774     WOLFSSL_LEAVE("wolfSSL_GetSessionIndex", ssl->sessionIndex);
15775     return ssl->sessionIndex;
15776 }
15777 
15778 
wolfSSL_GetSessionAtIndex(int idx,WOLFSSL_SESSION * session)15779 int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
15780 {
15781     int row, col, result = WOLFSSL_FAILURE;
15782     SessionRow* sessRow;
15783 
15784     WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
15785 
15786     row = idx >> SESSIDX_ROW_SHIFT;
15787     col = idx & SESSIDX_IDX_MASK;
15788 
15789     if (session == NULL ||
15790             row < 0 || row >= SESSION_ROWS || col >= SESSIONS_PER_ROW) {
15791         return WOLFSSL_FAILURE;
15792     }
15793 
15794     sessRow = &SessionCache[row];
15795     if (SESSION_ROW_LOCK(sessRow) != 0) {
15796         return BAD_MUTEX_E;
15797     }
15798 
15799     XMEMCPY(session, &sessRow->Sessions[col], sizeof(WOLFSSL_SESSION));
15800     result = WOLFSSL_SUCCESS;
15801 
15802     SESSION_ROW_UNLOCK(sessRow);
15803 
15804     WOLFSSL_LEAVE("wolfSSL_GetSessionAtIndex", result);
15805     return result;
15806 }
15807 
15808 #endif /* SESSION_INDEX */
15809 
15810 #if defined(SESSION_CERTS)
15811 
wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION * session)15812 WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
15813 {
15814     WOLFSSL_X509_CHAIN* chain = NULL;
15815 
15816     WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
15817 
15818     session = GetSessionPtr(session);
15819     if (session)
15820         chain = &session->chain;
15821 
15822     WOLFSSL_LEAVE("wolfSSL_SESSION_get_peer_chain", chain ? 1 : 0);
15823     return chain;
15824 }
15825 
15826 
15827 #ifdef OPENSSL_EXTRA
15828 /* gets the peer certificate associated with the session passed in
15829  * returns null on failure, the caller should not free the returned pointer */
wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION * session)15830 WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session)
15831 {
15832     WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
15833 
15834     session = GetSessionPtr(session);
15835     if (session) {
15836         int count;
15837 
15838         count = wolfSSL_get_chain_count(&session->chain);
15839         if (count < 1 || count >= MAX_CHAIN_DEPTH) {
15840             WOLFSSL_MSG("bad count found");
15841             return NULL;
15842         }
15843 
15844         if (session->peer == NULL) {
15845             session->peer = wolfSSL_get_chain_X509(&session->chain, 0);
15846         }
15847         return session->peer;
15848     }
15849     WOLFSSL_MSG("No session passed in");
15850 
15851     return NULL;
15852 }
15853 #endif /* OPENSSL_EXTRA */
15854 #endif /* SESSION_INDEX && SESSION_CERTS */
15855 
15856 
15857 #ifdef WOLFSSL_SESSION_STATS
15858 
get_locked_session_stats(word32 * active,word32 * total,word32 * peak)15859 static int get_locked_session_stats(word32* active, word32* total, word32* peak)
15860 {
15861     int result = WOLFSSL_SUCCESS;
15862     int i;
15863     int count;
15864     int idx;
15865     word32 now   = 0;
15866     word32 seen  = 0;
15867     word32 ticks = LowResTimer();
15868 
15869     WOLFSSL_ENTER("get_locked_session_stats");
15870 
15871     for (i = 0; i < SESSION_ROWS; i++) {
15872         SessionRow* row = &SessionCache[i];
15873     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
15874         if (SESSION_ROW_LOCK(row) != 0) {
15875             WOLFSSL_MSG("Session row cache mutex lock failed");
15876             return BAD_MUTEX_E;
15877         }
15878     #endif
15879 
15880         seen += row->totalCount;
15881 
15882         if (active == NULL) {
15883             SESSION_ROW_UNLOCK(row);
15884             continue;
15885         }
15886 
15887         count = min((word32)row->totalCount, SESSIONS_PER_ROW);
15888         idx   = row->nextIdx - 1;
15889         if (idx < 0 || idx >= SESSIONS_PER_ROW) {
15890             idx = SESSIONS_PER_ROW - 1; /* if back to front previous was end */
15891         }
15892 
15893         for (; count > 0; --count) {
15894             /* if not expired then good */
15895             if (ticks < (row->Sessions[idx].bornOn +
15896                             row->Sessions[idx].timeout) ) {
15897                 now++;
15898             }
15899 
15900             idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1;
15901         }
15902 
15903     #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
15904         SESSION_ROW_UNLOCK(row);
15905     #endif
15906     }
15907 #ifndef ENABLE_SESSION_CACHE_ROW_LOCK
15908     wc_UnLockMutex(&session_mutex);
15909 #endif
15910 
15911     if (active) {
15912         *active = now;
15913     }
15914     if (total) {
15915         *total = seen;
15916     }
15917 
15918 #ifdef WOLFSSL_PEAK_SESSIONS
15919     if (peak) {
15920         *peak = PeakSessions;
15921     }
15922 #else
15923     (void)peak;
15924 #endif
15925 
15926     WOLFSSL_LEAVE("get_locked_session_stats", result);
15927 
15928     return result;
15929 }
15930 
15931 
15932 /* return WOLFSSL_SUCCESS on ok */
wolfSSL_get_session_stats(word32 * active,word32 * total,word32 * peak,word32 * maxSessions)15933 int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
15934                               word32* maxSessions)
15935 {
15936     int result = WOLFSSL_SUCCESS;
15937 
15938     WOLFSSL_ENTER("wolfSSL_get_session_stats");
15939 
15940     if (maxSessions) {
15941         *maxSessions = SESSIONS_PER_ROW * SESSION_ROWS;
15942 
15943         if (active == NULL && total == NULL && peak == NULL)
15944             return result;  /* we're done */
15945     }
15946 
15947     /* user must provide at least one query value */
15948     if (active == NULL && total == NULL && peak == NULL) {
15949         return BAD_FUNC_ARG;
15950     }
15951 
15952     result = get_locked_session_stats(active, total, peak);
15953 
15954     WOLFSSL_LEAVE("wolfSSL_get_session_stats", result);
15955 
15956     return result;
15957 }
15958 
15959 #endif /* WOLFSSL_SESSION_STATS */
15960 
15961 
15962     #ifdef PRINT_SESSION_STATS
15963 
15964     /* WOLFSSL_SUCCESS on ok */
wolfSSL_PrintSessionStats(void)15965     int wolfSSL_PrintSessionStats(void)
15966     {
15967         word32 totalSessionsSeen = 0;
15968         word32 totalSessionsNow = 0;
15969         word32 peak = 0;
15970         word32 maxSessions = 0;
15971         int    i;
15972         int    ret;
15973         double E;               /* expected freq */
15974         double chiSquare = 0;
15975 
15976         ret = wolfSSL_get_session_stats(&totalSessionsNow, &totalSessionsSeen,
15977                                         &peak, &maxSessions);
15978         if (ret != WOLFSSL_SUCCESS)
15979             return ret;
15980         printf("Total Sessions Seen = %d\n", totalSessionsSeen);
15981         printf("Total Sessions Now  = %d\n", totalSessionsNow);
15982 #ifdef WOLFSSL_PEAK_SESSIONS
15983         printf("Peak  Sessions      = %d\n", peak);
15984 #endif
15985         printf("Max   Sessions      = %d\n", maxSessions);
15986 
15987         E = (double)totalSessionsSeen / SESSION_ROWS;
15988 
15989         for (i = 0; i < SESSION_ROWS; i++) {
15990             double diff = SessionCache[i].totalCount - E;
15991             diff *= diff;                /* square    */
15992             diff /= E;                   /* normalize */
15993 
15994             chiSquare += diff;
15995         }
15996         printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
15997                                                      SESSION_ROWS - 1);
15998         #if (SESSION_ROWS == 11)
15999             printf(" .05 p value =  18.3, chi-square should be less\n");
16000         #elif (SESSION_ROWS == 211)
16001             printf(".05 p value  = 244.8, chi-square should be less\n");
16002         #elif (SESSION_ROWS == 5981)
16003             printf(".05 p value  = 6161.0, chi-square should be less\n");
16004         #elif (SESSION_ROWS == 3)
16005             printf(".05 p value  =   6.0, chi-square should be less\n");
16006         #elif (SESSION_ROWS == 2861)
16007             printf(".05 p value  = 2985.5, chi-square should be less\n");
16008         #endif
16009         printf("\n");
16010 
16011         return ret;
16012     }
16013 
16014     #endif /* SESSION_STATS */
16015 
16016 #else  /* NO_SESSION_CACHE */
16017 
16018 /* No session cache version */
GetSession(WOLFSSL * ssl,byte * masterSecret,byte restoreSessionCerts)16019 WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
16020         byte restoreSessionCerts)
16021 {
16022     (void)ssl;
16023     (void)masterSecret;
16024     (void)restoreSessionCerts;
16025 
16026     return NULL;
16027 }
16028 
16029 #endif /* NO_SESSION_CACHE */
16030 
16031 
16032 /* call before SSL_connect, if verifying will add name check to
16033    date check and signature check */
16034 WOLFSSL_ABI
wolfSSL_check_domain_name(WOLFSSL * ssl,const char * dn)16035 int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
16036 {
16037     WOLFSSL_ENTER("wolfSSL_check_domain_name");
16038 
16039     if (ssl == NULL || dn == NULL) {
16040         WOLFSSL_MSG("Bad function argument: NULL");
16041         return WOLFSSL_FAILURE;
16042     }
16043 
16044     if (ssl->buffers.domainName.buffer)
16045         XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
16046 
16047     ssl->buffers.domainName.length = (word32)XSTRLEN(dn);
16048     ssl->buffers.domainName.buffer = (byte*)XMALLOC(
16049             ssl->buffers.domainName.length + 1, ssl->heap, DYNAMIC_TYPE_DOMAIN);
16050 
16051     if (ssl->buffers.domainName.buffer) {
16052         unsigned char* domainName = ssl->buffers.domainName.buffer;
16053         XMEMCPY(domainName, dn, ssl->buffers.domainName.length);
16054         domainName[ssl->buffers.domainName.length] = '\0';
16055         return WOLFSSL_SUCCESS;
16056     }
16057     else {
16058         ssl->error = MEMORY_ERROR;
16059         return WOLFSSL_FAILURE;
16060     }
16061 }
16062 
16063 
16064 /* turn on wolfSSL zlib compression
16065    returns WOLFSSL_SUCCESS for success, else error (not built in)
16066 */
wolfSSL_set_compression(WOLFSSL * ssl)16067 int wolfSSL_set_compression(WOLFSSL* ssl)
16068 {
16069     WOLFSSL_ENTER("wolfSSL_set_compression");
16070     (void)ssl;
16071 #ifdef HAVE_LIBZ
16072     ssl->options.usingCompression = 1;
16073     return WOLFSSL_SUCCESS;
16074 #else
16075     return NOT_COMPILED_IN;
16076 #endif
16077 }
16078 
16079 
16080 #ifndef USE_WINDOWS_API
16081     #ifndef NO_WRITEV
16082 
16083         /* simulate writev semantics, doesn't actually do block at a time though
16084            because of SSL_write behavior and because front adds may be small */
wolfSSL_writev(WOLFSSL * ssl,const struct iovec * iov,int iovcnt)16085         int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
16086         {
16087         #ifdef WOLFSSL_SMALL_STACK
16088             byte   staticBuffer[1]; /* force heap usage */
16089         #else
16090             byte   staticBuffer[FILE_BUFFER_SIZE];
16091         #endif
16092             byte* myBuffer  = staticBuffer;
16093             int   dynamic   = 0;
16094             int   sending   = 0;
16095             int   idx       = 0;
16096             int   i;
16097             int   ret;
16098 
16099             WOLFSSL_ENTER("wolfSSL_writev");
16100 
16101             for (i = 0; i < iovcnt; i++)
16102                 sending += (int)iov[i].iov_len;
16103 
16104             if (sending > (int)sizeof(staticBuffer)) {
16105                 myBuffer = (byte*)XMALLOC(sending, ssl->heap,
16106                                                            DYNAMIC_TYPE_WRITEV);
16107                 if (!myBuffer)
16108                     return MEMORY_ERROR;
16109 
16110                 dynamic = 1;
16111             }
16112 
16113             for (i = 0; i < iovcnt; i++) {
16114                 XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
16115                 idx += (int)iov[i].iov_len;
16116             }
16117 
16118            /* myBuffer may not be initialized fully, but the span up to the
16119             * sending length will be.
16120             */
16121             PRAGMA_GCC_DIAG_PUSH;
16122             PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"");
16123             ret = wolfSSL_write(ssl, myBuffer, sending);
16124             PRAGMA_GCC_DIAG_POP;
16125 
16126             if (dynamic)
16127                 XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
16128 
16129             return ret;
16130         }
16131     #endif
16132 #endif
16133 
16134 
16135 #ifdef WOLFSSL_CALLBACKS
16136 
16137     typedef struct itimerval Itimerval;
16138 
16139     /* don't keep calling simple functions while setting up timer and signals
16140        if no inlining these are the next best */
16141 
16142     #define AddTimes(a, b, c)                       \
16143         do {                                        \
16144             c.tv_sec  = a.tv_sec  + b.tv_sec;       \
16145             c.tv_usec = a.tv_usec + b.tv_usec;      \
16146             if (c.tv_usec >=  1000000) {            \
16147                 c.tv_sec++;                         \
16148                 c.tv_usec -= 1000000;               \
16149             }                                       \
16150         } while (0)
16151 
16152 
16153     #define SubtractTimes(a, b, c)                  \
16154         do {                                        \
16155             c.tv_sec  = a.tv_sec  - b.tv_sec;       \
16156             c.tv_usec = a.tv_usec - b.tv_usec;      \
16157             if (c.tv_usec < 0) {                    \
16158                 c.tv_sec--;                         \
16159                 c.tv_usec += 1000000;               \
16160             }                                       \
16161         } while (0)
16162 
16163     #define CmpTimes(a, b, cmp)                     \
16164         ((a.tv_sec  ==  b.tv_sec) ?                 \
16165             (a.tv_usec cmp b.tv_usec) :             \
16166             (a.tv_sec  cmp b.tv_sec))               \
16167 
16168 
16169     /* do nothing handler */
myHandler(int signo)16170     static void myHandler(int signo)
16171     {
16172         (void)signo;
16173         return;
16174     }
16175 
16176 
wolfSSL_ex_wrapper(WOLFSSL * ssl,HandShakeCallBack hsCb,TimeoutCallBack toCb,WOLFSSL_TIMEVAL timeout)16177     static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
16178                                  TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
16179     {
16180         int       ret        = WOLFSSL_FATAL_ERROR;
16181         int       oldTimerOn = 0;   /* was timer already on */
16182         WOLFSSL_TIMEVAL startTime;
16183         WOLFSSL_TIMEVAL endTime;
16184         WOLFSSL_TIMEVAL totalTime;
16185         Itimerval myTimeout;
16186         Itimerval oldTimeout; /* if old timer adjust from total time to reset */
16187         struct sigaction act, oact;
16188 
16189         #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
16190 
16191         if (hsCb) {
16192             ssl->hsInfoOn = 1;
16193             InitHandShakeInfo(&ssl->handShakeInfo, ssl);
16194         }
16195         if (toCb) {
16196             ssl->toInfoOn = 1;
16197             InitTimeoutInfo(&ssl->timeoutInfo);
16198 
16199             if (gettimeofday(&startTime, 0) < 0)
16200                 ERR_OUT(GETTIME_ERROR);
16201 
16202             /* use setitimer to simulate getitimer, init 0 myTimeout */
16203             myTimeout.it_interval.tv_sec  = 0;
16204             myTimeout.it_interval.tv_usec = 0;
16205             myTimeout.it_value.tv_sec     = 0;
16206             myTimeout.it_value.tv_usec    = 0;
16207             if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
16208                 ERR_OUT(SETITIMER_ERROR);
16209 
16210             if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
16211                 oldTimerOn = 1;
16212 
16213                 /* is old timer going to expire before ours */
16214                 if (CmpTimes(oldTimeout.it_value, timeout, <)) {
16215                     timeout.tv_sec  = oldTimeout.it_value.tv_sec;
16216                     timeout.tv_usec = oldTimeout.it_value.tv_usec;
16217                 }
16218             }
16219             myTimeout.it_value.tv_sec  = timeout.tv_sec;
16220             myTimeout.it_value.tv_usec = timeout.tv_usec;
16221 
16222             /* set up signal handler, don't restart socket send/recv */
16223             act.sa_handler = myHandler;
16224             sigemptyset(&act.sa_mask);
16225             act.sa_flags = 0;
16226 #ifdef SA_INTERRUPT
16227             act.sa_flags |= SA_INTERRUPT;
16228 #endif
16229             if (sigaction(SIGALRM, &act, &oact) < 0)
16230                 ERR_OUT(SIGACT_ERROR);
16231 
16232             if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
16233                 ERR_OUT(SETITIMER_ERROR);
16234         }
16235 
16236         /* do main work */
16237 #ifndef NO_WOLFSSL_CLIENT
16238         if (ssl->options.side == WOLFSSL_CLIENT_END)
16239             ret = wolfSSL_connect(ssl);
16240 #endif
16241 #ifndef NO_WOLFSSL_SERVER
16242         if (ssl->options.side == WOLFSSL_SERVER_END)
16243             ret = wolfSSL_accept(ssl);
16244 #endif
16245 
16246         /* do callbacks */
16247         if (toCb) {
16248             if (oldTimerOn) {
16249                 gettimeofday(&endTime, 0);
16250                 SubtractTimes(endTime, startTime, totalTime);
16251                 /* adjust old timer for elapsed time */
16252                 if (CmpTimes(totalTime, oldTimeout.it_value, <))
16253                     SubtractTimes(oldTimeout.it_value, totalTime,
16254                                   oldTimeout.it_value);
16255                 else {
16256                     /* reset value to interval, may be off */
16257                     oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
16258                     oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
16259                 }
16260                 /* keep iter the same whether there or not */
16261             }
16262             /* restore old handler */
16263             if (sigaction(SIGALRM, &oact, 0) < 0)
16264                 ret = SIGACT_ERROR;    /* more pressing error, stomp */
16265             else
16266                 /* use old settings which may turn off (expired or not there) */
16267                 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
16268                     ret = SETITIMER_ERROR;
16269 
16270             /* if we had a timeout call callback */
16271             if (ssl->timeoutInfo.timeoutName[0]) {
16272                 ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
16273                 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
16274                 (toCb)(&ssl->timeoutInfo);
16275             }
16276             /* clean up */
16277             FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
16278             ssl->toInfoOn = 0;
16279         }
16280         if (hsCb) {
16281             FinishHandShakeInfo(&ssl->handShakeInfo);
16282             (hsCb)(&ssl->handShakeInfo);
16283             ssl->hsInfoOn = 0;
16284         }
16285         return ret;
16286     }
16287 
16288 
16289 #ifndef NO_WOLFSSL_CLIENT
16290 
wolfSSL_connect_ex(WOLFSSL * ssl,HandShakeCallBack hsCb,TimeoutCallBack toCb,WOLFSSL_TIMEVAL timeout)16291     int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
16292                           TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
16293     {
16294         WOLFSSL_ENTER("wolfSSL_connect_ex");
16295         return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
16296     }
16297 
16298 #endif
16299 
16300 
16301 #ifndef NO_WOLFSSL_SERVER
16302 
wolfSSL_accept_ex(WOLFSSL * ssl,HandShakeCallBack hsCb,TimeoutCallBack toCb,WOLFSSL_TIMEVAL timeout)16303     int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
16304                          TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
16305     {
16306         WOLFSSL_ENTER("wolfSSL_accept_ex");
16307         return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
16308     }
16309 
16310 #endif
16311 
16312 #endif /* WOLFSSL_CALLBACKS */
16313 
16314 
16315 #ifndef NO_PSK
16316 
wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX * ctx,wc_psk_client_callback cb)16317     void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
16318                                          wc_psk_client_callback cb)
16319     {
16320         WOLFSSL_ENTER("SSL_CTX_set_psk_client_callback");
16321 
16322         if (ctx == NULL)
16323             return;
16324 
16325         ctx->havePSK = 1;
16326         ctx->client_psk_cb = cb;
16327     }
16328 
wolfSSL_set_psk_client_callback(WOLFSSL * ssl,wc_psk_client_callback cb)16329     void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
16330     {
16331         byte haveRSA = 1;
16332         int  keySz   = 0;
16333 
16334         WOLFSSL_ENTER("SSL_set_psk_client_callback");
16335 
16336         if (ssl == NULL)
16337             return;
16338 
16339         ssl->options.havePSK = 1;
16340         ssl->options.client_psk_cb = cb;
16341 
16342         #ifdef NO_RSA
16343             haveRSA = 0;
16344         #endif
16345         #ifndef NO_CERTS
16346             keySz = ssl->buffers.keySz;
16347         #endif
16348         InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
16349                    ssl->options.haveDH, ssl->options.haveECDSAsig,
16350                    ssl->options.haveECC, ssl->options.haveStaticECC,
16351                    ssl->options.haveFalconSig, ssl->options.haveAnon,
16352                    ssl->options.side);
16353     }
16354     #ifdef OPENSSL_EXTRA
16355     /**
16356      * set call back function for psk session use
16357      * @param ssl  a pointer to WOLFSSL structure
16358      * @param cb   a function pointer to wc_psk_use_session_cb
16359      * @return none
16360      */
wolfSSL_set_psk_use_session_callback(WOLFSSL * ssl,wc_psk_use_session_cb_func cb)16361     void wolfSSL_set_psk_use_session_callback(WOLFSSL* ssl,
16362                                                 wc_psk_use_session_cb_func cb)
16363     {
16364         WOLFSSL_ENTER("wolfSSL_set_psk_use_session_callback");
16365 
16366         ssl->options.havePSK = 1;
16367         ssl->options.session_psk_cb = cb;
16368 
16369         WOLFSSL_LEAVE("wolfSSL_set_psk_use_session_callback", WOLFSSL_SUCCESS);
16370     }
16371     #endif
16372 
wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX * ctx,wc_psk_server_callback cb)16373     void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
16374                                          wc_psk_server_callback cb)
16375     {
16376         WOLFSSL_ENTER("SSL_CTX_set_psk_server_callback");
16377         if (ctx == NULL)
16378             return;
16379         ctx->havePSK = 1;
16380         ctx->server_psk_cb = cb;
16381     }
16382 
wolfSSL_set_psk_server_callback(WOLFSSL * ssl,wc_psk_server_callback cb)16383     void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
16384     {
16385         byte haveRSA = 1;
16386         int  keySz   = 0;
16387 
16388         WOLFSSL_ENTER("SSL_set_psk_server_callback");
16389         if (ssl == NULL)
16390             return;
16391 
16392         ssl->options.havePSK = 1;
16393         ssl->options.server_psk_cb = cb;
16394 
16395         #ifdef NO_RSA
16396             haveRSA = 0;
16397         #endif
16398         #ifndef NO_CERTS
16399             keySz = ssl->buffers.keySz;
16400         #endif
16401         InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
16402                    ssl->options.haveDH, ssl->options.haveECDSAsig,
16403                    ssl->options.haveECC, ssl->options.haveStaticECC,
16404                    ssl->options.haveFalconSig, ssl->options.haveAnon,
16405                    ssl->options.side);
16406     }
16407 
wolfSSL_get_psk_identity_hint(const WOLFSSL * ssl)16408     const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
16409     {
16410         WOLFSSL_ENTER("SSL_get_psk_identity_hint");
16411 
16412         if (ssl == NULL || ssl->arrays == NULL)
16413             return NULL;
16414 
16415         return ssl->arrays->server_hint;
16416     }
16417 
16418 
wolfSSL_get_psk_identity(const WOLFSSL * ssl)16419     const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
16420     {
16421         WOLFSSL_ENTER("SSL_get_psk_identity");
16422 
16423         if (ssl == NULL || ssl->arrays == NULL)
16424             return NULL;
16425 
16426         return ssl->arrays->client_identity;
16427     }
16428 
wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX * ctx,const char * hint)16429     int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
16430     {
16431         WOLFSSL_ENTER("SSL_CTX_use_psk_identity_hint");
16432         if (hint == 0)
16433             ctx->server_hint[0] = '\0';
16434         else {
16435             /* Qt does not call CTX_set_*_psk_callbacks where havePSK is set */
16436             #ifdef WOLFSSL_QT
16437             ctx->havePSK=1;
16438             #endif
16439             XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
16440             ctx->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
16441         }
16442         return WOLFSSL_SUCCESS;
16443     }
16444 
wolfSSL_use_psk_identity_hint(WOLFSSL * ssl,const char * hint)16445     int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
16446     {
16447         WOLFSSL_ENTER("SSL_use_psk_identity_hint");
16448 
16449         if (ssl == NULL || ssl->arrays == NULL)
16450             return WOLFSSL_FAILURE;
16451 
16452         if (hint == 0)
16453             ssl->arrays->server_hint[0] = 0;
16454         else {
16455             XSTRNCPY(ssl->arrays->server_hint, hint,
16456                                             sizeof(ssl->arrays->server_hint)-1);
16457             ssl->arrays->server_hint[sizeof(ssl->arrays->server_hint)-1] = '\0';
16458         }
16459         return WOLFSSL_SUCCESS;
16460     }
16461 
wolfSSL_get_psk_callback_ctx(WOLFSSL * ssl)16462     void* wolfSSL_get_psk_callback_ctx(WOLFSSL* ssl)
16463     {
16464         return ssl ? ssl->options.psk_ctx : NULL;
16465     }
wolfSSL_CTX_get_psk_callback_ctx(WOLFSSL_CTX * ctx)16466     void* wolfSSL_CTX_get_psk_callback_ctx(WOLFSSL_CTX* ctx)
16467     {
16468         return ctx ? ctx->psk_ctx : NULL;
16469     }
wolfSSL_set_psk_callback_ctx(WOLFSSL * ssl,void * psk_ctx)16470     int wolfSSL_set_psk_callback_ctx(WOLFSSL* ssl, void* psk_ctx)
16471     {
16472         if (ssl == NULL)
16473             return WOLFSSL_FAILURE;
16474         ssl->options.psk_ctx = psk_ctx;
16475         return WOLFSSL_SUCCESS;
16476     }
wolfSSL_CTX_set_psk_callback_ctx(WOLFSSL_CTX * ctx,void * psk_ctx)16477     int wolfSSL_CTX_set_psk_callback_ctx(WOLFSSL_CTX* ctx, void* psk_ctx)
16478     {
16479         if (ctx == NULL)
16480             return WOLFSSL_FAILURE;
16481         ctx->psk_ctx = psk_ctx;
16482         return WOLFSSL_SUCCESS;
16483     }
16484 #endif /* NO_PSK */
16485 
16486 
16487 #ifdef HAVE_ANON
16488 
wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX * ctx)16489     int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
16490     {
16491         WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
16492 
16493         if (ctx == NULL)
16494             return WOLFSSL_FAILURE;
16495 
16496         ctx->haveAnon = 1;
16497 
16498         return WOLFSSL_SUCCESS;
16499     }
16500 
16501 #endif /* HAVE_ANON */
16502 
16503 
16504 #ifndef NO_CERTS
16505 /* used to be defined on NO_FILESYSTEM only, but are generally useful */
16506 
wolfSSL_CTX_load_verify_buffer_ex(WOLFSSL_CTX * ctx,const unsigned char * in,long sz,int format,int userChain,word32 flags)16507     int wolfSSL_CTX_load_verify_buffer_ex(WOLFSSL_CTX* ctx,
16508                                          const unsigned char* in,
16509                                          long sz, int format, int userChain,
16510                                          word32 flags)
16511     {
16512         int verify;
16513         int ret = WOLFSSL_FAILURE;
16514 
16515         WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer_ex");
16516 
16517         verify = GET_VERIFY_SETTING_CTX(ctx);
16518         if (flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY)
16519             verify = VERIFY_SKIP_DATE;
16520 
16521         if (format == WOLFSSL_FILETYPE_PEM)
16522             ret = ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL,
16523                                       verify);
16524         else
16525             ret = ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL, NULL,
16526                                  userChain, verify);
16527         WOLFSSL_LEAVE("wolfSSL_CTX_load_verify_buffer_ex", ret);
16528         return ret;
16529     }
16530 
16531     /* wolfSSL extension allows DER files to be loaded from buffers as well */
wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX * ctx,const unsigned char * in,long sz,int format)16532     int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx,
16533                                        const unsigned char* in,
16534                                        long sz, int format)
16535     {
16536         return wolfSSL_CTX_load_verify_buffer_ex(ctx, in, sz, format, 0,
16537             WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
16538     }
16539 
wolfSSL_CTX_load_verify_chain_buffer_format(WOLFSSL_CTX * ctx,const unsigned char * in,long sz,int format)16540     int wolfSSL_CTX_load_verify_chain_buffer_format(WOLFSSL_CTX* ctx,
16541                                        const unsigned char* in,
16542                                        long sz, int format)
16543     {
16544         return wolfSSL_CTX_load_verify_buffer_ex(ctx, in, sz, format, 1,
16545             WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
16546     }
16547 
16548 
16549 #ifdef WOLFSSL_TRUST_PEER_CERT
wolfSSL_CTX_trust_peer_buffer(WOLFSSL_CTX * ctx,const unsigned char * in,long sz,int format)16550     int wolfSSL_CTX_trust_peer_buffer(WOLFSSL_CTX* ctx,
16551                                        const unsigned char* in,
16552                                        long sz, int format)
16553     {
16554         WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_buffer");
16555 
16556         /* sanity check on arguments */
16557         if (sz < 0 || in == NULL || ctx == NULL) {
16558             return BAD_FUNC_ARG;
16559         }
16560 
16561         if (format == WOLFSSL_FILETYPE_PEM)
16562             return ProcessChainBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE,
16563                                       NULL, GET_VERIFY_SETTING_CTX(ctx));
16564         else
16565             return ProcessBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE, NULL,
16566                                  NULL, 0, GET_VERIFY_SETTING_CTX(ctx));
16567     }
16568 #endif /* WOLFSSL_TRUST_PEER_CERT */
16569 
16570 
wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX * ctx,const unsigned char * in,long sz,int format)16571     int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
16572                                  const unsigned char* in, long sz, int format)
16573     {
16574         int ret = WOLFSSL_FAILURE;
16575 
16576         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
16577         ret = ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0,
16578                              GET_VERIFY_SETTING_CTX(ctx));
16579         WOLFSSL_LEAVE("wolfSSL_CTX_use_certificate_buffer", ret);
16580         return ret;
16581     }
16582 
16583 
wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX * ctx,const unsigned char * in,long sz,int format)16584     int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx,
16585                                  const unsigned char* in, long sz, int format)
16586     {
16587         int ret = WOLFSSL_FAILURE;
16588 
16589         WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
16590         ret = ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL, NULL,
16591                              0, GET_VERIFY_SETTING_CTX(ctx));
16592         WOLFSSL_LEAVE("wolfSSL_CTX_use_PrivateKey_buffer", ret);
16593         return ret;
16594     }
16595 
16596 #if defined(HAVE_PKCS11) || defined(WOLF_CRYPTO_CB)
wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX * ctx,const unsigned char * id,long sz,int devId,long keySz)16597     int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX* ctx, const unsigned char* id,
16598                                       long sz, int devId, long keySz)
16599     {
16600         int ret = wolfSSL_CTX_use_PrivateKey_Id(ctx, id, sz, devId);
16601 
16602         if (ret == WOLFSSL_SUCCESS)
16603             ctx->privateKeySz = (word32)keySz;
16604 
16605         return ret;
16606     }
16607 
wolfSSL_CTX_use_PrivateKey_Id(WOLFSSL_CTX * ctx,const unsigned char * id,long sz,int devId)16608     int wolfSSL_CTX_use_PrivateKey_Id(WOLFSSL_CTX* ctx, const unsigned char* id,
16609                                       long sz, int devId)
16610     {
16611         int ret = WOLFSSL_FAILURE;
16612 
16613         FreeDer(&ctx->privateKey);
16614         if (AllocDer(&ctx->privateKey, (word32)sz, PRIVATEKEY_TYPE,
16615                                                               ctx->heap) == 0) {
16616             XMEMCPY(ctx->privateKey->buffer, id, sz);
16617             ctx->privateKeyId = 1;
16618             if (devId != INVALID_DEVID)
16619                 ctx->privateKeyDevId = devId;
16620             else
16621                 ctx->privateKeyDevId = ctx->devId;
16622 
16623             ret = WOLFSSL_SUCCESS;
16624         }
16625 
16626         return ret;
16627     }
16628 
wolfSSL_CTX_use_PrivateKey_Label(WOLFSSL_CTX * ctx,const char * label,int devId)16629     int wolfSSL_CTX_use_PrivateKey_Label(WOLFSSL_CTX* ctx, const char* label,
16630                                          int devId)
16631     {
16632         int ret = WOLFSSL_FAILURE;
16633         word32 sz = (word32)XSTRLEN(label) + 1;
16634 
16635         FreeDer(&ctx->privateKey);
16636         if (AllocDer(&ctx->privateKey, (word32)sz, PRIVATEKEY_TYPE,
16637                                                               ctx->heap) == 0) {
16638             XMEMCPY(ctx->privateKey->buffer, label, sz);
16639             ctx->privateKeyLabel = 1;
16640             if (devId != INVALID_DEVID)
16641                 ctx->privateKeyDevId = devId;
16642             else
16643                 ctx->privateKeyDevId = ctx->devId;
16644 
16645             ret = WOLFSSL_SUCCESS;
16646         }
16647 
16648         return ret;
16649     }
16650 #endif /* HAVE_PKCS11 || WOLF_CRYPTO_CB */
16651 
wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX * ctx,const unsigned char * in,long sz,int format)16652     int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX* ctx,
16653                                  const unsigned char* in, long sz, int format)
16654     {
16655         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer_format");
16656         return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 1,
16657                              GET_VERIFY_SETTING_CTX(ctx));
16658     }
16659 
wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX * ctx,const unsigned char * in,long sz)16660     int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
16661                                  const unsigned char* in, long sz)
16662     {
16663         return wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, in, sz,
16664                                                             WOLFSSL_FILETYPE_PEM);
16665     }
16666 
16667 
16668 #ifndef NO_DH
16669 
16670     /* server wrapper for ctx or ssl Diffie-Hellman parameters */
wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX * ctx,WOLFSSL * ssl,const unsigned char * buf,long sz,int format)16671     static int wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
16672                                                const unsigned char* buf,
16673                                                long sz, int format)
16674     {
16675         DerBuffer* der = NULL;
16676         int    ret      = 0;
16677         word32 pSz = MAX_DH_SIZE;
16678         word32 gSz = MAX_DH_SIZE;
16679     #ifdef WOLFSSL_SMALL_STACK
16680         byte*  p = NULL;
16681         byte*  g = NULL;
16682     #else
16683         byte   p[MAX_DH_SIZE];
16684         byte   g[MAX_DH_SIZE];
16685     #endif
16686 
16687         if (ctx == NULL || buf == NULL)
16688             return BAD_FUNC_ARG;
16689 
16690         ret = AllocDer(&der, 0, DH_PARAM_TYPE, ctx->heap);
16691         if (ret != 0) {
16692             return ret;
16693         }
16694         der->buffer = (byte*)buf;
16695         der->length = (word32)sz;
16696 
16697     #ifdef WOLFSSL_SMALL_STACK
16698         p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
16699         g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
16700 
16701         if (p == NULL || g == NULL) {
16702             XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
16703             XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
16704             return MEMORY_E;
16705         }
16706     #endif
16707 
16708         if (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM)
16709             ret = WOLFSSL_BAD_FILETYPE;
16710         else {
16711             if (format == WOLFSSL_FILETYPE_PEM) {
16712 #ifdef WOLFSSL_PEM_TO_DER
16713                 FreeDer(&der);
16714                 ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap,
16715                                NULL, NULL);
16716                 if (ret < 0) {
16717                     /* Also try X9.42 format */
16718                     ret = PemToDer(buf, sz, X942_PARAM_TYPE, &der, ctx->heap,
16719                                NULL, NULL);
16720                 }
16721     #ifdef WOLFSSL_WPAS
16722         #ifndef NO_DSA
16723                 if (ret < 0) {
16724                     ret = PemToDer(buf, sz, DSA_PARAM_TYPE, &der, ctx->heap,
16725                                NULL, NULL);
16726                 }
16727         #endif
16728     #endif /* WOLFSSL_WPAS */
16729 #else
16730                 ret = NOT_COMPILED_IN;
16731 #endif /* WOLFSSL_PEM_TO_DER */
16732             }
16733 
16734             if (ret == 0) {
16735                 if (wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz) < 0)
16736                     ret = WOLFSSL_BAD_FILETYPE;
16737                 else if (ssl)
16738                     ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
16739                 else
16740                     ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
16741             }
16742         }
16743 
16744         FreeDer(&der);
16745 
16746     #ifdef WOLFSSL_SMALL_STACK
16747         XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
16748         XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
16749     #endif
16750 
16751         return ret;
16752     }
16753 
16754 
16755     /* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
wolfSSL_SetTmpDH_buffer(WOLFSSL * ssl,const unsigned char * buf,long sz,int format)16756     int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
16757                                int format)
16758     {
16759         if (ssl == NULL)
16760             return BAD_FUNC_ARG;
16761 
16762         return wolfSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
16763     }
16764 
16765 
16766     /* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX * ctx,const unsigned char * buf,long sz,int format)16767     int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
16768                                    long sz, int format)
16769     {
16770         return wolfSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
16771     }
16772 
16773 #endif /* NO_DH */
16774 
16775 
wolfSSL_use_certificate_buffer(WOLFSSL * ssl,const unsigned char * in,long sz,int format)16776     int wolfSSL_use_certificate_buffer(WOLFSSL* ssl,
16777                                  const unsigned char* in, long sz, int format)
16778     {
16779         WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
16780         if (ssl == NULL)
16781             return BAD_FUNC_ARG;
16782 
16783         return ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE, ssl, NULL, 0,
16784                              GET_VERIFY_SETTING_SSL(ssl));
16785     }
16786 
16787 
wolfSSL_use_PrivateKey_buffer(WOLFSSL * ssl,const unsigned char * in,long sz,int format)16788     int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl,
16789                                  const unsigned char* in, long sz, int format)
16790     {
16791         WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
16792         if (ssl == NULL)
16793             return BAD_FUNC_ARG;
16794 
16795         return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
16796                              ssl, NULL, 0, GET_VERIFY_SETTING_SSL(ssl));
16797     }
16798 
16799 #ifdef WOLF_CRYPTO_CB
wolfSSL_use_PrivateKey_id(WOLFSSL * ssl,const unsigned char * id,long sz,int devId,long keySz)16800     int wolfSSL_use_PrivateKey_id(WOLFSSL* ssl, const unsigned char* id,
16801                                   long sz, int devId, long keySz)
16802     {
16803         int ret = wolfSSL_use_PrivateKey_Id(ssl, id, sz, devId);
16804 
16805         if (ret == WOLFSSL_SUCCESS)
16806             ssl->buffers.keySz = (word32)keySz;
16807 
16808         return ret;
16809     }
16810 
wolfSSL_use_PrivateKey_Id(WOLFSSL * ssl,const unsigned char * id,long sz,int devId)16811     int wolfSSL_use_PrivateKey_Id(WOLFSSL* ssl, const unsigned char* id,
16812                                   long sz, int devId)
16813     {
16814         int ret = WOLFSSL_FAILURE;
16815 
16816         if (ssl->buffers.weOwnKey)
16817             FreeDer(&ssl->buffers.key);
16818         if (AllocDer(&ssl->buffers.key, (word32)sz, PRIVATEKEY_TYPE,
16819                                                             ssl->heap) == 0) {
16820             XMEMCPY(ssl->buffers.key->buffer, id, sz);
16821             ssl->buffers.weOwnKey = 1;
16822             ssl->buffers.keyId = 1;
16823             if (devId != INVALID_DEVID)
16824                 ssl->buffers.keyDevId = devId;
16825             else
16826                 ssl->buffers.keyDevId = ssl->devId;
16827 
16828             ret = WOLFSSL_SUCCESS;
16829         }
16830 
16831         return ret;
16832     }
16833 
wolfSSL_use_PrivateKey_Label(WOLFSSL * ssl,const char * label,int devId)16834     int wolfSSL_use_PrivateKey_Label(WOLFSSL* ssl, const char* label, int devId)
16835     {
16836         int ret = WOLFSSL_FAILURE;
16837         word32 sz = (word32)XSTRLEN(label) + 1;
16838 
16839         if (ssl->buffers.weOwnKey)
16840             FreeDer(&ssl->buffers.key);
16841         if (AllocDer(&ssl->buffers.key, (word32)sz, PRIVATEKEY_TYPE,
16842                                                             ssl->heap) == 0) {
16843             XMEMCPY(ssl->buffers.key->buffer, label, sz);
16844             ssl->buffers.weOwnKey = 1;
16845             ssl->buffers.keyLabel = 1;
16846             if (devId != INVALID_DEVID)
16847                 ssl->buffers.keyDevId = devId;
16848             else
16849                 ssl->buffers.keyDevId = ssl->devId;
16850 
16851             ret = WOLFSSL_SUCCESS;
16852         }
16853 
16854         return ret;
16855     }
16856 #endif
16857 
wolfSSL_use_certificate_chain_buffer_format(WOLFSSL * ssl,const unsigned char * in,long sz,int format)16858     int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL* ssl,
16859                                  const unsigned char* in, long sz, int format)
16860     {
16861         WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
16862         if (ssl == NULL)
16863             return BAD_FUNC_ARG;
16864 
16865         return ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE,
16866                              ssl, NULL, 1, GET_VERIFY_SETTING_SSL(ssl));
16867     }
16868 
wolfSSL_use_certificate_chain_buffer(WOLFSSL * ssl,const unsigned char * in,long sz)16869     int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
16870                                  const unsigned char* in, long sz)
16871     {
16872         return wolfSSL_use_certificate_chain_buffer_format(ssl, in, sz,
16873                                                             WOLFSSL_FILETYPE_PEM);
16874     }
16875 
16876 
16877     /* unload any certs or keys that SSL owns, leave CTX as is
16878        WOLFSSL_SUCCESS on ok */
wolfSSL_UnloadCertsKeys(WOLFSSL * ssl)16879     int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
16880     {
16881         if (ssl == NULL) {
16882             WOLFSSL_MSG("Null function arg");
16883             return BAD_FUNC_ARG;
16884         }
16885 
16886         if (ssl->buffers.weOwnCert && !ssl->keepCert) {
16887             WOLFSSL_MSG("Unloading cert");
16888             FreeDer(&ssl->buffers.certificate);
16889             #ifdef KEEP_OUR_CERT
16890             wolfSSL_X509_free(ssl->ourCert);
16891             ssl->ourCert = NULL;
16892             #endif
16893             ssl->buffers.weOwnCert = 0;
16894         }
16895 
16896         if (ssl->buffers.weOwnCertChain) {
16897             WOLFSSL_MSG("Unloading cert chain");
16898             FreeDer(&ssl->buffers.certChain);
16899             ssl->buffers.weOwnCertChain = 0;
16900         }
16901 
16902         if (ssl->buffers.weOwnKey) {
16903             WOLFSSL_MSG("Unloading key");
16904             FreeDer(&ssl->buffers.key);
16905             ssl->buffers.weOwnKey = 0;
16906         }
16907 
16908         return WOLFSSL_SUCCESS;
16909     }
16910 
16911 
wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX * ctx)16912     int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
16913     {
16914         WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
16915 
16916         if (ctx == NULL)
16917             return BAD_FUNC_ARG;
16918 
16919         return wolfSSL_CertManagerUnloadCAs(ctx->cm);
16920     }
16921 
16922 
16923 #ifdef WOLFSSL_TRUST_PEER_CERT
wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX * ctx)16924     int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
16925     {
16926         WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
16927 
16928         if (ctx == NULL)
16929             return BAD_FUNC_ARG;
16930 
16931         return wolfSSL_CertManagerUnload_trust_peers(ctx->cm);
16932     }
16933 #endif /* WOLFSSL_TRUST_PEER_CERT */
16934 /* old NO_FILESYSTEM end */
16935 #endif /* !NO_CERTS */
16936 
16937 
16938 #ifdef OPENSSL_EXTRA
16939 
wolfSSL_add_all_algorithms(void)16940     int wolfSSL_add_all_algorithms(void)
16941     {
16942         WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
16943         if (initRefCount != 0 || wolfSSL_Init() == WOLFSSL_SUCCESS)
16944             return WOLFSSL_SUCCESS;
16945         else
16946             return WOLFSSL_FATAL_ERROR;
16947     }
16948 
wolfSSL_OpenSSL_add_all_algorithms_noconf(void)16949     int wolfSSL_OpenSSL_add_all_algorithms_noconf(void)
16950     {
16951         WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_noconf");
16952 
16953         if  (wolfSSL_add_all_algorithms() == WOLFSSL_FATAL_ERROR)
16954             return WOLFSSL_FATAL_ERROR;
16955 
16956         return  WOLFSSL_SUCCESS;
16957     }
16958 
wolfSSL_OpenSSL_add_all_algorithms_conf(void)16959     int wolfSSL_OpenSSL_add_all_algorithms_conf(void)
16960     {
16961         WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_conf");
16962         /* This function is currently the same as
16963         wolfSSL_OpenSSL_add_all_algorithms_noconf since we do not employ
16964         the use of a wolfssl.cnf type configuration file and is only used for
16965         OpenSSL compatability. */
16966 
16967         if (wolfSSL_add_all_algorithms() == WOLFSSL_FATAL_ERROR) {
16968             return WOLFSSL_FATAL_ERROR;
16969         }
16970         return WOLFSSL_SUCCESS;
16971     }
16972 
16973    /* returns previous set cache size which stays constant */
wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX * ctx,long sz)16974     long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz)
16975     {
16976         /* cache size fixed at compile time in wolfSSL */
16977         (void)ctx;
16978         (void)sz;
16979         WOLFSSL_MSG("session cache is set at compile time");
16980         #ifndef NO_SESSION_CACHE
16981             return (long)(SESSIONS_PER_ROW * SESSION_ROWS);
16982         #else
16983             return 0;
16984         #endif
16985     }
16986 
16987 #endif
16988 
16989 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX * ctx,int mode)16990     void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
16991     {
16992         WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
16993         if (mode)
16994             ctx->quietShutdown = 1;
16995     }
16996 
16997 
wolfSSL_set_quiet_shutdown(WOLFSSL * ssl,int mode)16998     void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
16999     {
17000         WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
17001         if (mode)
17002             ssl->options.quietShutdown = 1;
17003     }
17004 #endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
17005 
17006 #ifdef OPENSSL_EXTRA
17007 #ifndef NO_BIO
wolfSSL_set_bio(WOLFSSL * ssl,WOLFSSL_BIO * rd,WOLFSSL_BIO * wr)17008     void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
17009     {
17010         WOLFSSL_ENTER("wolfSSL_set_bio");
17011 
17012         if (ssl == NULL) {
17013             WOLFSSL_MSG("Bad argument, ssl was NULL");
17014             return;
17015         }
17016 
17017         /* free any existing WOLFSSL_BIOs in use but don't free those in
17018          * a chain */
17019         if (ssl->biord != NULL) {
17020             if (ssl->biord != ssl->biowr) {
17021                 if (ssl->biowr != NULL && ssl->biowr->prev != NULL)
17022                     wolfSSL_BIO_free(ssl->biowr);
17023                 ssl->biowr = NULL;
17024             }
17025             if (ssl->biord->prev != NULL)
17026                 wolfSSL_BIO_free(ssl->biord);
17027             ssl->biord = NULL;
17028         }
17029 
17030         ssl->biord = rd;
17031         ssl->biowr = wr;
17032 
17033         /* set SSL to use BIO callbacks instead */
17034         if (((ssl->cbioFlag & WOLFSSL_CBIO_RECV) == 0)) {
17035             ssl->CBIORecv = BioReceive;
17036         }
17037         if (((ssl->cbioFlag & WOLFSSL_CBIO_SEND) == 0)) {
17038             ssl->CBIOSend = BioSend;
17039         }
17040 
17041         /* User programs should always retry reading from these BIOs */
17042         if (rd) {
17043             /* User writes to rd */
17044             BIO_set_retry_write(rd);
17045         }
17046         if (wr) {
17047             /* User reads from wr */
17048             BIO_set_retry_read(wr);
17049         }
17050     }
17051 #endif /* !NO_BIO */
17052 #endif /* OPENSSL_EXTRA */
17053 
17054 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX * ctx,WOLF_STACK_OF (WOLFSSL_X509_NAME)* names)17055     void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
17056                                        WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
17057     {
17058         WOLFSSL_ENTER("wolfSSL_CTX_set_client_CA_list");
17059         if (ctx != NULL) {
17060             wolfSSL_sk_X509_NAME_pop_free(ctx->ca_names, NULL);
17061             ctx->ca_names = names;
17062         }
17063     }
17064 
wolfSSL_set_client_CA_list(WOLFSSL * ssl,WOLF_STACK_OF (WOLFSSL_X509_NAME)* names)17065     void wolfSSL_set_client_CA_list(WOLFSSL* ssl,
17066                                        WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
17067     {
17068         WOLFSSL_ENTER("wolfSSL_set_client_CA_list");
17069         if (ssl != NULL) {
17070             if (ssl->ca_names != ssl->ctx->ca_names)
17071                 wolfSSL_sk_X509_NAME_pop_free(ssl->ca_names, NULL);
17072             ssl->ca_names = names;
17073         }
17074     }
17075 
17076     #ifdef OPENSSL_EXTRA
17077     /* registers client cert callback, called during handshake if server
17078        requests client auth but user has not loaded client cert/key */
wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX * ctx,client_cert_cb cb)17079     void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb)
17080     {
17081         WOLFSSL_ENTER("wolfSSL_CTX_set_client_cert_cb");
17082 
17083         if (ctx != NULL) {
17084             ctx->CBClientCert = cb;
17085         }
17086     }
17087 
wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX * ctx,CertSetupCallback cb,void * arg)17088     void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx,
17089         CertSetupCallback cb, void *arg)
17090     {
17091         WOLFSSL_ENTER("wolfSSL_CTX_set_cert_cb");
17092         if (ctx == NULL)
17093             return;
17094 
17095         ctx->certSetupCb = cb;
17096         ctx->certSetupCbArg = arg;
17097     }
17098 
17099     /**
17100      * Internal wrapper for calling certSetupCb
17101      * @param ssl The SSL/TLS Object
17102      * @return 0 on success
17103      */
CertSetupCbWrapper(WOLFSSL * ssl)17104     int CertSetupCbWrapper(WOLFSSL* ssl)
17105     {
17106         int ret = 0;
17107         if (ssl->ctx->certSetupCb != NULL) {
17108             WOLFSSL_MSG("Calling user cert setup callback");
17109             ret = ssl->ctx->certSetupCb(ssl, ssl->ctx->certSetupCbArg);
17110             if (ret == 1) {
17111                 WOLFSSL_MSG("User cert callback returned success");
17112                 ret = 0;
17113             }
17114             else if (ret == 0) {
17115                 SendAlert(ssl, alert_fatal, internal_error);
17116                 ret = CLIENT_CERT_CB_ERROR;
17117             }
17118             else if (ret < 0) {
17119                 ret = WOLFSSL_ERROR_WANT_X509_LOOKUP;
17120             }
17121             else {
17122                 WOLFSSL_MSG("Unexpected user callback return");
17123                 ret = CLIENT_CERT_CB_ERROR;
17124             }
17125         }
17126         return ret;
17127     }
17128     #endif /* OPENSSL_EXTRA */
17129 
17130 #endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || HAVE_WEBSERVER */
17131 
17132 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
WOLF_STACK_OF(WOLFSSL_X509_NAME)17133     WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list(
17134             const WOLFSSL_CTX *ctx)
17135     {
17136         WOLFSSL_ENTER("wolfSSL_CTX_get_client_CA_list");
17137 
17138         if (ctx == NULL) {
17139             WOLFSSL_MSG("Bad argument passed to wolfSSL_CTX_get_client_CA_list");
17140             return NULL;
17141         }
17142 
17143         return ctx->ca_names;
17144     }
17145 
17146     /* returns the CA's set on server side or the CA's sent from server when
17147      * on client side */
WOLF_STACK_OF(WOLFSSL_X509_NAME)17148     WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get_client_CA_list(
17149             const WOLFSSL* ssl)
17150     {
17151         WOLFSSL_ENTER("wolfSSL_get_client_CA_list");
17152 
17153         if (ssl == NULL) {
17154             WOLFSSL_MSG("Bad argument passed to wolfSSL_get_client_CA_list");
17155             return NULL;
17156         }
17157 
17158         return SSL_CA_NAMES(ssl);
17159     }
17160 
17161     #if !defined(NO_CERTS)
wolfSSL_CTX_add_client_CA(WOLFSSL_CTX * ctx,WOLFSSL_X509 * x509)17162     int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
17163     {
17164         WOLFSSL_X509_NAME *nameCopy = NULL;
17165 
17166         WOLFSSL_ENTER("wolfSSL_CTX_add_client_CA");
17167 
17168         if (ctx == NULL || x509 == NULL){
17169             WOLFSSL_MSG("Bad argument");
17170             return WOLFSSL_FAILURE;
17171         }
17172 
17173         if (ctx->ca_names == NULL) {
17174             ctx->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
17175             if (ctx->ca_names == NULL) {
17176                 WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
17177                 return WOLFSSL_FAILURE;
17178             }
17179         }
17180 
17181         nameCopy = wolfSSL_X509_NAME_dup(wolfSSL_X509_get_subject_name(x509));
17182         if (nameCopy == NULL) {
17183             WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
17184             return WOLFSSL_FAILURE;
17185         }
17186 
17187         if (wolfSSL_sk_X509_NAME_push(ctx->ca_names, nameCopy) != WOLFSSL_SUCCESS) {
17188             WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
17189             wolfSSL_X509_NAME_free(nameCopy);
17190             return WOLFSSL_FAILURE;
17191         }
17192 
17193         return WOLFSSL_SUCCESS;
17194     }
17195     #endif
17196 
17197     #ifndef NO_BIO
17198         #if !defined(NO_RSA) && !defined(NO_CERTS)
WOLF_STACK_OF(WOLFSSL_X509_NAME)17199         WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
17200         {
17201             /* The webserver build is using this to load a CA into the server
17202              * for client authentication as an option. Have this return NULL in
17203              * that case. If OPENSSL_EXTRA is enabled, go ahead and include
17204              * the function. */
17205         #ifdef OPENSSL_EXTRA
17206             WOLFSSL_STACK *list = NULL;
17207             WOLFSSL_BIO* bio = NULL;
17208             WOLFSSL_X509 *cert = NULL;
17209             WOLFSSL_X509_NAME *nameCopy = NULL;
17210             unsigned long err = WOLFSSL_FAILURE;
17211 
17212             WOLFSSL_ENTER("wolfSSL_load_client_CA_file");
17213 
17214             bio = wolfSSL_BIO_new_file(fname, "rb");
17215             if (bio == NULL) {
17216                 WOLFSSL_MSG("wolfSSL_BIO_new_file error");
17217                 goto cleanup;
17218             }
17219 
17220             list = wolfSSL_sk_X509_NAME_new(NULL);
17221             if (list == NULL) {
17222                 WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
17223                 goto cleanup;
17224             }
17225 
17226             /* Read each certificate in the chain out of the file. */
17227             while (wolfSSL_PEM_read_bio_X509(bio, &cert, NULL, NULL) != NULL) {
17228                 /* Need a persistent copy of the subject name. */
17229                 nameCopy = wolfSSL_X509_NAME_dup(
17230                         wolfSSL_X509_get_subject_name(cert));
17231                 if (nameCopy == NULL) {
17232                     WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
17233                     goto cleanup;
17234                 }
17235                 /*
17236                 * Original cert will be freed so make sure not to try to access
17237                 * it in the future.
17238                 */
17239                 nameCopy->x509 = NULL;
17240 
17241                 if (wolfSSL_sk_X509_NAME_push(list, nameCopy) !=
17242                         WOLFSSL_SUCCESS) {
17243                     WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
17244                     /* Do free in loop because nameCopy is now responsibility
17245                      * of list to free and adding jumps to cleanup after this
17246                      * might result in a double free. */
17247                     wolfSSL_X509_NAME_free(nameCopy);
17248                     goto cleanup;
17249                 }
17250 
17251                 wolfSSL_X509_free(cert);
17252                 cert = NULL;
17253             }
17254 
17255             err = wolfSSL_ERR_peek_last_error();
17256 
17257             if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
17258                     ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
17259                 /*
17260                  * wolfSSL_PEM_read_bio_X509 pushes an ASN_NO_PEM_HEADER error
17261                  * to the error queue on file end. This should not be left
17262                  * for the caller to find so we clear the last error.
17263                  */
17264                 wc_RemoveErrorNode(-1);
17265             }
17266 
17267             err = WOLFSSL_SUCCESS;
17268 cleanup:
17269             wolfSSL_X509_free(cert);
17270             wolfSSL_BIO_free(bio);
17271             if (err != WOLFSSL_SUCCESS) {
17272                 /* We failed so return NULL */
17273                 wolfSSL_sk_X509_NAME_pop_free(list, NULL);
17274                 list = NULL;
17275             }
17276             return list;
17277         #else
17278             (void)fname;
17279             return NULL;
17280         #endif
17281         }
17282         #endif
17283     #endif /* !NO_BIO */
17284 #endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA */
17285 
17286 #ifdef OPENSSL_EXTRA
17287 
17288     #ifndef NO_WOLFSSL_STUB
wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX * ctx)17289     int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
17290     {
17291         /* TODO:, not needed in goahead */
17292         (void)ctx;
17293         WOLFSSL_STUB("SSL_CTX_set_default_verify_paths");
17294         return SSL_NOT_IMPLEMENTED;
17295     }
17296 
wolfSSL_X509_get_default_cert_file_env(void)17297     const char* wolfSSL_X509_get_default_cert_file_env(void)
17298     {
17299         WOLFSSL_STUB("X509_get_default_cert_file_env");
17300         return NULL;
17301     }
17302 
wolfSSL_X509_get_default_cert_file(void)17303     const char* wolfSSL_X509_get_default_cert_file(void)
17304     {
17305         WOLFSSL_STUB("X509_get_default_cert_file");
17306         return NULL;
17307     }
17308 
wolfSSL_X509_get_default_cert_dir_env(void)17309     const char* wolfSSL_X509_get_default_cert_dir_env(void)
17310     {
17311         WOLFSSL_STUB("X509_get_default_cert_dir_env");
17312         return NULL;
17313     }
17314 
wolfSSL_X509_get_default_cert_dir(void)17315     const char* wolfSSL_X509_get_default_cert_dir(void)
17316     {
17317         WOLFSSL_STUB("X509_get_default_cert_dir");
17318         return NULL;
17319     }
17320     #endif
17321 
17322     #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
17323         && !defined(WC_NO_RNG)
17324     static const byte srp_N[] = {
17325         0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6, 0x9C, 0x33, 0xF8,
17326         0x0A, 0xFA, 0x8F, 0xC5, 0xE8, 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF,
17327         0x3C, 0x0B, 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76, 0xD6,
17328         0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3, 0x38, 0x3B, 0x48, 0x13,
17329         0xD6, 0x92, 0xC6, 0xE0, 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B,
17330         0xE4, 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1, 0x5D, 0xC7,
17331         0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6, 0xCE, 0x8E, 0xF4, 0xAD, 0x69,
17332         0xB1, 0x5D, 0x49, 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
17333         0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC, 0x68, 0xED, 0xBC,
17334         0x3C, 0x05, 0x72, 0x6C, 0xC0, 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E,
17335         0xAA, 0x9A, 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B, 0x9F,
17336         0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
17337     };
17338     static const byte srp_g[] = {
17339         0x02
17340     };
17341 
wolfSSL_CTX_set_srp_username(WOLFSSL_CTX * ctx,char * username)17342     int wolfSSL_CTX_set_srp_username(WOLFSSL_CTX* ctx, char* username)
17343     {
17344         int r = 0;
17345         SrpSide srp_side = SRP_CLIENT_SIDE;
17346         byte salt[SRP_SALT_SIZE];
17347 
17348         WOLFSSL_ENTER("wolfSSL_CTX_set_srp_username");
17349         if (ctx == NULL || ctx->srp == NULL || username==NULL)
17350             return SSL_FAILURE;
17351 
17352         if (ctx->method->side == WOLFSSL_SERVER_END){
17353             srp_side = SRP_SERVER_SIDE;
17354         } else if (ctx->method->side == WOLFSSL_CLIENT_END){
17355             srp_side = SRP_CLIENT_SIDE;
17356         } else {
17357             WOLFSSL_MSG("Init CTX failed");
17358             return SSL_FAILURE;
17359         }
17360 
17361         if (wc_SrpInit(ctx->srp, SRP_TYPE_SHA256, srp_side) < 0) {
17362             WOLFSSL_MSG("Init SRP CTX failed");
17363             XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
17364             ctx->srp = NULL;
17365             return SSL_FAILURE;
17366         }
17367         r = wc_SrpSetUsername(ctx->srp, (const byte*)username,
17368                               (word32)XSTRLEN(username));
17369         if (r < 0) {
17370             WOLFSSL_MSG("fail to set srp username.");
17371             return SSL_FAILURE;
17372         }
17373 
17374         /* if wolfSSL_CTX_set_srp_password has already been called, */
17375         /* execute wc_SrpSetPassword here */
17376         if (ctx->srp_password != NULL) {
17377             WC_RNG rng;
17378             if (wc_InitRng(&rng) < 0){
17379                 WOLFSSL_MSG("wc_InitRng failed");
17380                 return SSL_FAILURE;
17381             }
17382             XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
17383             r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0]));
17384             wc_FreeRng(&rng);
17385             if (r <  0) {
17386                 WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
17387                 return SSL_FAILURE;
17388             }
17389 
17390             if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
17391                                 srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
17392                                 salt, sizeof(salt)/sizeof(salt[0])) < 0) {
17393                 WOLFSSL_MSG("wc_SrpSetParam failed");
17394                 return SSL_FAILURE;
17395             }
17396             r = wc_SrpSetPassword(ctx->srp,
17397                      (const byte*)ctx->srp_password,
17398                      (word32)XSTRLEN((char *)ctx->srp_password));
17399             if (r < 0) {
17400                 WOLFSSL_MSG("fail to set srp password.");
17401                 return SSL_FAILURE;
17402             }
17403 
17404             XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
17405             ctx->srp_password = NULL;
17406         }
17407 
17408         return WOLFSSL_SUCCESS;
17409     }
17410 
wolfSSL_CTX_set_srp_password(WOLFSSL_CTX * ctx,char * password)17411     int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX* ctx, char* password)
17412     {
17413         int r;
17414         byte salt[SRP_SALT_SIZE];
17415 
17416         WOLFSSL_ENTER("wolfSSL_CTX_set_srp_password");
17417         if (ctx == NULL || ctx->srp == NULL || password == NULL)
17418             return SSL_FAILURE;
17419 
17420         if (ctx->srp->user != NULL) {
17421             WC_RNG rng;
17422             if (wc_InitRng(&rng) < 0) {
17423                 WOLFSSL_MSG("wc_InitRng failed");
17424                 return SSL_FAILURE;
17425             }
17426             XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
17427             r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0]));
17428             wc_FreeRng(&rng);
17429             if (r <  0) {
17430                 WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
17431                 return SSL_FAILURE;
17432             }
17433             if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
17434                                 srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
17435                                 salt, sizeof(salt)/sizeof(salt[0])) < 0){
17436                 WOLFSSL_MSG("wc_SrpSetParam failed");
17437                 wc_FreeRng(&rng);
17438                 return SSL_FAILURE;
17439             }
17440             r = wc_SrpSetPassword(ctx->srp, (const byte*)password,
17441                                   (word32)XSTRLEN(password));
17442             if (r < 0) {
17443                 WOLFSSL_MSG("wc_SrpSetPassword failed.");
17444                 wc_FreeRng(&rng);
17445                 return SSL_FAILURE;
17446             }
17447             if (ctx->srp_password != NULL){
17448                 XFREE(ctx->srp_password,NULL,
17449                       DYNAMIC_TYPE_SRP);
17450                 ctx->srp_password = NULL;
17451             }
17452             wc_FreeRng(&rng);
17453         } else {
17454             /* save password for wolfSSL_set_srp_username */
17455             if (ctx->srp_password != NULL)
17456                 XFREE(ctx->srp_password,ctx->heap, DYNAMIC_TYPE_SRP);
17457 
17458             ctx->srp_password = (byte*)XMALLOC(XSTRLEN(password) + 1, ctx->heap,
17459                                                DYNAMIC_TYPE_SRP);
17460             if (ctx->srp_password == NULL){
17461                 WOLFSSL_MSG("memory allocation error");
17462                 return SSL_FAILURE;
17463             }
17464             XMEMCPY(ctx->srp_password, password, XSTRLEN(password) + 1);
17465         }
17466         return WOLFSSL_SUCCESS;
17467     }
17468 
17469     /**
17470      * The modulus passed to wc_SrpSetParams in ssl.c is constant so check
17471      * that the requested strength is less than or equal to the size of the
17472      * static modulus size.
17473      * @param ctx Not used
17474      * @param strength Minimum number of bits for the modulus
17475      * @return 1 if strength is less than or equal to static modulus
17476      *         0 if strength is greater than static modulus
17477      */
wolfSSL_CTX_set_srp_strength(WOLFSSL_CTX * ctx,int strength)17478     int  wolfSSL_CTX_set_srp_strength(WOLFSSL_CTX *ctx, int strength)
17479     {
17480         (void)ctx;
17481         WOLFSSL_ENTER("wolfSSL_CTX_set_srp_strength");
17482         if (strength > (int)(sizeof(srp_N)*8)) {
17483             WOLFSSL_MSG("Bad Parameter");
17484             return WOLFSSL_FAILURE;
17485         }
17486         return WOLFSSL_SUCCESS;
17487     }
17488 
wolfSSL_get_srp_username(WOLFSSL * ssl)17489     char* wolfSSL_get_srp_username(WOLFSSL *ssl)
17490     {
17491         if (ssl && ssl->ctx && ssl->ctx->srp) {
17492             return (char*) ssl->ctx->srp->user;
17493         }
17494         return NULL;
17495     }
17496     #endif /* WOLFCRYPT_HAVE_SRP && !NO_SHA256 && !WC_NO_RNG */
17497 
17498     /* keyblock size in bytes or -1 */
wolfSSL_get_keyblock_size(WOLFSSL * ssl)17499     int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
17500     {
17501         if (ssl == NULL)
17502             return WOLFSSL_FATAL_ERROR;
17503 
17504         return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
17505                     ssl->specs.hash_size);
17506     }
17507 
17508 #endif /* OPENSSL_EXTRA */
17509 
17510 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
17511 
17512     /* store keys returns WOLFSSL_SUCCESS or -1 on error */
wolfSSL_get_keys(WOLFSSL * ssl,unsigned char ** ms,unsigned int * msLen,unsigned char ** sr,unsigned int * srLen,unsigned char ** cr,unsigned int * crLen)17513     int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
17514                                      unsigned char** sr, unsigned int* srLen,
17515                                      unsigned char** cr, unsigned int* crLen)
17516     {
17517         if (ssl == NULL || ssl->arrays == NULL)
17518             return WOLFSSL_FATAL_ERROR;
17519 
17520         *ms = ssl->arrays->masterSecret;
17521         *sr = ssl->arrays->serverRandom;
17522         *cr = ssl->arrays->clientRandom;
17523 
17524         *msLen = SECRET_LEN;
17525         *srLen = RAN_LEN;
17526         *crLen = RAN_LEN;
17527 
17528         return WOLFSSL_SUCCESS;
17529     }
17530 
wolfSSL_set_accept_state(WOLFSSL * ssl)17531     void wolfSSL_set_accept_state(WOLFSSL* ssl)
17532     {
17533         WOLFSSL_ENTER("wolfSSL_set_accept_state");
17534 
17535         if (ssl == NULL)
17536             return;
17537 
17538         if (ssl->options.side == WOLFSSL_CLIENT_END) {
17539     #ifdef HAVE_ECC
17540             ecc_key key;
17541             word32 idx = 0;
17542 
17543             if (ssl->options.haveStaticECC && ssl->buffers.key != NULL) {
17544                 if (wc_ecc_init(&key) >= 0) {
17545                     if (wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx, &key,
17546                                                    ssl->buffers.key->length) != 0) {
17547                         ssl->options.haveECDSAsig = 0;
17548                         ssl->options.haveECC = 0;
17549                         ssl->options.haveStaticECC = 0;
17550                     }
17551                     wc_ecc_free(&key);
17552                 }
17553             }
17554     #endif
17555 
17556     #ifndef NO_DH
17557             if (!ssl->options.haveDH && ssl->ctx->haveDH) {
17558                 ssl->buffers.serverDH_P = ssl->ctx->serverDH_P;
17559                 ssl->buffers.serverDH_G = ssl->ctx->serverDH_G;
17560                 ssl->options.haveDH = 1;
17561             }
17562     #endif
17563         }
17564 
17565         if (InitSSL_Side(ssl, WOLFSSL_SERVER_END) != WOLFSSL_SUCCESS) {
17566             WOLFSSL_MSG("Error initializing server side");
17567         }
17568     }
17569 
17570 #endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
17571 
17572     /* return true if connection established */
wolfSSL_is_init_finished(WOLFSSL * ssl)17573     int wolfSSL_is_init_finished(WOLFSSL* ssl)
17574     {
17575         if (ssl == NULL)
17576             return 0;
17577 
17578         if (ssl->options.handShakeState == HANDSHAKE_DONE)
17579             return 1;
17580 
17581         return 0;
17582     }
17583 
17584 #ifdef OPENSSL_EXTRA
17585 
wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX * ctx,WOLFSSL_RSA * (* f)(WOLFSSL *,int,int))17586     void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
17587                                       WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
17588     {
17589         /* wolfSSL verifies all these internally */
17590         (void)ctx;
17591         (void)f;
17592     }
17593 
17594 
wolfSSL_set_shutdown(WOLFSSL * ssl,int opt)17595     void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
17596     {
17597         WOLFSSL_ENTER("wolfSSL_set_shutdown");
17598         if(ssl==NULL) {
17599             WOLFSSL_MSG("Shutdown not set. ssl is null");
17600             return;
17601         }
17602 
17603         ssl->options.sentNotify =  (opt&WOLFSSL_SENT_SHUTDOWN) > 0;
17604         ssl->options.closeNotify = (opt&WOLFSSL_RECEIVED_SHUTDOWN) > 0;
17605     }
17606 
17607 
wolfSSL_CTX_get_options(WOLFSSL_CTX * ctx)17608     long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
17609     {
17610         WOLFSSL_ENTER("wolfSSL_CTX_get_options");
17611         WOLFSSL_MSG("wolfSSL options are set through API calls and macros");
17612         if(ctx == NULL)
17613             return BAD_FUNC_ARG;
17614         return ctx->mask;
17615     }
17616 
17617 #endif
17618 
17619     static long wolf_set_options(long old_op, long op);
wolfSSL_CTX_set_options(WOLFSSL_CTX * ctx,long opt)17620     long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
17621     {
17622         WOLFSSL_ENTER("SSL_CTX_set_options");
17623 
17624         if (ctx == NULL)
17625             return BAD_FUNC_ARG;
17626 
17627         ctx->mask = wolf_set_options(ctx->mask, opt);
17628 
17629 #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER) && \
17630     defined(OPENSSL_EXTRA)
17631         if (ctx->mask & SSL_OP_NO_TICKET) {
17632             ctx->ticketEncCb = NULL;
17633             ctx->ticketEncCtx = NULL;
17634             WOLFSSL_MSG("\tSSL_OP_NO_TICKET");
17635         }
17636 #endif
17637 
17638         return ctx->mask;
17639     }
17640 
17641 #ifdef OPENSSL_EXTRA
17642 
wolfSSL_CTX_clear_options(WOLFSSL_CTX * ctx,long opt)17643     long wolfSSL_CTX_clear_options(WOLFSSL_CTX* ctx, long opt)
17644     {
17645         WOLFSSL_ENTER("SSL_CTX_clear_options");
17646         if(ctx == NULL)
17647             return BAD_FUNC_ARG;
17648         ctx->mask &= ~opt;
17649         return ctx->mask;
17650     }
17651 
wolfSSL_set_rfd(WOLFSSL * ssl,int rfd)17652     int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
17653     {
17654         WOLFSSL_ENTER("SSL_set_rfd");
17655         ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
17656 
17657         ssl->IOCB_ReadCtx  = &ssl->rfd;
17658 
17659     #ifdef WOLFSSL_DTLS
17660         if (ssl->options.dtls) {
17661             ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
17662             ssl->buffers.dtlsCtx.rfd = rfd;
17663         }
17664     #endif
17665 
17666         return WOLFSSL_SUCCESS;
17667     }
17668 
17669 
wolfSSL_set_wfd(WOLFSSL * ssl,int wfd)17670     int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
17671     {
17672         WOLFSSL_ENTER("SSL_set_wfd");
17673         ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
17674 
17675         ssl->IOCB_WriteCtx  = &ssl->wfd;
17676 
17677         return WOLFSSL_SUCCESS;
17678     }
17679 #endif /* OPENSSL_EXTRA */
17680 
17681 #if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
17682 
17683 #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
17684     /**
17685      * Implemented in a similar way that ngx_ssl_ocsp_validate does it when
17686      * SSL_get0_verified_chain is not available.
17687      * @param ssl WOLFSSL object to extract certs from
17688      * @return Stack of verified certs
17689      */
WOLF_STACK_OF(WOLFSSL_X509)17690     WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl)
17691     {
17692         WOLF_STACK_OF(WOLFSSL_X509)* chain = NULL;
17693         WOLFSSL_X509_STORE_CTX* storeCtx = NULL;
17694         WOLFSSL_X509* peerCert = NULL;
17695 
17696         WOLFSSL_ENTER("wolfSSL_get0_verified_chain");
17697 
17698         if (ssl == NULL || ssl->ctx == NULL) {
17699             WOLFSSL_MSG("Bad parameter");
17700             return NULL;
17701         }
17702 
17703         peerCert = wolfSSL_get_peer_certificate((WOLFSSL*)ssl);
17704         if (peerCert == NULL) {
17705             WOLFSSL_MSG("wolfSSL_get_peer_certificate error");
17706             return NULL;
17707         }
17708         chain = wolfSSL_get_peer_cert_chain(ssl);
17709         if (chain == NULL) {
17710             WOLFSSL_MSG("wolfSSL_get_peer_cert_chain error");
17711             return NULL;
17712         }
17713         storeCtx = wolfSSL_X509_STORE_CTX_new();
17714         if (storeCtx == NULL) {
17715             WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_new error");
17716             return NULL;
17717         }
17718         if (wolfSSL_X509_STORE_CTX_init(storeCtx, SSL_STORE(ssl),
17719                 peerCert, chain) != WOLFSSL_SUCCESS) {
17720             WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init error");
17721             wolfSSL_X509_STORE_CTX_free(storeCtx);
17722             return NULL;
17723         }
17724         if (wolfSSL_X509_verify_cert(storeCtx) <= 0) {
17725             WOLFSSL_MSG("wolfSSL_X509_verify_cert error");
17726             wolfSSL_X509_STORE_CTX_free(storeCtx);
17727             return NULL;
17728         }
17729         wolfSSL_X509_STORE_CTX_free(storeCtx);
17730         return chain;
17731     }
17732 #endif /* SESSION_CERTS && OPENSSL_EXTRA */
17733 
wolfSSL_CTX_get_cert_store(WOLFSSL_CTX * ctx)17734     WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx)
17735     {
17736         if (ctx == NULL) {
17737             return NULL;
17738         }
17739 
17740         if (ctx->x509_store_pt != NULL)
17741             return ctx->x509_store_pt;
17742         return &ctx->x509_store;
17743     }
17744 
wolfSSL_CTX_set_cert_store(WOLFSSL_CTX * ctx,WOLFSSL_X509_STORE * str)17745     void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str)
17746     {
17747         WOLFSSL_ENTER("wolfSSL_CTX_set_cert_store");
17748         if (ctx == NULL || str == NULL || ctx->cm == str->cm) {
17749             return;
17750         }
17751 
17752         if (wolfSSL_CertManager_up_ref(str->cm) != WOLFSSL_SUCCESS) {
17753             WOLFSSL_MSG("wolfSSL_CertManager_up_ref error");
17754             return;
17755         }
17756         /* free cert manager if have one */
17757         if (ctx->cm != NULL) {
17758             wolfSSL_CertManagerFree(ctx->cm);
17759         }
17760         ctx->cm               = str->cm;
17761         ctx->x509_store.cm    = str->cm;
17762 
17763         /* free existing store if it exists */
17764         wolfSSL_X509_STORE_free(ctx->x509_store_pt);
17765         ctx->x509_store.cache = str->cache;
17766         ctx->x509_store_pt    = str; /* take ownership of store and free it
17767                                         with CTX free */
17768         ctx->cm->x509_store_p = ctx->x509_store_pt;/* CTX has onwership
17769                                                     and free it with CTX free*/
17770     }
17771 
17772 
wolfSSL_set0_verify_cert_store(WOLFSSL * ssl,WOLFSSL_X509_STORE * str)17773     int wolfSSL_set0_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
17774     {
17775         WOLFSSL_ENTER("wolfSSL_set0_verify_cert_store");
17776 
17777         if (ssl == NULL || str == NULL) {
17778             WOLFSSL_MSG("Bad parameter");
17779             return WOLFSSL_FAILURE;
17780         }
17781 
17782         /* NO-OP when setting existing store */
17783         if (str == SSL_STORE(ssl))
17784             return WOLFSSL_SUCCESS;
17785 
17786         /* free existing store if it exists */
17787         wolfSSL_X509_STORE_free(ssl->x509_store_pt);
17788         if (str == ssl->ctx->x509_store_pt)
17789             ssl->x509_store_pt = NULL; /* if setting ctx store then just revert
17790                                           to using that instead */
17791         else
17792             ssl->x509_store_pt = str; /* take ownership of store and free it
17793                                          with SSL free */
17794         return WOLFSSL_SUCCESS;
17795     }
17796 
17797 
wolfSSL_set1_verify_cert_store(WOLFSSL * ssl,WOLFSSL_X509_STORE * str)17798     int wolfSSL_set1_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
17799     {
17800         WOLFSSL_ENTER("wolfSSL_set0_verify_cert_store");
17801 
17802         if (ssl == NULL || str == NULL) {
17803             WOLFSSL_MSG("Bad parameter");
17804             return WOLFSSL_FAILURE;
17805         }
17806 
17807         /* NO-OP when setting existing store */
17808         if (str == SSL_STORE(ssl))
17809             return WOLFSSL_SUCCESS;
17810 
17811         if (wolfSSL_X509_STORE_up_ref(str) != WOLFSSL_SUCCESS) {
17812             WOLFSSL_MSG("wolfSSL_X509_STORE_up_ref error");
17813             return WOLFSSL_FAILURE;
17814         }
17815 
17816         /* free existing store if it exists */
17817         wolfSSL_X509_STORE_free(ssl->x509_store_pt);
17818         if (str == ssl->ctx->x509_store_pt)
17819             ssl->x509_store_pt = NULL; /* if setting ctx store then just revert
17820                                           to using that instead */
17821         else
17822             ssl->x509_store_pt = str; /* take ownership of store and free it
17823                                          with SSL free */
17824         return WOLFSSL_SUCCESS;
17825     }
17826 #endif /* !NO_CERTS && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
17827 
17828 #ifdef WOLFSSL_ENCRYPTED_KEYS
17829 
wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX * ctx,void * userdata)17830     void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
17831                                                    void* userdata)
17832     {
17833         WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
17834         if (ctx)
17835             ctx->passwd_userdata = userdata;
17836     }
17837 
17838 
wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX * ctx,wc_pem_password_cb * cb)17839     void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx, wc_pem_password_cb*
17840                                            cb)
17841     {
17842         WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb");
17843         if (ctx)
17844             ctx->passwd_cb = cb;
17845     }
17846 
wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX * ctx)17847     wc_pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx)
17848     {
17849         if (ctx == NULL || ctx->passwd_cb == NULL) {
17850             return NULL;
17851         }
17852 
17853         return ctx->passwd_cb;
17854     }
17855 
17856 
wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX * ctx)17857     void* wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx)
17858     {
17859         if (ctx == NULL) {
17860             return NULL;
17861         }
17862 
17863         return ctx->passwd_userdata;
17864     }
17865 
17866 #endif /* WOLFSSL_ENCRYPTED_KEYS */
17867 
17868 
17869 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
wolfSSL_num_locks(void)17870     int wolfSSL_num_locks(void)
17871     {
17872         return 0;
17873     }
17874 
wolfSSL_set_locking_callback(void (* f)(int,int,const char *,int))17875     void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
17876     {
17877         WOLFSSL_ENTER("wolfSSL_set_locking_callback");
17878 
17879         if (wc_SetMutexCb(f) != 0) {
17880             WOLFSSL_MSG("Error when setting mutex call back");
17881         }
17882     }
17883 
17884 
17885     typedef unsigned long (idCb)(void);
17886     static idCb* inner_idCb = NULL;
17887 
wolfSSL_thread_id(void)17888     unsigned long wolfSSL_thread_id(void)
17889     {
17890         if (inner_idCb != NULL) {
17891             return inner_idCb();
17892         }
17893         else {
17894             return 0;
17895         }
17896     }
17897 
17898 
wolfSSL_set_id_callback(unsigned long (* f)(void))17899     void wolfSSL_set_id_callback(unsigned long (*f)(void))
17900     {
17901         inner_idCb = f;
17902     }
17903 
wolfSSL_ERR_get_error(void)17904     unsigned long wolfSSL_ERR_get_error(void)
17905     {
17906         WOLFSSL_ENTER("wolfSSL_ERR_get_error");
17907 
17908 #ifdef WOLFSSL_HAVE_ERROR_QUEUE
17909 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
17910         {
17911             unsigned long ret = wolfSSL_ERR_peek_error_line_data(NULL, NULL,
17912                                                                  NULL, NULL);
17913             wc_RemoveErrorNode(-1);
17914             return ret;
17915         }
17916 #else
17917         {
17918             int ret = wc_PullErrorNode(NULL, NULL, NULL);
17919 
17920             if (ret < 0) {
17921                 if (ret == BAD_STATE_E) return 0; /* no errors in queue */
17922                 WOLFSSL_MSG("Error with pulling error node!");
17923                 WOLFSSL_LEAVE("wolfSSL_ERR_get_error", ret);
17924                 ret = 0 - ret; /* return absolute value of error */
17925 
17926                 /* panic and try to clear out nodes */
17927                 wc_ClearErrorNodes();
17928             }
17929 
17930             return (unsigned long)ret;
17931         }
17932 #endif
17933 #else
17934         return (unsigned long)(0 - NOT_COMPILED_IN);
17935 #endif
17936     }
17937 
17938 #ifdef WOLFSSL_HAVE_ERROR_QUEUE
17939 #ifndef NO_BIO
17940     /* print out and clear all errors */
wolfSSL_ERR_print_errors(WOLFSSL_BIO * bio)17941     void wolfSSL_ERR_print_errors(WOLFSSL_BIO* bio)
17942     {
17943         const char* file = NULL;
17944         const char* reason = NULL;
17945         int ret;
17946         int line = 0;
17947         char buf[WOLFSSL_MAX_ERROR_SZ * 2];
17948 
17949         WOLFSSL_ENTER("wolfSSL_ERR_print_errors");
17950 
17951         if (bio == NULL) {
17952             WOLFSSL_MSG("BIO passed in was null");
17953             return;
17954         }
17955 
17956         do {
17957         ret = wc_PeekErrorNode(0, &file, &reason, &line);
17958         if (ret >= 0) {
17959             const char* r = wolfSSL_ERR_reason_error_string(0 - ret);
17960             XSNPRINTF(buf, sizeof(buf), "error:%d:wolfSSL library:%s:%s:%d\n",
17961                     ret, r, file, line);
17962             wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf));
17963             wc_RemoveErrorNode(0);
17964         }
17965         } while (ret >= 0);
17966         if (wolfSSL_BIO_write(bio, "", 1) != 1) {
17967             WOLFSSL_MSG("Issue writing final string terminator");
17968         }
17969     }
17970 #endif /* !NO_BIO */
17971 #endif /* WOLFSSL_HAVE_ERROR_QUEUE */
17972 
17973 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
17974 
17975 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
17976     defined(HAVE_SECRET_CALLBACK)
17977 #if !defined(NO_WOLFSSL_SERVER)
17978 /* Return the amount of random bytes copied over or error case.
17979  * ssl : ssl struct after handshake
17980  * out : buffer to hold random bytes
17981  * outSz : either 0 (return max buffer sz) or size of out buffer
17982  */
wolfSSL_get_server_random(const WOLFSSL * ssl,unsigned char * out,size_t outSz)17983 size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out,
17984                                                                    size_t outSz)
17985 {
17986     size_t size;
17987 
17988     /* return max size of buffer */
17989     if (outSz == 0) {
17990         return RAN_LEN;
17991     }
17992 
17993     if (ssl == NULL || out == NULL) {
17994         return 0;
17995     }
17996 
17997     if (ssl->arrays == NULL) {
17998         WOLFSSL_MSG("Arrays struct not saved after handshake");
17999         return 0;
18000     }
18001 
18002     if (outSz > RAN_LEN) {
18003         size = RAN_LEN;
18004     }
18005     else {
18006         size = outSz;
18007     }
18008 
18009     XMEMCPY(out, ssl->arrays->serverRandom, size);
18010     return size;
18011 }
18012 #endif /* !NO_WOLFSSL_SERVER */
18013 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
18014 
18015 #ifdef OPENSSL_EXTRA
18016 #if !defined(NO_WOLFSSL_SERVER)
18017 /* Used to get the peer ephemeral public key sent during the connection
18018  * NOTE: currently wolfSSL_KeepHandshakeResources(WOLFSSL* ssl) must be called
18019  *       before the ephemeral key is stored.
18020  * return WOLFSSL_SUCCESS on success */
wolfSSL_get_server_tmp_key(const WOLFSSL * ssl,WOLFSSL_EVP_PKEY ** pkey)18021 int wolfSSL_get_server_tmp_key(const WOLFSSL* ssl, WOLFSSL_EVP_PKEY** pkey)
18022 {
18023     WOLFSSL_EVP_PKEY* ret = NULL;
18024 
18025     WOLFSSL_ENTER("wolfSSL_get_server_tmp_key");
18026 
18027     if (ssl == NULL || pkey == NULL) {
18028         WOLFSSL_MSG("Bad argument passed in");
18029         return WOLFSSL_FAILURE;
18030     }
18031 
18032 #ifdef HAVE_ECC
18033     if (ssl->peerEccKey != NULL) {
18034         unsigned char* der;
18035         const unsigned char* pt;
18036         unsigned int   derSz = 0;
18037         int sz;
18038 
18039         PRIVATE_KEY_UNLOCK();
18040         if (wc_ecc_export_x963(ssl->peerEccKey, NULL, &derSz) !=
18041                 LENGTH_ONLY_E) {
18042             WOLFSSL_MSG("get ecc der size failed");
18043             PRIVATE_KEY_LOCK();
18044             return WOLFSSL_FAILURE;
18045         }
18046         PRIVATE_KEY_LOCK();
18047 
18048         derSz += MAX_SEQ_SZ + (2 * MAX_ALGO_SZ) + MAX_SEQ_SZ + TRAILING_ZERO;
18049         der = (unsigned char*)XMALLOC(derSz, ssl->heap, DYNAMIC_TYPE_KEY);
18050         if (der == NULL) {
18051             WOLFSSL_MSG("Memory error");
18052             return WOLFSSL_FAILURE;
18053         }
18054 
18055         if ((sz = wc_EccPublicKeyToDer(ssl->peerEccKey, der, derSz, 1)) <= 0) {
18056             WOLFSSL_MSG("get ecc der failed");
18057             XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
18058             return WOLFSSL_FAILURE;
18059         }
18060         pt = der; /* in case pointer gets advanced */
18061         ret = wolfSSL_d2i_PUBKEY(NULL, &pt, sz);
18062         XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
18063     }
18064 #endif
18065 
18066     *pkey = ret;
18067 #ifdef HAVE_ECC
18068     if (ret != NULL)
18069         return WOLFSSL_SUCCESS;
18070     else
18071 #endif
18072         return WOLFSSL_FAILURE;
18073 }
18074 
18075 #endif /* !NO_WOLFSSL_SERVER */
18076 
18077 /**
18078  * This function checks if any compiled in protocol versions are
18079  * left enabled after calls to set_min or set_max API.
18080  * @param major The SSL/TLS major version
18081  * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
18082  *         protocol versions are left enabled.
18083  */
CheckSslMethodVersion(byte major,unsigned long options)18084 static int CheckSslMethodVersion(byte major, unsigned long options)
18085 {
18086     int sanityConfirmed = 0;
18087 
18088     (void)options;
18089 
18090     switch (major) {
18091     #ifndef NO_TLS
18092         case SSLv3_MAJOR:
18093             #ifdef WOLFSSL_ALLOW_SSLV3
18094                 if (!(options & WOLFSSL_OP_NO_SSLv3)) {
18095                     sanityConfirmed = 1;
18096                 }
18097             #endif
18098             #ifndef NO_OLD_TLS
18099                 if (!(options & WOLFSSL_OP_NO_TLSv1))
18100                     sanityConfirmed = 1;
18101                 if (!(options & WOLFSSL_OP_NO_TLSv1_1))
18102                     sanityConfirmed = 1;
18103             #endif
18104             #ifndef WOLFSSL_NO_TLS12
18105                 if (!(options & WOLFSSL_OP_NO_TLSv1_2))
18106                     sanityConfirmed = 1;
18107             #endif
18108             #ifdef WOLFSSL_TLS13
18109                 if (!(options & WOLFSSL_OP_NO_TLSv1_3))
18110                     sanityConfirmed = 1;
18111             #endif
18112             break;
18113     #endif
18114     #ifdef WOLFSSL_DTLS
18115         case DTLS_MAJOR:
18116             sanityConfirmed = 1;
18117             break;
18118     #endif
18119         default:
18120             WOLFSSL_MSG("Invalid major version");
18121             return WOLFSSL_FAILURE;
18122     }
18123     if (!sanityConfirmed) {
18124         WOLFSSL_MSG("All compiled in TLS versions disabled");
18125         return WOLFSSL_FAILURE;
18126     }
18127     return WOLFSSL_SUCCESS;
18128 }
18129 
18130 /**
18131  * protoVerTbl holds (D)TLS version numbers in ascending order.
18132  * Except DTLS versions, the newer version is located in the latter part of
18133  * the table. This table is referred by wolfSSL_CTX_set_min_proto_version and
18134  * wolfSSL_CTX_set_max_proto_version.
18135  */
18136 static const int protoVerTbl[] = {
18137     SSL3_VERSION,
18138     TLS1_VERSION,
18139     TLS1_1_VERSION,
18140     TLS1_2_VERSION,
18141     TLS1_3_VERSION,
18142     DTLS1_VERSION,
18143     DTLS1_2_VERSION
18144 };
18145 /* number of protocol versions listed in protoVerTbl */
18146 #define NUMBER_OF_PROTOCOLS sizeof(protoVerTbl)/sizeof(int)
18147 
18148 /**
18149  * wolfSSL_CTX_set_min_proto_version attempts to set the minimum protocol
18150  * version to use by SSL objects created from this WOLFSSL_CTX.
18151  * This API guarantees that a version of SSL/TLS lower than specified
18152  * here will not be allowed. If the version specified is not compiled in
18153  * then this API sets the lowest compiled in protocol version.
18154  * This API also accept 0 as version, to set the minimum version automatically.
18155  * CheckSslMethodVersion() is called to check if any remaining protocol versions
18156  * are enabled.
18157  * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
18158  * @param version Any of the following
18159  *          * 0
18160  *          * SSL3_VERSION
18161  *          * TLS1_VERSION
18162  *          * TLS1_1_VERSION
18163  *          * TLS1_2_VERSION
18164  *          * TLS1_3_VERSION
18165  *          * DTLS1_VERSION
18166  *          * DTLS1_2_VERSION
18167  * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
18168  *         protocol versions are left enabled.
18169  */
Set_CTX_min_proto_version(WOLFSSL_CTX * ctx,int version)18170 static int Set_CTX_min_proto_version(WOLFSSL_CTX* ctx, int version)
18171 {
18172     WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version_ex");
18173 
18174     if (ctx == NULL) {
18175         return WOLFSSL_FAILURE;
18176     }
18177 
18178     switch (version) {
18179 #ifndef NO_TLS
18180         case SSL3_VERSION:
18181 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
18182             ctx->minDowngrade = SSLv3_MINOR;
18183             break;
18184 #endif
18185         case TLS1_VERSION:
18186         #ifdef WOLFSSL_ALLOW_TLSV10
18187             ctx->minDowngrade = TLSv1_MINOR;
18188             break;
18189         #endif
18190         case TLS1_1_VERSION:
18191         #ifndef NO_OLD_TLS
18192             ctx->minDowngrade = TLSv1_1_MINOR;
18193             break;
18194         #endif
18195         case TLS1_2_VERSION:
18196         #ifndef WOLFSSL_NO_TLS12
18197             ctx->minDowngrade = TLSv1_2_MINOR;
18198             break;
18199         #endif
18200         case TLS1_3_VERSION:
18201         #ifdef WOLFSSL_TLS13
18202             ctx->minDowngrade = TLSv1_3_MINOR;
18203             break;
18204         #endif
18205 #endif
18206 #ifdef WOLFSSL_DTLS
18207         case DTLS1_VERSION:
18208     #ifndef NO_OLD_TLS
18209             ctx->minDowngrade = DTLS_MINOR;
18210             break;
18211     #endif
18212         case DTLS1_2_VERSION:
18213             ctx->minDowngrade = DTLSv1_2_MINOR;
18214             break;
18215 #endif
18216         default:
18217             WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
18218             return WOLFSSL_FAILURE;
18219     }
18220 
18221     switch (version) {
18222 #ifndef NO_TLS
18223     case TLS1_3_VERSION:
18224         wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
18225         FALL_THROUGH;
18226     case TLS1_2_VERSION:
18227         wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
18228         FALL_THROUGH;
18229     case TLS1_1_VERSION:
18230         wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
18231         FALL_THROUGH;
18232     case TLS1_VERSION:
18233         wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_SSLv3);
18234         break;
18235     case SSL3_VERSION:
18236     case SSL2_VERSION:
18237         /* Nothing to do here */
18238         break;
18239 #endif
18240 #ifdef WOLFSSL_DTLS
18241     case DTLS1_VERSION:
18242     case DTLS1_2_VERSION:
18243         break;
18244 #endif
18245     default:
18246         WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
18247         return WOLFSSL_FAILURE;
18248     }
18249 
18250     return CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
18251 }
18252 
18253 /* Sets the min protocol version allowed with WOLFSSL_CTX
18254  * returns WOLFSSL_SUCCESS on success */
wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX * ctx,int version)18255 int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
18256 {
18257     int ret;
18258     int proto    = 0;
18259     int maxProto = 0;
18260     int i;
18261     int idx = 0;
18262 
18263     WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version");
18264 
18265     if (ctx == NULL) {
18266         return WOLFSSL_FAILURE;
18267     }
18268     if (version != 0) {
18269         proto = version;
18270         ctx->minProto = 0; /* turn min proto flag off */
18271         for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
18272             if (protoVerTbl[i] == version) {
18273                 break;
18274             }
18275         }
18276     }
18277     else {
18278         /* when 0 is specified as version, try to find out the min version */
18279         for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
18280             ret = Set_CTX_min_proto_version(ctx, protoVerTbl[i]);
18281             if (ret == WOLFSSL_SUCCESS) {
18282                 proto = protoVerTbl[i];
18283                 ctx->minProto = 1; /* turn min proto flag on */
18284                 break;
18285             }
18286         }
18287     }
18288 
18289     /* check case where max > min , if so then clear the NO_* options
18290      * i is the index into the table for proto version used, see if the max
18291      * proto version index found is smaller */
18292     maxProto = wolfSSL_CTX_get_max_proto_version(ctx);
18293     for (idx = 0; (unsigned)idx < NUMBER_OF_PROTOCOLS; idx++) {
18294         if (protoVerTbl[idx] == maxProto) {
18295             break;
18296         }
18297     }
18298     if (idx < i) {
18299         wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_NO_TLSv1 |
18300                 WOLFSSL_OP_NO_TLSv1_1 | WOLFSSL_OP_NO_TLSv1_2 |
18301                 WOLFSSL_OP_NO_TLSv1_3);
18302     }
18303 
18304     ret = Set_CTX_min_proto_version(ctx, proto);
18305     return ret;
18306 }
18307 
18308 /**
18309  * wolfSSL_CTX_set_max_proto_version attempts to set the maximum protocol
18310  * version to use by SSL objects created from this WOLFSSL_CTX.
18311  * This API guarantees that a version of SSL/TLS higher than specified
18312  * here will not be allowed. If the version specified is not compiled in
18313  * then this API sets the highest compiled in protocol version.
18314  * This API also accept 0 as version, to set the maximum version automatically.
18315  * CheckSslMethodVersion() is called to check if any remaining protocol versions
18316  * are enabled.
18317  * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
18318  * @param ver Any of the following
18319  *          * 0
18320  *          * SSL3_VERSION
18321  *          * TLS1_VERSION
18322  *          * TLS1_1_VERSION
18323  *          * TLS1_2_VERSION
18324  *          * TLS1_3_VERSION
18325  *          * DTLS1_VERSION
18326  *          * DTLS1_2_VERSION
18327  * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
18328  *         protocol versions are left enabled.
18329  */
Set_CTX_max_proto_version(WOLFSSL_CTX * ctx,int ver)18330 static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver)
18331 {
18332     WOLFSSL_ENTER("Set_CTX_max_proto_version");
18333 
18334     if (!ctx || !ctx->method) {
18335         WOLFSSL_MSG("Bad parameter");
18336         return WOLFSSL_FAILURE;
18337     }
18338 
18339     switch (ver) {
18340     case SSL2_VERSION:
18341         WOLFSSL_MSG("wolfSSL does not support SSLv2");
18342         return WOLFSSL_FAILURE;
18343 #ifndef NO_TLS
18344     case SSL3_VERSION:
18345         wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
18346         FALL_THROUGH;
18347     case TLS1_VERSION:
18348         wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
18349         FALL_THROUGH;
18350     case TLS1_1_VERSION:
18351         wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
18352         FALL_THROUGH;
18353     case TLS1_2_VERSION:
18354         wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_3);
18355         FALL_THROUGH;
18356     case TLS1_3_VERSION:
18357         /* Nothing to do here */
18358         break;
18359 #endif
18360 #ifdef WOLFSSL_DTLS
18361     case DTLS1_VERSION:
18362     case DTLS1_2_VERSION:
18363         break;
18364 #endif
18365     default:
18366         WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
18367         return WOLFSSL_FAILURE;
18368     }
18369 
18370     return CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
18371 }
18372 
18373 
18374 /* Sets the max protocol version allowed with WOLFSSL_CTX
18375  * returns WOLFSSL_SUCCESS on success */
wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX * ctx,int version)18376 int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version)
18377 {
18378     int i;
18379     int ret = WOLFSSL_FAILURE;
18380     int minProto;
18381 
18382     WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version");
18383 
18384     if (ctx == NULL) {
18385         return ret;
18386     }
18387 
18388     /* clear out flags and reset min protocol version */
18389     minProto = wolfSSL_CTX_get_min_proto_version(ctx);
18390     wolfSSL_CTX_clear_options(ctx,
18391             WOLFSSL_OP_NO_TLSv1 | WOLFSSL_OP_NO_TLSv1_1 |
18392             WOLFSSL_OP_NO_TLSv1_2 | WOLFSSL_OP_NO_TLSv1_3);
18393     wolfSSL_CTX_set_min_proto_version(ctx, minProto);
18394     if (version != 0) {
18395         ctx->maxProto = 0; /* turn max proto flag off */
18396         return Set_CTX_max_proto_version(ctx, version);
18397     }
18398 
18399     /* when 0 is specified as version, try to find out the min version from
18400      * the bottom to top of the protoverTbl.
18401      */
18402     for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
18403         ret = Set_CTX_max_proto_version(ctx, protoVerTbl[i]);
18404         if (ret == WOLFSSL_SUCCESS) {
18405             ctx->maxProto = 1; /* turn max proto flag on */
18406             break;
18407         }
18408     }
18409 
18410     return ret;
18411 }
18412 
18413 
Set_SSL_min_proto_version(WOLFSSL * ssl,int ver)18414 static int Set_SSL_min_proto_version(WOLFSSL* ssl, int ver)
18415 {
18416     WOLFSSL_ENTER("Set_SSL_min_proto_version");
18417 
18418     if (ssl == NULL) {
18419         return WOLFSSL_FAILURE;
18420     }
18421 
18422     switch (ver) {
18423 #ifndef NO_TLS
18424         case SSL3_VERSION:
18425 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
18426             ssl->options.minDowngrade = SSLv3_MINOR;
18427             break;
18428 #endif
18429         case TLS1_VERSION:
18430         #ifdef WOLFSSL_ALLOW_TLSV10
18431             ssl->options.minDowngrade = TLSv1_MINOR;
18432             break;
18433         #endif
18434         case TLS1_1_VERSION:
18435         #ifndef NO_OLD_TLS
18436             ssl->options.minDowngrade = TLSv1_1_MINOR;
18437             break;
18438         #endif
18439         case TLS1_2_VERSION:
18440         #ifndef WOLFSSL_NO_TLS12
18441             ssl->options.minDowngrade = TLSv1_2_MINOR;
18442             break;
18443         #endif
18444         case TLS1_3_VERSION:
18445         #ifdef WOLFSSL_TLS13
18446             ssl->options.minDowngrade = TLSv1_3_MINOR;
18447             break;
18448         #endif
18449 #endif
18450 #ifdef WOLFSSL_DTLS
18451         case DTLS1_VERSION:
18452     #ifndef NO_OLD_TLS
18453             ssl->options.minDowngrade = DTLS_MINOR;
18454             break;
18455     #endif
18456         case DTLS1_2_VERSION:
18457             ssl->options.minDowngrade = DTLSv1_2_MINOR;
18458             break;
18459 #endif
18460         default:
18461             WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
18462             return WOLFSSL_FAILURE;
18463     }
18464 
18465     switch (ver) {
18466 #ifndef NO_TLS
18467     case TLS1_3_VERSION:
18468         ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
18469         FALL_THROUGH;
18470     case TLS1_2_VERSION:
18471         ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
18472         FALL_THROUGH;
18473     case TLS1_1_VERSION:
18474         ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
18475         FALL_THROUGH;
18476     case TLS1_VERSION:
18477         ssl->options.mask |= WOLFSSL_OP_NO_SSLv3;
18478         break;
18479     case SSL3_VERSION:
18480     case SSL2_VERSION:
18481         /* Nothing to do here */
18482         break;
18483 #endif
18484 #ifdef WOLFSSL_DTLS
18485     case DTLS1_VERSION:
18486     case DTLS1_2_VERSION:
18487         break;
18488 #endif
18489     default:
18490         WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
18491         return WOLFSSL_FAILURE;
18492     }
18493 
18494     return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
18495 }
18496 
wolfSSL_set_min_proto_version(WOLFSSL * ssl,int version)18497 int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version)
18498 {
18499     int i;
18500     int ret = WOLFSSL_FAILURE;;
18501 
18502     WOLFSSL_ENTER("wolfSSL_set_min_proto_version");
18503 
18504     if (ssl == NULL) {
18505         return WOLFSSL_FAILURE;
18506     }
18507     if (version != 0) {
18508         return Set_SSL_min_proto_version(ssl, version);
18509     }
18510 
18511     /* when 0 is specified as version, try to find out the min version */
18512     for (i= 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
18513         ret = Set_SSL_min_proto_version(ssl, protoVerTbl[i]);
18514         if (ret == WOLFSSL_SUCCESS)
18515             break;
18516     }
18517 
18518     return ret;
18519 }
18520 
Set_SSL_max_proto_version(WOLFSSL * ssl,int ver)18521 static int Set_SSL_max_proto_version(WOLFSSL* ssl, int ver)
18522 {
18523 
18524     WOLFSSL_ENTER("Set_SSL_max_proto_version");
18525 
18526     if (!ssl) {
18527         WOLFSSL_MSG("Bad parameter");
18528         return WOLFSSL_FAILURE;
18529     }
18530 
18531     switch (ver) {
18532     case SSL2_VERSION:
18533         WOLFSSL_MSG("wolfSSL does not support SSLv2");
18534         return WOLFSSL_FAILURE;
18535 #ifndef NO_TLS
18536     case SSL3_VERSION:
18537         ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
18538         FALL_THROUGH;
18539     case TLS1_VERSION:
18540         ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
18541         FALL_THROUGH;
18542     case TLS1_1_VERSION:
18543         ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
18544         FALL_THROUGH;
18545     case TLS1_2_VERSION:
18546         ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_3;
18547         FALL_THROUGH;
18548     case TLS1_3_VERSION:
18549         /* Nothing to do here */
18550         break;
18551 #endif
18552 #ifdef WOLFSSL_DTLS
18553     case DTLS1_VERSION:
18554     case DTLS1_2_VERSION:
18555         break;
18556 #endif
18557     default:
18558         WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
18559         return WOLFSSL_FAILURE;
18560     }
18561 
18562     return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
18563 }
18564 
wolfSSL_set_max_proto_version(WOLFSSL * ssl,int version)18565 int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version)
18566 {
18567     int i;
18568     int ret = WOLFSSL_FAILURE;;
18569 
18570     WOLFSSL_ENTER("wolfSSL_set_max_proto_version");
18571 
18572     if (ssl == NULL) {
18573         return WOLFSSL_FAILURE;
18574     }
18575     if (version != 0) {
18576         return Set_SSL_max_proto_version(ssl, version);
18577     }
18578 
18579     /* when 0 is specified as version, try to find out the min version from
18580      * the bottom to top of the protoverTbl.
18581      */
18582     for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
18583         ret = Set_SSL_max_proto_version(ssl, protoVerTbl[i]);
18584         if (ret == WOLFSSL_SUCCESS)
18585             break;
18586     }
18587 
18588     return ret;
18589 }
18590 
GetMinProtoVersion(int minDowngrade)18591 static int GetMinProtoVersion(int minDowngrade)
18592 {
18593     int ret;
18594 
18595     switch (minDowngrade) {
18596 #ifndef NO_OLD_TLS
18597     #ifdef WOLFSSL_ALLOW_SSLV3
18598         case SSLv3_MINOR:
18599             ret = SSL3_VERSION;
18600             break;
18601     #endif
18602     #ifdef WOLFSSL_ALLOW_TLSV10
18603         case TLSv1_MINOR:
18604             ret = TLS1_VERSION;
18605             break;
18606     #endif
18607         case TLSv1_1_MINOR:
18608             ret = TLS1_1_VERSION;
18609             break;
18610 #endif
18611 #ifndef WOLFSSL_NO_TLS12
18612         case TLSv1_2_MINOR:
18613             ret = TLS1_2_VERSION;
18614             break;
18615 #endif
18616 #ifdef WOLFSSL_TLS13
18617         case TLSv1_3_MINOR:
18618             ret = TLS1_3_VERSION;
18619             break;
18620 #endif
18621         default:
18622             ret = 0;
18623             break;
18624     }
18625 
18626     return ret;
18627 }
18628 
wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX * ctx)18629 WOLFSSL_API int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX* ctx)
18630 {
18631     int ret = 0;
18632 
18633     WOLFSSL_ENTER("wolfSSL_CTX_get_min_proto_version");
18634 
18635     if (ctx != NULL) {
18636         if (ctx->minProto) {
18637             ret = 0;
18638         }
18639         else {
18640             ret = GetMinProtoVersion(ctx->minDowngrade);
18641         }
18642     }
18643     else {
18644         ret = GetMinProtoVersion(WOLFSSL_MIN_DOWNGRADE);
18645     }
18646 
18647     WOLFSSL_LEAVE("wolfSSL_CTX_get_min_proto_version", ret);
18648 
18649     return ret;
18650 }
18651 
18652 
18653 /* returns the maximum allowed protocol version given the 'options' used
18654  * returns WOLFSSL_FATAL_ERROR on no match */
GetMaxProtoVersion(long options)18655 static int GetMaxProtoVersion(long options)
18656 {
18657 #ifdef WOLFSSL_TLS13
18658     if (!(options & WOLFSSL_OP_NO_TLSv1_3))
18659         return TLS1_3_VERSION;
18660 #endif
18661 #ifndef WOLFSSL_NO_TLS12
18662     if (!(options & WOLFSSL_OP_NO_TLSv1_2))
18663         return TLS1_2_VERSION;
18664 #endif
18665 #ifndef NO_OLD_TLS
18666     if (!(options & WOLFSSL_OP_NO_TLSv1_1))
18667         return TLS1_1_VERSION;
18668     #ifdef WOLFSSL_ALLOW_TLSV10
18669     if (!(options & WOLFSSL_OP_NO_TLSv1))
18670         return TLS1_VERSION;
18671     #endif
18672     #ifdef WOLFSSL_ALLOW_SSLV3
18673     if (!(options & WOLFSSL_OP_NO_SSLv3))
18674         return SSL3_VERSION;
18675     #endif
18676 #endif
18677 
18678     return WOLFSSL_FATAL_ERROR;
18679 }
18680 
18681 
18682 /* returns the maximum protocol version for 'ctx' */
wolfSSL_CTX_get_max_proto_version(WOLFSSL_CTX * ctx)18683 int wolfSSL_CTX_get_max_proto_version(WOLFSSL_CTX* ctx)
18684 {
18685     int ret = 0;
18686     long options = 0; /* default to nothing set */
18687 
18688     WOLFSSL_ENTER("wolfSSL_CTX_get_max_proto_version");
18689 
18690     if (ctx != NULL) {
18691         options = wolfSSL_CTX_get_options(ctx);
18692     }
18693 
18694     if (ctx->maxProto) {
18695         ret = 0;
18696     }
18697     else {
18698         ret = GetMaxProtoVersion(options);
18699     }
18700 
18701     WOLFSSL_LEAVE("wolfSSL_CTX_get_max_proto_version", ret);
18702 
18703     if (ret == WOLFSSL_FATAL_ERROR) {
18704         WOLFSSL_MSG("Error getting max proto version");
18705         ret = 0; /* setting ret to 0 to match compat return */
18706     }
18707     return ret;
18708 }
18709 #endif /* OPENSSL_EXTRA */
18710 
18711 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
18712     defined(HAVE_SECRET_CALLBACK)
18713 #if !defined(NO_WOLFSSL_CLIENT)
18714 /* Return the amount of random bytes copied over or error case.
18715  * ssl : ssl struct after handshake
18716  * out : buffer to hold random bytes
18717  * outSz : either 0 (return max buffer sz) or size of out buffer
18718  */
wolfSSL_get_client_random(const WOLFSSL * ssl,unsigned char * out,size_t outSz)18719 size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
18720                                                                    size_t outSz)
18721 {
18722     size_t size;
18723 
18724     /* return max size of buffer */
18725     if (outSz == 0) {
18726         return RAN_LEN;
18727     }
18728 
18729     if (ssl == NULL || out == NULL) {
18730         return 0;
18731     }
18732 
18733     if (ssl->arrays == NULL) {
18734         WOLFSSL_MSG("Arrays struct not saved after handshake");
18735         return 0;
18736     }
18737 
18738     if (outSz > RAN_LEN) {
18739         size = RAN_LEN;
18740     }
18741     else {
18742         size = outSz;
18743     }
18744 
18745     XMEMCPY(out, ssl->arrays->clientRandom, size);
18746     return size;
18747 }
18748 #endif /* !NO_WOLFSSL_CLIENT */
18749 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
18750 
18751 #ifdef OPENSSL_EXTRA
wolfSSLeay(void)18752     unsigned long wolfSSLeay(void)
18753     {
18754         return SSLEAY_VERSION_NUMBER;
18755     }
18756 
wolfSSL_OpenSSL_version_num(void)18757     unsigned long wolfSSL_OpenSSL_version_num(void)
18758     {
18759         return OPENSSL_VERSION_NUMBER;
18760     }
18761 
wolfSSLeay_version(int type)18762     const char* wolfSSLeay_version(int type)
18763     {
18764         static const char* version = "SSLeay wolfSSL compatibility";
18765         (void)type;
18766         return version;
18767     }
18768 
18769 
18770 #ifndef NO_MD5
wolfSSL_MD5_Init(WOLFSSL_MD5_CTX * md5)18771     int wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
18772     {
18773         int ret;
18774         typedef char md5_test[sizeof(MD5_CTX) >= sizeof(wc_Md5) ? 1 : -1];
18775         (void)sizeof(md5_test);
18776 
18777         WOLFSSL_ENTER("MD5_Init");
18778         ret = wc_InitMd5((wc_Md5*)md5);
18779 
18780         /* return 1 on success, 0 otherwise */
18781         if (ret == 0)
18782             return 1;
18783 
18784         return 0;
18785     }
18786 
18787 
wolfSSL_MD5_Update(WOLFSSL_MD5_CTX * md5,const void * input,unsigned long sz)18788     int wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
18789                            unsigned long sz)
18790     {
18791         int ret;
18792 
18793         WOLFSSL_ENTER("wolfSSL_MD5_Update");
18794         ret = wc_Md5Update((wc_Md5*)md5, (const byte*)input, (word32)sz);
18795 
18796         /* return 1 on success, 0 otherwise */
18797         if (ret == 0)
18798             return 1;
18799 
18800         return 0;
18801     }
18802 
18803 
wolfSSL_MD5_Final(byte * input,WOLFSSL_MD5_CTX * md5)18804     int wolfSSL_MD5_Final(byte* input, WOLFSSL_MD5_CTX* md5)
18805     {
18806         int ret;
18807 
18808         WOLFSSL_ENTER("MD5_Final");
18809         ret = wc_Md5Final((wc_Md5*)md5, input);
18810 
18811         /* have to actually free the resources (if any) here, because the
18812          * OpenSSL API doesn't include SHA*_Free().
18813          */
18814         wc_Md5Free((wc_Md5*)md5);
18815 
18816         /* return 1 on success, 0 otherwise */
18817         if (ret == 0)
18818             return 1;
18819 
18820         return 0;
18821     }
18822     /* Apply MD5 transformation to the data */
wolfSSL_MD5_Transform(WOLFSSL_MD5_CTX * md5,const unsigned char * data)18823     int wolfSSL_MD5_Transform(WOLFSSL_MD5_CTX* md5, const unsigned char* data)
18824     {
18825         int ret;
18826 
18827        WOLFSSL_ENTER("MD5_Transform");
18828 
18829        /* sanity check */
18830        if (md5 == NULL || data == NULL) {
18831             return 0;
18832        }
18833        #if defined(BIG_ENDIAN_ORDER)
18834        {
18835             ByteReverseWords((word32*)data, (word32*)data, WC_MD5_BLOCK_SIZE);
18836        }
18837        #endif
18838 
18839        ret = wc_Md5Transform((wc_Md5*)md5, data);
18840 
18841        /* return 1 on success, 0 otherwise */
18842         if (ret == 0)
18843             return 1;
18844         else
18845             return 0;
18846     }
18847 
wolfSSL_MD5(const unsigned char * data,size_t len,unsigned char * hash)18848     unsigned char *wolfSSL_MD5(const unsigned char* data, size_t len,
18849             unsigned char* hash)
18850     {
18851         static unsigned char out[WC_MD5_DIGEST_SIZE];
18852 
18853         WOLFSSL_ENTER("wolfSSL_MD5");
18854 
18855         if (hash == NULL)
18856             hash = out;
18857         if (wc_Md5Hash(data, (word32)len, hash) != 0) {
18858             WOLFSSL_MSG("wc_Md5Hash error");
18859             return NULL;
18860         }
18861         return hash;
18862     }
18863 #endif /* !NO_MD5 */
18864 
18865 
18866 #ifndef NO_SHA
wolfSSL_SHA_Init(WOLFSSL_SHA_CTX * sha)18867     int wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
18868     {
18869         int ret;
18870 
18871         typedef char sha_test[sizeof(SHA_CTX) >= sizeof(wc_Sha) ? 1 : -1];
18872         (void)sizeof(sha_test);
18873 
18874         WOLFSSL_ENTER("SHA_Init");
18875         ret = wc_InitSha((wc_Sha*)sha);
18876 
18877         /* return 1 on success, 0 otherwise */
18878         if (ret == 0)
18879             return 1;
18880 
18881         return 0;
18882     }
18883 
18884 
wolfSSL_SHA_Update(WOLFSSL_SHA_CTX * sha,const void * input,unsigned long sz)18885     int wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
18886                            unsigned long sz)
18887     {
18888         int ret;
18889 
18890         WOLFSSL_ENTER("SHA_Update");
18891         ret = wc_ShaUpdate((wc_Sha*)sha, (const byte*)input, (word32)sz);
18892 
18893         /* return 1 on success, 0 otherwise */
18894         if (ret == 0)
18895             return 1;
18896 
18897         return 0;
18898     }
18899 
18900 
wolfSSL_SHA_Final(byte * input,WOLFSSL_SHA_CTX * sha)18901     int wolfSSL_SHA_Final(byte* input, WOLFSSL_SHA_CTX* sha)
18902     {
18903         int ret;
18904 
18905         WOLFSSL_ENTER("SHA_Final");
18906         ret = wc_ShaFinal((wc_Sha*)sha, input);
18907 
18908         /* have to actually free the resources (if any) here, because the
18909          * OpenSSL API doesn't include SHA*_Free().
18910          */
18911         wc_ShaFree((wc_Sha*)sha);
18912 
18913         /* return 1 on success, 0 otherwise */
18914         if (ret == 0)
18915             return 1;
18916 
18917         return 0;
18918     }
18919 
18920     #if defined(OPENSSL_EXTRA)
18921     #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
18922         (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
18923     /* Apply SHA1 transformation to the data */
wolfSSL_SHA_Transform(WOLFSSL_SHA_CTX * sha,const unsigned char * data)18924     int wolfSSL_SHA_Transform(WOLFSSL_SHA_CTX* sha,
18925                                          const unsigned char* data)
18926     {
18927        int ret;
18928 
18929        WOLFSSL_ENTER("SHA_Transform");
18930        /* sanity check */
18931        if (sha == NULL || data == NULL) {
18932             return 0;
18933        }
18934        #if defined(LITTLE_ENDIAN_ORDER)
18935        {
18936             ByteReverseWords((word32*)data, (word32*)data, WC_SHA_BLOCK_SIZE);
18937        }
18938        #endif
18939        ret = wc_ShaTransform((wc_Sha*)sha, data);
18940 
18941        /* return 1 on success, 0 otherwise */
18942         if (ret == 0)
18943             return 1;
18944         else
18945             return 0;
18946     }
18947     #endif
18948     #endif
18949 
wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX * sha)18950     int wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
18951     {
18952         WOLFSSL_ENTER("SHA1_Init");
18953         return SHA_Init(sha);
18954     }
18955 
18956 
wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX * sha,const void * input,unsigned long sz)18957     int wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
18958                             unsigned long sz)
18959     {
18960         WOLFSSL_ENTER("SHA1_Update");
18961         return SHA_Update(sha, input, sz);
18962     }
18963 
18964 
wolfSSL_SHA1_Final(byte * input,WOLFSSL_SHA_CTX * sha)18965     int wolfSSL_SHA1_Final(byte* input, WOLFSSL_SHA_CTX* sha)
18966     {
18967         WOLFSSL_ENTER("SHA1_Final");
18968         return SHA_Final(input, sha);
18969     }
18970     #if defined(OPENSSL_EXTRA)
18971     #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
18972         (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
18973     /* Apply SHA1 transformation to the data */
wolfSSL_SHA1_Transform(WOLFSSL_SHA_CTX * sha,const unsigned char * data)18974     int wolfSSL_SHA1_Transform(WOLFSSL_SHA_CTX* sha,
18975                                          const unsigned char* data)
18976     {
18977        WOLFSSL_ENTER("SHA1_Transform");
18978        return (wolfSSL_SHA_Transform(sha, data));
18979     }
18980     #endif
18981     #endif
18982 #endif /* !NO_SHA */
18983 
18984 #ifdef WOLFSSL_SHA224
18985 
wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX * sha)18986     int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha)
18987     {
18988         int ret;
18989 
18990         typedef char sha_test[sizeof(SHA224_CTX) >= sizeof(wc_Sha224) ? 1 : -1];
18991         (void)sizeof(sha_test);
18992 
18993         WOLFSSL_ENTER("SHA224_Init");
18994         ret = wc_InitSha224((wc_Sha224*)sha);
18995 
18996         /* return 1 on success, 0 otherwise */
18997         if (ret == 0)
18998             return 1;
18999 
19000         return 0;
19001     }
19002 
19003 
wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX * sha,const void * input,unsigned long sz)19004     int wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX* sha, const void* input,
19005                            unsigned long sz)
19006     {
19007         int ret;
19008 
19009         WOLFSSL_ENTER("SHA224_Update");
19010         ret = wc_Sha224Update((wc_Sha224*)sha, (const byte*)input, (word32)sz);
19011 
19012         /* return 1 on success, 0 otherwise */
19013         if (ret == 0)
19014             return 1;
19015 
19016         return 0;
19017     }
19018 
19019 
wolfSSL_SHA224_Final(byte * input,WOLFSSL_SHA224_CTX * sha)19020     int wolfSSL_SHA224_Final(byte* input, WOLFSSL_SHA224_CTX* sha)
19021     {
19022         int ret;
19023 
19024         WOLFSSL_ENTER("SHA224_Final");
19025         ret = wc_Sha224Final((wc_Sha224*)sha, input);
19026 
19027         /* have to actually free the resources (if any) here, because the
19028          * OpenSSL API doesn't include SHA*_Free().
19029          */
19030         wc_Sha224Free((wc_Sha224*)sha);
19031 
19032         /* return 1 on success, 0 otherwise */
19033         if (ret == 0)
19034             return 1;
19035 
19036         return 0;
19037     }
19038 
19039 #endif /* WOLFSSL_SHA224 */
19040 
19041 
wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX * sha256)19042     int wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
19043     {
19044         int ret;
19045 
19046         typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(wc_Sha256) ? 1 : -1];
19047         (void)sizeof(sha_test);
19048 
19049         WOLFSSL_ENTER("SHA256_Init");
19050         ret = wc_InitSha256((wc_Sha256*)sha256);
19051 
19052         /* return 1 on success, 0 otherwise */
19053         if (ret == 0)
19054             return 1;
19055 
19056         return 0;
19057     }
19058 
19059 
wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX * sha,const void * input,unsigned long sz)19060     int wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input,
19061                               unsigned long sz)
19062     {
19063         int ret;
19064 
19065         WOLFSSL_ENTER("SHA256_Update");
19066         ret = wc_Sha256Update((wc_Sha256*)sha, (const byte*)input, (word32)sz);
19067 
19068         /* return 1 on success, 0 otherwise */
19069         if (ret == 0)
19070             return 1;
19071 
19072         return 0;
19073     }
19074 
19075 
wolfSSL_SHA256_Final(byte * input,WOLFSSL_SHA256_CTX * sha)19076     int wolfSSL_SHA256_Final(byte* input, WOLFSSL_SHA256_CTX* sha)
19077     {
19078         int ret;
19079 
19080         WOLFSSL_ENTER("SHA256_Final");
19081         ret = wc_Sha256Final((wc_Sha256*)sha, input);
19082 
19083         /* have to actually free the resources (if any) here, because the
19084          * OpenSSL API doesn't include SHA*_Free().
19085          */
19086         wc_Sha256Free((wc_Sha256*)sha);
19087 
19088         /* return 1 on success, 0 otherwise */
19089         if (ret == 0)
19090             return 1;
19091 
19092         return 0;
19093     }
19094 
19095     #if defined(OPENSSL_EXTRA)
19096     #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
19097         (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \
19098         !defined(WOLFSSL_DEVCRYPTO_HASH) && !defined(WOLFSSL_AFALG_HASH)
19099     /* Apply SHA256 transformation to the data */
wolfSSL_SHA256_Transform(WOLFSSL_SHA256_CTX * sha256,const unsigned char * data)19100     int wolfSSL_SHA256_Transform(WOLFSSL_SHA256_CTX* sha256,
19101                                                 const unsigned char* data)
19102     {
19103        int ret;
19104 
19105        WOLFSSL_ENTER("SHA256_Transform");
19106        /* sanity check */
19107        if (sha256 == NULL || data == NULL) {
19108             return 0;
19109        }
19110        #if defined(LITTLE_ENDIAN_ORDER)
19111        {
19112             ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE);
19113        }
19114        #endif
19115        ret = wc_Sha256Transform((wc_Sha256*)sha256, data);
19116 
19117        /* return 1 on success, 0 otherwise */
19118         if (ret == 0)
19119             return 1;
19120         else
19121             return 0;
19122     }
19123     #endif
19124     #endif
19125 
19126 #ifdef WOLFSSL_SHA384
19127 
wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX * sha)19128     int wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha)
19129     {
19130         int ret;
19131 
19132         typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(wc_Sha384) ? 1 : -1];
19133         (void)sizeof(sha_test);
19134 
19135         WOLFSSL_ENTER("SHA384_Init");
19136         ret = wc_InitSha384((wc_Sha384*)sha);
19137 
19138         /* return 1 on success, 0 otherwise */
19139         if (ret == 0)
19140             return 1;
19141 
19142         return 0;
19143     }
19144 
19145 
wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX * sha,const void * input,unsigned long sz)19146     int wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input,
19147                            unsigned long sz)
19148     {
19149         int ret;
19150 
19151         WOLFSSL_ENTER("SHA384_Update");
19152         ret = wc_Sha384Update((wc_Sha384*)sha, (const byte*)input, (word32)sz);
19153 
19154         /* return 1 on success, 0 otherwise */
19155         if (ret == 0)
19156             return 1;
19157 
19158         return 0;
19159     }
19160 
19161 
wolfSSL_SHA384_Final(byte * input,WOLFSSL_SHA384_CTX * sha)19162     int wolfSSL_SHA384_Final(byte* input, WOLFSSL_SHA384_CTX* sha)
19163     {
19164         int ret;
19165 
19166         WOLFSSL_ENTER("SHA384_Final");
19167         ret = wc_Sha384Final((wc_Sha384*)sha, input);
19168 
19169         /* have to actually free the resources (if any) here, because the
19170          * OpenSSL API doesn't include SHA*_Free().
19171          */
19172         wc_Sha384Free((wc_Sha384*)sha);
19173 
19174         /* return 1 on success, 0 otherwise */
19175         if (ret == 0)
19176             return 1;
19177 
19178         return 0;
19179     }
19180 
19181 #endif /* WOLFSSL_SHA384 */
19182 
19183 
19184 #ifdef WOLFSSL_SHA512
19185 
wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX * sha)19186     int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha)
19187     {
19188         int ret;
19189 
19190         typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(wc_Sha512) ? 1 : -1];
19191         (void)sizeof(sha_test);
19192 
19193         WOLFSSL_ENTER("SHA512_Init");
19194         ret = wc_InitSha512((wc_Sha512*)sha);
19195 
19196         /* return 1 on success, 0 otherwise */
19197         if (ret == 0)
19198             return 1;
19199 
19200         return 0;
19201     }
19202 
19203 
wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX * sha,const void * input,unsigned long sz)19204     int wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input,
19205                            unsigned long sz)
19206     {
19207         int ret;
19208 
19209         WOLFSSL_ENTER("SHA512_Update");
19210         ret = wc_Sha512Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
19211 
19212         /* return 1 on success, 0 otherwise */
19213         if (ret == 0)
19214             return 1;
19215 
19216         return 0;
19217     }
19218 
19219 
wolfSSL_SHA512_Final(byte * input,WOLFSSL_SHA512_CTX * sha)19220     int wolfSSL_SHA512_Final(byte* input, WOLFSSL_SHA512_CTX* sha)
19221     {
19222         int ret;
19223 
19224         WOLFSSL_ENTER("SHA512_Final");
19225         ret = wc_Sha512Final((wc_Sha512*)sha, input);
19226 
19227         /* have to actually free the resources (if any) here, because the
19228          * OpenSSL API doesn't include SHA*_Free().
19229          */
19230         wc_Sha512Free((wc_Sha512*)sha);
19231 
19232         /* return 1 on success, 0 otherwise */
19233         if (ret == 0)
19234             return 1;
19235 
19236         return 0;
19237     }
19238 
19239     #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
19240         (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
19241     /* Apply SHA512 transformation to the data */
wolfSSL_SHA512_Transform(WOLFSSL_SHA512_CTX * sha512,const unsigned char * data)19242     int wolfSSL_SHA512_Transform(WOLFSSL_SHA512_CTX* sha512,
19243                                           const unsigned char* data)
19244     {
19245        int ret;
19246 
19247        WOLFSSL_ENTER("SHA512_Transform");
19248        /* sanity check */
19249        if (sha512 == NULL || data == NULL) {
19250             return WOLFSSL_FAILURE;
19251        }
19252 
19253        ret = wc_Sha512Transform((wc_Sha512*)sha512, data);
19254 
19255        /* return 1 on success, 0 otherwise */
19256         if (ret == 0)
19257             return WOLFSSL_SUCCESS;
19258         else
19259             return WOLFSSL_FAILURE;
19260     }
19261     #endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
19262               (HAVE_FIPS_VERSION > 2)) */
19263 
19264 #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
19265 #if !defined(WOLFSSL_NOSHA512_224)
wolfSSL_SHA512_224_Init(WOLFSSL_SHA512_224_CTX * sha)19266     int wolfSSL_SHA512_224_Init(WOLFSSL_SHA512_224_CTX* sha)
19267     {
19268         int ret;
19269 
19270         WOLFSSL_ENTER("wolfSSL_SHA512_224_Init");
19271         ret = wc_InitSha512_224((wc_Sha512*)sha);
19272 
19273         /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
19274         if (ret == 0)
19275             return WOLFSSL_SUCCESS;
19276 
19277         return WOLFSSL_FAILURE;
19278     }
19279 
wolfSSL_SHA512_224_Update(WOLFSSL_SHA512_224_CTX * sha,const void * input,unsigned long sz)19280     int wolfSSL_SHA512_224_Update(WOLFSSL_SHA512_224_CTX* sha,
19281                                         const void* input, unsigned long sz)
19282     {
19283         int ret;
19284 
19285         WOLFSSL_ENTER("wolfSSL_SHA512_224_Update");
19286         ret = wc_Sha512_224Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
19287 
19288         /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
19289         if (ret == 0)
19290             return WOLFSSL_SUCCESS;
19291 
19292         return WOLFSSL_FAILURE;
19293     }
19294 
wolfSSL_SHA512_224_Final(byte * input,WOLFSSL_SHA512_224_CTX * sha)19295     int wolfSSL_SHA512_224_Final(byte* input, WOLFSSL_SHA512_224_CTX* sha)
19296     {
19297         int ret;
19298 
19299         WOLFSSL_ENTER("wolfSSL_SHA512_224_Final");
19300         ret = wc_Sha512_224Final((wc_Sha512*)sha, input);
19301 
19302         /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
19303         if (ret == 0)
19304             return WOLFSSL_SUCCESS;
19305 
19306         return WOLFSSL_FAILURE;
19307     }
19308 #endif /* !WOLFSSL_NOSHA512_224 */
19309 #if !defined(WOLFSSL_NOSHA512_256)
wolfSSL_SHA512_256_Init(WOLFSSL_SHA512_256_CTX * sha)19310     int wolfSSL_SHA512_256_Init(WOLFSSL_SHA512_256_CTX* sha)
19311     {
19312         int ret;
19313 
19314         WOLFSSL_ENTER("wolfSSL_SHA512_256_Init");
19315         ret = wc_InitSha512_256((wc_Sha512*)sha);
19316 
19317         /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
19318         if (ret == 0)
19319             return WOLFSSL_SUCCESS;
19320 
19321         return WOLFSSL_FAILURE;
19322     }
19323 
wolfSSL_SHA512_256_Update(WOLFSSL_SHA512_256_CTX * sha,const void * input,unsigned long sz)19324     int wolfSSL_SHA512_256_Update(WOLFSSL_SHA512_256_CTX* sha,
19325                                         const void* input, unsigned long sz)
19326     {
19327         int ret;
19328 
19329         WOLFSSL_ENTER("wolfSSL_SHA512_256_Update");
19330         ret = wc_Sha512_256Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
19331 
19332         /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
19333         if (ret == 0)
19334             return WOLFSSL_SUCCESS;
19335 
19336         return WOLFSSL_FAILURE;
19337     }
19338 
wolfSSL_SHA512_256_Final(byte * input,WOLFSSL_SHA512_256_CTX * sha)19339     int wolfSSL_SHA512_256_Final(byte* input, WOLFSSL_SHA512_256_CTX* sha)
19340     {
19341         int ret;
19342 
19343         WOLFSSL_ENTER("wolfSSL_SHA512_256_Final");
19344         ret = wc_Sha512_256Final((wc_Sha512*)sha, input);
19345 
19346         /* return WOLFSSL_SUCCESS on success, 0 otherwise */
19347         if (ret == 0)
19348             return WOLFSSL_SUCCESS;
19349 
19350         return WOLFSSL_FAILURE;
19351     }
19352 #endif /* !WOLFSSL_NOSHA512_256 */
19353 #endif /* !HAVE_FIPS && !HAVE_SELFTEST */
19354 
19355 #endif /* WOLFSSL_SHA512 */
19356 
19357 #ifdef WOLFSSL_SHA3
19358 #ifndef WOLFSSL_NOSHA3_224
19359 
wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX * sha)19360     int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX* sha)
19361     {
19362         int ret;
19363 
19364         typedef char sha_test[sizeof(SHA3_224_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
19365         (void)sizeof(sha_test);
19366 
19367         WOLFSSL_ENTER("SHA3_224_Init");
19368         ret = wc_InitSha3_224((wc_Sha3*)sha, NULL, INVALID_DEVID);
19369 
19370         /* return 1 on success, 0 otherwise */
19371         if (ret == 0)
19372             return 1;
19373 
19374         return 0;
19375     }
19376 
19377 
wolfSSL_SHA3_224_Update(WOLFSSL_SHA3_224_CTX * sha,const void * input,unsigned long sz)19378     int wolfSSL_SHA3_224_Update(WOLFSSL_SHA3_224_CTX* sha, const void* input,
19379                            unsigned long sz)
19380     {
19381         int ret;
19382 
19383         WOLFSSL_ENTER("SHA3_224_Update");
19384         ret = wc_Sha3_224_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
19385 
19386         /* return 1 on success, 0 otherwise */
19387         if (ret == 0)
19388             return 1;
19389 
19390         return 0;
19391     }
19392 
19393 
wolfSSL_SHA3_224_Final(byte * input,WOLFSSL_SHA3_224_CTX * sha)19394     int wolfSSL_SHA3_224_Final(byte* input, WOLFSSL_SHA3_224_CTX* sha)
19395     {
19396         int ret;
19397 
19398         WOLFSSL_ENTER("SHA3_224_Final");
19399         ret = wc_Sha3_224_Final((wc_Sha3*)sha, input);
19400 
19401         /* have to actually free the resources (if any) here, because the
19402          * OpenSSL API doesn't include SHA*_Free().
19403          */
19404         wc_Sha3_224_Free((wc_Sha3*)sha);
19405 
19406         /* return 1 on success, 0 otherwise */
19407         if (ret == 0)
19408             return 1;
19409 
19410         return 0;
19411     }
19412 
19413 #endif /* WOLFSSL_NOSHA3_224 */
19414 
19415 
19416 #ifndef WOLFSSL_NOSHA3_256
wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX * sha3_256)19417     int wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX* sha3_256)
19418     {
19419         int ret;
19420 
19421         typedef char sha_test[sizeof(SHA3_256_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
19422         (void)sizeof(sha_test);
19423 
19424         WOLFSSL_ENTER("SHA3_256_Init");
19425         ret = wc_InitSha3_256((wc_Sha3*)sha3_256, NULL, INVALID_DEVID);
19426 
19427         /* return 1 on success, 0 otherwise */
19428         if (ret == 0)
19429             return 1;
19430 
19431         return 0;
19432     }
19433 
19434 
wolfSSL_SHA3_256_Update(WOLFSSL_SHA3_256_CTX * sha,const void * input,unsigned long sz)19435     int wolfSSL_SHA3_256_Update(WOLFSSL_SHA3_256_CTX* sha, const void* input,
19436                               unsigned long sz)
19437     {
19438         int ret;
19439 
19440         WOLFSSL_ENTER("SHA3_256_Update");
19441         ret = wc_Sha3_256_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
19442 
19443         /* return 1 on success, 0 otherwise */
19444         if (ret == 0)
19445             return 1;
19446 
19447         return 0;
19448     }
19449 
19450 
wolfSSL_SHA3_256_Final(byte * input,WOLFSSL_SHA3_256_CTX * sha)19451     int wolfSSL_SHA3_256_Final(byte* input, WOLFSSL_SHA3_256_CTX* sha)
19452     {
19453         int ret;
19454 
19455         WOLFSSL_ENTER("SHA3_256_Final");
19456         ret = wc_Sha3_256_Final((wc_Sha3*)sha, input);
19457 
19458         /* have to actually free the resources (if any) here, because the
19459          * OpenSSL API doesn't include SHA*_Free().
19460          */
19461         wc_Sha3_256_Free((wc_Sha3*)sha);
19462 
19463         /* return 1 on success, 0 otherwise */
19464         if (ret == 0)
19465             return 1;
19466 
19467         return 0;
19468     }
19469 #endif /* WOLFSSL_NOSHA3_256 */
19470 
19471 
wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX * sha)19472     int wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX* sha)
19473     {
19474         int ret;
19475 
19476         typedef char sha_test[sizeof(SHA3_384_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
19477         (void)sizeof(sha_test);
19478 
19479         WOLFSSL_ENTER("SHA3_384_Init");
19480         ret = wc_InitSha3_384((wc_Sha3*)sha, NULL, INVALID_DEVID);
19481 
19482         /* return 1 on success, 0 otherwise */
19483         if (ret == 0)
19484             return 1;
19485 
19486         return 0;
19487     }
19488 
19489 
wolfSSL_SHA3_384_Update(WOLFSSL_SHA3_384_CTX * sha,const void * input,unsigned long sz)19490     int wolfSSL_SHA3_384_Update(WOLFSSL_SHA3_384_CTX* sha, const void* input,
19491                            unsigned long sz)
19492     {
19493         int ret;
19494 
19495         WOLFSSL_ENTER("SHA3_384_Update");
19496         ret = wc_Sha3_384_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
19497 
19498         /* return 1 on success, 0 otherwise */
19499         if (ret == 0)
19500             return 1;
19501 
19502         return 0;
19503     }
19504 
19505 
wolfSSL_SHA3_384_Final(byte * input,WOLFSSL_SHA3_384_CTX * sha)19506     int wolfSSL_SHA3_384_Final(byte* input, WOLFSSL_SHA3_384_CTX* sha)
19507     {
19508         int ret;
19509 
19510         WOLFSSL_ENTER("SHA3_384_Final");
19511         ret = wc_Sha3_384_Final((wc_Sha3*)sha, input);
19512 
19513         /* have to actually free the resources (if any) here, because the
19514          * OpenSSL API doesn't include SHA*_Free().
19515          */
19516         wc_Sha3_384_Free((wc_Sha3*)sha);
19517 
19518         /* return 1 on success, 0 otherwise */
19519         if (ret == 0)
19520             return 1;
19521 
19522         return 0;
19523     }
19524 
19525 
19526 
19527 #ifndef WOLFSSL_NOSHA3_512
19528 
wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX * sha)19529     int wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX* sha)
19530     {
19531         int ret;
19532 
19533         typedef char sha_test[sizeof(SHA3_512_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
19534         (void)sizeof(sha_test);
19535 
19536         WOLFSSL_ENTER("SHA3_512_Init");
19537         ret = wc_InitSha3_512((wc_Sha3*)sha, NULL, INVALID_DEVID);
19538 
19539         /* return 1 on success, 0 otherwise */
19540         if (ret == 0)
19541             return 1;
19542 
19543         return 0;
19544     }
19545 
19546 
wolfSSL_SHA3_512_Update(WOLFSSL_SHA3_512_CTX * sha,const void * input,unsigned long sz)19547     int wolfSSL_SHA3_512_Update(WOLFSSL_SHA3_512_CTX* sha, const void* input,
19548                            unsigned long sz)
19549     {
19550         int ret;
19551 
19552         WOLFSSL_ENTER("SHA3_512_Update");
19553         ret = wc_Sha3_512_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
19554 
19555         /* return 1 on success, 0 otherwise */
19556         if (ret == 0)
19557             return 1;
19558 
19559         return 0;
19560     }
19561 
19562 
wolfSSL_SHA3_512_Final(byte * input,WOLFSSL_SHA3_512_CTX * sha)19563     int wolfSSL_SHA3_512_Final(byte* input, WOLFSSL_SHA3_512_CTX* sha)
19564     {
19565         int ret;
19566 
19567         WOLFSSL_ENTER("SHA3_512_Final");
19568         ret = wc_Sha3_512_Final((wc_Sha3*)sha, input);
19569 
19570         /* have to actually free the resources (if any) here, because the
19571          * OpenSSL API doesn't include SHA*_Free().
19572          */
19573         wc_Sha3_512_Free((wc_Sha3*)sha);
19574 
19575         /* return 1 on success, 0 otherwise */
19576         if (ret == 0)
19577             return 1;
19578 
19579         return 0;
19580     }
19581 
19582 #endif /* WOLFSSL_NOSHA3_512 */
19583 #endif /* WOLFSSL_SHA3 */
19584 
wolfSSL_HMAC(const WOLFSSL_EVP_MD * evp_md,const void * key,int key_len,const unsigned char * d,int n,unsigned char * md,unsigned int * md_len)19585     unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
19586                                 int key_len, const unsigned char* d, int n,
19587                                 unsigned char* md, unsigned int* md_len)
19588     {
19589         int type;
19590         int mdlen;
19591         unsigned char* ret = NULL;
19592 #ifdef WOLFSSL_SMALL_STACK
19593         Hmac* hmac = NULL;
19594 #else
19595         Hmac  hmac[1];
19596 #endif
19597         void* heap = NULL;
19598 
19599         WOLFSSL_ENTER("wolfSSL_HMAC");
19600         if (!md) {
19601             WOLFSSL_MSG("Static buffer not supported, pass in md buffer");
19602             return NULL;  /* no static buffer support */
19603         }
19604 
19605 #ifndef NO_MD5
19606         if (XSTRNCMP(evp_md, "MD5", 3) == 0) {
19607             type = WC_MD5;
19608             mdlen = WC_MD5_DIGEST_SIZE;
19609         } else
19610 #endif
19611 #ifdef WOLFSSL_SHA224
19612         if (XSTRNCMP(evp_md, "SHA224", 6) == 0) {
19613             type = WC_SHA224;
19614             mdlen = WC_SHA224_DIGEST_SIZE;
19615         } else
19616 #endif
19617 #ifndef NO_SHA256
19618         if (XSTRNCMP(evp_md, "SHA256", 6) == 0) {
19619             type = WC_SHA256;
19620             mdlen = WC_SHA256_DIGEST_SIZE;
19621         } else
19622 #endif
19623 #ifdef WOLFSSL_SHA384
19624         if (XSTRNCMP(evp_md, "SHA384", 6) == 0) {
19625             type = WC_SHA384;
19626             mdlen = WC_SHA384_DIGEST_SIZE;
19627         } else
19628 #endif
19629 #ifdef WOLFSSL_SHA512
19630         if (XSTRNCMP(evp_md, "SHA512", 6) == 0) {
19631             type = WC_SHA512;
19632             mdlen = WC_SHA512_DIGEST_SIZE;
19633         } else
19634 #endif
19635 #ifdef WOLFSSL_SHA3
19636     #ifndef WOLFSSL_NOSHA3_224
19637         if (XSTRNCMP(evp_md, "SHA3_224", 8) == 0) {
19638             type = WC_SHA3_224;
19639             mdlen = WC_SHA3_224_DIGEST_SIZE;
19640         } else
19641     #endif
19642     #ifndef WOLFSSL_NOSHA3_256
19643         if (XSTRNCMP(evp_md, "SHA3_256", 8) == 0) {
19644             type = WC_SHA3_256;
19645             mdlen = WC_SHA3_256_DIGEST_SIZE;
19646         } else
19647     #endif
19648         if (XSTRNCMP(evp_md, "SHA3_384", 8) == 0) {
19649             type = WC_SHA3_384;
19650             mdlen = WC_SHA3_384_DIGEST_SIZE;
19651         } else
19652     #ifndef WOLFSSL_NOSHA3_512
19653         if (XSTRNCMP(evp_md, "SHA3_512", 8) == 0) {
19654             type = WC_SHA3_512;
19655             mdlen = WC_SHA3_512_DIGEST_SIZE;
19656         } else
19657     #endif
19658 #endif
19659 #ifndef NO_SHA
19660         if (XSTRNCMP(evp_md, "SHA", 3) == 0) {
19661             type = WC_SHA;
19662             mdlen = WC_SHA_DIGEST_SIZE;
19663         } else
19664 #endif
19665         {
19666             return NULL;
19667         }
19668 
19669     #ifdef WOLFSSL_SMALL_STACK
19670         hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
19671         if (hmac == NULL)
19672             return NULL;
19673     #endif
19674 
19675         if (wc_HmacInit(hmac, heap, INVALID_DEVID) == 0) {
19676             if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0) {
19677                 if (wc_HmacUpdate(hmac, d, n) == 0) {
19678                     if (wc_HmacFinal(hmac, md) == 0) {
19679                         if (md_len)
19680                             *md_len = mdlen;
19681                         ret = md;
19682                     }
19683                 }
19684             }
19685             wc_HmacFree(hmac);
19686         }
19687 
19688     #ifdef WOLFSSL_SMALL_STACK
19689         XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
19690     #endif
19691 
19692         (void)evp_md;
19693         return ret;
19694     }
19695 
wolfSSL_ERR_clear_error(void)19696     void wolfSSL_ERR_clear_error(void)
19697     {
19698         WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
19699 #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
19700         wc_ClearErrorNodes();
19701 #endif
19702     }
19703 
19704 #ifndef NO_DES3
19705     /* 0 on ok */
wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock * key,WOLFSSL_DES_key_schedule * schedule)19706     int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
19707                               WOLFSSL_DES_key_schedule* schedule)
19708     {
19709         WOLFSSL_ENTER("wolfSSL_DES_key_sched");
19710 
19711         if (key == NULL || schedule == NULL) {
19712             WOLFSSL_MSG("Null argument passed in");
19713         }
19714         else {
19715             XMEMCPY(schedule, key, sizeof(WOLFSSL_const_DES_cblock));
19716         }
19717 
19718         return 0;
19719     }
19720 
19721 
19722     /* intended to behave similar to Kerberos mit_des_cbc_cksum
19723      * return the last 4 bytes of cipher text */
wolfSSL_DES_cbc_cksum(const unsigned char * in,WOLFSSL_DES_cblock * out,long length,WOLFSSL_DES_key_schedule * sc,WOLFSSL_const_DES_cblock * iv)19724     WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in,
19725             WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc,
19726             WOLFSSL_const_DES_cblock* iv)
19727     {
19728         WOLFSSL_DES_LONG ret;
19729         unsigned char* tmp;
19730         unsigned char* data   = (unsigned char*)in;
19731         long           dataSz = length;
19732         byte dynamicFlag = 0; /* when padding the buffer created needs free'd */
19733 
19734         WOLFSSL_ENTER("wolfSSL_DES_cbc_cksum");
19735 
19736         if (in == NULL || out == NULL || sc == NULL || iv == NULL) {
19737             WOLFSSL_MSG("Bad argument passed in");
19738             return 0;
19739         }
19740 
19741         /* if input length is not a multiple of DES_BLOCK_SIZE pad with 0s */
19742         if (dataSz % DES_BLOCK_SIZE) {
19743             dataSz += DES_BLOCK_SIZE - (dataSz % DES_BLOCK_SIZE);
19744             data = (unsigned char*)XMALLOC(dataSz, NULL,
19745                                            DYNAMIC_TYPE_TMP_BUFFER);
19746             if (data == NULL) {
19747                 WOLFSSL_MSG("Issue creating temporary buffer");
19748                 return 0;
19749             }
19750             dynamicFlag = 1; /* set to free buffer at end */
19751             XMEMCPY(data, in, length);
19752             XMEMSET(data + length, 0, dataSz - length); /* padding */
19753         }
19754 
19755         tmp = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19756         if (tmp == NULL) {
19757             WOLFSSL_MSG("Issue creating temporary buffer");
19758             if (dynamicFlag == 1) {
19759                 XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19760             }
19761             return 0;
19762         }
19763 
19764         wolfSSL_DES_cbc_encrypt(data, tmp, dataSz, sc,
19765                 (WOLFSSL_DES_cblock*)iv, 1);
19766         XMEMCPY((unsigned char*)out, tmp + (dataSz - DES_BLOCK_SIZE),
19767                 DES_BLOCK_SIZE);
19768 
19769         ret = (((*((unsigned char*)out + 4) & 0xFF) << 24)|
19770                ((*((unsigned char*)out + 5) & 0xFF) << 16)|
19771                ((*((unsigned char*)out + 6) & 0xFF) << 8) |
19772                (*((unsigned char*)out + 7) & 0xFF));
19773 
19774         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19775         if (dynamicFlag == 1) {
19776             XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19777         }
19778 
19779         return ret;
19780     }
19781 
19782 
wolfSSL_DES_cbc_encrypt(const unsigned char * input,unsigned char * output,long length,WOLFSSL_DES_key_schedule * schedule,WOLFSSL_DES_cblock * ivec,int enc)19783     void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
19784                                  unsigned char* output, long length,
19785                                  WOLFSSL_DES_key_schedule* schedule,
19786                                  WOLFSSL_DES_cblock* ivec, int enc)
19787     {
19788         Des myDes;
19789         byte lastblock[DES_BLOCK_SIZE];
19790         int  lb_sz;
19791         long  blk;
19792 
19793         WOLFSSL_ENTER("DES_cbc_encrypt");
19794 
19795         /* OpenSSL compat, no ret */
19796         if (wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec,
19797                 !enc) != 0) {
19798             WOLFSSL_MSG("wc_Des_SetKey return error.");
19799             return;
19800         }
19801         lb_sz = length%DES_BLOCK_SIZE;
19802         blk   = length/DES_BLOCK_SIZE;
19803 
19804         if (enc){
19805             wc_Des_CbcEncrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
19806             if(lb_sz){
19807                 XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
19808                 XMEMCPY(lastblock, input+length-lb_sz, lb_sz);
19809                 wc_Des_CbcEncrypt(&myDes, output+blk*DES_BLOCK_SIZE,
19810                     lastblock, (word32)DES_BLOCK_SIZE);
19811             }
19812         }
19813         else {
19814             wc_Des_CbcDecrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
19815             if(lb_sz){
19816                 wc_Des_CbcDecrypt(&myDes, lastblock, input+length-lb_sz, (word32)DES_BLOCK_SIZE);
19817                 XMEMCPY(output+length-lb_sz, lastblock, lb_sz);
19818             }
19819         }
19820     }
19821 
19822 
19823     /* WOLFSSL_DES_key_schedule is a unsigned char array of size 8 */
wolfSSL_DES_ede3_cbc_encrypt(const unsigned char * input,unsigned char * output,long sz,WOLFSSL_DES_key_schedule * ks1,WOLFSSL_DES_key_schedule * ks2,WOLFSSL_DES_key_schedule * ks3,WOLFSSL_DES_cblock * ivec,int enc)19824     void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input,
19825                                       unsigned char* output, long sz,
19826                                       WOLFSSL_DES_key_schedule* ks1,
19827                                       WOLFSSL_DES_key_schedule* ks2,
19828                                       WOLFSSL_DES_key_schedule* ks3,
19829                                       WOLFSSL_DES_cblock* ivec, int enc)
19830     {
19831         int ret;
19832         Des3 des;
19833         byte key[24];/* EDE uses 24 size key */
19834         byte lastblock[DES_BLOCK_SIZE];
19835         int  lb_sz;
19836         long  blk;
19837 
19838         WOLFSSL_ENTER("wolfSSL_DES_ede3_cbc_encrypt");
19839 
19840         XMEMSET(key, 0, sizeof(key));
19841         XMEMCPY(key, *ks1, DES_BLOCK_SIZE);
19842         XMEMCPY(&key[DES_BLOCK_SIZE], *ks2, DES_BLOCK_SIZE);
19843         XMEMCPY(&key[DES_BLOCK_SIZE * 2], *ks3, DES_BLOCK_SIZE);
19844         lb_sz = sz%DES_BLOCK_SIZE;
19845         blk   = sz/DES_BLOCK_SIZE;
19846 
19847         /* OpenSSL compat, no ret */
19848         (void)wc_Des3Init(&des, NULL, INVALID_DEVID);
19849 
19850         if (enc) {
19851             if (wc_Des3_SetKey(&des, key, (const byte*)ivec,
19852                     DES_ENCRYPTION) == 0) {
19853                 ret = wc_Des3_CbcEncrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE);
19854             #if defined(WOLFSSL_ASYNC_CRYPT)
19855                 ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
19856             #endif
19857                 (void)ret; /* ignore return codes for processing */
19858                 if(lb_sz){
19859                     XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
19860                     XMEMCPY(lastblock, input+sz-lb_sz, lb_sz);
19861                     ret = wc_Des3_CbcEncrypt(&des, output+blk*DES_BLOCK_SIZE,
19862                         lastblock, (word32)DES_BLOCK_SIZE);
19863                 #if defined(WOLFSSL_ASYNC_CRYPT)
19864                     ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
19865                 #endif
19866                     (void)ret; /* ignore return codes for processing */
19867                 }
19868             }
19869         }
19870         else {
19871             if (wc_Des3_SetKey(&des, key, (const byte*)ivec,
19872                     DES_DECRYPTION) == 0) {
19873                 ret = wc_Des3_CbcDecrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE);
19874             #if defined(WOLFSSL_ASYNC_CRYPT)
19875                 ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
19876             #endif
19877                 (void)ret; /* ignore return codes for processing */
19878                 if(lb_sz){
19879                     ret = wc_Des3_CbcDecrypt(&des, lastblock, input+sz-lb_sz, (word32)DES_BLOCK_SIZE);
19880                 #if defined(WOLFSSL_ASYNC_CRYPT)
19881                     ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
19882                 #endif
19883                     (void)ret; /* ignore return codes for processing */
19884                     XMEMCPY(output+sz-lb_sz, lastblock, lb_sz);
19885                 }
19886             }
19887         }
19888         wc_Des3Free(&des);
19889     }
19890 
19891 
19892     /* correctly sets ivec for next call */
wolfSSL_DES_ncbc_encrypt(const unsigned char * input,unsigned char * output,long length,WOLFSSL_DES_key_schedule * schedule,WOLFSSL_DES_cblock * ivec,int enc)19893     void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
19894                      unsigned char* output, long length,
19895                      WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
19896                      int enc)
19897     {
19898         Des myDes;
19899         byte lastblock[DES_BLOCK_SIZE];
19900         int  lb_sz;
19901         long idx = length;
19902         long blk;
19903 
19904         WOLFSSL_ENTER("DES_ncbc_encrypt");
19905 
19906         /* OpenSSL compat, no ret */
19907         if (wc_Des_SetKey(&myDes, (const byte*)schedule,
19908                          (const byte*)ivec, !enc) != 0) {
19909             WOLFSSL_MSG("wc_Des_SetKey return error.");
19910             return;
19911         }
19912 
19913         lb_sz = length%DES_BLOCK_SIZE;
19914         blk   = length/DES_BLOCK_SIZE;
19915         idx  -= sizeof(DES_cblock);
19916         if (lb_sz) {
19917             idx += DES_BLOCK_SIZE - lb_sz;
19918         }
19919         if (enc){
19920             wc_Des_CbcEncrypt(&myDes, output, input,
19921                     (word32)blk * DES_BLOCK_SIZE);
19922             if (lb_sz){
19923                 XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
19924                 XMEMCPY(lastblock, input+length-lb_sz, lb_sz);
19925                 wc_Des_CbcEncrypt(&myDes, output + blk * DES_BLOCK_SIZE,
19926                     lastblock, (word32)DES_BLOCK_SIZE);
19927             }
19928             XMEMCPY(ivec, output + idx, sizeof(DES_cblock));
19929         } else {
19930             WOLFSSL_DES_cblock tmp;
19931             XMEMCPY(tmp, input + idx, sizeof(DES_cblock));
19932             wc_Des_CbcDecrypt(&myDes, output, input,
19933                     (word32)blk * DES_BLOCK_SIZE);
19934             if (lb_sz){
19935                 wc_Des_CbcDecrypt(&myDes, lastblock, input + length - lb_sz,
19936                         (word32)DES_BLOCK_SIZE);
19937                 XMEMCPY(output+length-lb_sz, lastblock, lb_sz);
19938             }
19939             XMEMCPY(ivec, tmp, sizeof(WOLFSSL_DES_cblock));
19940         }
19941 
19942     }
19943 
19944 #endif /* NO_DES3 */
19945 
wolfSSL_ERR_free_strings(void)19946     void wolfSSL_ERR_free_strings(void)
19947     {
19948         /* handled internally */
19949     }
19950 
wolfSSL_cleanup_all_ex_data(void)19951     void wolfSSL_cleanup_all_ex_data(void)
19952     {
19953         /* nothing to do here */
19954     }
19955 
19956 #endif /* OPENSSL_EXTRA */
19957 
19958 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
wolfSSL_clear(WOLFSSL * ssl)19959     int wolfSSL_clear(WOLFSSL* ssl)
19960     {
19961         if (ssl == NULL) {
19962             return WOLFSSL_FAILURE;
19963         }
19964 
19965         ssl->options.isClosed = 0;
19966         ssl->options.connReset = 0;
19967         ssl->options.sentNotify = 0;
19968         ssl->options.closeNotify = 0;
19969         ssl->options.sendVerify = 0;
19970         ssl->options.serverState = NULL_STATE;
19971         ssl->options.clientState = NULL_STATE;
19972         ssl->options.connectState = CONNECT_BEGIN;
19973         ssl->options.acceptState  = ACCEPT_BEGIN;
19974         ssl->options.handShakeState  = NULL_STATE;
19975         ssl->options.handShakeDone = 0;
19976         ssl->options.processReply = 0; /* doProcessInit */
19977 
19978         ssl->keys.encryptionOn = 0;
19979         XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
19980 
19981         if (ssl->hsHashes != NULL) {
19982 #ifndef NO_OLD_TLS
19983 #ifndef NO_MD5
19984             if (wc_InitMd5_ex(&ssl->hsHashes->hashMd5, ssl->heap,
19985                     ssl->devId) != 0) {
19986                 return WOLFSSL_FAILURE;
19987             }
19988         #ifdef WOLFSSL_HASH_FLAGS
19989             wc_Md5SetFlags(&ssl->hsHashes->hashMd5, WC_HASH_FLAG_WILLCOPY);
19990         #endif
19991 #endif
19992 #ifndef NO_SHA
19993             if (wc_InitSha_ex(&ssl->hsHashes->hashSha, ssl->heap,
19994                     ssl->devId) != 0) {
19995                 return WOLFSSL_FAILURE;
19996             }
19997         #ifdef WOLFSSL_HASH_FLAGS
19998             wc_ShaSetFlags(&ssl->hsHashes->hashSha, WC_HASH_FLAG_WILLCOPY);
19999         #endif
20000 #endif
20001 #endif
20002 #ifndef NO_SHA256
20003             if (wc_InitSha256_ex(&ssl->hsHashes->hashSha256, ssl->heap,
20004                     ssl->devId) != 0) {
20005                 return WOLFSSL_FAILURE;
20006             }
20007         #ifdef WOLFSSL_HASH_FLAGS
20008             wc_Sha256SetFlags(&ssl->hsHashes->hashSha256, WC_HASH_FLAG_WILLCOPY);
20009         #endif
20010 #endif
20011 #ifdef WOLFSSL_SHA384
20012             if (wc_InitSha384_ex(&ssl->hsHashes->hashSha384, ssl->heap,
20013                     ssl->devId) != 0) {
20014                 return WOLFSSL_FAILURE;
20015             }
20016         #ifdef WOLFSSL_HASH_FLAGS
20017             wc_Sha384SetFlags(&ssl->hsHashes->hashSha384, WC_HASH_FLAG_WILLCOPY);
20018         #endif
20019 #endif
20020 #ifdef WOLFSSL_SHA512
20021             if (wc_InitSha512_ex(&ssl->hsHashes->hashSha512, ssl->heap,
20022                     ssl->devId) != 0) {
20023                 return WOLFSSL_FAILURE;
20024             }
20025         #ifdef WOLFSSL_HASH_FLAGS
20026             wc_Sha512SetFlags(&ssl->hsHashes->hashSha512, WC_HASH_FLAG_WILLCOPY);
20027         #endif
20028 #endif
20029         }
20030 #ifdef SESSION_CERTS
20031         ssl->session.chain.count = 0;
20032 #endif
20033 #ifdef KEEP_PEER_CERT
20034         FreeX509(&ssl->peerCert);
20035         InitX509(&ssl->peerCert, 0, ssl->heap);
20036 #endif
20037 
20038         return WOLFSSL_SUCCESS;
20039     }
20040 
20041 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
20042 
20043 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
wolfSSL_CTX_set_mode(WOLFSSL_CTX * ctx,long mode)20044     long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
20045     {
20046         /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
20047 
20048         WOLFSSL_ENTER("SSL_CTX_set_mode");
20049         switch(mode) {
20050             case SSL_MODE_ENABLE_PARTIAL_WRITE:
20051                 ctx->partialWrite = 1;
20052                 break;
20053             #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
20054             case SSL_MODE_RELEASE_BUFFERS:
20055                 WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
20056                 break;
20057             #endif
20058             case SSL_MODE_AUTO_RETRY:
20059                 ctx->autoRetry = 1;
20060                 break;
20061             default:
20062                 WOLFSSL_MSG("Mode Not Implemented");
20063         }
20064 
20065         /* SSL_MODE_AUTO_RETRY
20066          * Should not return -1 with renegotiation on read/write */
20067 
20068         return mode;
20069     }
20070 
wolfSSL_CTX_clear_mode(WOLFSSL_CTX * ctx,long mode)20071     long wolfSSL_CTX_clear_mode(WOLFSSL_CTX* ctx, long mode)
20072     {
20073         /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
20074 
20075         WOLFSSL_ENTER("SSL_CTX_set_mode");
20076         switch(mode) {
20077             case SSL_MODE_ENABLE_PARTIAL_WRITE:
20078                 ctx->partialWrite = 0;
20079                 break;
20080             #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
20081             case SSL_MODE_RELEASE_BUFFERS:
20082                 WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
20083                 break;
20084             #endif
20085             case SSL_MODE_AUTO_RETRY:
20086                 ctx->autoRetry = 0;
20087                 break;
20088             default:
20089                 WOLFSSL_MSG("Mode Not Implemented");
20090         }
20091 
20092         /* SSL_MODE_AUTO_RETRY
20093          * Should not return -1 with renegotiation on read/write */
20094 
20095         return 0;
20096     }
20097 #endif
20098 
20099 #ifdef OPENSSL_EXTRA
20100 
20101     #ifndef NO_WOLFSSL_STUB
wolfSSL_SSL_get_mode(WOLFSSL * ssl)20102     long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
20103     {
20104         /* TODO: */
20105         (void)ssl;
20106         WOLFSSL_STUB("SSL_get_mode");
20107         return 0;
20108     }
20109     #endif
20110 
20111     #ifndef NO_WOLFSSL_STUB
wolfSSL_CTX_get_mode(WOLFSSL_CTX * ctx)20112     long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
20113     {
20114         /* TODO: */
20115         (void)ctx;
20116         WOLFSSL_STUB("SSL_CTX_get_mode");
20117         return 0;
20118     }
20119     #endif
20120 
20121     #ifndef NO_WOLFSSL_STUB
wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX * ctx,int m)20122     void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
20123     {
20124         /* TODO: maybe? */
20125         (void)ctx;
20126         (void)m;
20127         WOLFSSL_STUB("SSL_CTX_set_default_read_ahead");
20128     }
20129     #endif
20130 
20131 
20132     /* Storing app session context id, this value is inherited by WOLFSSL
20133      * objects created from WOLFSSL_CTX. Any session that is imported with a
20134      * different session context id will be rejected.
20135      *
20136      * ctx         structure to set context in
20137      * sid_ctx     value of context to set
20138      * sid_ctx_len length of sid_ctx buffer
20139      *
20140      * Returns WOLFSSL_SUCCESS in success case and SSL_FAILURE when failing
20141      */
wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX * ctx,const unsigned char * sid_ctx,unsigned int sid_ctx_len)20142     int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
20143                                            const unsigned char* sid_ctx,
20144                                            unsigned int sid_ctx_len)
20145     {
20146         WOLFSSL_ENTER("SSL_CTX_set_session_id_context");
20147 
20148         /* No application specific context needed for wolfSSL */
20149         if (sid_ctx_len > ID_LEN || ctx == NULL || sid_ctx == NULL) {
20150             return SSL_FAILURE;
20151         }
20152         XMEMCPY(ctx->sessionCtx, sid_ctx, sid_ctx_len);
20153         ctx->sessionCtxSz = (byte)sid_ctx_len;
20154 
20155         return WOLFSSL_SUCCESS;
20156     }
20157 
20158 
20159 
20160     /* Storing app session context id. Any session that is imported with a
20161      * different session context id will be rejected.
20162      *
20163      * ssl  structure to set context in
20164      * id   value of context to set
20165      * len  length of sid_ctx buffer
20166      *
20167      * Returns WOLFSSL_SUCCESS in success case and SSL_FAILURE when failing
20168      */
wolfSSL_set_session_id_context(WOLFSSL * ssl,const unsigned char * id,unsigned int len)20169     int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id,
20170                                    unsigned int len)
20171     {
20172         WOLFSSL_ENTER("wolfSSL_set_session_id_context");
20173 
20174         if (len > ID_LEN || ssl == NULL || id == NULL) {
20175             return SSL_FAILURE;
20176         }
20177         XMEMCPY(ssl->sessionCtx, id, len);
20178         ssl->sessionCtxSz = (byte)len;
20179 
20180         return WOLFSSL_SUCCESS;
20181     }
20182 
20183 
wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX * ctx)20184     long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx)
20185     {
20186         (void)ctx;
20187         #ifndef NO_SESSION_CACHE
20188             return (long)(SESSIONS_PER_ROW * SESSION_ROWS);
20189         #else
20190             return 0;
20191         #endif
20192     }
20193 
20194 
20195     /* returns the unsigned error value and increments the pointer into the
20196      * error queue.
20197      *
20198      * file  pointer to file name
20199      * line  gets set to line number of error when not NULL
20200      */
wolfSSL_ERR_get_error_line(const char ** file,int * line)20201     unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line)
20202     {
20203     #ifdef WOLFSSL_HAVE_ERROR_QUEUE
20204         int ret = wc_PullErrorNode(file, NULL, line);
20205         if (ret < 0) {
20206             if (ret == BAD_STATE_E) return 0; /* no errors in queue */
20207             WOLFSSL_MSG("Issue getting error node");
20208             WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line", ret);
20209             ret = 0 - ret; /* return absolute value of error */
20210 
20211             /* panic and try to clear out nodes */
20212             wc_ClearErrorNodes();
20213         }
20214         return (unsigned long)ret;
20215     #else
20216         (void)file;
20217         (void)line;
20218 
20219         return 0;
20220     #endif
20221     }
20222 
20223 
20224 #if (defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)) && \
20225     (!defined(_WIN32) && !defined(NO_ERROR_QUEUE))
20226     static const char WOLFSSL_SYS_ACCEPT_T[]  = "accept";
20227     static const char WOLFSSL_SYS_BIND_T[]    = "bind";
20228     static const char WOLFSSL_SYS_CONNECT_T[] = "connect";
20229     static const char WOLFSSL_SYS_FOPEN_T[]   = "fopen";
20230     static const char WOLFSSL_SYS_FREAD_T[]   = "fread";
20231     static const char WOLFSSL_SYS_GETADDRINFO_T[] = "getaddrinfo";
20232     static const char WOLFSSL_SYS_GETSOCKOPT_T[]  = "getsockopt";
20233     static const char WOLFSSL_SYS_GETSOCKNAME_T[] = "getsockname";
20234     static const char WOLFSSL_SYS_GETHOSTBYNAME_T[] = "gethostbyname";
20235     static const char WOLFSSL_SYS_GETNAMEINFO_T[]   = "getnameinfo";
20236     static const char WOLFSSL_SYS_GETSERVBYNAME_T[] = "getservbyname";
20237     static const char WOLFSSL_SYS_IOCTLSOCKET_T[]   = "ioctlsocket";
20238     static const char WOLFSSL_SYS_LISTEN_T[]        = "listen";
20239     static const char WOLFSSL_SYS_OPENDIR_T[]       = "opendir";
20240     static const char WOLFSSL_SYS_SETSOCKOPT_T[]    = "setsockopt";
20241     static const char WOLFSSL_SYS_SOCKET_T[]        = "socket";
20242 
20243     /* switch with int mapped to function name for compatibility */
wolfSSL_ERR_sys_func(int fun)20244     static const char* wolfSSL_ERR_sys_func(int fun)
20245     {
20246         switch (fun) {
20247             case WOLFSSL_SYS_ACCEPT:      return WOLFSSL_SYS_ACCEPT_T;
20248             case WOLFSSL_SYS_BIND:        return WOLFSSL_SYS_BIND_T;
20249             case WOLFSSL_SYS_CONNECT:     return WOLFSSL_SYS_CONNECT_T;
20250             case WOLFSSL_SYS_FOPEN:       return WOLFSSL_SYS_FOPEN_T;
20251             case WOLFSSL_SYS_FREAD:       return WOLFSSL_SYS_FREAD_T;
20252             case WOLFSSL_SYS_GETADDRINFO: return WOLFSSL_SYS_GETADDRINFO_T;
20253             case WOLFSSL_SYS_GETSOCKOPT:  return WOLFSSL_SYS_GETSOCKOPT_T;
20254             case WOLFSSL_SYS_GETSOCKNAME: return WOLFSSL_SYS_GETSOCKNAME_T;
20255             case WOLFSSL_SYS_GETHOSTBYNAME: return WOLFSSL_SYS_GETHOSTBYNAME_T;
20256             case WOLFSSL_SYS_GETNAMEINFO: return WOLFSSL_SYS_GETNAMEINFO_T;
20257             case WOLFSSL_SYS_GETSERVBYNAME: return WOLFSSL_SYS_GETSERVBYNAME_T;
20258             case WOLFSSL_SYS_IOCTLSOCKET: return WOLFSSL_SYS_IOCTLSOCKET_T;
20259             case WOLFSSL_SYS_LISTEN:      return WOLFSSL_SYS_LISTEN_T;
20260             case WOLFSSL_SYS_OPENDIR:     return WOLFSSL_SYS_OPENDIR_T;
20261             case WOLFSSL_SYS_SETSOCKOPT:  return WOLFSSL_SYS_SETSOCKOPT_T;
20262             case WOLFSSL_SYS_SOCKET:      return WOLFSSL_SYS_SOCKET_T;
20263             default:
20264                 return "NULL";
20265         }
20266     }
20267 #endif /* DEBUG_WOLFSSL */
20268 
20269 
20270     /* @TODO when having an error queue this needs to push to the queue */
wolfSSL_ERR_put_error(int lib,int fun,int err,const char * file,int line)20271     void wolfSSL_ERR_put_error(int lib, int fun, int err, const char* file,
20272             int line)
20273     {
20274         WOLFSSL_ENTER("wolfSSL_ERR_put_error");
20275 
20276         #if !defined(DEBUG_WOLFSSL) && !defined(OPENSSL_EXTRA)
20277         (void)fun;
20278         (void)err;
20279         (void)file;
20280         (void)line;
20281         WOLFSSL_MSG("Not compiled in debug mode");
20282         #elif defined(OPENSSL_EXTRA) && \
20283                 (defined(_WIN32) || defined(NO_ERROR_QUEUE))
20284         (void)fun;
20285         (void)file;
20286         (void)line;
20287         WOLFSSL_ERROR(err);
20288         #else
20289         WOLFSSL_ERROR_LINE(err, wolfSSL_ERR_sys_func(fun), (unsigned int)line,
20290             file, NULL);
20291         #endif
20292         (void)lib;
20293     }
20294 
20295 
20296     /* Similar to wolfSSL_ERR_get_error_line but takes in a flags argument for
20297      * more flexibility.
20298      *
20299      * file  output pointer to file where error happened
20300      * line  output to line number of error
20301      * data  output data. Is a string if ERR_TXT_STRING flag is used
20302      * flags bit flag to adjust data output
20303      *
20304      * Returns the error value or 0 if no errors are in the queue
20305      */
wolfSSL_ERR_get_error_line_data(const char ** file,int * line,const char ** data,int * flags)20306     unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
20307                                                   const char** data, int *flags)
20308     {
20309 #ifdef WOLFSSL_HAVE_ERROR_QUEUE
20310         int ret;
20311 
20312         WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
20313 
20314         if (flags != NULL) {
20315             if ((*flags & ERR_TXT_STRING) == ERR_TXT_STRING) {
20316                 ret = wc_PullErrorNode(file, data, line);
20317                 if (ret < 0) {
20318                     if (ret == BAD_STATE_E) return 0; /* no errors in queue */
20319                     WOLFSSL_MSG("Error with pulling error node!");
20320                     WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
20321                     ret = 0 - ret; /* return absolute value of error */
20322 
20323                     /* panic and try to clear out nodes */
20324                     wc_ClearErrorNodes();
20325                 }
20326 
20327                 return (unsigned long)ret;
20328             }
20329         }
20330 
20331         ret = wc_PullErrorNode(file, NULL, line);
20332         if (ret < 0) {
20333             if (ret == BAD_STATE_E) return 0; /* no errors in queue */
20334             WOLFSSL_MSG("Error with pulling error node!");
20335             WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
20336             ret = 0 - ret; /* return absolute value of error */
20337 
20338             /* panic and try to clear out nodes */
20339             wc_ClearErrorNodes();
20340         }
20341 
20342         return (unsigned long)ret;
20343 #else
20344         WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
20345         WOLFSSL_MSG("Error queue turned off, can not get error line");
20346         (void)file;
20347         (void)line;
20348         (void)data;
20349         (void)flags;
20350         return 0;
20351 #endif
20352     }
20353 
20354 #endif /* OPENSSL_EXTRA */
20355 
20356 
20357 #if (defined(KEEP_PEER_CERT) && defined(SESSION_CERTS)) || \
20358                                    (defined(OPENSSL_ALL) && defined(HAVE_PKCS7))
20359     /* Decode the X509 DER encoded certificate into a WOLFSSL_X509 object.
20360      *
20361      * x509  WOLFSSL_X509 object to decode into.
20362      * in    X509 DER data.
20363      * len   Length of the X509 DER data.
20364      * returns the new certificate on success, otherwise NULL.
20365      */
DecodeToX509(WOLFSSL_X509 * x509,const byte * in,int len)20366     static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len)
20367     {
20368         int          ret;
20369     #ifdef WOLFSSL_SMALL_STACK
20370         DecodedCert* cert;
20371     #else
20372         DecodedCert  cert[1];
20373     #endif
20374         if (x509 == NULL || in == NULL || len <= 0)
20375             return BAD_FUNC_ARG;
20376 
20377     #ifdef WOLFSSL_SMALL_STACK
20378         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
20379                                      DYNAMIC_TYPE_DCERT);
20380         if (cert == NULL)
20381             return MEMORY_E;
20382     #endif
20383 
20384         /* Create a DecodedCert object and copy fields into WOLFSSL_X509 object.
20385          */
20386         InitDecodedCert(cert, (byte*)in, len, NULL);
20387         if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) == 0) {
20388         /* Check if x509 was not previously initialized by wolfSSL_X509_new() */
20389             if (x509->dynamicMemory != TRUE)
20390                 InitX509(x509, 0, NULL);
20391             ret = CopyDecodedToX509(x509, cert);
20392             FreeDecodedCert(cert);
20393         }
20394     #ifdef WOLFSSL_SMALL_STACK
20395         XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
20396     #endif
20397 
20398         return ret;
20399     }
20400 #endif /* (KEEP_PEER_CERT && SESSION_CERTS) || (OPENSSL_ALL && HAVE_PKCS7) */
20401 
20402 
20403 #ifdef KEEP_PEER_CERT
20404     WOLFSSL_ABI
wolfSSL_get_peer_certificate(WOLFSSL * ssl)20405     WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
20406     {
20407         WOLFSSL_ENTER("SSL_get_peer_certificate");
20408         if (ssl == NULL)
20409             return NULL;
20410 
20411         if (ssl->peerCert.issuer.sz)
20412             return &ssl->peerCert;
20413 #ifdef SESSION_CERTS
20414         else if (ssl->session.chain.count > 0) {
20415             if (DecodeToX509(&ssl->peerCert, ssl->session.chain.certs[0].buffer,
20416                     ssl->session.chain.certs[0].length) == 0) {
20417                 return &ssl->peerCert;
20418             }
20419         }
20420 #endif
20421         return NULL;
20422     }
20423 
20424 #endif /* KEEP_PEER_CERT */
20425 
20426 #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
20427 /* Return stack of peer certs.
20428  * Caller does not need to free return. The stack is Free'd when WOLFSSL* ssl is.
20429  */
WOLF_STACK_OF(WOLFSSL_X509)20430 WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
20431 {
20432     WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
20433 
20434     if (ssl == NULL)
20435         return NULL;
20436 
20437     /* Try to populate if NULL or empty */
20438     if (ssl->peerCertChain == NULL ||
20439             wolfSSL_sk_X509_num(ssl->peerCertChain) == 0)
20440         wolfSSL_set_peer_cert_chain((WOLFSSL*) ssl);
20441     return ssl->peerCertChain;
20442 }
20443 
20444 #ifndef WOLFSSL_QT
20445 static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
20446         WOLFSSL_X509 *x);
20447 /**
20448  * Recursively push the issuer CA chain onto the stack
20449  * @param cm The cert manager that is queried for the issuer
20450  * @param x  This cert's issuer will be queried in cm
20451  * @param sk The issuer is pushed onto this stack
20452  * @return WOLFSSL_SUCCESS on success
20453  *         WOLFSSL_FAILURE on no issuer found
20454  *         WOLFSSL_FATAL_ERROR on a fatal error
20455  */
PushCAx509Chain(WOLFSSL_CERT_MANAGER * cm,WOLFSSL_X509 * x,WOLFSSL_STACK * sk)20456 static int PushCAx509Chain(WOLFSSL_CERT_MANAGER* cm,
20457         WOLFSSL_X509 *x, WOLFSSL_STACK* sk)
20458 {
20459     WOLFSSL_X509* issuer[MAX_CHAIN_DEPTH];
20460     int i;
20461     int push = 1;
20462     int ret = WOLFSSL_SUCCESS;
20463 
20464     for (i = 0; i < MAX_CHAIN_DEPTH; i++) {
20465         if (x509GetIssuerFromCM(&issuer[i], cm, x)
20466                 != WOLFSSL_SUCCESS)
20467             break;
20468         x = issuer[i];
20469     }
20470     if (i == 0) /* No further chain found */
20471         return WOLFSSL_FAILURE;
20472     i--;
20473     for (; i >= 0; i--) {
20474         if (push) {
20475             if (wolfSSL_sk_X509_push(sk, issuer[i]) != WOLFSSL_SUCCESS) {
20476                 wolfSSL_X509_free(issuer[i]);
20477                 ret = WOLFSSL_FATAL_ERROR;
20478                 push = 0; /* Free the rest of the unpushed certs */
20479             }
20480         }
20481         else {
20482             wolfSSL_X509_free(issuer[i]);
20483         }
20484     }
20485     return ret;
20486 }
20487 #endif /* !WOLFSSL_QT */
20488 
20489 /* Builds up and creates a stack of peer certificates for ssl->peerCertChain
20490     based off of the ssl session chain. Attempts to place CA certificates
20491     at the bottom of the stack. Returns stack of WOLFSSL_X509 certs or
20492     NULL on failure */
WOLF_STACK_OF(WOLFSSL_X509)20493 WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
20494 {
20495     WOLFSSL_STACK* sk;
20496     WOLFSSL_X509* x509;
20497     int i = 0;
20498     int ret;
20499 
20500     WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain");
20501     if ((ssl == NULL) || (ssl->session.chain.count == 0))
20502         return NULL;
20503 
20504     sk = wolfSSL_sk_X509_new();
20505     i = ssl->session.chain.count-1;
20506     for (; i >= 0; i--) {
20507         x509 = wolfSSL_X509_new();
20508         if (x509 == NULL) {
20509             WOLFSSL_MSG("Error Creating X509");
20510             wolfSSL_sk_X509_pop_free(sk, NULL);
20511             return NULL;
20512         }
20513         ret = DecodeToX509(x509, ssl->session.chain.certs[i].buffer,
20514                              ssl->session.chain.certs[i].length);
20515 #if !defined(WOLFSSL_QT)
20516         if (ret == 0 && i == ssl->session.chain.count-1) {
20517             /* On the last element in the chain try to add the CA chain
20518              * first if we have one for this cert */
20519             if (PushCAx509Chain(SSL_CM(ssl), x509, sk)
20520                     == WOLFSSL_FATAL_ERROR) {
20521                 ret = WOLFSSL_FATAL_ERROR;
20522             }
20523         }
20524 #endif
20525 
20526         if (ret != 0 || wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) {
20527             WOLFSSL_MSG("Error decoding cert");
20528             wolfSSL_X509_free(x509);
20529             wolfSSL_sk_X509_pop_free(sk, NULL);
20530             return NULL;
20531         }
20532     }
20533 
20534     if (sk == NULL) {
20535         WOLFSSL_MSG("Null session chain");
20536     }
20537 #if defined(OPENSSL_ALL)
20538     else if (ssl->options.side == WOLFSSL_SERVER_END) {
20539         /* to be compliant with openssl
20540            first element is kept as peer cert on server side.*/
20541         wolfSSL_sk_X509_shift(sk);
20542     }
20543 #endif
20544     if (ssl->peerCertChain != NULL)
20545         wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL);
20546     /* This is Free'd when ssl is Free'd */
20547     ssl->peerCertChain = sk;
20548     return sk;
20549 }
20550 #endif /* SESSION_CERTS && OPENSSL_EXTRA */
20551 
20552 #ifndef NO_CERTS
20553 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
20554     defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
20555 
20556 /* user externally called free X509, if dynamic go ahead with free, otherwise
20557  * don't */
ExternalFreeX509(WOLFSSL_X509 * x509)20558 static void ExternalFreeX509(WOLFSSL_X509* x509)
20559 {
20560 #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
20561     int doFree = 0;
20562 #endif
20563 
20564     WOLFSSL_ENTER("ExternalFreeX509");
20565     if (x509) {
20566 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
20567         wolfSSL_CRYPTO_cleanup_ex_data(&x509->ex_data);
20568 #endif
20569         if (x509->dynamicMemory) {
20570         #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
20571         #ifndef SINGLE_THREADED
20572             if (wc_LockMutex(&x509->refMutex) != 0) {
20573                 WOLFSSL_MSG("Couldn't lock x509 mutex");
20574             }
20575         #endif
20576             /* only free if all references to it are done */
20577             x509->refCount--;
20578             if (x509->refCount == 0)
20579                 doFree = 1;
20580         #ifndef SINGLE_THREADED
20581             wc_UnLockMutex(&x509->refMutex);
20582         #endif
20583         #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
20584 
20585         #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
20586             if (doFree)
20587         #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
20588             {
20589                 FreeX509(x509);
20590                 XFREE(x509, x509->heap, DYNAMIC_TYPE_X509);
20591             }
20592         } else {
20593             WOLFSSL_MSG("free called on non dynamic object, not freeing");
20594         }
20595     }
20596 }
20597 
20598 /* Frees an external WOLFSSL_X509 structure */
20599 WOLFSSL_ABI
wolfSSL_X509_free(WOLFSSL_X509 * x509)20600 void wolfSSL_X509_free(WOLFSSL_X509* x509)
20601 {
20602     WOLFSSL_ENTER("wolfSSL_FreeX509");
20603     ExternalFreeX509(x509);
20604 }
20605 
20606 
20607 /* copy name into in buffer, at most sz bytes, if buffer is null will
20608    malloc buffer, call responsible for freeing                     */
20609 WOLFSSL_ABI
wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME * name,char * in,int sz)20610 char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
20611 {
20612     int copySz;
20613 
20614     if (name == NULL) {
20615         WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL");
20616         return NULL;
20617     }
20618 
20619     copySz = min(sz, name->sz);
20620 
20621     WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
20622     if (!name->sz) return in;
20623 
20624     if (!in) {
20625     #ifdef WOLFSSL_STATIC_MEMORY
20626         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
20627         return NULL;
20628     #else
20629         in = (char*)XMALLOC(name->sz, NULL, DYNAMIC_TYPE_OPENSSL);
20630         if (!in ) return in;
20631         copySz = name->sz;
20632     #endif
20633     }
20634 
20635     if (copySz <= 0)
20636         return in;
20637 
20638     XMEMCPY(in, name->name, copySz - 1);
20639     in[copySz - 1] = 0;
20640 
20641     return in;
20642 }
20643 
wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME * name)20644 unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name)
20645 {
20646 #ifndef NO_SHA
20647     byte digest[WC_SHA_DIGEST_SIZE];
20648     unsigned long ret = 0;
20649     WOLFSSL_ENTER("wolfSSL_X509_NAME_hash");
20650     if (name == NULL) {
20651         WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL");
20652         return 0;
20653     }
20654     if (name->sz == 0) {
20655         WOLFSSL_MSG("nothing to hash in WOLFSSL_X509_NAME");
20656         return 0;
20657     }
20658     if (wc_ShaHash((byte*)name->name, name->sz, digest) != 0) {
20659         WOLFSSL_MSG("wc_ShaHash error");
20660         return 0;
20661     }
20662     ret  =  (unsigned long) digest[0];
20663     ret |= ((unsigned long) digest[1]) << 8;
20664     ret |= ((unsigned long) digest[2]) << 16;
20665     ret |= ((unsigned long) digest[3]) << 24;
20666     return ret;
20667 #else
20668     (void)name;
20669     WOLFSSL_MSG("wolfSSL_X509_NAME_hash sha support not compiled in");
20670     return 0;
20671 #endif
20672 }
20673 
20674 #if defined(OPENSSL_EXTRA) && defined(XSNPRINTF)
20675 /* Copies X509 subject name into a buffer, with comma-separated name entries
20676  *   (matching OpenSSL v1.0.0 format)
20677  * Example Output for Issuer:
20678  *
20679  * C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting,
20680  *  CN=www.wolfssl.com, emailAddress=info@wolfssl.com
20681  */
wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME * name,char * in,int sz)20682 char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
20683 {
20684     WOLFSSL_X509_NAME_ENTRY* entry;
20685     int nameSz, strSz, count, i;
20686     int totalSz = 0;
20687     char *str;
20688     char tmpBuf[256];
20689     char buf[80];
20690     const char* sn;
20691     WOLFSSL_ENTER("wolfSSL_X509_get_name_oneline");
20692 
20693     if (name == NULL) {
20694         WOLFSSL_MSG("wolfSSL_X509_get_subject_name failed");
20695         return NULL;
20696     }
20697     #ifdef WOLFSSL_STATIC_MEMORY
20698     if (!in) {
20699         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
20700         return NULL;
20701     }
20702     #endif
20703 
20704     tmpBuf[0] = '\0'; /* Make sure tmpBuf is NULL terminated */
20705     /* Loop through X509 name entries and copy new format to buffer */
20706     count = wolfSSL_X509_NAME_entry_count(name);
20707     for (i = 0; i < count; i++) {
20708 
20709         /* Get name entry and size */
20710         entry = wolfSSL_X509_NAME_get_entry(name, i);
20711         if (entry == NULL) {
20712             WOLFSSL_MSG("wolfSSL_X509_NAME_get_entry failed");
20713             return NULL;
20714         }
20715         nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, entry->nid, buf,
20716                                                                    sizeof(buf));
20717         if (nameSz < 0) {
20718             WOLFSSL_MSG("wolfSSL_X509_NAME_get_text_by_NID failed");
20719             return NULL;
20720         }
20721 
20722         /* Get short name */
20723         sn = wolfSSL_OBJ_nid2sn(entry->nid);
20724         if (sn == NULL) {
20725             WOLFSSL_MSG("OBJ_nid2sn failed");
20726             return NULL;
20727         }
20728 
20729         /* Copy sn and name text to buffer
20730          * Add extra strSz for '=', ',', ' ' and '\0' characters in XSNPRINTF.
20731          */
20732         if (i != count - 1) {
20733             strSz = (int)XSTRLEN(sn) + nameSz + 4;
20734             totalSz+= strSz;
20735             str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20736             if (str == NULL) {
20737                 WOLFSSL_MSG("Memory error");
20738                 return NULL;
20739             }
20740             XSNPRINTF(str, strSz, "%s=%s, ", sn, buf);
20741         }
20742         else {
20743             /* Copy last name entry
20744             * Add extra strSz for '=' and '\0' characters in XSNPRINTF.
20745             */
20746             strSz = (int)XSTRLEN(sn) + nameSz + 2;
20747             totalSz+= strSz;
20748             str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20749             if (str == NULL) {
20750                 WOLFSSL_MSG("Memory error");
20751                 return NULL;
20752             }
20753             XSNPRINTF(str, strSz, "%s=%s", sn, buf);
20754         }
20755         /* Copy string to tmpBuf */
20756         XSTRNCAT(tmpBuf, str, strSz);
20757         XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20758     }
20759 
20760     /* Allocate space based on total string size if no buffer was provided */
20761     if (!in) {
20762         in = (char*)XMALLOC(totalSz+1, NULL, DYNAMIC_TYPE_OPENSSL);
20763         if (in == NULL) {
20764             WOLFSSL_MSG("Memory error");
20765             return in;
20766         }
20767     }
20768     else {
20769         if (totalSz > sz) {
20770             WOLFSSL_MSG("Memory error");
20771             return NULL;
20772         }
20773     }
20774 
20775     XMEMCPY(in, tmpBuf, totalSz);
20776     in[totalSz] = '\0';
20777 
20778     return in;
20779 }
20780 #endif
20781 
20782 
20783 /* Wraps wolfSSL_X509_d2i
20784  *
20785  * returns a WOLFSSL_X509 structure pointer on success and NULL on fail
20786  */
wolfSSL_d2i_X509(WOLFSSL_X509 ** x509,const unsigned char ** in,int len)20787 WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in,
20788         int len)
20789 {
20790     WOLFSSL_X509* newX509 = NULL;
20791     WOLFSSL_ENTER("wolfSSL_d2i_X509");
20792 
20793     if (in == NULL) {
20794         WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509");
20795         return NULL;
20796     }
20797 
20798     newX509 = wolfSSL_X509_d2i(x509, *in, len);
20799     if (newX509 != NULL) {
20800         *in += newX509->derCert->length;
20801     }
20802     return newX509;
20803 }
20804 
d2i_X509orX509REQ(WOLFSSL_X509 ** x509,const byte * in,int len,int req)20805 static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
20806                                         const byte* in, int len, int req)
20807 {
20808     WOLFSSL_X509 *newX509 = NULL;
20809     int type = req ? CERTREQ_TYPE : CERT_TYPE;
20810 
20811     WOLFSSL_ENTER("wolfSSL_X509_d2i");
20812 
20813     if (in != NULL && len != 0
20814     #ifndef WOLFSSL_CERT_REQ
20815             && req == 0
20816     #else
20817             && (req == 0 || req == 1)
20818     #endif
20819             ) {
20820     #ifdef WOLFSSL_SMALL_STACK
20821         DecodedCert* cert;
20822     #else
20823         DecodedCert  cert[1];
20824     #endif
20825 
20826     #ifdef WOLFSSL_SMALL_STACK
20827         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
20828                                      DYNAMIC_TYPE_DCERT);
20829         if (cert == NULL)
20830             return NULL;
20831     #endif
20832 
20833         InitDecodedCert(cert, (byte*)in, len, NULL);
20834     #ifdef WOLFSSL_CERT_REQ
20835         cert->isCSR = req;
20836     #endif
20837         if (ParseCertRelative(cert, type, 0, NULL) == 0) {
20838             newX509 = wolfSSL_X509_new();
20839             if (newX509 != NULL) {
20840                 if (CopyDecodedToX509(newX509, cert) != 0) {
20841                     wolfSSL_X509_free(newX509);
20842                     newX509 = NULL;
20843                 }
20844             }
20845         }
20846         FreeDecodedCert(cert);
20847     #ifdef WOLFSSL_SMALL_STACK
20848         XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
20849     #endif
20850     }
20851 
20852     if (x509 != NULL)
20853         *x509 = newX509;
20854 
20855     return newX509;
20856 }
20857 
wolfSSL_X509_get_isCA(WOLFSSL_X509 * x509)20858 int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
20859 {
20860     int isCA = 0;
20861 
20862     WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
20863 
20864     if (x509 != NULL)
20865         isCA = x509->isCa;
20866 
20867     WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
20868 
20869     return isCA;
20870 }
20871 
wolfSSL_X509_d2i(WOLFSSL_X509 ** x509,const byte * in,int len)20872 WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
20873 {
20874     return d2i_X509orX509REQ(x509, in, len, 0);
20875 }
20876 
20877 #ifdef WOLFSSL_CERT_REQ
wolfSSL_X509_REQ_d2i(WOLFSSL_X509 ** x509,const unsigned char * in,int len)20878 WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509,
20879         const unsigned char* in, int len)
20880 {
20881     return d2i_X509orX509REQ(x509, in, len, 1);
20882 }
20883 #endif
20884 #endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA ||
20885           OPENSSL_EXTRA_X509_SMALL */
20886 
20887 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
20888 /* returns the number of entries in the WOLFSSL_X509_NAME */
wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME * name)20889 int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
20890 {
20891     int count = 0;
20892 
20893     WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
20894 
20895     if (name != NULL)
20896         count = name->entrySz;
20897 
20898     WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
20899     return count;
20900 }
20901 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
20902 
20903 #if defined(OPENSSL_EXTRA) || \
20904     defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
20905 
20906 /* return the next, if any, altname from the peer cert */
20907 WOLFSSL_ABI
wolfSSL_X509_get_next_altname(WOLFSSL_X509 * cert)20908 char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
20909 {
20910     char* ret = NULL;
20911     WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
20912 
20913     /* don't have any to work with */
20914     if (cert == NULL || cert->altNames == NULL)
20915         return NULL;
20916 
20917     /* already went through them */
20918     if (cert->altNamesNext == NULL)
20919         return NULL;
20920 
20921     ret = cert->altNamesNext->name;
20922 #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
20923     /* return the IP address as a string */
20924     if (cert->altNamesNext->type == ASN_IP_TYPE) {
20925         ret = cert->altNamesNext->ipString;
20926     }
20927 #endif
20928     cert->altNamesNext = cert->altNamesNext->next;
20929 
20930     return ret;
20931 }
20932 
wolfSSL_X509_get_signature(WOLFSSL_X509 * x509,unsigned char * buf,int * bufSz)20933 int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
20934                                                 unsigned char* buf, int* bufSz)
20935 {
20936     WOLFSSL_ENTER("wolfSSL_X509_get_signature");
20937     if (x509 == NULL || bufSz == NULL || (*bufSz < (int)x509->sig.length &&
20938                 buf != NULL))
20939         return WOLFSSL_FATAL_ERROR;
20940 
20941     if (buf != NULL)
20942         XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
20943     *bufSz = x509->sig.length;
20944 
20945     return WOLFSSL_SUCCESS;
20946 }
20947 
20948 
20949 /* Getter function that copies over the DER public key buffer to "buf" and
20950     * sets the size in bufSz. If "buf" is NULL then just bufSz is set to needed
20951     * buffer size. "bufSz" passed in should initially be set by the user to be
20952     * the size of "buf". This gets checked to make sure the buffer is large
20953     * enough to hold the public key.
20954     *
20955     * Note: this is the X.509 form of key with "header" info.
20956     * return WOLFSSL_SUCCESS on success
20957     */
wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509 * x509,unsigned char * buf,int * bufSz)20958 int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509,
20959                                             unsigned char* buf, int* bufSz)
20960 {
20961 #ifdef WOLFSSL_SMALL_STACK
20962     DecodedCert* cert;
20963 #else
20964     DecodedCert cert[1];
20965 #endif
20966     word32 idx;
20967     const byte*  der;
20968     int length = 0;
20969     int    ret = 0, derSz = 0;
20970     int badDate = 0;
20971     const byte* pubKeyX509 = NULL;
20972     int   pubKeyX509Sz = 0;
20973 
20974     WOLFSSL_ENTER("wolfSSL_X509_get_pubkey_buffer");
20975     if (x509 == NULL || bufSz == NULL) {
20976         WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BAD_FUNC_ARG);
20977         return WOLFSSL_FATAL_ERROR;
20978     }
20979 
20980 
20981 #ifdef WOLFSSL_SMALL_STACK
20982     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
20983                                     x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
20984     if (cert == NULL) {
20985         WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", MEMORY_E);
20986         return WOLFSSL_FATAL_ERROR;
20987     }
20988 #endif
20989 
20990     der = wolfSSL_X509_get_der(x509, &derSz);
20991     if (der != NULL) {
20992         InitDecodedCert(cert, der, derSz, NULL);
20993         ret = wc_GetPubX509(cert, 0, &badDate);
20994         if (ret >= 0) {
20995             idx = cert->srcIdx;
20996             pubKeyX509 = cert->source + cert->srcIdx;
20997             ret = GetSequence(cert->source, &cert->srcIdx, &length,
20998                     cert->maxIdx);
20999             pubKeyX509Sz = length + (cert->srcIdx - idx);
21000         }
21001         FreeDecodedCert(cert);
21002     }
21003 #ifdef WOLFSSL_SMALL_STACK
21004     XFREE(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
21005 #endif
21006 
21007     if (ret < 0) {
21008         WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", ret);
21009         return WOLFSSL_FATAL_ERROR;
21010     }
21011 
21012     if (buf != NULL && pubKeyX509 != NULL) {
21013         if (pubKeyX509Sz > *bufSz) {
21014             WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BUFFER_E);
21015             return WOLFSSL_FATAL_ERROR;
21016         }
21017         XMEMCPY(buf, pubKeyX509, pubKeyX509Sz);
21018     }
21019     *bufSz = pubKeyX509Sz;
21020 
21021     return WOLFSSL_SUCCESS;
21022 }
21023 
21024 
21025 /* Getter function for the public key OID value
21026     * return public key OID stored in WOLFSSL_X509 structure */
wolfSSL_X509_get_pubkey_type(WOLFSSL_X509 * x509)21027 int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509)
21028 {
21029     if (x509 == NULL)
21030         return WOLFSSL_FAILURE;
21031     return x509->pubKeyOID;
21032 }
21033 
21034 #endif /* OPENSSL_EXTRA || KEEP_OUR_CERT || KEEP_PEER_CERT || SESSION_CERTS */
21035 
21036 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
21037     defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
21038 
21039 /* write X509 serial number in unsigned binary to buffer
21040     buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
21041     return WOLFSSL_SUCCESS on success */
wolfSSL_X509_get_serial_number(WOLFSSL_X509 * x509,byte * in,int * inOutSz)21042 int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
21043                                     byte* in, int* inOutSz)
21044 {
21045     WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
21046     if (x509 == NULL || inOutSz == NULL) {
21047         WOLFSSL_MSG("Null argument passed in");
21048         return BAD_FUNC_ARG;
21049     }
21050 
21051     if (in != NULL) {
21052         if (*inOutSz < x509->serialSz) {
21053             WOLFSSL_MSG("Serial buffer too small");
21054             return BUFFER_E;
21055         }
21056         XMEMCPY(in, x509->serial, x509->serialSz);
21057     }
21058     *inOutSz = x509->serialSz;
21059 
21060     return WOLFSSL_SUCCESS;
21061 }
21062 
21063 /* not an openssl compatibility function - getting for derCert */
wolfSSL_X509_get_der(WOLFSSL_X509 * x509,int * outSz)21064 const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
21065 {
21066     WOLFSSL_ENTER("wolfSSL_X509_get_der");
21067 
21068     if (x509 == NULL || x509->derCert == NULL || outSz == NULL)
21069         return NULL;
21070 
21071     *outSz = (int)x509->derCert->length;
21072     return x509->derCert->buffer;
21073 }
21074 
21075 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_OUR_CERT || KEEP_PEER_CERT || SESSION_CERTS */
21076 
21077 #ifdef OPENSSL_EXTRA
21078 
21079 /* used by JSSE (not a standard compatibility function) */
21080 WOLFSSL_ABI
wolfSSL_X509_notBefore(WOLFSSL_X509 * x509)21081 const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
21082 {
21083     WOLFSSL_ENTER("wolfSSL_X509_notBefore");
21084 
21085     if (x509 == NULL)
21086         return NULL;
21087 
21088     XMEMSET(x509->notBeforeData, 0, sizeof(x509->notBeforeData));
21089     x509->notBeforeData[0] = (byte)x509->notBefore.type;
21090     x509->notBeforeData[1] = (byte)x509->notBefore.length;
21091     XMEMCPY(&x509->notBeforeData[2], x509->notBefore.data, x509->notBefore.length);
21092 
21093     return x509->notBeforeData;
21094 }
21095 
21096 /* used by JSSE (not a standard compatibility function) */
21097 WOLFSSL_ABI
wolfSSL_X509_notAfter(WOLFSSL_X509 * x509)21098 const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
21099 {
21100     WOLFSSL_ENTER("wolfSSL_X509_notAfter");
21101 
21102     if (x509 == NULL)
21103         return NULL;
21104 
21105     XMEMSET(x509->notAfterData, 0, sizeof(x509->notAfterData));
21106     x509->notAfterData[0] = (byte)x509->notAfter.type;
21107     x509->notAfterData[1] = (byte)x509->notAfter.length;
21108     XMEMCPY(&x509->notAfterData[2], x509->notAfter.data, x509->notAfter.length);
21109 
21110     return x509->notAfterData;
21111 }
21112 
21113 /* get the buffer to be signed (tbs) from the WOLFSSL_X509 certificate
21114     *
21115     * outSz : gets set to the size of the buffer
21116     * returns a pointer to the internal buffer at the location of TBS on
21117     *         on success and NULL on failure.
21118     */
wolfSSL_X509_get_tbs(WOLFSSL_X509 * x509,int * outSz)21119 const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509* x509, int* outSz)
21120 {
21121     int sz = 0, len;
21122     unsigned int idx = 0, tmpIdx;
21123     const unsigned char* der = NULL;
21124     const unsigned char* tbs = NULL;
21125 
21126     if (x509 == NULL || outSz == NULL) {
21127         return NULL;
21128     }
21129 
21130     der = wolfSSL_X509_get_der(x509, &sz);
21131     if (der == NULL) {
21132         return NULL;
21133     }
21134 
21135     if (GetSequence(der, &idx, &len, sz) < 0) {
21136         return NULL;
21137     }
21138     tbs = der + idx;
21139     tmpIdx = idx;
21140     if (GetSequence(der, &idx, &len, sz) < 0) {
21141         return NULL;
21142     }
21143     *outSz = len + (idx - tmpIdx);
21144     return tbs;
21145 }
21146 
wolfSSL_X509_version(WOLFSSL_X509 * x509)21147 int wolfSSL_X509_version(WOLFSSL_X509* x509)
21148 {
21149     WOLFSSL_ENTER("wolfSSL_X509_version");
21150 
21151     if (x509 == NULL)
21152         return 0;
21153 
21154     return x509->version;
21155 }
21156 
21157 #ifdef WOLFSSL_SEP
21158 
21159 /* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
21160    malloc buffer, call responsible for freeing. Actual size returned in
21161    *inOutSz. Requires inOutSz be non-null */
wolfSSL_X509_get_device_type(WOLFSSL_X509 * x509,byte * in,int * inOutSz)21162 byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
21163 {
21164     int copySz;
21165 
21166     WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
21167     if (inOutSz == NULL) return NULL;
21168     if (!x509->deviceTypeSz) return in;
21169 
21170     copySz = min(*inOutSz, x509->deviceTypeSz);
21171 
21172     if (!in) {
21173     #ifdef WOLFSSL_STATIC_MEMORY
21174         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
21175         return NULL;
21176     #else
21177         in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
21178         if (!in) return in;
21179         copySz = x509->deviceTypeSz;
21180     #endif
21181     }
21182 
21183     XMEMCPY(in, x509->deviceType, copySz);
21184     *inOutSz = copySz;
21185 
21186     return in;
21187 }
21188 
21189 
wolfSSL_X509_get_hw_type(WOLFSSL_X509 * x509,byte * in,int * inOutSz)21190 byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
21191 {
21192     int copySz;
21193 
21194     WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
21195     if (inOutSz == NULL) return NULL;
21196     if (!x509->hwTypeSz) return in;
21197 
21198     copySz = min(*inOutSz, x509->hwTypeSz);
21199 
21200     if (!in) {
21201     #ifdef WOLFSSL_STATIC_MEMORY
21202         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
21203         return NULL;
21204     #else
21205         in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
21206         if (!in) return in;
21207         copySz = x509->hwTypeSz;
21208     #endif
21209     }
21210 
21211     XMEMCPY(in, x509->hwType, copySz);
21212     *inOutSz = copySz;
21213 
21214     return in;
21215 }
21216 
21217 
wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509 * x509,byte * in,int * inOutSz)21218 byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
21219                                         int* inOutSz)
21220 {
21221     int copySz;
21222 
21223     WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
21224     if (inOutSz == NULL) return NULL;
21225     if (!x509->hwTypeSz) return in;
21226 
21227     copySz = min(*inOutSz, x509->hwSerialNumSz);
21228 
21229     if (!in) {
21230     #ifdef WOLFSSL_STATIC_MEMORY
21231         WOLFSSL_MSG("Using static memory -- please pass in a buffer");
21232         return NULL;
21233     #else
21234         in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
21235         if (!in) return in;
21236         copySz = x509->hwSerialNumSz;
21237     #endif
21238     }
21239 
21240     XMEMCPY(in, x509->hwSerialNum, copySz);
21241     *inOutSz = copySz;
21242 
21243     return in;
21244 }
21245 
21246 #endif /* WOLFSSL_SEP */
21247 #endif /* OPENSSL_EXTRA */
21248 
21249 /* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */
21250 #if !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
21251 
wolfSSL_X509_get_notBefore(const WOLFSSL_X509 * x509)21252 WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509)
21253 {
21254     WOLFSSL_ENTER("wolfSSL_X509_get_notBefore");
21255 
21256     if (x509 == NULL)
21257         return NULL;
21258 
21259     return (WOLFSSL_ASN1_TIME*)&x509->notBefore;
21260 }
21261 
21262 
wolfSSL_X509_get_notAfter(const WOLFSSL_X509 * x509)21263 WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509)
21264 {
21265     WOLFSSL_ENTER("wolfSSL_X509_get_notAfter");
21266 
21267     if (x509 == NULL)
21268         return NULL;
21269 
21270     return (WOLFSSL_ASN1_TIME*)&x509->notAfter;
21271 }
21272 
21273 
21274 /* return 1 on success 0 on fail */
wolfSSL_sk_X509_push(WOLF_STACK_OF (WOLFSSL_X509_NAME)* sk,WOLFSSL_X509 * x509)21275 int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509)
21276 {
21277     WOLFSSL_ENTER("wolfSSL_sk_X509_push");
21278 
21279     if (sk == NULL || x509 == NULL) {
21280         return WOLFSSL_FAILURE;
21281     }
21282 
21283     return wolfSSL_sk_push(sk, x509);
21284 }
21285 
21286 
wolfSSL_sk_X509_pop(WOLF_STACK_OF (WOLFSSL_X509_NAME)* sk)21287 WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) {
21288     WOLFSSL_STACK* node;
21289     WOLFSSL_X509*  x509;
21290 
21291     if (sk == NULL) {
21292         return NULL;
21293     }
21294 
21295     node = sk->next;
21296     x509 = sk->data.x509;
21297 
21298     if (node != NULL) { /* update sk and remove node from stack */
21299         sk->data.x509 = node->data.x509;
21300         sk->next = node->next;
21301         XFREE(node, NULL, DYNAMIC_TYPE_X509);
21302     }
21303     else { /* last x509 in stack */
21304         sk->data.x509 = NULL;
21305     }
21306 
21307     if (sk->num > 0) {
21308         sk->num -= 1;
21309     }
21310 
21311     return x509;
21312 }
21313 
21314 /* Getter function for WOLFSSL_X509 pointer
21315  *
21316  * sk is the stack to retrieve pointer from
21317  * i  is the index value in stack
21318  *
21319  * returns a pointer to a WOLFSSL_X509 structure on success and NULL on
21320  *         fail
21321  */
wolfSSL_sk_X509_value(STACK_OF (WOLFSSL_X509)* sk,int i)21322 WOLFSSL_X509* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i)
21323 {
21324     WOLFSSL_ENTER("wolfSSL_sk_X509_value");
21325 
21326     for (; sk != NULL && i > 0; i--)
21327         sk = sk->next;
21328 
21329     if (i != 0 || sk == NULL)
21330         return NULL;
21331     return sk->data.x509;
21332 }
21333 
wolfSSL_sk_X509_shift(WOLF_STACK_OF (WOLFSSL_X509)* sk)21334 WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk)
21335 {
21336     return wolfSSL_sk_X509_pop(sk);
21337 }
21338 
21339 #endif /* !NO_CERTS && OPENSSL_EXTRA */
21340 
21341 #if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
21342 /* Free's all nodes in X509 stack. This is different then wolfSSL_sk_X509_free
21343  * in that it free's the underlying objects pushed to the stack.
21344  *
21345  * sk  stack to free nodes in
21346  * f   X509 free function
21347  */
wolfSSL_sk_X509_pop_free(STACK_OF (WOLFSSL_X509)* sk,void (* f)(WOLFSSL_X509 *))21348 void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk,
21349     void (*f) (WOLFSSL_X509*))
21350 {
21351     WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free");
21352     wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
21353 }
21354 
21355 
21356 /* free just the stack structure */
wolfSSL_sk_X509_free(WOLF_STACK_OF (WOLFSSL_X509)* sk)21357 void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk)
21358 {
21359     wolfSSL_sk_free(sk);
21360 }
21361 
21362 #ifdef HAVE_CRL
wolfSSL_sk_X509_CRL_new(void)21363 WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new(void)
21364 {
21365     WOLFSSL_STACK* s = wolfSSL_sk_new_node(NULL);
21366     if (s != NULL)
21367         s->type = STACK_TYPE_X509_CRL;
21368     return s;
21369 }
21370 
wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF (WOLFSSL_X509_CRL)* sk,void (* f)(WOLFSSL_X509_CRL *))21371 void wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
21372     void (*f) (WOLFSSL_X509_CRL*))
21373 {
21374     WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_pop_free");
21375     wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
21376 }
21377 
wolfSSL_sk_X509_CRL_free(WOLF_STACK_OF (WOLFSSL_X509_CRL)* sk)21378 void wolfSSL_sk_X509_CRL_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk)
21379 {
21380     wolfSSL_sk_X509_CRL_pop_free(sk, NULL);
21381 }
21382 
21383 /* return 1 on success 0 on fail */
wolfSSL_sk_X509_CRL_push(WOLF_STACK_OF (WOLFSSL_X509_CRL)* sk,WOLFSSL_X509_CRL * crl)21384 int wolfSSL_sk_X509_CRL_push(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk, WOLFSSL_X509_CRL* crl)
21385 {
21386     WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_push");
21387 
21388     if (sk == NULL || crl == NULL) {
21389         return WOLFSSL_FAILURE;
21390     }
21391 
21392     return wolfSSL_sk_push(sk, crl);
21393 }
21394 
wolfSSL_sk_X509_CRL_value(WOLF_STACK_OF (WOLFSSL_X509)* sk,int i)21395 WOLFSSL_X509_CRL* wolfSSL_sk_X509_CRL_value(WOLF_STACK_OF(WOLFSSL_X509)* sk,
21396                                             int i)
21397 {
21398     WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_value");
21399     if (sk)
21400         return (WOLFSSL_X509_CRL*)wolfSSL_sk_value(sk, i);
21401     return NULL;
21402 }
21403 
wolfSSL_sk_X509_CRL_num(WOLF_STACK_OF (WOLFSSL_X509)* sk)21404 int wolfSSL_sk_X509_CRL_num(WOLF_STACK_OF(WOLFSSL_X509)* sk)
21405 {
21406     WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_num");
21407     if (sk)
21408         return wolfSSL_sk_num(sk);
21409     return 0;
21410 }
21411 #endif /* HAVE_CRL */
21412 
21413 #endif /* !NO_CERTS && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
21414 
21415 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
21416 /* return 1 on success 0 on fail */
wolfSSL_sk_ACCESS_DESCRIPTION_push(WOLF_STACK_OF (ACCESS_DESCRIPTION)* sk,WOLFSSL_ACCESS_DESCRIPTION * access)21417 int wolfSSL_sk_ACCESS_DESCRIPTION_push(WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk,
21418                                               WOLFSSL_ACCESS_DESCRIPTION* access)
21419 {
21420     WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_push");
21421 
21422     return wolfSSL_sk_push(sk, access);
21423 }
21424 
21425 /* Frees all nodes in ACCESS_DESCRIPTION stack
21426 *
21427 * sk stack of nodes to free
21428 * f  free function to use
21429 */
wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK * sk,void (* f)(WOLFSSL_ACCESS_DESCRIPTION *))21430 void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk,
21431     void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
21432 {
21433    WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_pop_free");
21434    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
21435 }
21436 
wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK * sk)21437 void wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK* sk)
21438 {
21439     wolfSSL_sk_free(sk);
21440 }
21441 
21442 
21443 /* AUTHORITY_INFO_ACCESS object is a stack of ACCESS_DESCRIPTION objects,
21444  * to free the stack the WOLFSSL_ACCESS_DESCRIPTION stack free function is
21445  * used */
wolfSSL_AUTHORITY_INFO_ACCESS_free(WOLF_STACK_OF (WOLFSSL_ACCESS_DESCRIPTION)* sk)21446 void wolfSSL_AUTHORITY_INFO_ACCESS_free(
21447         WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk)
21448 {
21449     WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
21450     wolfSSL_sk_ACCESS_DESCRIPTION_free(sk);
21451 }
21452 
wolfSSL_AUTHORITY_INFO_ACCESS_pop_free(WOLF_STACK_OF (WOLFSSL_ACCESS_DESCRIPTION)* sk,void (* f)(WOLFSSL_ACCESS_DESCRIPTION *))21453 void wolfSSL_AUTHORITY_INFO_ACCESS_pop_free(
21454         WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk,
21455         void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
21456 {
21457     WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
21458     wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk, f);
21459 }
21460 
21461 
wolfSSL_ACCESS_DESCRIPTION_free(WOLFSSL_ACCESS_DESCRIPTION * access)21462 void wolfSSL_ACCESS_DESCRIPTION_free(WOLFSSL_ACCESS_DESCRIPTION* access)
21463 {
21464     WOLFSSL_ENTER("wolfSSL_ACCESS_DESCRIPTION_free");
21465     if (access == NULL)
21466         return;
21467 
21468     if (access->method)
21469         wolfSSL_ASN1_OBJECT_free(access->method);
21470     if (access->location)
21471         wolfSSL_GENERAL_NAME_free(access->location);
21472     XFREE(access, NULL, DYNAMIC_TYPE_X509_EXT);
21473 
21474     /* access = NULL, don't try to access or double free it */
21475 }
21476 #endif /* OPENSSL_ALL || WOLFSSL_QT */
21477 
21478 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
21479 
21480 /* create a generic wolfSSL stack node
21481  * returns a new WOLFSSL_STACK structure on success */
wolfSSL_sk_new_node(void * heap)21482 WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap)
21483 {
21484     WOLFSSL_STACK* sk;
21485     WOLFSSL_ENTER("wolfSSL_sk_new_node");
21486 
21487     sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), heap,
21488                                                           DYNAMIC_TYPE_OPENSSL);
21489     if (sk != NULL) {
21490         XMEMSET(sk, 0, sizeof(*sk));
21491         sk->heap = heap;
21492     }
21493 
21494     return sk;
21495 }
21496 
21497 /* free's node but does not free internal data such as in->data.x509 */
wolfSSL_sk_free_node(WOLFSSL_STACK * in)21498 void wolfSSL_sk_free_node(WOLFSSL_STACK* in)
21499 {
21500     if (in != NULL) {
21501         XFREE(in, in->heap, DYNAMIC_TYPE_OPENSSL);
21502     }
21503 }
21504 
21505 /* pushes node "in" onto "stack" and returns pointer to the new stack on success
21506  * also handles internal "num" for number of nodes on stack
21507  * return WOLFSSL_SUCCESS on success
21508  */
wolfSSL_sk_push_node(WOLFSSL_STACK ** stack,WOLFSSL_STACK * in)21509 int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in)
21510 {
21511     if (stack == NULL || in == NULL) {
21512         return WOLFSSL_FAILURE;
21513     }
21514 
21515     if (*stack == NULL) {
21516         in->num = 1;
21517         *stack = in;
21518         return WOLFSSL_SUCCESS;
21519     }
21520 
21521     in->num  = (*stack)->num + 1;
21522     in->next = *stack;
21523     *stack   = in;
21524     return WOLFSSL_SUCCESS;
21525 }
21526 
21527 /* return 1 on success 0 on fail */
wolfSSL_sk_push(WOLFSSL_STACK * sk,const void * data)21528 int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data)
21529 {
21530     WOLFSSL_STACK* node;
21531 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
21532     WOLFSSL_CIPHER ciph;
21533 #endif
21534     WOLFSSL_ENTER("wolfSSL_sk_push");
21535 
21536     if (!sk) {
21537         return WOLFSSL_FAILURE;
21538     }
21539 
21540     /* Check if empty data */
21541     switch (sk->type) {
21542         case STACK_TYPE_CIPHER:
21543 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
21544             /* check if entire struct is zero */
21545             XMEMSET(&ciph, 0, sizeof(WOLFSSL_CIPHER));
21546             if (XMEMCMP(&sk->data.cipher, &ciph,
21547                     sizeof(WOLFSSL_CIPHER)) == 0) {
21548                 sk->data.cipher = *(WOLFSSL_CIPHER*)data;
21549                 sk->num = 1;
21550                 if (sk->hash_fn) {
21551                     sk->hash = sk->hash_fn(&sk->data.cipher);
21552                 }
21553                 return WOLFSSL_SUCCESS;
21554             }
21555             break;
21556 #endif
21557         case STACK_TYPE_X509:
21558         case STACK_TYPE_GEN_NAME:
21559         case STACK_TYPE_BIO:
21560         case STACK_TYPE_OBJ:
21561         case STACK_TYPE_STRING:
21562         case STACK_TYPE_ACCESS_DESCRIPTION:
21563         case STACK_TYPE_X509_EXT:
21564         case STACK_TYPE_NULL:
21565         case STACK_TYPE_X509_NAME:
21566         case STACK_TYPE_CONF_VALUE:
21567         case STACK_TYPE_X509_INFO:
21568         case STACK_TYPE_BY_DIR_entry:
21569         case STACK_TYPE_BY_DIR_hash:
21570         case STACK_TYPE_X509_OBJ:
21571         case STACK_TYPE_DIST_POINT:
21572         case STACK_TYPE_X509_CRL:
21573         default:
21574             /* All other types are pointers */
21575             if (!sk->data.generic) {
21576                 sk->data.generic = (void*)data;
21577                 sk->num = 1;
21578 #ifdef OPENSSL_ALL
21579                 if (sk->hash_fn) {
21580                     sk->hash = sk->hash_fn(sk->data.generic);
21581                 }
21582 #endif
21583                 return WOLFSSL_SUCCESS;
21584             }
21585             break;
21586     }
21587 
21588     /* stack already has value(s) create a new node and add more */
21589     node = wolfSSL_sk_new_node(sk->heap);
21590     if (!node) {
21591         WOLFSSL_MSG("Memory error");
21592         return WOLFSSL_FAILURE;
21593     }
21594 
21595     /* push new x509 onto head of stack */
21596     node->next      = sk->next;
21597     node->type      = sk->type;
21598     sk->next        = node;
21599     sk->num        += 1;
21600 
21601 #ifdef OPENSSL_ALL
21602     node->comp = sk->comp;
21603     node->hash_fn = sk->hash_fn;
21604     node->hash = sk->hash;
21605     sk->hash = 0;
21606 #endif
21607     switch (sk->type) {
21608         case STACK_TYPE_CIPHER:
21609 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
21610             node->data.cipher = sk->data.cipher;
21611             sk->data.cipher = *(WOLFSSL_CIPHER*)data;
21612             if (sk->hash_fn) {
21613                 sk->hash = sk->hash_fn(&sk->data.cipher);
21614             }
21615             break;
21616 #endif
21617         case STACK_TYPE_X509:
21618         case STACK_TYPE_GEN_NAME:
21619         case STACK_TYPE_BIO:
21620         case STACK_TYPE_OBJ:
21621         case STACK_TYPE_STRING:
21622         case STACK_TYPE_ACCESS_DESCRIPTION:
21623         case STACK_TYPE_X509_EXT:
21624         case STACK_TYPE_NULL:
21625         case STACK_TYPE_X509_NAME:
21626         case STACK_TYPE_CONF_VALUE:
21627         case STACK_TYPE_X509_INFO:
21628         case STACK_TYPE_BY_DIR_entry:
21629         case STACK_TYPE_BY_DIR_hash:
21630         case STACK_TYPE_X509_OBJ:
21631         case STACK_TYPE_DIST_POINT:
21632         case STACK_TYPE_X509_CRL:
21633         default:
21634             /* All other types are pointers */
21635             node->data.generic = sk->data.generic;
21636             sk->data.generic = (void*)data;
21637 #ifdef OPENSSL_ALL
21638             if (sk->hash_fn) {
21639                 sk->hash = sk->hash_fn(sk->data.generic);
21640             }
21641 #endif
21642             break;
21643     }
21644 
21645     return WOLFSSL_SUCCESS;
21646 }
21647 
21648 /* Creates and returns new GENERAL_NAME structure */
wolfSSL_GENERAL_NAME_new(void)21649 WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void)
21650 {
21651     WOLFSSL_GENERAL_NAME* gn;
21652     WOLFSSL_ENTER("GENERAL_NAME_new");
21653 
21654     gn = (WOLFSSL_GENERAL_NAME*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAME), NULL,
21655                                                              DYNAMIC_TYPE_ASN1);
21656     if (gn == NULL) {
21657         return NULL;
21658     }
21659     XMEMSET(gn, 0, sizeof(WOLFSSL_GENERAL_NAME));
21660 
21661     gn->d.ia5 = wolfSSL_ASN1_STRING_new();
21662     if (gn->d.ia5 == NULL) {
21663         WOLFSSL_MSG("Issue creating ASN1_STRING struct");
21664         wolfSSL_GENERAL_NAME_free(gn);
21665         return NULL;
21666     }
21667     return gn;
21668 }
21669 
wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME * gn)21670 static WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME* gn)
21671 {
21672     WOLFSSL_GENERAL_NAME* dupl = NULL;
21673 
21674     WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_dup");
21675 
21676     if (!gn) {
21677         WOLFSSL_MSG("Bad parameter");
21678         return NULL;
21679     }
21680 
21681     if (!(dupl = wolfSSL_GENERAL_NAME_new())) {
21682         WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
21683         return NULL;
21684     }
21685 
21686     switch (gn->type) {
21687     /* WOLFSSL_ASN1_STRING types */
21688     case GEN_DNS:
21689         if (!(dupl->d.dNSName = wolfSSL_ASN1_STRING_dup(gn->d.dNSName))) {
21690             WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
21691             goto error;
21692         }
21693         break;
21694     case GEN_IPADD:
21695         if (!(dupl->d.iPAddress = wolfSSL_ASN1_STRING_dup(gn->d.iPAddress))) {
21696             WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
21697             goto error;
21698         }
21699         break;
21700     case GEN_EMAIL:
21701         if (!(dupl->d.rfc822Name = wolfSSL_ASN1_STRING_dup(gn->d.rfc822Name))) {
21702             WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
21703             goto error;
21704         }
21705         break;
21706     case GEN_URI:
21707         if (!(dupl->d.uniformResourceIdentifier =
21708                 wolfSSL_ASN1_STRING_dup(gn->d.uniformResourceIdentifier))) {
21709             WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
21710             goto error;
21711         }
21712         break;
21713     case GEN_OTHERNAME:
21714     case GEN_X400:
21715     case GEN_DIRNAME:
21716     case GEN_EDIPARTY:
21717     case GEN_RID:
21718     default:
21719         WOLFSSL_MSG("Unrecognized or unsupported GENERAL_NAME type");
21720         goto error;
21721     }
21722 
21723     return dupl;
21724 error:
21725     if (dupl) {
21726         wolfSSL_GENERAL_NAME_free(dupl);
21727     }
21728     return NULL;
21729 }
21730 
21731 
21732 /* return 1 on success 0 on fail */
wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES * sk,WOLFSSL_GENERAL_NAME * gn)21733 int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk,
21734                                  WOLFSSL_GENERAL_NAME* gn)
21735 {
21736     WOLFSSL_STACK* node;
21737     WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_push");
21738 
21739     if (sk == NULL || gn == NULL) {
21740         return WOLFSSL_FAILURE;
21741     }
21742 
21743     /* no previous values in stack */
21744     if (sk->data.gn == NULL) {
21745         sk->data.gn = gn;
21746         sk->num += 1;
21747 
21748         return WOLFSSL_SUCCESS;
21749     }
21750 
21751     /* stack already has value(s) create a new node and add more */
21752     node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
21753                                                              DYNAMIC_TYPE_ASN1);
21754     if (node == NULL) {
21755         WOLFSSL_MSG("Memory error");
21756         return WOLFSSL_FAILURE;
21757     }
21758     XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
21759 
21760     /* push new obj onto head of stack */
21761     node->data.gn = sk->data.gn;
21762     node->next    = sk->next;
21763     sk->next      = node;
21764     sk->data.gn   = gn;
21765     sk->num      += 1;
21766 
21767     return WOLFSSL_SUCCESS;
21768 }
21769 
21770 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
21771 
21772 #ifdef OPENSSL_EXTRA
21773 
21774 /* Returns the general name at index i from the stack
21775  *
21776  * sk  stack to get general name from
21777  * idx index to get
21778  *
21779  * return a pointer to the internal node of the stack
21780  */
wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK * sk,int idx)21781 WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int idx)
21782 {
21783     WOLFSSL_STACK* ret;
21784 
21785     if (sk == NULL) {
21786         return NULL;
21787     }
21788 
21789     ret = wolfSSL_sk_get_node(sk, idx);
21790     if (ret != NULL) {
21791         return ret->data.gn;
21792     }
21793     return NULL;
21794 }
21795 
21796 /* Gets the number of nodes in the stack
21797  *
21798  * sk  stack to get the number of nodes from
21799  *
21800  * returns the number of nodes, -1 if no nodes
21801  */
wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK * sk)21802 int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk)
21803 {
21804     WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_num");
21805 
21806     if (sk == NULL) {
21807         return -1;
21808     }
21809 
21810     return (int)sk->num;
21811 }
21812 
21813 #endif /* OPENSSL_EXTRA */
21814 
21815 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
21816 
21817 /* Frees all nodes in a GENERAL NAME stack
21818  *
21819  * sk stack of nodes to free
21820  * f  free function to use, not called with wolfSSL
21821  */
wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK * sk,void (* f)(WOLFSSL_GENERAL_NAME *))21822 void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk,
21823         void (*f) (WOLFSSL_GENERAL_NAME*))
21824 {
21825     WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_pop_free");
21826     wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
21827 }
21828 
wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK * sk)21829 void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk)
21830 {
21831     WOLFSSL_ENTER("sk_GENERAL_NAME_free");
21832     wolfSSL_sk_X509_pop_free(sk, NULL);
21833 }
21834 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
21835 
21836 #ifdef OPENSSL_EXTRA
21837 
wolfSSL_DIST_POINT_NAME_free(WOLFSSL_DIST_POINT_NAME * dpn)21838 static void wolfSSL_DIST_POINT_NAME_free(WOLFSSL_DIST_POINT_NAME* dpn)
21839 {
21840     if (dpn != NULL) {
21841         if (dpn->name.fullname != NULL) {
21842             wolfSSL_sk_X509_pop_free(dpn->name.fullname, NULL);
21843         }
21844         XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
21845     }
21846 }
21847 
21848 
21849 /* returns new pointer on success and NULL on fail */
wolfSSL_DIST_POINT_NAME_new(void)21850 static WOLFSSL_DIST_POINT_NAME* wolfSSL_DIST_POINT_NAME_new(void)
21851 {
21852     WOLFSSL_DIST_POINT_NAME* dpn = NULL;
21853     WOLFSSL_GENERAL_NAMES* gns = NULL;
21854 
21855     dpn = (WOLFSSL_DIST_POINT_NAME*)XMALLOC(sizeof(WOLFSSL_DIST_POINT_NAME),
21856                                             NULL, DYNAMIC_TYPE_OPENSSL);
21857     if (dpn == NULL) {
21858         return NULL;
21859     }
21860     XMEMSET(dpn, 0, sizeof(WOLFSSL_DIST_POINT_NAME));
21861 
21862     gns = wolfSSL_sk_new_null();
21863     if (gns == NULL) {
21864         WOLFSSL_MSG("wolfSSL_sk_new_null error");
21865         XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
21866         return NULL;
21867     }
21868     gns->type = STACK_TYPE_GEN_NAME;
21869 
21870     dpn->name.fullname = gns;
21871     dpn->type = CRL_DIST_OID;
21872 
21873     return dpn;
21874 }
21875 
21876 
21877 /* Creates and returns new DIST_POINT structure */
wolfSSL_DIST_POINT_new(void)21878 WOLFSSL_DIST_POINT* wolfSSL_DIST_POINT_new(void)
21879 {
21880     WOLFSSL_DIST_POINT* dp = NULL;
21881     WOLFSSL_DIST_POINT_NAME* dpn = NULL;
21882 
21883     WOLFSSL_ENTER("DIST_POINT_new");
21884 
21885     dp = (WOLFSSL_DIST_POINT*)XMALLOC(sizeof(WOLFSSL_DIST_POINT), NULL,
21886                                       DYNAMIC_TYPE_OPENSSL);
21887     if (dp == NULL) {
21888         return NULL;
21889     }
21890     XMEMSET(dp, 0, sizeof(WOLFSSL_DIST_POINT));
21891 
21892     dpn = wolfSSL_DIST_POINT_NAME_new();
21893     if (dpn == NULL) {
21894         XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
21895         return NULL;
21896     }
21897     dp->distpoint = dpn;
21898 
21899     return dp;
21900 }
21901 
21902 
21903 /* Frees DIST_POINT objects.
21904 */
wolfSSL_DIST_POINT_free(WOLFSSL_DIST_POINT * dp)21905 void wolfSSL_DIST_POINT_free(WOLFSSL_DIST_POINT* dp)
21906 {
21907     WOLFSSL_ENTER("wolfSSL_DIST_POINT_free");
21908     if (dp != NULL) {
21909         wolfSSL_DIST_POINT_NAME_free(dp->distpoint);
21910         XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
21911     }
21912 }
21913 
wolfSSL_DIST_POINTS_free(WOLFSSL_DIST_POINTS * dps)21914 void wolfSSL_DIST_POINTS_free(WOLFSSL_DIST_POINTS *dps)
21915 {
21916     WOLFSSL_ENTER("wolfSSL_DIST_POINTS_free");
21917 
21918     if (dps == NULL) {
21919         return;
21920     }
21921 
21922     wolfSSL_sk_free(dps);
21923 }
21924 
21925 /* return 1 on success 0 on fail */
wolfSSL_sk_DIST_POINT_push(WOLFSSL_DIST_POINTS * sk,WOLFSSL_DIST_POINT * dp)21926 int wolfSSL_sk_DIST_POINT_push(WOLFSSL_DIST_POINTS* sk, WOLFSSL_DIST_POINT* dp)
21927 {
21928     WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_push");
21929 
21930     if (sk == NULL || dp == NULL) {
21931         return WOLFSSL_FAILURE;
21932     }
21933 
21934     return wolfSSL_sk_push(sk, dp);
21935 }
21936 
21937 /* Returns the CRL dist point at index i from the stack
21938  *
21939  * sk  stack to get general name from
21940  * idx index to get
21941  *
21942  * return a pointer to the internal node of the stack
21943  */
wolfSSL_sk_DIST_POINT_value(WOLFSSL_STACK * sk,int idx)21944 WOLFSSL_DIST_POINT* wolfSSL_sk_DIST_POINT_value(WOLFSSL_STACK* sk, int idx)
21945 {
21946     if (sk == NULL) {
21947         return NULL;
21948     }
21949 
21950     return (WOLFSSL_DIST_POINT*)wolfSSL_sk_value(sk, idx);
21951 }
21952 
21953 /* Gets the number of nodes in the stack
21954  *
21955  * sk  stack to get the number of nodes from
21956  *
21957  * returns the number of nodes, -1 if no nodes
21958  */
wolfSSL_sk_DIST_POINT_num(WOLFSSL_STACK * sk)21959 int wolfSSL_sk_DIST_POINT_num(WOLFSSL_STACK* sk)
21960 {
21961     WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_num");
21962 
21963     if (sk == NULL) {
21964         return -1;
21965     }
21966 
21967     return wolfSSL_sk_num(sk);
21968 }
21969 
21970 /* Frees all nodes in a DIST_POINT stack
21971  *
21972  * sk stack of nodes to free
21973  * f  free function to use
21974  */
wolfSSL_sk_DIST_POINT_pop_free(WOLFSSL_STACK * sk,void (* f)(WOLFSSL_DIST_POINT *))21975 void wolfSSL_sk_DIST_POINT_pop_free(WOLFSSL_STACK* sk,
21976         void (*f) (WOLFSSL_DIST_POINT*))
21977 {
21978     WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_pop_free");
21979     wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
21980 }
21981 
wolfSSL_sk_DIST_POINT_free(WOLFSSL_STACK * sk)21982 void wolfSSL_sk_DIST_POINT_free(WOLFSSL_STACK* sk)
21983 {
21984     WOLFSSL_ENTER("sk_DIST_POINT_free");
21985     wolfSSL_sk_free(sk);
21986 }
21987 
21988 /* returns the number of nodes in stack on success and WOLFSSL_FATAL_ERROR
21989  * on fail */
wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK * sk)21990 int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk)
21991 {
21992     if (sk == NULL) {
21993         return WOLFSSL_FATAL_ERROR;
21994     }
21995 
21996     return (int)sk->num;
21997 }
21998 
21999 
22000 /* returns the node at index "idx", NULL if not found */
wolfSSL_sk_get_node(WOLFSSL_STACK * sk,int idx)22001 WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx)
22002 {
22003     int i;
22004     WOLFSSL_STACK* ret = NULL;
22005     WOLFSSL_STACK* current;
22006 
22007     current = sk;
22008     for (i = 0; i <= idx && current != NULL; i++) {
22009         if (i == idx) {
22010             ret = current;
22011             break;
22012         }
22013         current = current->next;
22014     }
22015     return ret;
22016 }
22017 
22018 /* returns NULL on fail and pointer to internal data on success */
wolfSSL_sk_ACCESS_DESCRIPTION_value(WOLFSSL_STACK * sk,int idx)22019 WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value(
22020         WOLFSSL_STACK* sk, int idx)
22021 {
22022     WOLFSSL_STACK* ret;
22023 
22024     if (sk == NULL) {
22025         return NULL;
22026     }
22027 
22028     ret = wolfSSL_sk_get_node(sk, idx);
22029     if (ret != NULL) {
22030         return ret->data.access;
22031     }
22032     return NULL;
22033 }
22034 #endif /* OPENSSL_EXTRA */
22035 
22036 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
22037 /* free's the internal type for the general name */
wolfSSL_GENERAL_NAME_type_free(WOLFSSL_GENERAL_NAME * name)22038 static void wolfSSL_GENERAL_NAME_type_free(WOLFSSL_GENERAL_NAME* name)
22039 {
22040     if (name != NULL) {
22041         if (name->d.dNSName != NULL) {
22042             wolfSSL_ASN1_STRING_free(name->d.dNSName);
22043             name->d.dNSName = NULL;
22044         }
22045         if (name->d.dirn != NULL) {
22046             wolfSSL_X509_NAME_free(name->d.dirn);
22047             name->d.dirn = NULL;
22048         }
22049         if (name->d.uniformResourceIdentifier != NULL) {
22050             wolfSSL_ASN1_STRING_free(name->d.uniformResourceIdentifier);
22051             name->d.uniformResourceIdentifier = NULL;
22052         }
22053         if (name->d.iPAddress != NULL) {
22054             wolfSSL_ASN1_STRING_free(name->d.iPAddress);
22055             name->d.iPAddress = NULL;
22056         }
22057         if (name->d.registeredID != NULL) {
22058             wolfSSL_ASN1_OBJECT_free(name->d.registeredID);
22059             name->d.registeredID = NULL;
22060         }
22061         if (name->d.ia5 != NULL) {
22062             wolfSSL_ASN1_STRING_free(name->d.ia5);
22063             name->d.ia5 = NULL;
22064         }
22065     }
22066 }
22067 
22068 
22069 /* sets the general name type and free's the existing one
22070  * can fail with a memory error if malloc fails or bad arg error
22071  * otherwise return WOLFSSL_SUCCESS */
wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME * name,int typ)22072 int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name, int typ)
22073 {
22074     int ret = WOLFSSL_SUCCESS;
22075 
22076     if (name != NULL) {
22077         wolfSSL_GENERAL_NAME_type_free(name);
22078         name->type = typ;
22079 
22080         switch (typ) {
22081             case GEN_URI:
22082                 name->d.uniformResourceIdentifier = wolfSSL_ASN1_STRING_new();
22083                 if (name->d.uniformResourceIdentifier == NULL)
22084                     ret = MEMORY_E;
22085                 break;
22086             default:
22087                 name->d.ia5 = wolfSSL_ASN1_STRING_new();
22088                 if (name->d.ia5 == NULL)
22089                     ret = MEMORY_E;
22090         }
22091     }
22092     else {
22093         ret = BAD_FUNC_ARG;
22094     }
22095 
22096     return ret;
22097 }
22098 
22099 
22100 /* Frees GENERAL_NAME objects.
22101 */
wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME * name)22102 void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name)
22103 {
22104     WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_Free");
22105     if (name != NULL) {
22106         wolfSSL_GENERAL_NAME_type_free(name);
22107         XFREE(name, NULL, DYNAMIC_TYPE_OPENSSL);
22108     }
22109 }
22110 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
22111 
22112 #ifdef OPENSSL_EXTRA
wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES * gens)22113 void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens)
22114 {
22115     WOLFSSL_ENTER("wolfSSL_GENERAL_NAMES_free");
22116 
22117     if (gens == NULL) {
22118         return;
22119     }
22120 
22121     wolfSSL_sk_free(gens);
22122 }
22123 
22124 #if defined(OPENSSL_ALL) && !defined(NO_BIO)
22125 /* Outputs name string of the given WOLFSSL_GENERAL_NAME_OBJECT to WOLFSSL_BIO.
22126  * Can handle following GENERAL_NAME_OBJECT types:
22127  *  - GEN_OTHERNAME #
22128  *  - GEN_EMAIL
22129  *  - GEN_DNS
22130  *  - GEN_X400  #
22131  *  - GEN_DIRNAME
22132  *  - GEN_EDIPARTY #
22133  *  - GEN_URI
22134  *  - GEN_RID
22135  * The each name string to be output has "typename:namestring" format.
22136  * For instance, email name string will be output as "email:info@wolfssl.com".
22137  * However,some types above marked with "#" will be output with
22138  * "typename:<unsupported>".
22139  *
22140  * Parameters:
22141  *  - out: WOLFSSL_BIO object which is the output destination
22142  *  - gen: WOLFSSL_GENERAL_NAME object to be output its name
22143  *
22144  * Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure.
22145  */
wolfSSL_GENERAL_NAME_print(WOLFSSL_BIO * out,WOLFSSL_GENERAL_NAME * gen)22146 int wolfSSL_GENERAL_NAME_print(WOLFSSL_BIO* out, WOLFSSL_GENERAL_NAME* gen)
22147 {
22148     int ret, i;
22149     unsigned int wd;
22150     unsigned char* p;
22151     (void)wd;
22152     (void)p;
22153     (void)i;
22154     WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_print");
22155 
22156     if (out == NULL || gen == NULL)
22157         return WOLFSSL_FAILURE;
22158 
22159     ret = WOLFSSL_FAILURE;
22160     switch (gen->type)
22161     {
22162     case GEN_OTHERNAME:
22163         ret = wolfSSL_BIO_printf(out, "othername:<unsupported>");
22164         ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
22165         break;
22166 
22167     case GEN_EMAIL:
22168         ret = wolfSSL_BIO_printf(out, "email:");
22169         ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
22170         if (ret == WOLFSSL_SUCCESS)
22171         {
22172             ret = wolfSSL_ASN1_STRING_print(out, gen->d.rfc822Name);
22173         }
22174         break;
22175 
22176     case GEN_DNS:
22177         ret = wolfSSL_BIO_printf(out, "DNS:");
22178         ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
22179         if (ret == WOLFSSL_SUCCESS) {
22180             ret = wolfSSL_BIO_printf(out, gen->d.dNSName->strData);
22181             ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
22182         }
22183         break;
22184 
22185     case GEN_X400:
22186         ret = wolfSSL_BIO_printf(out, "X400Name:<unsupported>");
22187         ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
22188         break;
22189 
22190     case GEN_DIRNAME:
22191         ret = wolfSSL_BIO_printf(out, "DirName:");
22192         if (ret == WOLFSSL_SUCCESS) {
22193             ret = wolfSSL_X509_NAME_print_ex(out, gen->d.directoryName, 0,
22194                                                          XN_FLAG_ONELINE);
22195         }
22196         break;
22197 
22198     case GEN_EDIPARTY:
22199         ret = wolfSSL_BIO_printf(out, "EdiPartyName:<unsupported>");
22200         ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
22201         break;
22202 
22203     case GEN_URI:
22204         ret = wolfSSL_BIO_printf(out, "URI:");
22205         ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
22206         if (ret == WOLFSSL_SUCCESS) {
22207             ret = wolfSSL_ASN1_STRING_print(out,
22208                                     gen->d.uniformResourceIdentifier);
22209         }
22210         break;
22211 
22212     case GEN_IPADD:
22213         ret = wolfSSL_BIO_printf(out, "IP Address");
22214         ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
22215         if (ret == WOLFSSL_SUCCESS) {
22216 
22217             if (!gen->d.iPAddress->length) {
22218                 ret = WOLFSSL_FAILURE;
22219                 break;
22220             }
22221             p = (unsigned char*)gen->d.iPAddress->strData;
22222 
22223             if (gen->d.iPAddress->length == 4) {
22224                 ret = wolfSSL_BIO_printf(out, ":%d.%d.%d.%d",
22225                                   p[0],p[1],p[2],p[3]);
22226             }
22227             else if (gen->d.iPAddress->length == 16) {
22228 
22229                 for (i = 0; i < 16 && ret == WOLFSSL_SUCCESS;) {
22230                     wd = p[i] << 8 | p[i+1];
22231 
22232                     i += 2;
22233                     ret = wolfSSL_BIO_printf(out, ":%X", wd);
22234                     ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
22235                 }
22236             }
22237             else {
22238                 ret = wolfSSL_BIO_printf(out, "<unsupported>");
22239             }
22240             ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
22241         }
22242         break;
22243 
22244     case GEN_RID:
22245         ret = wolfSSL_BIO_printf(out, "Registered ID:");
22246         if (ret == WOLFSSL_SUCCESS) {
22247             ret = wolfSSL_i2a_ASN1_OBJECT(out, gen->d.registeredID);
22248         }
22249         break;
22250 
22251     default:
22252         /* unsupported type */
22253         break;
22254     }
22255 
22256     if (ret == WOLFSSL_FAILURE)
22257         return WOLFSSL_FAILURE;
22258     else
22259         return WOLFSSL_SUCCESS;
22260 }
22261 #endif /* OPENSSL_ALL */
22262 
22263 #if defined(OPENSSL_ALL)
22264 
wolfSSL_lh_retrieve(WOLFSSL_STACK * sk,void * data)22265 void *wolfSSL_lh_retrieve(WOLFSSL_STACK *sk, void *data)
22266 {
22267     unsigned long hash;
22268 
22269     WOLFSSL_ENTER("wolfSSL_lh_retrieve");
22270 
22271     if (!sk || !data) {
22272         WOLFSSL_MSG("Bad parameters");
22273         return NULL;
22274     }
22275 
22276     if (!sk->hash_fn) {
22277         WOLFSSL_MSG("No hash function defined");
22278         return NULL;
22279     }
22280 
22281     hash = sk->hash_fn(data);
22282 
22283     while (sk) {
22284         /* Calc hash if not done so yet */
22285         if (!sk->hash) {
22286             switch (sk->type) {
22287                 case STACK_TYPE_CIPHER:
22288                     sk->hash = sk->hash_fn(&sk->data.cipher);
22289                     break;
22290                 case STACK_TYPE_X509:
22291                 case STACK_TYPE_GEN_NAME:
22292                 case STACK_TYPE_BIO:
22293                 case STACK_TYPE_OBJ:
22294                 case STACK_TYPE_STRING:
22295                 case STACK_TYPE_ACCESS_DESCRIPTION:
22296                 case STACK_TYPE_X509_EXT:
22297                 case STACK_TYPE_NULL:
22298                 case STACK_TYPE_X509_NAME:
22299                 case STACK_TYPE_CONF_VALUE:
22300                 case STACK_TYPE_X509_INFO:
22301                 case STACK_TYPE_BY_DIR_entry:
22302                 case STACK_TYPE_BY_DIR_hash:
22303                 case STACK_TYPE_X509_OBJ:
22304                 case STACK_TYPE_DIST_POINT:
22305                 case STACK_TYPE_X509_CRL:
22306                 default:
22307                     sk->hash = sk->hash_fn(sk->data.generic);
22308                     break;
22309             }
22310         }
22311         if (sk->hash == hash) {
22312             switch (sk->type) {
22313                 case STACK_TYPE_CIPHER:
22314                     return &sk->data.cipher;
22315                 case STACK_TYPE_X509:
22316                 case STACK_TYPE_GEN_NAME:
22317                 case STACK_TYPE_BIO:
22318                 case STACK_TYPE_OBJ:
22319                 case STACK_TYPE_STRING:
22320                 case STACK_TYPE_ACCESS_DESCRIPTION:
22321                 case STACK_TYPE_X509_EXT:
22322                 case STACK_TYPE_NULL:
22323                 case STACK_TYPE_X509_NAME:
22324                 case STACK_TYPE_CONF_VALUE:
22325                 case STACK_TYPE_X509_INFO:
22326                 case STACK_TYPE_BY_DIR_entry:
22327                 case STACK_TYPE_BY_DIR_hash:
22328                 case STACK_TYPE_X509_OBJ:
22329                 case STACK_TYPE_DIST_POINT:
22330                 case STACK_TYPE_X509_CRL:
22331                 default:
22332                     return sk->data.generic;
22333             }
22334         }
22335         sk = sk->next;
22336     }
22337 
22338     return NULL;
22339 }
22340 
WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)22341 WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void)
22342 {
22343     WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
22344     if (sk) {
22345         sk->type = STACK_TYPE_X509_EXT;
22346     }
22347 
22348     return (WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)*)sk;;
22349 }
22350 
22351 /* returns the number of nodes on the stack */
wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF (WOLFSSL_X509_EXTENSION)* sk)22352 int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
22353 {
22354     if (sk != NULL) {
22355         return (int)sk->num;
22356     }
22357     return WOLFSSL_FATAL_ERROR;
22358 }
22359 
22360 
22361 /* returns null on failure and pointer to internal value on success */
wolfSSL_sk_X509_EXTENSION_value(WOLF_STACK_OF (WOLFSSL_X509_EXTENSION)* sk,int idx)22362 WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value(
22363         WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx)
22364 {
22365     WOLFSSL_STACK* ret;
22366 
22367     if (sk == NULL) {
22368         return NULL;
22369     }
22370 
22371     ret = wolfSSL_sk_get_node(sk, idx);
22372     if (ret != NULL) {
22373         return ret->data.ext;
22374     }
22375     return NULL;
22376 }
22377 
22378 /* frees all of the nodes and the values in stack */
wolfSSL_sk_X509_EXTENSION_pop_free(WOLF_STACK_OF (WOLFSSL_X509_EXTENSION)* sk,void (* f)(WOLFSSL_X509_EXTENSION *))22379 void wolfSSL_sk_X509_EXTENSION_pop_free(
22380         WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
22381         void (*f) (WOLFSSL_X509_EXTENSION*))
22382 {
22383     wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
22384 }
22385 
22386 #if defined(HAVE_ECC)
22387 /* Copies ecc_key into new WOLFSSL_EC_KEY object
22388  *
22389  * src  : EC_KEY to duplicate. If EC_KEY is not null, create new EC_KEY and copy
22390  * internal ecc_key from src to dup.
22391  *
22392  * Returns pointer to duplicate EC_KEY.
22393  */
wolfSSL_EC_KEY_dup(const WOLFSSL_EC_KEY * src)22394 WOLFSSL_EC_KEY *wolfSSL_EC_KEY_dup(const WOLFSSL_EC_KEY *src)
22395 {
22396     WOLFSSL_EC_KEY *dup;
22397     ecc_key *key, *srcKey;
22398     int ret;
22399 
22400     WOLFSSL_ENTER("wolfSSL_EC_KEY_dup");
22401 
22402     if (src == NULL || src->internal == NULL || src->group == NULL || \
22403        src->pub_key == NULL || src->priv_key == NULL) {
22404 
22405         WOLFSSL_MSG("src NULL error");
22406         return NULL;
22407     }
22408 
22409     dup = wolfSSL_EC_KEY_new();
22410     if (dup == NULL) {
22411         WOLFSSL_MSG("wolfSSL_EC_KEY_new error");
22412         return NULL;
22413     }
22414 
22415     key = (ecc_key*)dup->internal;
22416     if (key == NULL) {
22417         WOLFSSL_MSG("ecc_key NULL error");
22418         wolfSSL_EC_KEY_free(dup);
22419         return NULL;
22420     }
22421     srcKey = (ecc_key*)src->internal;
22422 
22423     /* ecc_key */
22424     /* copy pubkey */
22425     ret = wc_ecc_copy_point(&srcKey->pubkey, &key->pubkey);
22426     if (ret != MP_OKAY) {
22427         WOLFSSL_MSG("wc_ecc_copy_point error");
22428         wolfSSL_EC_KEY_free(dup);
22429         return NULL;
22430     }
22431 
22432     /* copy private key k */
22433     ret = mp_copy(&srcKey->k, &key->k);
22434     if (ret != MP_OKAY) {
22435         WOLFSSL_MSG("mp_copy error");
22436         wolfSSL_EC_KEY_free(dup);
22437         return NULL;
22438     }
22439 
22440     /* copy domain parameters */
22441     if (srcKey->dp) {
22442         ret = wc_ecc_set_curve(key, 0, srcKey->dp->id);
22443         if (ret != 0) {
22444             WOLFSSL_MSG("wc_ecc_set_curve error");
22445             return NULL;
22446         }
22447     }
22448 
22449     key->type  = srcKey->type;
22450     key->idx   = srcKey->idx;
22451     key->state = srcKey->state;
22452     key->flags = srcKey->flags;
22453 
22454     /* Copy group */
22455     if (dup->group == NULL) {
22456         WOLFSSL_MSG("EC_GROUP_new_by_curve_name error");
22457         wolfSSL_EC_KEY_free(dup);
22458         return NULL;
22459     }
22460 
22461     dup->group->curve_idx = src->group->curve_idx;
22462     dup->group->curve_nid = src->group->curve_nid;
22463     dup->group->curve_oid = src->group->curve_oid;
22464 
22465     /* Copy public key */
22466     if (src->pub_key->internal == NULL || dup->pub_key->internal == NULL) {
22467         WOLFSSL_MSG("NULL pub_key error");
22468         wolfSSL_EC_KEY_free(dup);
22469         return NULL;
22470     }
22471 
22472     /* Copy public key internal */
22473     ret = wc_ecc_copy_point((ecc_point*)src->pub_key->internal, \
22474                             (ecc_point*)dup->pub_key->internal);
22475     if (ret != MP_OKAY) {
22476         WOLFSSL_MSG("ecc_copy_point error");
22477         wolfSSL_EC_KEY_free(dup);
22478         return NULL;
22479     }
22480 
22481     /* Copy X, Y, Z */
22482     dup->pub_key->X = wolfSSL_BN_dup(src->pub_key->X);
22483     if (!dup->pub_key->X && src->pub_key->X) {
22484         WOLFSSL_MSG("Error copying EC_POINT");
22485         wolfSSL_EC_KEY_free(dup);
22486         return NULL;
22487     }
22488     dup->pub_key->Y = wolfSSL_BN_dup(src->pub_key->Y);
22489     if (!dup->pub_key->Y && src->pub_key->Y) {
22490         WOLFSSL_MSG("Error copying EC_POINT");
22491         wolfSSL_EC_KEY_free(dup);
22492         return NULL;
22493     }
22494     dup->pub_key->Z = wolfSSL_BN_dup(src->pub_key->Z);
22495     if (!dup->pub_key->Z && src->pub_key->Z) {
22496         WOLFSSL_MSG("Error copying EC_POINT");
22497         wolfSSL_EC_KEY_free(dup);
22498         return NULL;
22499     }
22500 
22501     dup->pub_key->inSet = src->pub_key->inSet;
22502     dup->pub_key->exSet = src->pub_key->exSet;
22503     dup->pkcs8HeaderSz = src->pkcs8HeaderSz;
22504 
22505     /* Copy private key */
22506     if (src->priv_key->internal == NULL || dup->priv_key->internal == NULL) {
22507         WOLFSSL_MSG("NULL priv_key error");
22508         wolfSSL_EC_KEY_free(dup);
22509         return NULL;
22510     }
22511 
22512     /* Free priv_key before call to dup function */
22513     wolfSSL_BN_free(dup->priv_key);
22514     dup->priv_key = wolfSSL_BN_dup(src->priv_key);
22515     if (dup->priv_key == NULL) {
22516         WOLFSSL_MSG("BN_dup error");
22517         wolfSSL_EC_KEY_free(dup);
22518         return NULL;
22519     }
22520 
22521     return dup;
22522 
22523 }
22524 #endif /* HAVE_ECC */
22525 
22526 #if !defined(NO_DH)
wolfSSL_DH_check(const WOLFSSL_DH * dh,int * codes)22527 int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes)
22528 {
22529     int isPrime = MP_NO, codeTmp = 0;
22530     WC_RNG rng;
22531 
22532     WOLFSSL_ENTER("wolfSSL_DH_check");
22533     if (dh == NULL){
22534         return WOLFSSL_FAILURE;
22535     }
22536 
22537     if (dh->g == NULL || dh->g->internal == NULL){
22538         codeTmp = DH_NOT_SUITABLE_GENERATOR;
22539     }
22540 
22541     if (dh->p == NULL || dh->p->internal == NULL){
22542         codeTmp = DH_CHECK_P_NOT_PRIME;
22543     }
22544     else
22545     {
22546         /* test if dh->p has prime */
22547         if (wc_InitRng(&rng) == 0){
22548             mp_prime_is_prime_ex((mp_int*)dh->p->internal,8,&isPrime,&rng);
22549         }
22550         else {
22551             WOLFSSL_MSG("Error initializing rng");
22552             return WOLFSSL_FAILURE;
22553         }
22554         wc_FreeRng(&rng);
22555         if (isPrime != MP_YES){
22556             codeTmp = DH_CHECK_P_NOT_PRIME;
22557         }
22558     }
22559     /* User may choose to enter NULL for codes if they don't want to check it*/
22560     if (codes != NULL){
22561         *codes = codeTmp;
22562     }
22563 
22564     /* if codeTmp was set,some check was flagged invalid */
22565     if (codeTmp){
22566         return WOLFSSL_FAILURE;
22567     }
22568 
22569     return WOLFSSL_SUCCESS;
22570 }
22571 
22572 #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
22573 /* Converts DER encoded DH parameters to a WOLFSSL_DH structure.
22574  *
22575  * dh   : structure to copy DH parameters into.
22576  * pp   : DER encoded DH parameters
22577  * length   : length to copy
22578  *
22579  * Returns pointer to WOLFSSL_DH structure on success, or NULL on failure
22580  */
wolfSSL_d2i_DHparams(WOLFSSL_DH ** dh,const unsigned char ** pp,long length)22581 WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, const unsigned char **pp,
22582                                                                     long length)
22583 {
22584     WOLFSSL_DH *newDH = NULL;
22585     int ret;
22586     word32 idx = 0;
22587 
22588     WOLFSSL_ENTER("wolfSSL_d2i_DHparams");
22589 
22590     if (pp == NULL || length <= 0) {
22591         WOLFSSL_MSG("bad argument");
22592         return NULL;
22593     }
22594 
22595     if ((newDH = wolfSSL_DH_new()) == NULL) {
22596         WOLFSSL_MSG("wolfSSL_DH_new() failed");
22597         return NULL;
22598     }
22599 
22600     ret = wc_DhKeyDecode(*pp, &idx, (DhKey*)newDH->internal, (word32)length);
22601     if (ret != 0) {
22602         WOLFSSL_MSG("DhKeyDecode() failed");
22603         wolfSSL_DH_free(newDH);
22604         return NULL;
22605     }
22606     newDH->inSet = 1;
22607 
22608     if (SetDhExternal(newDH) != WOLFSSL_SUCCESS) {
22609         WOLFSSL_MSG("SetDhExternal failed");
22610         wolfSSL_DH_free(newDH);
22611         return NULL;
22612     }
22613 
22614     *pp += length;
22615     if (dh != NULL){
22616         *dh = newDH;
22617     }
22618 
22619     return newDH;
22620 }
22621 #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
22622 
22623 #define ASN_LEN_SIZE(l)             \
22624     (((l) < 128) ? 1 : (((l) < 256) ? 2 : 3))
22625 
22626 /* Converts internal WOLFSSL_DH structure to DER encoded DH.
22627  *
22628  * dh   : structure to copy DH parameters from.
22629  * out  : DER buffer for DH parameters
22630  *
22631  * Returns size of DER on success and WOLFSSL_FAILURE if error
22632  */
wolfSSL_i2d_DHparams(const WOLFSSL_DH * dh,unsigned char ** out)22633 int wolfSSL_i2d_DHparams(const WOLFSSL_DH *dh, unsigned char **out)
22634 {
22635     word32 len;
22636     int ret = 0;
22637     int pSz;
22638     int gSz;
22639 
22640     WOLFSSL_ENTER("wolfSSL_i2d_DHparams");
22641 
22642     if (dh == NULL) {
22643         WOLFSSL_MSG("Bad parameters");
22644         return WOLFSSL_FAILURE;
22645     }
22646 
22647     /* Get total length */
22648     pSz = mp_unsigned_bin_size((mp_int*)dh->p->internal);
22649     gSz = mp_unsigned_bin_size((mp_int*)dh->g->internal);
22650     len = 1 + ASN_LEN_SIZE(pSz) + mp_leading_bit((mp_int*)dh->p->internal) +
22651           pSz +
22652           1 + ASN_LEN_SIZE(gSz) + mp_leading_bit((mp_int*)dh->g->internal) +
22653           gSz;
22654 
22655     /* Two bytes required for length if ASN.1 SEQ data greater than 127 bytes
22656      * and less than 256 bytes.
22657      */
22658     len += 1 + ASN_LEN_SIZE(len);
22659 
22660     if (out != NULL && *out != NULL) {
22661         ret = StoreDHparams(*out, &len, (mp_int*)dh->p->internal,
22662                                         (mp_int*)dh->g->internal);
22663         if (ret != MP_OKAY) {
22664             WOLFSSL_MSG("StoreDHparams error");
22665             len = 0;
22666         }
22667         else{
22668             *out += len;
22669         }
22670     }
22671     return (int)len;
22672 }
22673 #endif /* !NO_DH */
22674 
22675 #endif /* OPENSSL_ALL */
22676 
22677 #endif /* OPENSSL_EXTRA */
22678 
22679 #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
22680 
wolfSSL_X509_d2i_fp(WOLFSSL_X509 ** x509,XFILE file)22681 WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
22682 {
22683     WOLFSSL_X509* newX509 = NULL;
22684 
22685     WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
22686 
22687     if (file != XBADFILE) {
22688         byte* fileBuffer = NULL;
22689         long sz = 0;
22690 
22691         if (XFSEEK(file, 0, XSEEK_END) != 0)
22692             return NULL;
22693         sz = XFTELL(file);
22694         XREWIND(file);
22695 
22696         if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
22697             WOLFSSL_MSG("X509_d2i file size error");
22698             return NULL;
22699         }
22700 
22701         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
22702         if (fileBuffer != NULL) {
22703             int ret = (int)XFREAD(fileBuffer, 1, sz, file);
22704             if (ret == sz) {
22705                 newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
22706             }
22707             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
22708         }
22709     }
22710 
22711     if (x509 != NULL)
22712         *x509 = newX509;
22713 
22714     return newX509;
22715 }
22716 
22717 #endif /* OPENSSL_EXTRA && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
22718 
22719 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
22720     defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
22721 
22722 #ifndef NO_FILESYSTEM
22723 WOLFSSL_ABI
wolfSSL_X509_load_certificate_file(const char * fname,int format)22724 WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
22725 {
22726 #ifdef WOLFSSL_SMALL_STACK
22727     byte  staticBuffer[1]; /* force heap usage */
22728 #else
22729     byte  staticBuffer[FILE_BUFFER_SIZE];
22730 #endif
22731     byte* fileBuffer = staticBuffer;
22732     int   dynamic = 0;
22733     int   ret;
22734     long  sz = 0;
22735     XFILE file;
22736 
22737     WOLFSSL_X509* x509 = NULL;
22738 
22739     /* Check the inputs */
22740     if ((fname == NULL) ||
22741         (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM))
22742         return NULL;
22743 
22744     file = XFOPEN(fname, "rb");
22745     if (file == XBADFILE)
22746         return NULL;
22747 
22748     if (XFSEEK(file, 0, XSEEK_END) != 0){
22749         XFCLOSE(file);
22750         return NULL;
22751     }
22752     sz = XFTELL(file);
22753     XREWIND(file);
22754 
22755     if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
22756         WOLFSSL_MSG("X509_load_certificate_file size error");
22757         XFCLOSE(file);
22758         return NULL;
22759     }
22760 
22761     if (sz > (long)sizeof(staticBuffer)) {
22762         fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
22763         if (fileBuffer == NULL) {
22764             XFCLOSE(file);
22765             return NULL;
22766         }
22767         dynamic = 1;
22768     }
22769 
22770     ret = (int)XFREAD(fileBuffer, 1, sz, file);
22771     if (ret != sz) {
22772         XFCLOSE(file);
22773         if (dynamic)
22774             XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
22775         return NULL;
22776     }
22777 
22778     XFCLOSE(file);
22779 
22780     x509 = wolfSSL_X509_load_certificate_buffer(fileBuffer, (int)sz, format);
22781 
22782     if (dynamic)
22783         XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
22784 
22785     return x509;
22786 }
22787 #endif /* !NO_FILESYSTEM */
22788 
loadX509orX509REQFromBuffer(const unsigned char * buf,int sz,int format,int type)22789 static WOLFSSL_X509* loadX509orX509REQFromBuffer(
22790     const unsigned char* buf, int sz, int format, int type)
22791 {
22792 
22793     int ret;
22794     WOLFSSL_X509* x509 = NULL;
22795     DerBuffer* der = NULL;
22796 
22797     WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex");
22798 
22799     if (format == WOLFSSL_FILETYPE_PEM) {
22800     #ifdef WOLFSSL_PEM_TO_DER
22801         if (PemToDer(buf, sz, type, &der, NULL, NULL, NULL) != 0) {
22802             FreeDer(&der);
22803         }
22804     #else
22805         ret = NOT_COMPILED_IN;
22806     #endif
22807     }
22808     else {
22809         ret = AllocDer(&der, (word32)sz, type, NULL);
22810         if (ret == 0) {
22811             XMEMCPY(der->buffer, buf, sz);
22812         }
22813     }
22814 
22815     /* At this point we want `der` to have the certificate in DER format */
22816     /* ready to be decoded. */
22817     if (der != NULL && der->buffer != NULL) {
22818     #ifdef WOLFSSL_SMALL_STACK
22819         DecodedCert* cert;
22820     #else
22821         DecodedCert  cert[1];
22822     #endif
22823 
22824     #ifdef WOLFSSL_SMALL_STACK
22825         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
22826                                      DYNAMIC_TYPE_DCERT);
22827         if (cert != NULL)
22828     #endif
22829         {
22830             InitDecodedCert(cert, der->buffer, der->length, NULL);
22831             if (ParseCertRelative(cert, type, 0, NULL) == 0) {
22832                 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
22833                                                              DYNAMIC_TYPE_X509);
22834                 if (x509 != NULL) {
22835                     InitX509(x509, 1, NULL);
22836                     if (CopyDecodedToX509(x509, cert) != 0) {
22837                         wolfSSL_X509_free(x509);
22838                         x509 = NULL;
22839                     }
22840                 }
22841             }
22842 
22843             FreeDecodedCert(cert);
22844         #ifdef WOLFSSL_SMALL_STACK
22845             XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
22846         #endif
22847         }
22848 
22849         FreeDer(&der);
22850     }
22851 
22852     return x509;
22853 }
22854 
wolfSSL_X509_load_certificate_buffer(const unsigned char * buf,int sz,int format)22855 WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
22856     const unsigned char* buf, int sz, int format)
22857 {
22858     return loadX509orX509REQFromBuffer(buf, sz,
22859             format, CERT_TYPE);
22860 }
22861 
22862 #ifdef WOLFSSL_CERT_REQ
wolfSSL_X509_REQ_load_certificate_buffer(const unsigned char * buf,int sz,int format)22863 WOLFSSL_X509* wolfSSL_X509_REQ_load_certificate_buffer(
22864     const unsigned char* buf, int sz, int format)
22865 {
22866     return loadX509orX509REQFromBuffer(buf, sz,
22867             format, CERTREQ_TYPE);
22868 }
22869 #endif
22870 
22871 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
22872 
22873 /* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function
22874    KEEP_OUR_CERT is to insure ability for returning ssl certificate */
22875 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
22876     defined(KEEP_OUR_CERT)
wolfSSL_get_certificate(WOLFSSL * ssl)22877 WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
22878 {
22879     if (ssl == NULL) {
22880         return NULL;
22881     }
22882 
22883     if (ssl->buffers.weOwnCert) {
22884         if (ssl->ourCert == NULL) {
22885             if (ssl->buffers.certificate == NULL) {
22886                 WOLFSSL_MSG("Certificate buffer not set!");
22887                 return NULL;
22888             }
22889             #ifndef WOLFSSL_X509_STORE_CERTS
22890             ssl->ourCert = wolfSSL_X509_d2i(NULL,
22891                                               ssl->buffers.certificate->buffer,
22892                                               ssl->buffers.certificate->length);
22893             #endif
22894         }
22895         return ssl->ourCert;
22896     }
22897     else { /* if cert not owned get parent ctx cert or return null */
22898         if (ssl->ctx) {
22899             if (ssl->ctx->ourCert == NULL) {
22900                 if (ssl->ctx->certificate == NULL) {
22901                     WOLFSSL_MSG("Ctx Certificate buffer not set!");
22902                     return NULL;
22903                 }
22904                 #ifndef WOLFSSL_X509_STORE_CERTS
22905                 ssl->ctx->ourCert = wolfSSL_X509_d2i(NULL,
22906                                                ssl->ctx->certificate->buffer,
22907                                                ssl->ctx->certificate->length);
22908                 #endif
22909                 ssl->ctx->ownOurCert = 1;
22910             }
22911             return ssl->ctx->ourCert;
22912         }
22913     }
22914 
22915     return NULL;
22916 }
22917 
wolfSSL_CTX_get0_certificate(WOLFSSL_CTX * ctx)22918 WOLFSSL_X509* wolfSSL_CTX_get0_certificate(WOLFSSL_CTX* ctx)
22919 {
22920     if (ctx) {
22921         if (ctx->ourCert == NULL) {
22922             if (ctx->certificate == NULL) {
22923                 WOLFSSL_MSG("Ctx Certificate buffer not set!");
22924                 return NULL;
22925             }
22926             #ifndef WOLFSSL_X509_STORE_CERTS
22927             ctx->ourCert = wolfSSL_X509_d2i(NULL,
22928                                            ctx->certificate->buffer,
22929                                            ctx->certificate->length);
22930             #endif
22931             ctx->ownOurCert = 1;
22932         }
22933         return ctx->ourCert;
22934     }
22935     return NULL;
22936 }
22937 #endif /* OPENSSL_EXTRA && KEEP_OUR_CERT */
22938 #endif /* NO_CERTS */
22939 
22940 
22941 #if !defined(NO_ASN) && (defined(OPENSSL_EXTRA) || \
22942         defined(OPENSSL_EXTRA_X509_SMALL))
wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT * obj)22943 void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj)
22944 {
22945     if (obj == NULL) {
22946         return;
22947     }
22948     if ((obj->obj != NULL) && ((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0)) {
22949 #ifdef WOLFSSL_DEBUG_OPENSSL
22950         WOLFSSL_MSG("Freeing ASN1 data");
22951 #endif
22952         XFREE((void*)obj->obj, obj->heap, DYNAMIC_TYPE_ASN1);
22953         obj->obj = NULL;
22954     }
22955     #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
22956     if (obj->pathlen != NULL) {
22957         wolfSSL_ASN1_INTEGER_free(obj->pathlen);
22958         obj->pathlen = NULL;
22959     }
22960     #endif
22961     if ((obj->dynamic & WOLFSSL_ASN1_DYNAMIC) != 0) {
22962 #ifdef WOLFSSL_DEBUG_OPENSSL
22963         WOLFSSL_MSG("Freeing ASN1 OBJECT");
22964 #endif
22965         XFREE(obj, NULL, DYNAMIC_TYPE_ASN1);
22966     }
22967 }
22968 
wolfSSL_ASN1_OBJECT_new(void)22969 WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void)
22970 {
22971     WOLFSSL_ASN1_OBJECT* obj;
22972 
22973     obj = (WOLFSSL_ASN1_OBJECT*)XMALLOC(sizeof(WOLFSSL_ASN1_OBJECT), NULL,
22974                                         DYNAMIC_TYPE_ASN1);
22975     if (obj == NULL) {
22976         return NULL;
22977     }
22978 
22979     XMEMSET(obj, 0, sizeof(WOLFSSL_ASN1_OBJECT));
22980     obj->d.ia5 = &(obj->d.ia5_internal);
22981 #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
22982     obj->d.iPAddress = &(obj->d.iPAddress_internal);
22983 #endif
22984     obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
22985     return obj;
22986 }
22987 
wolfSSL_ASN1_OBJECT_dup(WOLFSSL_ASN1_OBJECT * obj)22988 WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_dup(WOLFSSL_ASN1_OBJECT* obj)
22989 {
22990     WOLFSSL_ASN1_OBJECT* dupl = NULL;
22991 
22992     WOLFSSL_ENTER("wolfSSL_ASN1_OBJECT_dup");
22993 
22994     if (!obj) {
22995         WOLFSSL_MSG("Bad parameter");
22996         return NULL;
22997     }
22998     dupl = wolfSSL_ASN1_OBJECT_new();
22999     if (!dupl) {
23000         WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new error");
23001         return NULL;
23002     }
23003     /* Copy data */
23004     XMEMCPY(dupl->sName, obj->sName, WOLFSSL_MAX_SNAME);
23005     dupl->type = obj->type;
23006     dupl->grp = obj->grp;
23007     dupl->nid = obj->nid;
23008     dupl->objSz = obj->objSz;
23009     if (obj->obj) {
23010         dupl->obj = (const unsigned char*)XMALLOC(
23011                 obj->objSz, NULL, DYNAMIC_TYPE_ASN1);
23012         if (!dupl->obj) {
23013             WOLFSSL_MSG("ASN1 obj malloc error");
23014             wolfSSL_ASN1_OBJECT_free(dupl);
23015             return NULL;
23016         }
23017         XMEMCPY((byte*)dupl->obj, obj->obj, obj->objSz);
23018         dupl->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
23019     }
23020     return dupl;
23021 }
23022 #endif /* !NO_ASN && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
23023 
23024 #ifndef NO_ASN
23025 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
23026 /* Creates and returns a new WOLFSSL_CIPHER stack. */
wolfSSL_sk_new_asn1_obj(void)23027 WOLFSSL_STACK* wolfSSL_sk_new_asn1_obj(void)
23028 {
23029     WOLFSSL_STACK* sk;
23030     WOLFSSL_ENTER("wolfSSL_sk_new_asn1_obj");
23031 
23032     sk = wolfSSL_sk_new_null();
23033     if (sk == NULL)
23034         return NULL;
23035     sk->type = STACK_TYPE_OBJ;
23036 
23037     return sk;
23038 }
23039 
23040 /* return 1 on success 0 on fail */
wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF (WOLFSSL_ASN1_OBJECT)* sk,WOLFSSL_ASN1_OBJECT * obj)23041 int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
23042                                               WOLFSSL_ASN1_OBJECT* obj)
23043 {
23044     WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_push");
23045 
23046     if (sk == NULL || obj == NULL) {
23047         return WOLFSSL_FAILURE;
23048     }
23049 
23050     return wolfSSL_sk_push(sk, obj);
23051 }
23052 
23053 
wolfSSL_sk_ASN1_OBJECT_pop(WOLF_STACK_OF (WOLFSSL_ASN1_OBJECT)* sk)23054 WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJECT_pop(
23055                                         WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
23056 {
23057     WOLFSSL_STACK* node;
23058     WOLFSSL_ASN1_OBJECT* obj;
23059 
23060     if (sk == NULL) {
23061         return NULL;
23062     }
23063 
23064     node = sk->next;
23065     obj = sk->data.obj;
23066 
23067     if (node != NULL) { /* update sk and remove node from stack */
23068         sk->data.obj = node->data.obj;
23069         sk->next = node->next;
23070         XFREE(node, NULL, DYNAMIC_TYPE_ASN1);
23071     }
23072     else { /* last obj in stack */
23073         sk->data.obj = NULL;
23074     }
23075 
23076     if (sk->num > 0) {
23077         sk->num -= 1;
23078     }
23079 
23080     return obj;
23081 }
23082 
23083 
23084 /* Free the structure for ASN1_OBJECT stack
23085  *
23086  * sk  stack to free nodes in
23087  */
wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF (WOLFSSL_ASN1_OBJECT)* sk)23088 void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
23089 {
23090     wolfSSL_sk_free(sk);
23091 }
23092 
23093 /* Free's all nodes in ASN1_OBJECT stack.
23094  * This is different then wolfSSL_ASN1_OBJECT_free in that it allows for
23095  * choosing the function to use when freeing an ASN1_OBJECT stack.
23096  *
23097  * sk  stack to free nodes in
23098  * f   X509 free function
23099  */
wolfSSL_sk_ASN1_OBJECT_pop_free(WOLF_STACK_OF (WOLFSSL_ASN1_OBJECT)* sk,void (* f)(WOLFSSL_ASN1_OBJECT *))23100 void wolfSSL_sk_ASN1_OBJECT_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
23101                                      void (*f) (WOLFSSL_ASN1_OBJECT*))
23102 {
23103     WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_pop_free");
23104     wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
23105 }
23106 
23107 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
23108 #endif /* !NO_ASN */
23109 
23110 #ifdef OPENSSL_EXTRA
23111 #ifndef NO_ASN
23112 
wolfSSL_ASN1_STRING_to_UTF8(unsigned char ** out,WOLFSSL_ASN1_STRING * in)23113 int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in)
23114 {
23115     /*
23116        ASN1_STRING_to_UTF8() converts the string in to UTF8 format,
23117        the converted data is allocated in a buffer in *out.
23118        The length of out is returned or a negative error code.
23119        The buffer *out should be free using OPENSSL_free().
23120        */
23121     unsigned char* buf;
23122     unsigned char* inPtr;
23123     int inLen;
23124 
23125     if (!out || !in) {
23126         return -1;
23127     }
23128 
23129     inPtr = wolfSSL_ASN1_STRING_data(in);
23130     inLen = wolfSSL_ASN1_STRING_length(in);
23131     if (!inPtr || inLen < 0) {
23132         return -1;
23133     }
23134     buf = (unsigned char*)XMALLOC(inLen + 1, NULL, DYNAMIC_TYPE_OPENSSL);
23135     if (!buf) {
23136         return -1;
23137     }
23138     XMEMCPY(buf, inPtr, inLen + 1);
23139     *out = buf;
23140     return inLen;
23141 }
23142 
wolfSSL_ASN1_UNIVERSALSTRING_to_string(WOLFSSL_ASN1_STRING * s)23143 int wolfSSL_ASN1_UNIVERSALSTRING_to_string(WOLFSSL_ASN1_STRING *s)
23144 {
23145     char *idx;
23146     char *copy;
23147     WOLFSSL_ENTER("wolfSSL_ASN1_UNIVERSALSTRING_to_string");
23148 
23149     if (!s) {
23150         WOLFSSL_MSG("Bad parameter");
23151         return WOLFSSL_FAILURE;
23152     }
23153 
23154     if (s->type != V_ASN1_UNIVERSALSTRING) {
23155         WOLFSSL_MSG("Input is not a universal string");
23156         return WOLFSSL_FAILURE;
23157     }
23158 
23159     if ((s->length % 4) != 0) {
23160         WOLFSSL_MSG("Input string must be divisible by 4");
23161         return WOLFSSL_FAILURE;
23162     }
23163 
23164     for (idx = s->data; idx < s->data + s->length; idx += 4)
23165         if ((idx[0] != '\0') || (idx[1] != '\0') || (idx[2] != '\0'))
23166             break;
23167 
23168     if (idx != s->data + s->length) {
23169         WOLFSSL_MSG("Wrong string format");
23170         return WOLFSSL_FAILURE;
23171     }
23172 
23173     for (copy = idx = s->data; idx < s->data + s->length; idx += 4)
23174         *copy++ = idx[3];
23175     *copy = '\0';
23176     s->length /= 4;
23177     s->type = V_ASN1_PRINTABLESTRING;
23178     return WOLFSSL_SUCCESS;
23179 }
23180 
23181 /* Returns string representation of ASN1_STRING */
wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method * method,const WOLFSSL_ASN1_STRING * s)23182 char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method,
23183     const WOLFSSL_ASN1_STRING *s)
23184 {
23185     int i;
23186     int tmpSz = 100;
23187     int valSz = 5;
23188     char* tmp;
23189     char val[5];
23190     unsigned char* str;
23191 
23192     WOLFSSL_ENTER("wolfSSL_i2s_ASN1_STRING");
23193     (void)method;
23194 
23195     if(s == NULL || s->data == NULL) {
23196         WOLFSSL_MSG("Bad Function Argument");
23197         return NULL;
23198     }
23199     str = (unsigned char*)XMALLOC(s->length, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23200     if (str == NULL) {
23201         WOLFSSL_MSG("Memory Error");
23202         return NULL;
23203     }
23204     XMEMCPY(str, (unsigned char*)s->data, s->length);
23205 
23206     tmp = (char*)XMALLOC(tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23207     if (tmp == NULL) {
23208         WOLFSSL_MSG("Memory Error");
23209         XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23210         return NULL;
23211     }
23212     XMEMSET(tmp, 0, tmpSz);
23213 
23214     for (i = 0; i < tmpSz && i < (s->length - 1); i++) {
23215         XSNPRINTF(val, valSz - 1, "%02X:", str[i]);
23216         XSTRNCAT(tmp, val, valSz);
23217     }
23218     XSNPRINTF(val, valSz - 1, "%02X", str[i]);
23219     XSTRNCAT(tmp, val, valSz);
23220     XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23221 
23222     return tmp;
23223 }
23224 #endif /* NO_ASN */
23225 #endif /* OPENSSL_EXTRA */
23226 
23227 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
wolfSSL_set_connect_state(WOLFSSL * ssl)23228 void wolfSSL_set_connect_state(WOLFSSL* ssl)
23229 {
23230     WOLFSSL_ENTER("wolfSSL_set_connect_state");
23231     if (ssl == NULL) {
23232         WOLFSSL_MSG("WOLFSSL struct pointer passed in was null");
23233         return;
23234     }
23235 
23236     #ifndef NO_DH
23237     /* client creates its own DH parameters on handshake */
23238     if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
23239         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
23240             DYNAMIC_TYPE_PUBLIC_KEY);
23241     }
23242     ssl->buffers.serverDH_P.buffer = NULL;
23243     if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
23244         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
23245             DYNAMIC_TYPE_PUBLIC_KEY);
23246     }
23247     ssl->buffers.serverDH_G.buffer = NULL;
23248     #endif
23249 
23250     if (InitSSL_Side(ssl, WOLFSSL_CLIENT_END) != WOLFSSL_SUCCESS) {
23251         WOLFSSL_MSG("Error initializing client side");
23252     }
23253 }
23254 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
23255 
23256 
wolfSSL_get_shutdown(const WOLFSSL * ssl)23257 int wolfSSL_get_shutdown(const WOLFSSL* ssl)
23258 {
23259     int isShutdown = 0;
23260 
23261     WOLFSSL_ENTER("wolfSSL_get_shutdown");
23262 
23263     if (ssl) {
23264 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
23265         if (ssl->options.handShakeState == NULL_STATE) {
23266             /* The SSL object was possibly cleared with wolfSSL_clear after
23267              * a successful shutdown. Simulate a response for a full
23268              * bidirectional shutdown. */
23269             isShutdown = WOLFSSL_SENT_SHUTDOWN | WOLFSSL_RECEIVED_SHUTDOWN;
23270         }
23271         else
23272 #endif
23273         {
23274             /* in OpenSSL, WOLFSSL_SENT_SHUTDOWN = 1, when closeNotifySent   *
23275              * WOLFSSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */
23276             if (ssl->options.sentNotify)
23277                 isShutdown |= WOLFSSL_SENT_SHUTDOWN;
23278             if (ssl->options.closeNotify||ssl->options.connReset)
23279                 isShutdown |= WOLFSSL_RECEIVED_SHUTDOWN;
23280         }
23281 
23282     }
23283     return isShutdown;
23284 }
23285 
23286 
wolfSSL_session_reused(WOLFSSL * ssl)23287 int wolfSSL_session_reused(WOLFSSL* ssl)
23288 {
23289     int resuming = 0;
23290     if (ssl)
23291         resuming = ssl->options.resuming;
23292     return resuming;
23293 }
23294 
GetSessionRef(WOLFSSL * ssl)23295 WOLFSSL_SESSION* GetSessionRef(WOLFSSL* ssl)
23296 {
23297     WOLFSSL_SESSION* session;
23298 #ifdef ENABLE_CLIENT_SESSION_REF
23299     WOLFSSL_SESSION* ref = NULL;
23300     const word32     refSize = (word32)OFFSETOF(WOLFSSL_SESSION, refPtr) +
23301                                        (word32)sizeof(wc_ptr_t);
23302     int refCount = 0;
23303 #endif
23304 
23305     session = GetSession(ssl, NULL, 1);
23306     if (session == NULL) {
23307         return session;
23308     }
23309 
23310 #ifdef ENABLE_CLIENT_SESSION_REF
23311     /* if GetSessionRef has already been called then use existing pointer */
23312     ref = (WOLFSSL_SESSION*)ssl->session.refPtr;
23313     if (ref == NULL) {
23314         ref = (WOLFSSL_SESSION*)XMALLOC(refSize, ssl->heap,
23315                                         DYNAMIC_TYPE_SESSION);
23316     }
23317     else {
23318         /* use existing ref count */
23319         refCount = ref->refCount;
23320     }
23321     if (ref == NULL) {
23322         WOLFSSL_MSG("Error allocating client session reference");
23323         return NULL;
23324     }
23325 
23326     XMEMCPY(ref, session, refSize);
23327     ref->type = WOLFSSL_SESSION_TYPE_REF;
23328     ref->refCount = refCount;
23329     ref->refPtr = (void*)session;
23330     ref->heap = ssl->heap;
23331     ssl->session.refPtr = ref;
23332     session = ref;
23333 #endif /* ENABLE_CLIENT_SESSION_REF */
23334 
23335     return session;
23336 }
23337 
23338 #if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE)
23339 
23340 /* return a new malloc'd session with default settings on success */
NewSession(void * heap)23341 WOLFSSL_SESSION* NewSession(void* heap)
23342 {
23343     WOLFSSL_SESSION* ret = NULL;
23344 
23345     ret = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), heap,
23346             DYNAMIC_TYPE_SESSION);
23347     if (ret != NULL) {
23348         XMEMSET(ret, 0, sizeof(WOLFSSL_SESSION));
23349         ret->type = WOLFSSL_SESSION_TYPE_HEAP;
23350         ret->heap = heap;
23351         ret->masterSecret = ret->_masterSecret;
23352     #ifndef NO_CLIENT_CACHE
23353         ret->serverID = ret->_serverID;
23354     #endif
23355     #ifdef OPENSSL_EXTRA
23356         ret->sessionCtx = ret->_sessionCtx;
23357     #endif
23358     #ifdef HAVE_SESSION_TICKET
23359         ret->ticket = ret->_staticTicket;
23360     #endif
23361     }
23362     (void)heap;
23363     return ret;
23364 }
23365 
wolfSSL_SESSION_new_ex(void * heap)23366 WOLFSSL_SESSION* wolfSSL_SESSION_new_ex(void* heap)
23367 {
23368     WOLFSSL_SESSION* ret = NewSession(heap);
23369 
23370 #ifdef OPENSSL_EXTRA
23371     if (ret != NULL) {
23372 #ifndef SINGLE_THREADED
23373         if (wc_InitMutex(&ret->refMutex) != 0) {
23374             WOLFSSL_MSG("Error setting up session reference mutex");
23375             XFREE(ret, ret->heap, DYNAMIC_TYPE_SESSION);
23376             return NULL;
23377         }
23378 #endif
23379         ret->refCount = 1;
23380     }
23381 #endif
23382 
23383     return ret;
23384 }
wolfSSL_SESSION_new(void)23385 WOLFSSL_SESSION* wolfSSL_SESSION_new(void)
23386 {
23387     return wolfSSL_SESSION_new_ex(NULL);
23388 }
23389 
23390 /* add one to session reference count
23391  * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error */
wolfSSL_SESSION_up_ref(WOLFSSL_SESSION * session)23392 int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session)
23393 {
23394     session = GetSessionPtr(session);
23395     if (session == NULL)
23396         return WOLFSSL_FAILURE;
23397 
23398 #ifdef OPENSSL_EXTRA
23399 #ifndef SINGLE_THREADED
23400     if (wc_LockMutex(&session->refMutex) != 0) {
23401         WOLFSSL_MSG("Failed to lock session mutex");
23402     }
23403 #endif
23404     session->refCount++;
23405 #ifndef SINGLE_THREADED
23406     wc_UnLockMutex(&session->refMutex);
23407 #endif
23408 #endif
23409     return WOLFSSL_SUCCESS;
23410 }
23411 
23412 
wolfSSL_SESSION_dup(WOLFSSL_SESSION * session)23413 WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
23414 {
23415 #ifdef HAVE_EXT_CACHE
23416     WOLFSSL_SESSION* copy;
23417 
23418     WOLFSSL_ENTER("wolfSSL_SESSION_dup");
23419 
23420     session = GetSessionPtr(session);
23421     if (session == NULL)
23422         return NULL;
23423 
23424 #ifdef HAVE_SESSION_TICKET
23425     if (session->ticketLenAlloc > 0 && !session->ticket) {
23426         WOLFSSL_MSG("Session dynamic flag is set but ticket pointer is null");
23427         return NULL;
23428     }
23429 #endif
23430 
23431     copy = NewSession(session->heap);
23432     if (copy != NULL) {
23433         XMEMCPY(copy, session, sizeof(WOLFSSL_SESSION));
23434         copy->type = WOLFSSL_SESSION_TYPE_HEAP;
23435         copy->cacheRow = -1; /* not in cache */
23436         copy->masterSecret = copy->_masterSecret;
23437     #ifndef NO_CLIENT_CACHE
23438         copy->serverID = copy->_serverID;
23439     #endif
23440     #ifdef OPENSSL_EXTRA
23441         copy->sessionCtx = copy->_sessionCtx;
23442     #endif
23443 #ifdef OPENSSL_EXTRA
23444 #ifndef SINGLE_THREADED
23445         if (wc_InitMutex(&copy->refMutex) != 0) {
23446             WOLFSSL_MSG("Error setting up session reference mutex");
23447             XFREE(copy, copy->heap, DYNAMIC_TYPE_SESSION);
23448             return NULL;
23449         }
23450 #endif
23451         copy->refCount = 1;
23452 #endif
23453 #ifdef HAVE_SESSION_TICKET
23454         if (session->ticketLenAlloc > 0) {
23455             copy->ticket = (byte*)XMALLOC(session->ticketLen, copy->heap,
23456                                                     DYNAMIC_TYPE_SESSION_TICK);
23457             XMEMCPY(copy->ticket, session->ticket, session->ticketLen);
23458         } else {
23459             copy->ticket = copy->_staticTicket;
23460         }
23461 #endif
23462 #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
23463         copy->peer = wolfSSL_X509_dup(session->peer);
23464 #endif
23465     }
23466     return copy;
23467 #else
23468     WOLFSSL_MSG("wolfSSL_SESSION_dup feature not compiled in");
23469     (void)session;
23470     return NULL;
23471 #endif /* HAVE_EXT_CACHE */
23472 }
23473 
23474 #endif /* OPENSSL_EXTRA || HAVE_EXT_CACHE */
23475 
FreeSession(WOLFSSL_SESSION * session)23476 void FreeSession(WOLFSSL_SESSION* session)
23477 {
23478     if (session == NULL)
23479         return;
23480 
23481 #ifdef ENABLE_CLIENT_SESSION_REF
23482     if (session->type == WOLFSSL_SESSION_TYPE_REF) {
23483         WOLFSSL_SESSION* ref;
23484         session->refCount--;
23485         if (session->refCount > 0) {
23486             return; /* don't free yet */
23487         }
23488         ref = session;
23489         session = (WOLFSSL_SESSION*)session->refPtr;
23490         XFREE(ref, ref->heap, DYNAMIC_TYPE_SESSION);
23491     }
23492 #endif
23493 
23494 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
23495     wolfSSL_CRYPTO_cleanup_ex_data(&session->ex_data);
23496 #endif
23497 
23498 #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
23499     if (session->peer) {
23500         wolfSSL_X509_free(session->peer);
23501         session->peer = NULL;
23502     }
23503 #endif
23504 
23505 #ifdef OPENSSL_EXTRA
23506     /* refCount will always be 1 or more if created externally.
23507      * Internal cache sessions don't initialize a refMutex. */
23508     if (session->refCount > 0) {
23509 #ifndef SINGLE_THREADED
23510         if (wc_LockMutex(&session->refMutex) != 0) {
23511             WOLFSSL_MSG("Failed to lock session mutex");
23512         }
23513 #endif
23514         if (session->refCount > 1) {
23515             session->refCount--;
23516 #ifndef SINGLE_THREADED
23517             wc_UnLockMutex(&session->refMutex);
23518 #endif
23519             return;
23520         }
23521 #ifndef SINGLE_THREADED
23522         wc_UnLockMutex(&session->refMutex);
23523 #endif
23524     }
23525 #endif
23526 
23527 #ifdef HAVE_SESSION_TICKET
23528     if (session->ticketLenAlloc > 0) {
23529         XFREE(session->ticket, session->heap, DYNAMIC_TYPE_SESSION_TICK);
23530     }
23531 #endif
23532 
23533     if (session->type == WOLFSSL_SESSION_TYPE_HEAP) {
23534         XFREE(session, session->heap, DYNAMIC_TYPE_SESSION);
23535     }
23536 }
23537 
wolfSSL_SESSION_free(WOLFSSL_SESSION * session)23538 void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
23539 {
23540     FreeSession(session);
23541 }
23542 
23543 #if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE)
23544 
23545 /**
23546 * set cipher to WOLFSSL_SESSION from WOLFSSL_CIPHER
23547 * @param session  a pointer to WOLFSSL_SESSION structure
23548 * @param cipher   a function pointer to WOLFSSL_CIPHER
23549 * @return WOLFSSL_SUCCESS on success, otherwise WOLFSSL_FAILURE
23550 */
wolfSSL_SESSION_set_cipher(WOLFSSL_SESSION * session,const WOLFSSL_CIPHER * cipher)23551 int wolfSSL_SESSION_set_cipher(WOLFSSL_SESSION* session,
23552                                             const WOLFSSL_CIPHER* cipher)
23553 {
23554     WOLFSSL_ENTER("wolfSSL_SESSION_set_cipher");
23555 
23556     /* sanity check */
23557     session = GetSessionPtr(session);
23558     if (session == NULL || cipher == NULL) {
23559         WOLFSSL_MSG("bad argument");
23560         return WOLFSSL_FAILURE;
23561     }
23562     session->cipherSuite0 = cipher->cipherSuite0;
23563     session->cipherSuite  = cipher->cipherSuite;
23564 
23565     WOLFSSL_LEAVE("wolfSSL_SESSION_set_cipher", WOLFSSL_SUCCESS);
23566     return WOLFSSL_SUCCESS;
23567 }
23568 #endif /* OPENSSL_EXTRA || HAVE_EXT_CACHE */
23569 
23570 
23571 /* helper function that takes in a protocol version struct and returns string */
wolfSSL_internal_get_version(const ProtocolVersion * version)23572 static const char* wolfSSL_internal_get_version(const ProtocolVersion* version)
23573 {
23574     WOLFSSL_ENTER("wolfSSL_get_version");
23575 
23576     if (version == NULL) {
23577         return "Bad arg";
23578     }
23579 
23580     if (version->major == SSLv3_MAJOR) {
23581         switch (version->minor) {
23582             case SSLv3_MINOR :
23583                 return "SSLv3";
23584             case TLSv1_MINOR :
23585                 return "TLSv1";
23586             case TLSv1_1_MINOR :
23587                 return "TLSv1.1";
23588             case TLSv1_2_MINOR :
23589                 return "TLSv1.2";
23590             case TLSv1_3_MINOR :
23591                 return "TLSv1.3";
23592             default:
23593                 return "unknown";
23594         }
23595     }
23596 #ifdef WOLFSSL_DTLS
23597     else if (version->major == DTLS_MAJOR) {
23598         switch (version->minor) {
23599             case DTLS_MINOR :
23600                 return "DTLS";
23601             case DTLSv1_2_MINOR :
23602                 return "DTLSv1.2";
23603             default:
23604                 return "unknown";
23605         }
23606     }
23607 #endif /* WOLFSSL_DTLS */
23608     return "unknown";
23609 }
23610 
23611 
wolfSSL_get_version(const WOLFSSL * ssl)23612 const char* wolfSSL_get_version(const WOLFSSL* ssl)
23613 {
23614     if (ssl == NULL) {
23615         WOLFSSL_MSG("Bad argument");
23616         return "unknown";
23617     }
23618 
23619     return wolfSSL_internal_get_version(&ssl->version);
23620 }
23621 
23622 
23623 /* current library version */
wolfSSL_lib_version(void)23624 const char* wolfSSL_lib_version(void)
23625 {
23626     return LIBWOLFSSL_VERSION_STRING;
23627 }
23628 
23629 #ifdef OPENSSL_EXTRA
23630 #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
wolfSSL_OpenSSL_version(int a)23631 const char* wolfSSL_OpenSSL_version(int a)
23632 {
23633     (void)a;
23634     return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
23635 }
23636 #else
wolfSSL_OpenSSL_version(void)23637 const char* wolfSSL_OpenSSL_version(void)
23638 {
23639     return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
23640 }
23641 #endif /* WOLFSSL_QT */
23642 #endif
23643 
23644 
23645 /* current library version in hex */
wolfSSL_lib_version_hex(void)23646 word32 wolfSSL_lib_version_hex(void)
23647 {
23648     return LIBWOLFSSL_VERSION_HEX;
23649 }
23650 
23651 
wolfSSL_get_current_cipher_suite(WOLFSSL * ssl)23652 int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
23653 {
23654     WOLFSSL_ENTER("SSL_get_current_cipher_suite");
23655     if (ssl)
23656         return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
23657     return 0;
23658 }
23659 
wolfSSL_get_current_cipher(WOLFSSL * ssl)23660 WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
23661 {
23662     WOLFSSL_ENTER("SSL_get_current_cipher");
23663     if (ssl) {
23664         ssl->cipher.cipherSuite0 = ssl->options.cipherSuite0;
23665         ssl->cipher.cipherSuite  = ssl->options.cipherSuite;
23666 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
23667         ssl->cipher.bits = ssl->specs.key_size * 8;
23668 #endif
23669         return &ssl->cipher;
23670     }
23671     else
23672         return NULL;
23673 }
23674 
23675 
wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER * cipher)23676 const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
23677 {
23678     WOLFSSL_ENTER("wolfSSL_CIPHER_get_name");
23679 
23680     if (cipher == NULL) {
23681         return NULL;
23682     }
23683 
23684     #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS) && \
23685         !defined(WOLFSSL_QT)
23686         return GetCipherNameIana(cipher->cipherSuite0, cipher->cipherSuite);
23687     #else
23688         return wolfSSL_get_cipher_name_from_suite(cipher->cipherSuite0,
23689                 cipher->cipherSuite);
23690     #endif
23691 }
23692 
wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER * cipher)23693 const char*  wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER* cipher)
23694 {
23695     WOLFSSL_ENTER("SSL_CIPHER_get_version");
23696 
23697     if (cipher == NULL || cipher->ssl == NULL) {
23698         return NULL;
23699     }
23700 
23701     return wolfSSL_get_version(cipher->ssl);
23702 }
23703 
wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION * session)23704 const char* wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION* session)
23705 {
23706     session = GetSessionPtr(session);
23707     if (session == NULL) {
23708         return NULL;
23709     }
23710 
23711 #if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
23712                         (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
23713     #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS)
23714         return GetCipherNameIana(session->cipherSuite0, session->cipherSuite);
23715     #else
23716         return GetCipherNameInternal(session->cipherSuite0, session->cipherSuite);
23717     #endif
23718 #else
23719     return NULL;
23720 #endif
23721 }
23722 
wolfSSL_get_cipher(WOLFSSL * ssl)23723 const char* wolfSSL_get_cipher(WOLFSSL* ssl)
23724 {
23725     WOLFSSL_ENTER("wolfSSL_get_cipher");
23726     return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
23727 }
23728 
23729 /* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */
wolfSSL_get_cipher_name(WOLFSSL * ssl)23730 const char* wolfSSL_get_cipher_name(WOLFSSL* ssl)
23731 {
23732     /* get access to cipher_name_idx in internal.c */
23733     return wolfSSL_get_cipher_name_internal(ssl);
23734 }
23735 
wolfSSL_get_cipher_name_from_suite(const byte cipherSuite0,const byte cipherSuite)23736 const char* wolfSSL_get_cipher_name_from_suite(const byte cipherSuite0,
23737     const byte cipherSuite)
23738 {
23739     return GetCipherNameInternal(cipherSuite0, cipherSuite);
23740 }
23741 
wolfSSL_get_cipher_name_iana_from_suite(const byte cipherSuite0,const byte cipherSuite)23742 const char* wolfSSL_get_cipher_name_iana_from_suite(const byte cipherSuite0,
23743         const byte cipherSuite)
23744 {
23745     return GetCipherNameIana(cipherSuite0, cipherSuite);
23746 }
23747 
wolfSSL_get_cipher_suite_from_name(const char * name,byte * cipherSuite0,byte * cipherSuite,int * flags)23748 int wolfSSL_get_cipher_suite_from_name(const char* name, byte* cipherSuite0,
23749                                        byte* cipherSuite, int *flags) {
23750     if ((name == NULL) ||
23751         (cipherSuite0 == NULL) ||
23752         (cipherSuite == NULL) ||
23753         (flags == NULL))
23754         return BAD_FUNC_ARG;
23755     return GetCipherSuiteFromName(name, cipherSuite0, cipherSuite, flags);
23756 }
23757 
23758 
23759 #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
23760 /* Creates and returns a new WOLFSSL_CIPHER stack. */
wolfSSL_sk_new_cipher(void)23761 WOLFSSL_STACK* wolfSSL_sk_new_cipher(void)
23762 {
23763     WOLFSSL_STACK* sk;
23764     WOLFSSL_ENTER("wolfSSL_sk_new_cipher");
23765 
23766     sk = wolfSSL_sk_new_null();
23767     if (sk == NULL)
23768         return NULL;
23769     sk->type = STACK_TYPE_CIPHER;
23770 
23771     return sk;
23772 }
23773 
23774 /* return 1 on success 0 on fail */
wolfSSL_sk_CIPHER_push(WOLF_STACK_OF (WOLFSSL_CIPHER)* sk,WOLFSSL_CIPHER * cipher)23775 int wolfSSL_sk_CIPHER_push(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk,
23776                                                       WOLFSSL_CIPHER* cipher)
23777 {
23778     return wolfSSL_sk_push(sk, cipher);
23779 }
23780 
23781 #ifndef NO_WOLFSSL_STUB
wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF (WOLFSSL_CIPHER)* sk)23782 WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
23783 {
23784     WOLFSSL_STUB("wolfSSL_sk_CIPHER_pop");
23785     (void)sk;
23786     return NULL;
23787 }
23788 #endif /* NO_WOLFSSL_STUB */
23789 #endif /* WOLFSSL_QT || OPENSSL_ALL */
23790 
wolfSSL_CIPHER_get_id(const WOLFSSL_CIPHER * cipher)23791 word32 wolfSSL_CIPHER_get_id(const WOLFSSL_CIPHER* cipher)
23792 {
23793     word16 cipher_id = 0;
23794 
23795     WOLFSSL_ENTER("SSL_CIPHER_get_id");
23796 
23797     if (cipher && cipher->ssl) {
23798         cipher_id = (cipher->ssl->options.cipherSuite0 << 8) |
23799                      cipher->ssl->options.cipherSuite;
23800     }
23801 
23802     return cipher_id;
23803 }
23804 
wolfSSL_get_cipher_by_value(word16 value)23805 const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value)
23806 {
23807     const WOLFSSL_CIPHER* cipher = NULL;
23808     byte cipherSuite0, cipherSuite;
23809     WOLFSSL_ENTER("SSL_get_cipher_by_value");
23810 
23811     /* extract cipher id information */
23812     cipherSuite =   (value       & 0xFF);
23813     cipherSuite0 = ((value >> 8) & 0xFF);
23814 
23815     /* TODO: lookup by cipherSuite0 / cipherSuite */
23816     (void)cipherSuite0;
23817     (void)cipherSuite;
23818 
23819     return cipher;
23820 }
23821 
23822 
23823 #if defined(OPENSSL_ALL)
23824 /* Free the structure for WOLFSSL_CIPHER stack
23825  *
23826  * sk  stack to free nodes in
23827  */
wolfSSL_sk_CIPHER_free(WOLF_STACK_OF (WOLFSSL_CIPHER)* sk)23828 void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
23829 {
23830     WOLFSSL_STACK* node;
23831     WOLFSSL_STACK* tmp;
23832     WOLFSSL_ENTER("wolfSSL_sk_CIPHER_free");
23833 
23834     if (sk == NULL)
23835         return;
23836 
23837     /* parse through stack freeing each node */
23838     node = sk->next;
23839     while (node) {
23840         tmp  = node;
23841         node = node->next;
23842         XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
23843     }
23844 
23845     /* free head of stack */
23846     XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
23847 }
23848 #endif /* OPENSSL_ALL */
23849 
23850 #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
23851                                                                  !defined(NO_DH)
23852 #ifdef HAVE_FFDHE
wolfssl_ffdhe_name(word16 group)23853 static const char* wolfssl_ffdhe_name(word16 group)
23854 {
23855     const char* str = NULL;
23856     switch (group) {
23857         case WOLFSSL_FFDHE_2048:
23858             str = "FFDHE_2048";
23859             break;
23860         case WOLFSSL_FFDHE_3072:
23861             str = "FFDHE_3072";
23862             break;
23863         case WOLFSSL_FFDHE_4096:
23864             str = "FFDHE_4096";
23865             break;
23866         case WOLFSSL_FFDHE_6144:
23867             str = "FFDHE_6144";
23868             break;
23869         case WOLFSSL_FFDHE_8192:
23870             str = "FFDHE_8192";
23871             break;
23872         default:
23873             break;
23874     }
23875     return str;
23876 }
23877 #endif
23878 /* Return the name of the curve used for key exchange as a printable string.
23879  *
23880  * ssl  The SSL/TLS object.
23881  * returns NULL if ECDH was not used, otherwise the name as a string.
23882  */
wolfSSL_get_curve_name(WOLFSSL * ssl)23883 const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
23884 {
23885     const char* cName = NULL;
23886 
23887     if (ssl == NULL)
23888         return NULL;
23889 
23890 #ifdef HAVE_FFDHE
23891     if (ssl->namedGroup != 0) {
23892         cName = wolfssl_ffdhe_name(ssl->namedGroup);
23893     }
23894 #endif
23895 
23896 #ifdef HAVE_CURVE25519
23897     if (ssl->ecdhCurveOID == ECC_X25519_OID && cName == NULL) {
23898         cName = "X25519";
23899     }
23900 #endif
23901 
23902 #ifdef HAVE_CURVE448
23903     if (ssl->ecdhCurveOID == ECC_X448_OID && cName == NULL) {
23904         cName = "X448";
23905     }
23906 #endif
23907 
23908 #ifdef HAVE_ECC
23909     if (ssl->ecdhCurveOID != 0 && cName == NULL) {
23910         cName = wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL,
23911                                 NULL));
23912     }
23913 #endif
23914 
23915     return cName;
23916 }
23917 #endif
23918 
23919 
23920 #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(KEEP_PEER_CERT) || \
23921     defined(SESSION_CERTS)
23922 /* Smaller subset of X509 compatibility functions. Avoid increasing the size of
23923  * this subset and its memory usage */
23924 
23925 #if !defined(NO_CERTS)
23926 /* returns a pointer to a new WOLFSSL_X509 structure on success and NULL on
23927  * fail
23928  */
wolfSSL_X509_new(void)23929 WOLFSSL_X509* wolfSSL_X509_new(void)
23930 {
23931     WOLFSSL_X509* x509;
23932 
23933     x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
23934             DYNAMIC_TYPE_X509);
23935     if (x509 != NULL) {
23936         InitX509(x509, 1, NULL);
23937     }
23938 
23939     return x509;
23940 }
23941 
23942 WOLFSSL_ABI
wolfSSL_X509_get_subject_name(WOLFSSL_X509 * cert)23943 WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
23944 {
23945     WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
23946     if (cert && cert->subject.sz > 0)
23947         return &cert->subject;
23948     return NULL;
23949 }
23950 
23951 #if defined(OPENSSL_EXTRA) && (!defined(NO_SHA) || !defined(NO_SHA256))
23952 /******************************************************************************
23953 * wolfSSL_X509_subject_name_hash - compute the hash digest of the raw subject name
23954 * This function prefers SHA-1 (if available) for compatibility
23955 *
23956 * RETURNS:
23957 * The beginning of the hash digest. Otherwise, returns zero.
23958 * Note:
23959 * Returns a different hash value from OpenSSL's X509_subject_name_hash() API
23960 * depending on the subject name.
23961 */
wolfSSL_X509_subject_name_hash(const WOLFSSL_X509 * x509)23962 unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
23963 {
23964     unsigned long ret = 0;
23965     int retHash = NOT_COMPILED_IN;
23966     WOLFSSL_X509_NAME *subjectName = NULL;
23967     byte digest[WC_MAX_DIGEST_SIZE];
23968 
23969     if (x509 == NULL) {
23970         return ret;
23971     }
23972 
23973     subjectName = wolfSSL_X509_get_subject_name((WOLFSSL_X509*)x509);
23974     if (subjectName != NULL) {
23975     #ifndef NO_SHA
23976         retHash = wc_ShaHash((const byte*)subjectName->name,
23977                              (word32)subjectName->sz, digest);
23978     #elif !defined(NO_SHA256)
23979         retHash = wc_Sha256Hash((const byte*)subjectName->name,
23980                                 (word32)subjectName->sz, digest);
23981     #endif
23982         if (retHash == 0) {
23983             ret = (unsigned long)MakeWordFromHash(digest);
23984         }
23985     }
23986 
23987     return ret;
23988 }
23989 
wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509 * x509)23990 unsigned long wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509* x509)
23991 {
23992     unsigned long ret = 0;
23993     int retHash = NOT_COMPILED_IN;
23994     WOLFSSL_X509_NAME *issuerName = NULL;
23995     byte digest[WC_MAX_DIGEST_SIZE];
23996 
23997     if (x509 == NULL) {
23998         return ret;
23999     }
24000 
24001     issuerName = wolfSSL_X509_get_issuer_name((WOLFSSL_X509*)x509);
24002     if (issuerName != NULL) {
24003     #ifndef NO_SHA
24004         retHash = wc_ShaHash((const byte*)issuerName->name,
24005                              (word32)issuerName->sz, digest);
24006     #elif !defined(NO_SHA256)
24007         retHash = wc_Sha256Hash((const byte*)issuerName->name,
24008                                 (word32)issuerName->sz, digest);
24009     #endif
24010         if (retHash == 0) {
24011             ret = (unsigned long)MakeWordFromHash(digest);
24012         }
24013     }
24014     return ret;
24015 }
24016 #endif /* OPENSSL_EXTRA && (!NO_SHA || !NO_SHA256) */
24017 
24018 WOLFSSL_ABI
wolfSSL_X509_get_issuer_name(WOLFSSL_X509 * cert)24019 WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
24020 {
24021     WOLFSSL_ENTER("X509_get_issuer_name");
24022     if (cert && cert->issuer.sz > 0)
24023         return &cert->issuer;
24024     return NULL;
24025 }
24026 
24027 
wolfSSL_X509_get_signature_type(WOLFSSL_X509 * x509)24028 int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
24029 {
24030     int type = 0;
24031 
24032     WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
24033 
24034     if (x509 != NULL)
24035         type = x509->sigOID;
24036 
24037     return type;
24038 }
24039 
24040 #if defined(OPENSSL_EXTRA_X509_SMALL)
24041 
wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME * name)24042 int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
24043 {
24044     WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
24045     if (!name)
24046         return -1;
24047     return name->sz;
24048 }
24049 
24050 /* Searches for the first ENTRY of type NID
24051  * idx is the location to start searching from, the value at when the entry was
24052  *     found is stored into idx
24053  * returns a pointer to the entry on success and null on fail */
GetEntryByNID(WOLFSSL_X509_NAME * name,int nid,int * idx)24054 static WOLFSSL_X509_NAME_ENTRY* GetEntryByNID(WOLFSSL_X509_NAME* name, int nid,
24055         int* idx)
24056 {
24057     int i;
24058     WOLFSSL_X509_NAME_ENTRY* ret = NULL;
24059 
24060     /* and index of less than 0 is assumed to be starting from 0 */
24061     if (*idx < 0) {
24062         *idx = 0;
24063     }
24064 
24065     for (i = *idx; i < MAX_NAME_ENTRIES; i++) {
24066         if (name->entry[i].nid == nid) {
24067             ret = &name->entry[i];
24068             *idx = i;
24069             break;
24070         }
24071     }
24072     return ret;
24073 }
24074 
24075 
24076 /* Used to get a string from the WOLFSSL_X509_NAME structure that
24077  * corresponds with the NID value passed in. This finds the first entry with
24078  * matching NID value, if searching for the case where there is multiple
24079  * entries with the same NID value than other functions should be used
24080  * (i.e. wolfSSL_X509_NAME_get_index_by_NID, wolfSSL_X509_NAME_get_entry)
24081  *
24082  * name structure to get string from
24083  * nid  NID value to search for
24084  * buf  [out] buffer to hold results. If NULL then the buffer size minus the
24085  *      null char is returned.
24086  * len  size of "buf" passed in
24087  *
24088  * returns the length of string found, not including the NULL terminator.
24089  *         It's possible the function could return a negative value in the
24090  *         case that len is less than or equal to 0. A negative value is
24091  *         considered an error case.
24092  */
wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME * name,int nid,char * buf,int len)24093 int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
24094                                       int nid, char* buf, int len)
24095 {
24096     WOLFSSL_X509_NAME_ENTRY* e;
24097     unsigned char *text = NULL;
24098     int textSz = 0;
24099     int idx    = 0;
24100 
24101     WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
24102 
24103     if (name == NULL) {
24104         WOLFSSL_MSG("NULL argument passed in");
24105         return WOLFSSL_FATAL_ERROR;
24106     }
24107 
24108     e = GetEntryByNID(name, nid, &idx);
24109     if (e == NULL) {
24110         WOLFSSL_MSG("Entry type not found");
24111         return WOLFSSL_FATAL_ERROR;
24112     }
24113     text   = wolfSSL_ASN1_STRING_data(e->value);
24114     textSz = wolfSSL_ASN1_STRING_length(e->value);
24115 
24116     if (text == NULL) {
24117         WOLFSSL_MSG("Unable to get entry text");
24118         return WOLFSSL_FATAL_ERROR;
24119     }
24120 
24121     /* if buf is NULL return size of buffer needed (minus null char) */
24122     if (buf == NULL) {
24123         WOLFSSL_MSG("Buffer is NULL, returning buffer size only");
24124         return textSz;
24125     }
24126 
24127     /* buf is not NULL from above */
24128     if (text != NULL) {
24129         textSz = min(textSz + 1, len); /* + 1 to account for null char */
24130         if (textSz > 0) {
24131             XMEMCPY(buf, text, textSz - 1);
24132             buf[textSz - 1] = '\0';
24133         }
24134     }
24135 
24136     WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
24137     return (textSz - 1); /* do not include null character in size */
24138 }
24139 
24140 /* Creates a new WOLFSSL_EVP_PKEY structure that has the public key from x509
24141  *
24142  * returns a pointer to the created WOLFSSL_EVP_PKEY on success and NULL on fail
24143  */
wolfSSL_X509_get_pubkey(WOLFSSL_X509 * x509)24144 WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
24145 {
24146     WOLFSSL_EVP_PKEY* key = NULL;
24147     WOLFSSL_ENTER("X509_get_pubkey");
24148     if (x509 != NULL) {
24149         key = wolfSSL_EVP_PKEY_new_ex(x509->heap);
24150         if (key != NULL) {
24151             if (x509->pubKeyOID == RSAk) {
24152                 key->type = EVP_PKEY_RSA;
24153             }
24154             else if (x509->pubKeyOID == DSAk) {
24155                 key->type = EVP_PKEY_DSA;
24156             }
24157             else {
24158                 key->type = EVP_PKEY_EC;
24159             }
24160             key->save_type = 0;
24161             key->pkey.ptr = (char*)XMALLOC(
24162                         x509->pubKey.length, x509->heap,
24163                                                        DYNAMIC_TYPE_PUBLIC_KEY);
24164             if (key->pkey.ptr == NULL) {
24165                 wolfSSL_EVP_PKEY_free(key);
24166                 return NULL;
24167             }
24168             XMEMCPY(key->pkey.ptr, x509->pubKey.buffer, x509->pubKey.length);
24169             key->pkey_sz = x509->pubKey.length;
24170 
24171             #ifdef HAVE_ECC
24172                 key->pkey_curve = (int)x509->pkCurveOID;
24173             #endif /* HAVE_ECC */
24174 
24175             /* decode RSA key */
24176             #ifndef NO_RSA
24177             if (key->type == EVP_PKEY_RSA) {
24178                 key->ownRsa = 1;
24179                 key->rsa = wolfSSL_RSA_new();
24180                 if (key->rsa == NULL) {
24181                     wolfSSL_EVP_PKEY_free(key);
24182                     return NULL;
24183                 }
24184 
24185                 if (wolfSSL_RSA_LoadDer_ex(key->rsa,
24186                             (const unsigned char*)key->pkey.ptr, key->pkey_sz,
24187                             WOLFSSL_RSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
24188                     wolfSSL_EVP_PKEY_free(key);
24189                     return NULL;
24190                 }
24191             }
24192             #endif /* NO_RSA */
24193 
24194             /* decode ECC key */
24195             #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
24196             if (key->type == EVP_PKEY_EC) {
24197                 word32 idx = 0;
24198 
24199                 key->ownEcc = 1;
24200                 key->ecc = wolfSSL_EC_KEY_new();
24201                 if (key->ecc == NULL || key->ecc->internal == NULL) {
24202                     wolfSSL_EVP_PKEY_free(key);
24203                     return NULL;
24204                 }
24205 
24206                 /* not using wolfSSL_EC_KEY_LoadDer because public key in x509
24207                  * is in the format of x963 (no sequence at start of buffer) */
24208                 if (wc_EccPublicKeyDecode((const unsigned char*)key->pkey.ptr,
24209                         &idx, (ecc_key*)key->ecc->internal, key->pkey_sz) < 0) {
24210                     WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
24211                     wolfSSL_EVP_PKEY_free(key);
24212                     return NULL;
24213                 }
24214 
24215                 if (SetECKeyExternal(key->ecc) != WOLFSSL_SUCCESS) {
24216                     WOLFSSL_MSG("SetECKeyExternal failed");
24217                     wolfSSL_EVP_PKEY_free(key);
24218                     return NULL;
24219                 }
24220 
24221                 key->ecc->inSet = 1;
24222             }
24223             #endif /* HAVE_ECC */
24224 
24225             #ifndef NO_DSA
24226             if (key->type == EVP_PKEY_DSA) {
24227                 key->ownDsa = 1;
24228                 key->dsa = wolfSSL_DSA_new();
24229                 if (key->dsa == NULL) {
24230                     wolfSSL_EVP_PKEY_free(key);
24231                     return NULL;
24232                 }
24233 
24234                 if (wolfSSL_DSA_LoadDer_ex(key->dsa,
24235                             (const unsigned char*)key->pkey.ptr, key->pkey_sz, \
24236                             WOLFSSL_DSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
24237                     wolfSSL_DSA_free(key->dsa);
24238                     key->dsa = NULL;
24239                     wolfSSL_EVP_PKEY_free(key);
24240                     return NULL;
24241                 }
24242             }
24243             #endif /* NO_DSA */
24244         }
24245     }
24246     return key;
24247 }
24248 #endif /* OPENSSL_EXTRA_X509_SMALL */
24249 #endif /* !NO_CERTS */
24250 
24251 /* End of smaller subset of X509 compatibility functions. Avoid increasing the
24252  * size of this subset and its memory usage */
24253 #endif /* OPENSSL_EXTRA_X509_SMALL || KEEP_PEER_CERT || SESSION_CERTS */
24254 
24255 #if defined(OPENSSL_ALL)
24256 /* Takes two WOLFSSL_X509* certificates and performs a Sha hash of each, if the
24257    * hash values are the same, then it will do an XMEMCMP to confirm they are
24258    * identical. Returns a 0 when certificates match, returns a negative number
24259    * when certificates are not a match.
24260 */
wolfSSL_X509_cmp(const WOLFSSL_X509 * a,const WOLFSSL_X509 * b)24261 int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
24262 {
24263         const byte* derA;
24264         const byte* derB;
24265         int outSzA = 0;
24266         int outSzB = 0;
24267 
24268         if (a == NULL || b == NULL){
24269             return BAD_FUNC_ARG;
24270         }
24271 
24272         derA = wolfSSL_X509_get_der((WOLFSSL_X509*)a, &outSzA);
24273         if (derA == NULL){
24274             WOLFSSL_MSG("wolfSSL_X509_get_der - certificate A has failed");
24275             return WOLFSSL_FATAL_ERROR;
24276         }
24277         derB = wolfSSL_X509_get_der((WOLFSSL_X509*)b, &outSzB);
24278         if (derB == NULL){
24279             WOLFSSL_MSG("wolfSSL_X509_get_der - certificate B has failed");
24280             return WOLFSSL_FATAL_ERROR;
24281         }
24282 
24283         if (outSzA != outSzB || XMEMCMP(derA, derB, outSzA) != 0) {
24284             WOLFSSL_LEAVE("wolfSSL_X509_cmp", WOLFSSL_FATAL_ERROR);
24285             return WOLFSSL_FATAL_ERROR;
24286         }
24287 
24288         WOLFSSL_LEAVE("wolfSSL_X509_cmp", 0);
24289         return 0;
24290     }
24291 #endif /* OPENSSL_ALL */
24292 
24293 #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS)
wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509 * x509,int nid)24294     int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
24295     {
24296         int isSet = 0;
24297 
24298         WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
24299 
24300         if (x509 != NULL) {
24301             switch (nid) {
24302                 case NID_basic_constraints: isSet = x509->basicConstSet; break;
24303                 case NID_subject_alt_name: isSet = x509->subjAltNameSet; break;
24304                 case NID_authority_key_identifier: isSet = x509->authKeyIdSet; break;
24305                 case NID_subject_key_identifier: isSet = x509->subjKeyIdSet; break;
24306                 case NID_key_usage: isSet = x509->keyUsageSet; break;
24307                 case NID_crl_distribution_points: isSet = x509->CRLdistSet; break;
24308                 case NID_ext_key_usage: isSet = ((x509->extKeyUsageSrc) ? 1 : 0);
24309                     break;
24310                 case NID_info_access: isSet = x509->authInfoSet; break;
24311                 #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
24312                     case NID_certificate_policies: isSet = x509->certPolicySet; break;
24313                 #endif /* WOLFSSL_SEP || WOLFSSL_QT */
24314                 default:
24315                     WOLFSSL_MSG("NID not in table");
24316             }
24317         }
24318 
24319         WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
24320 
24321         return isSet;
24322     }
24323 
24324 
wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509 * x509,int nid)24325     int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
24326     {
24327         int crit = 0;
24328 
24329         WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
24330 
24331         if (x509 != NULL) {
24332             switch (nid) {
24333                 case NID_basic_constraints: crit = x509->basicConstCrit; break;
24334                 case NID_subject_alt_name: crit = x509->subjAltNameCrit; break;
24335                 case NID_authority_key_identifier: crit = x509->authKeyIdCrit; break;
24336                 case NID_subject_key_identifier: crit = x509->subjKeyIdCrit; break;
24337                 case NID_key_usage: crit = x509->keyUsageCrit; break;
24338                 case NID_crl_distribution_points: crit= x509->CRLdistCrit; break;
24339                 case NID_ext_key_usage: crit= x509->extKeyUsageCrit; break;
24340                 #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
24341                     case NID_certificate_policies: crit = x509->certPolicyCrit; break;
24342                 #endif /* WOLFSSL_SEP || WOLFSSL_QT */
24343             }
24344         }
24345 
24346         WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
24347 
24348         return crit;
24349     }
24350 
24351 
wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509 * x509)24352     int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
24353     {
24354         int isSet = 0;
24355 
24356         WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
24357 
24358         if (x509 != NULL)
24359             isSet = x509->basicConstPlSet;
24360 
24361         WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
24362 
24363         return isSet;
24364     }
24365 
24366 
wolfSSL_X509_get_pathLength(WOLFSSL_X509 * x509)24367     word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
24368     {
24369         word32 pathLength = 0;
24370 
24371         WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
24372 
24373         if (x509 != NULL)
24374             pathLength = x509->pathLength;
24375 
24376         WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
24377 
24378         return pathLength;
24379     }
24380 
24381 
wolfSSL_X509_get_keyUsage(WOLFSSL_X509 * x509)24382     unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
24383     {
24384         word16 usage = 0;
24385 
24386         WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
24387 
24388         if (x509 != NULL)
24389             usage = x509->keyUsage;
24390 
24391         WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
24392 
24393         return usage;
24394     }
24395 
24396 
wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509 * x509,byte * dst,int * dstLen)24397     byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
24398                                           byte* dst, int* dstLen)
24399     {
24400         byte *id = NULL;
24401         int copySz = 0;
24402 
24403         WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
24404 
24405         if (x509 != NULL) {
24406             if (x509->authKeyIdSet) {
24407                 copySz = min(dstLen != NULL ? *dstLen : 0,
24408                              (int)x509->authKeyIdSz);
24409                 id = x509->authKeyId;
24410             }
24411 
24412             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
24413                 XMEMCPY(dst, id, copySz);
24414                 id = dst;
24415                 *dstLen = copySz;
24416             }
24417         }
24418 
24419         WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
24420 
24421         return id;
24422     }
24423 
wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509 * x509,byte * dst,int * dstLen)24424     byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
24425                                         byte* dst, int* dstLen)
24426     {
24427         byte *id = NULL;
24428         int copySz = 0;
24429 
24430         WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
24431 
24432         if (x509 != NULL) {
24433             if (x509->subjKeyIdSet) {
24434                 copySz = min(dstLen != NULL ? *dstLen : 0,
24435                                                         (int)x509->subjKeyIdSz);
24436                 id = x509->subjKeyId;
24437             }
24438 
24439             if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
24440                 XMEMCPY(dst, id, copySz);
24441                 id = dst;
24442                 *dstLen = copySz;
24443             }
24444         }
24445 
24446         WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
24447 
24448         return id;
24449     }
24450 #endif /* !NO_CERTS && OPENSSL_EXTRA */
24451 
24452 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
24453     defined(OPENSSL_EXTRA_X509_SMALL)
24454 
24455     /* Looks up the index of the first entry encountered with matching NID
24456      * The search starts from index 'pos'
24457      * returns a negative value on failure and positive index value on success*/
wolfSSL_X509_NAME_get_index_by_NID(WOLFSSL_X509_NAME * name,int nid,int pos)24458     int wolfSSL_X509_NAME_get_index_by_NID(WOLFSSL_X509_NAME* name,
24459                                           int nid, int pos)
24460     {
24461         int value = nid, i;
24462 
24463         WOLFSSL_ENTER("wolfSSL_X509_NAME_get_index_by_NID");
24464 
24465         if (name == NULL) {
24466             return BAD_FUNC_ARG;
24467         }
24468 
24469         i = pos + 1; /* start search after index passed in */
24470         if (i < 0) {
24471             i = 0;
24472         }
24473 
24474         for (;i < name->entrySz && i < MAX_NAME_ENTRIES; i++) {
24475             if (name->entry[i].nid == value) {
24476                 return i;
24477             }
24478         }
24479         return WOLFSSL_FATAL_ERROR;
24480     }
24481 
24482 
wolfSSL_X509_NAME_ENTRY_get_data(WOLFSSL_X509_NAME_ENTRY * in)24483     WOLFSSL_ASN1_STRING*  wolfSSL_X509_NAME_ENTRY_get_data(
24484                                                     WOLFSSL_X509_NAME_ENTRY* in)
24485     {
24486         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_data");
24487         if (in == NULL)
24488             return NULL;
24489 
24490         return in->value;
24491     }
24492 
24493 
24494     /* Creates a new WOLFSSL_ASN1_STRING structure.
24495      *
24496      * returns a pointer to the new structure created on success or NULL if fail
24497      */
wolfSSL_ASN1_STRING_new(void)24498     WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_new(void)
24499     {
24500         WOLFSSL_ASN1_STRING* asn1;
24501 
24502 #ifdef WOLFSSL_DEBUG_OPENSSL
24503         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_new");
24504 #endif
24505 
24506         asn1 = (WOLFSSL_ASN1_STRING*)XMALLOC(sizeof(WOLFSSL_ASN1_STRING), NULL,
24507                 DYNAMIC_TYPE_OPENSSL);
24508         if (asn1 != NULL) {
24509             XMEMSET(asn1, 0, sizeof(WOLFSSL_ASN1_STRING));
24510         }
24511 
24512         return asn1; /* no check for null because error case is returning null*/
24513     }
24514 
24515     /**
24516      * Used to duplicate a passed in WOLFSSL_ASN1_STRING*
24517      * @param asn1 WOLFSSL_ASN1_STRING* to be duplicated
24518      * @return WOLFSSL_ASN1_STRING* the duplicate struct or NULL on error
24519      */
wolfSSL_ASN1_STRING_dup(WOLFSSL_ASN1_STRING * asn1)24520     WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_dup(WOLFSSL_ASN1_STRING* asn1)
24521     {
24522         WOLFSSL_ASN1_STRING* dupl = NULL;
24523 
24524         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_dup");
24525         if (!asn1) {
24526             WOLFSSL_MSG("Bad parameter");
24527             return NULL;
24528         }
24529 
24530         dupl = wolfSSL_ASN1_STRING_new();
24531         if (!dupl) {
24532             WOLFSSL_MSG("wolfSSL_ASN1_STRING_new error");
24533             return NULL;
24534         }
24535 
24536         dupl->type = asn1->type;
24537         dupl->flags = asn1->flags;
24538 
24539         if (wolfSSL_ASN1_STRING_set(dupl, asn1->data, asn1->length)
24540                 != WOLFSSL_SUCCESS) {
24541             WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
24542             wolfSSL_ASN1_STRING_free(dupl);
24543             return NULL;
24544         }
24545 
24546         return dupl;
24547     }
24548 
24549 
24550     /* used to free a WOLFSSL_ASN1_STRING structure */
wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING * asn1)24551     void wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING* asn1)
24552     {
24553 #ifdef WOLFSSL_DEBUG_OPENSSL
24554         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_free");
24555 #endif
24556 
24557         if (asn1 != NULL) {
24558             if (asn1->length > 0 && asn1->data != NULL && asn1->isDynamic) {
24559                 XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
24560             }
24561             XFREE(asn1, NULL, DYNAMIC_TYPE_OPENSSL);
24562         }
24563     }
24564 
wolfSSL_ASN1_STRING_cmp(const WOLFSSL_ASN1_STRING * a,const WOLFSSL_ASN1_STRING * b)24565     int wolfSSL_ASN1_STRING_cmp(const WOLFSSL_ASN1_STRING *a, const WOLFSSL_ASN1_STRING *b)
24566     {
24567         int i;
24568         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_cmp");
24569 
24570         if (!a || !b) {
24571             return WOLFSSL_FATAL_ERROR;
24572         }
24573 
24574         if (a->length != b->length) {
24575             return a->length - b->length;
24576         }
24577 
24578         if ((i = XMEMCMP(a->data, b->data, a->length)) != 0) {
24579             return i;
24580         }
24581 
24582         return a->type - b->type;
24583     }
24584 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
24585 
24586 #if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \
24587     defined(OPENSSL_EXTRA_X509_SMALL))
24588 
wolfSSL_ASN1_STRING_copy(WOLFSSL_ASN1_STRING * dest,const WOLFSSL_ASN1_STRING * src)24589     int wolfSSL_ASN1_STRING_copy(WOLFSSL_ASN1_STRING* dest,
24590                             const WOLFSSL_ASN1_STRING* src)
24591     {
24592         if (src == NULL || dest == NULL) {
24593             return WOLFSSL_FAILURE;
24594         }
24595         dest->type = src->type;
24596         if(wolfSSL_ASN1_STRING_set(dest, src->data, src->length)
24597                     != WOLFSSL_SUCCESS) {
24598                 return WOLFSSL_FAILURE;
24599         }
24600         dest->flags = src->flags;
24601 
24602         return WOLFSSL_SUCCESS;
24603     }
24604     /* Creates a new WOLFSSL_ASN1_STRING structure given the input type.
24605      *
24606      * type is the type of set when WOLFSSL_ASN1_STRING is created
24607      *
24608      * returns a pointer to the new structure created on success or NULL if fail
24609      */
wolfSSL_ASN1_STRING_type_new(int type)24610     WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_type_new(int type)
24611     {
24612         WOLFSSL_ASN1_STRING* asn1;
24613 
24614 #ifdef WOLFSSL_DEBUG_OPENSSL
24615         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_type_new");
24616 #endif
24617 
24618         asn1 = wolfSSL_ASN1_STRING_new();
24619         if (asn1 == NULL) {
24620             return NULL;
24621         }
24622         asn1->type = type;
24623 
24624         return asn1;
24625     }
24626 
24627 
24628 /******************************************************************************
24629 * wolfSSL_ASN1_STRING_type - returns the type of <asn1>
24630 *
24631 * RETURNS:
24632 * returns the type set for <asn1>. Otherwise, returns WOLFSSL_FAILURE.
24633 */
wolfSSL_ASN1_STRING_type(const WOLFSSL_ASN1_STRING * asn1)24634     int wolfSSL_ASN1_STRING_type(const WOLFSSL_ASN1_STRING* asn1)
24635     {
24636 
24637 #ifdef WOLFSSL_DEBUG_OPENSSL
24638         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_type");
24639 #endif
24640 
24641         if (asn1 == NULL) {
24642             return WOLFSSL_FAILURE;
24643         }
24644 
24645         return asn1->type;
24646     }
24647 
24648 #endif /* !NO_CERTS && OPENSSL_EXTRA */
24649 
24650 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
24651     defined(OPENSSL_EXTRA_X509_SMALL)
24652     /* if dataSz is negative then use XSTRLEN to find length of data
24653      * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
24654     /* `data` can be NULL and only buffer will be allocated */
wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING * asn1,const void * data,int dataSz)24655     int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data,
24656             int dataSz)
24657     {
24658         int sz;
24659 
24660 #ifdef WOLFSSL_DEBUG_OPENSSL
24661         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_set");
24662 #endif
24663 
24664         if (asn1 == NULL || (data == NULL && dataSz < 0)) {
24665             return WOLFSSL_FAILURE;
24666         }
24667 
24668         if (dataSz < 0) {
24669             sz = (int)XSTRLEN((const char*)data);
24670         }
24671         else {
24672             sz = dataSz;
24673         }
24674 
24675         if (sz < 0) {
24676             return WOLFSSL_FAILURE;
24677         }
24678 
24679         /* free any existing data before copying */
24680         if (asn1->data != NULL && asn1->isDynamic) {
24681             XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
24682             asn1->data = NULL;
24683         }
24684 
24685         if (sz + 1 > CTC_NAME_SIZE) { /* account for null char */
24686             /* create new data buffer and copy over */
24687             asn1->data = (char*)XMALLOC(sz + 1, NULL, DYNAMIC_TYPE_OPENSSL);
24688             if (asn1->data == NULL) {
24689                 return WOLFSSL_FAILURE;
24690             }
24691             asn1->isDynamic = 1;
24692         }
24693         else {
24694             XMEMSET(asn1->strData, 0, CTC_NAME_SIZE);
24695             asn1->data = asn1->strData;
24696             asn1->isDynamic = 0;
24697         }
24698         if (data != NULL) {
24699             XMEMCPY(asn1->data, data, sz);
24700             asn1->data[sz] = '\0';
24701         }
24702         asn1->length = sz;
24703 
24704         return WOLFSSL_SUCCESS;
24705     }
24706 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
24707 
24708 #ifndef NO_CERTS
24709 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
wolfSSL_ASN1_STRING_get0_data(const WOLFSSL_ASN1_STRING * asn)24710     const unsigned char* wolfSSL_ASN1_STRING_get0_data(
24711                                             const WOLFSSL_ASN1_STRING* asn)
24712     {
24713         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_get0_data");
24714 
24715         if (asn) {
24716             return (const unsigned char*)asn->data;
24717         } else {
24718             return NULL;
24719         }
24720     }
24721 
wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING * asn)24722     unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING* asn)
24723     {
24724 #ifdef WOLFSSL_DEBUG_OPENSSL
24725         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_data");
24726 #endif
24727 
24728         if (asn) {
24729             return (unsigned char*)asn->data;
24730         }
24731         else {
24732             return NULL;
24733         }
24734     }
24735 
24736 
wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING * asn)24737     int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING* asn)
24738     {
24739 #ifdef WOLFSSL_DEBUG_OPENSSL
24740         WOLFSSL_ENTER("wolfSSL_ASN1_STRING_length");
24741 #endif
24742 
24743         if (asn) {
24744             return asn->length;
24745         }
24746         else {
24747             return 0;
24748         }
24749     }
24750 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
24751 
24752 #ifdef OPENSSL_EXTRA
24753 #ifndef NO_WOLFSSL_STUB
wolfSSL_d2i_DISPLAYTEXT(WOLFSSL_ASN1_STRING ** asn,const unsigned char ** in,long len)24754     WOLFSSL_ASN1_STRING* wolfSSL_d2i_DISPLAYTEXT(WOLFSSL_ASN1_STRING **asn,
24755                                              const unsigned char **in, long len)
24756     {
24757         WOLFSSL_STUB("d2i_DISPLAYTEXT");
24758         (void)asn;
24759         (void)in;
24760         (void)len;
24761         return NULL;
24762     }
24763 #endif
24764 
24765 #ifndef NO_BIO
24766 #ifdef XSNPRINTF /* a snprintf function needs to be available */
24767     /* Writes the human readable form of x509 to bio.
24768      *
24769      * bio  WOLFSSL_BIO to write to.
24770      * x509 Certificate to write.
24771      *
24772      * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
24773      */
wolfSSL_X509_print_ex(WOLFSSL_BIO * bio,WOLFSSL_X509 * x509,unsigned long nmflags,unsigned long cflag)24774     int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
24775         unsigned long nmflags, unsigned long cflag)
24776     {
24777         WOLFSSL_ENTER("wolfSSL_X509_print_ex");
24778 
24779         /* flags currently not supported */
24780         (void)nmflags;
24781         (void)cflag;
24782 
24783         if (bio == NULL || x509 == NULL) {
24784             return WOLFSSL_FAILURE;
24785         }
24786 
24787         if (wolfSSL_BIO_write(bio, "Certificate:\n",
24788                       (int)XSTRLEN("Certificate:\n")) <= 0) {
24789                 return WOLFSSL_FAILURE;
24790         }
24791 
24792         if (wolfSSL_BIO_write(bio, "    Data:\n",
24793                       (int)XSTRLEN("    Data:\n")) <= 0) {
24794                 return WOLFSSL_FAILURE;
24795         }
24796 
24797         /* print version of cert */
24798         {
24799             int version;
24800             char tmp[20];
24801 
24802             if ((version = wolfSSL_X509_version(x509)) < 0) {
24803                 WOLFSSL_MSG("Error getting X509 version");
24804                 return WOLFSSL_FAILURE;
24805             }
24806             if (wolfSSL_BIO_write(bio, "        Version:",
24807                           (int)XSTRLEN("        Version:")) <= 0) {
24808                 return WOLFSSL_FAILURE;
24809             }
24810             XSNPRINTF(tmp, sizeof(tmp), " %d (0x%x)\n", version, (byte)version-1);
24811             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
24812                 return WOLFSSL_FAILURE;
24813             }
24814         }
24815 
24816         /* print serial number out */
24817         {
24818             unsigned char serial[32];
24819             int  sz = sizeof(serial);
24820 
24821             XMEMSET(serial, 0, sz);
24822             if (wolfSSL_X509_get_serial_number(x509, serial, &sz)
24823                     != WOLFSSL_SUCCESS) {
24824                 WOLFSSL_MSG("Error getting x509 serial number");
24825                 return WOLFSSL_FAILURE;
24826             }
24827             if (wolfSSL_BIO_write(bio, "        Serial Number:",
24828                           (int)XSTRLEN("        Serial Number:")) <= 0) {
24829                 return WOLFSSL_FAILURE;
24830             }
24831 
24832             /* if serial can fit into byte than print on the same line */
24833             if (sz <= (int)sizeof(byte)) {
24834                 char tmp[17];
24835                 XSNPRINTF(tmp, sizeof(tmp), " %d (0x%x)\n", serial[0],serial[0]);
24836                 if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
24837                     return WOLFSSL_FAILURE;
24838                 }
24839             }
24840             else {
24841                 int i;
24842                 char tmp[100];
24843                 int  tmpSz = 100;
24844                 char val[5];
24845                 int  valSz = 5;
24846 
24847                 /* serial is larger than int size so print off hex values */
24848                 if (wolfSSL_BIO_write(bio, "\n            ",
24849                               (int)XSTRLEN("\n            ")) <= 0) {
24850                     return WOLFSSL_FAILURE;
24851                 }
24852                 tmp[0] = '\0';
24853                 for (i = 0; i < sz - 1 && (3 * i) < tmpSz - valSz; i++) {
24854                     XSNPRINTF(val, sizeof(val) - 1, "%02x:", serial[i]);
24855                     val[3] = '\0'; /* make sure is null terminated */
24856                     XSTRNCAT(tmp, val, valSz);
24857                 }
24858                 XSNPRINTF(val, sizeof(val) - 1, "%02x\n", serial[i]);
24859                 val[3] = '\0'; /* make sure is null terminated */
24860                 XSTRNCAT(tmp, val, valSz);
24861                 if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
24862                     return WOLFSSL_FAILURE;
24863                 }
24864             }
24865         }
24866 
24867         /* print signature algo */
24868         {
24869             int oid;
24870             const char* sig;
24871 
24872             if ((oid = wolfSSL_X509_get_signature_type(x509)) <= 0) {
24873                 WOLFSSL_MSG("Error getting x509 signature type");
24874                 return WOLFSSL_FAILURE;
24875             }
24876             if (wolfSSL_BIO_write(bio, "        Signature Algorithm: ",
24877                           (int)XSTRLEN("        Signature Algorithm: ")) <= 0) {
24878                 return WOLFSSL_FAILURE;
24879             }
24880             sig = GetSigName(oid);
24881             if (wolfSSL_BIO_write(bio, sig, (int)XSTRLEN(sig)) <= 0) {
24882                 return WOLFSSL_FAILURE;
24883             }
24884             if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
24885                 return WOLFSSL_FAILURE;
24886             }
24887         }
24888 
24889         /* print issuer */
24890         {
24891             char* issuer;
24892         #ifdef WOLFSSL_SMALL_STACK
24893             char* buff  = NULL;
24894             int   issSz = 0;
24895         #else
24896             char buff[256];
24897             int  issSz = 256;
24898         #endif
24899 
24900         #if defined(WOLFSSL_QT)
24901             issuer = wolfSSL_X509_get_name_oneline(
24902                                wolfSSL_X509_get_issuer_name(x509), buff, issSz);
24903         #else
24904             issuer = wolfSSL_X509_NAME_oneline(
24905                                wolfSSL_X509_get_issuer_name(x509), buff, issSz);
24906         #endif
24907 
24908             if (wolfSSL_BIO_write(bio, "        Issuer: ",
24909                           (int)XSTRLEN("        Issuer: ")) <= 0) {
24910                 #ifdef WOLFSSL_SMALL_STACK
24911                 XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
24912                 #endif
24913                 return WOLFSSL_FAILURE;
24914             }
24915             if (issuer != NULL) {
24916                 if (wolfSSL_BIO_write(bio, issuer, (int)XSTRLEN(issuer)) <= 0) {
24917                     #ifdef WOLFSSL_SMALL_STACK
24918                     XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
24919                     #endif
24920                     return WOLFSSL_FAILURE;
24921                 }
24922             }
24923             #ifdef WOLFSSL_SMALL_STACK
24924             XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
24925             #endif
24926             if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
24927                 return WOLFSSL_FAILURE;
24928             }
24929         }
24930 
24931     #ifndef NO_ASN_TIME
24932         /* print validity */
24933         {
24934             char tmp[80];
24935 
24936             if (wolfSSL_BIO_write(bio, "        Validity\n",
24937                           (int)XSTRLEN("        Validity\n")) <= 0) {
24938                 return WOLFSSL_FAILURE;
24939             }
24940 
24941             if (wolfSSL_BIO_write(bio, "            Not Before: ",
24942                           (int)XSTRLEN("            Not Before: ")) <= 0) {
24943                 return WOLFSSL_FAILURE;
24944             }
24945             if (x509->notBefore.length > 0) {
24946                 if (GetTimeString(x509->notBefore.data, ASN_UTC_TIME,
24947                     tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
24948                     if (GetTimeString(x509->notBefore.data, ASN_GENERALIZED_TIME,
24949                     tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
24950                         WOLFSSL_MSG("Error getting not before date");
24951                         return WOLFSSL_FAILURE;
24952                     }
24953                 }
24954             }
24955             else {
24956                 XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
24957             }
24958             tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
24959             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
24960                 return WOLFSSL_FAILURE;
24961             }
24962 
24963             if (wolfSSL_BIO_write(bio, "\n            Not After : ",
24964                           (int)XSTRLEN("\n            Not After : ")) <= 0) {
24965                 return WOLFSSL_FAILURE;
24966             }
24967             if (x509->notAfter.length > 0) {
24968                 if (GetTimeString(x509->notAfter.data, ASN_UTC_TIME,
24969                     tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
24970                     if (GetTimeString(x509->notAfter.data, ASN_GENERALIZED_TIME,
24971                         tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
24972                         WOLFSSL_MSG("Error getting not after date");
24973                         return WOLFSSL_FAILURE;
24974                     }
24975                 }
24976             }
24977             else {
24978                 XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
24979             }
24980             tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
24981             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
24982                 return WOLFSSL_FAILURE;
24983             }
24984         }
24985     #endif
24986 
24987         /* print subject */
24988         {
24989             char* subject;
24990         #ifdef WOLFSSL_SMALL_STACK
24991             char* buff  = NULL;
24992             int   subSz = 0;
24993         #else
24994             char buff[256];
24995             int  subSz = 256;
24996         #endif
24997 
24998         #if defined(WOLFSSL_QT)
24999             subject = wolfSSL_X509_get_name_oneline(
25000                               wolfSSL_X509_get_subject_name(x509), buff, subSz);
25001         #else
25002             subject = wolfSSL_X509_NAME_oneline(
25003                               wolfSSL_X509_get_subject_name(x509), buff, subSz);
25004         #endif
25005 
25006             if (wolfSSL_BIO_write(bio, "\n        Subject: ",
25007                           (int)XSTRLEN("\n        Subject: ")) <= 0) {
25008                 #ifdef WOLFSSL_SMALL_STACK
25009                 XFREE(subject, NULL, DYNAMIC_TYPE_OPENSSL);
25010                 #endif
25011                 return WOLFSSL_FAILURE;
25012             }
25013             if (subject != NULL) {
25014                 if (wolfSSL_BIO_write(bio, subject, (int)XSTRLEN(subject)) <= 0) {
25015                     #ifdef WOLFSSL_SMALL_STACK
25016                     XFREE(subject, NULL, DYNAMIC_TYPE_OPENSSL);
25017                     #endif
25018                     return WOLFSSL_FAILURE;
25019                 }
25020             }
25021             #ifdef WOLFSSL_SMALL_STACK
25022             XFREE(subject, NULL, DYNAMIC_TYPE_OPENSSL);
25023             #endif
25024         }
25025 
25026         /* get and print public key */
25027         if (wolfSSL_BIO_write(bio, "\n        Subject Public Key Info:\n",
25028                       (int)XSTRLEN("\n        Subject Public Key Info:\n")) <= 0) {
25029             return WOLFSSL_FAILURE;
25030         }
25031         {
25032         #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || defined(HAVE_ECC)
25033             char tmp[100];
25034         #endif
25035 
25036             switch (x509->pubKeyOID) {
25037             #ifndef NO_RSA
25038                 case RSAk:
25039                     if (wolfSSL_BIO_write(bio,
25040                                 "            Public Key Algorithm: rsaEncryption\n",
25041                    (int)XSTRLEN("            Public Key Algorithm: rsaEncryption\n")) <= 0) {
25042                         return WOLFSSL_FAILURE;
25043                     }
25044                 #ifdef HAVE_USER_RSA
25045                     if (wolfSSL_BIO_write(bio,
25046                         "                Build without user RSA to print key\n",
25047            (int)XSTRLEN("                Build without user RSA to print key\n"))
25048                         <= 0) {
25049                         return WOLFSSL_FAILURE;
25050                     }
25051                 #else
25052                     {
25053                     #ifdef WOLFSSL_SMALL_STACK
25054                         RsaKey *rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
25055                                 DYNAMIC_TYPE_RSA);
25056                         if (rsa == NULL) {
25057                             WOLFSSL_MSG("RsaKey malloc failure");
25058                             return WOLFSSL_FAILURE;
25059                         }
25060                     #else
25061                         RsaKey rsa[1];
25062                     #endif
25063                         word32 idx = 0;
25064                         int  sz;
25065                         byte lbit = 0;
25066                         int  rawLen;
25067                         unsigned char* rawKey;
25068 
25069                         if (wc_InitRsaKey(rsa, NULL) != 0) {
25070                             WOLFSSL_MSG("wc_InitRsaKey failure");
25071                             return WOLFSSL_FAILURE;
25072                         }
25073                         if (wc_RsaPublicKeyDecode(x509->pubKey.buffer,
25074                                 &idx, rsa, x509->pubKey.length) != 0) {
25075                             WOLFSSL_MSG("Error decoding RSA key");
25076                             wc_FreeRsaKey(rsa);
25077                         #ifdef WOLFSSL_SMALL_STACK
25078                             XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
25079                         #endif
25080                             return WOLFSSL_FAILURE;
25081                         }
25082                         if ((sz = wc_RsaEncryptSize(rsa)) < 0) {
25083                             WOLFSSL_MSG("Error getting RSA key size");
25084                             wc_FreeRsaKey(rsa);
25085                         #ifdef WOLFSSL_SMALL_STACK
25086                             XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
25087                         #endif
25088                             return WOLFSSL_FAILURE;
25089                         }
25090                         XSNPRINTF(tmp, sizeof(tmp) - 1, "%s%s: (%d bit)\n%s\n",
25091                                 "                ", "Public-Key", 8 * sz,
25092                                 "                Modulus:");
25093                         tmp[sizeof(tmp) - 1] = '\0';
25094                         if (wolfSSL_BIO_write(bio, tmp,
25095                                                       (int)XSTRLEN(tmp)) <= 0) {
25096                             wc_FreeRsaKey(rsa);
25097                         #ifdef WOLFSSL_SMALL_STACK
25098                             XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
25099                         #endif
25100                             return WOLFSSL_FAILURE;
25101                         }
25102 
25103                         /* print out modulus */
25104                         XSNPRINTF(tmp, sizeof(tmp) - 1,"                    ");
25105                         tmp[sizeof(tmp) - 1] = '\0';
25106                         if (mp_leading_bit(&rsa->n)) {
25107                             lbit = 1;
25108                             XSTRNCAT(tmp, "00", 3);
25109                         }
25110 
25111                         rawLen = mp_unsigned_bin_size(&rsa->n);
25112                         rawKey = (unsigned char*)XMALLOC(rawLen, NULL,
25113                                 DYNAMIC_TYPE_TMP_BUFFER);
25114                         if (rawKey == NULL) {
25115                             WOLFSSL_MSG("Memory error");
25116                             wc_FreeRsaKey(rsa);
25117                         #ifdef WOLFSSL_SMALL_STACK
25118                             XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
25119                         #endif
25120                             return WOLFSSL_FAILURE;
25121                         }
25122                         mp_to_unsigned_bin(&rsa->n, rawKey);
25123                         for (idx = 0; idx < (word32)rawLen; idx++) {
25124                             char val[5];
25125                             int valSz = 5;
25126 
25127                             if ((idx == 0) && !lbit) {
25128                                 XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]);
25129                             }
25130                             else if ((idx != 0) && (((idx + lbit) % 15) == 0)) {
25131                                 tmp[sizeof(tmp) - 1] = '\0';
25132                                 if (wolfSSL_BIO_write(bio, tmp,
25133                                                       (int)XSTRLEN(tmp)) <= 0) {
25134                                     XFREE(rawKey, NULL,
25135                                         DYNAMIC_TYPE_TMP_BUFFER);
25136                                     wc_FreeRsaKey(rsa);
25137                                 #ifdef WOLFSSL_SMALL_STACK
25138                                     XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
25139                                 #endif
25140                                     return WOLFSSL_FAILURE;
25141                                 }
25142                                 XSNPRINTF(tmp, sizeof(tmp) - 1,
25143                                         ":\n                    ");
25144                                 XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]);
25145                             }
25146                             else {
25147                                 XSNPRINTF(val, valSz - 1, ":%02x", rawKey[idx]);
25148                             }
25149                             XSTRNCAT(tmp, val, valSz);
25150                         }
25151                         XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25152 
25153                         /* print out remaining modulus values */
25154                         if ((idx > 0) && (((idx - 1 + lbit) % 15) != 0)) {
25155                             tmp[sizeof(tmp) - 1] = '\0';
25156                             if (wolfSSL_BIO_write(bio, tmp,
25157                                                       (int)XSTRLEN(tmp)) <= 0) {
25158                                 wc_FreeRsaKey(rsa);
25159                             #ifdef WOLFSSL_SMALL_STACK
25160                                 XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
25161                             #endif
25162                                 return WOLFSSL_FAILURE;
25163                             }
25164                         }
25165 
25166                         /* print out exponent values */
25167                         rawLen = mp_unsigned_bin_size(&rsa->e);
25168                         if (rawLen < 0) {
25169                             WOLFSSL_MSG("Error getting exponent size");
25170                             wc_FreeRsaKey(rsa);
25171                         #ifdef WOLFSSL_SMALL_STACK
25172                             XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
25173                         #endif
25174                             return WOLFSSL_FAILURE;
25175                         }
25176 
25177                         if ((word32)rawLen < sizeof(word32)) {
25178                             rawLen = sizeof(word32);
25179                         }
25180                         rawKey = (unsigned char*)XMALLOC(rawLen, NULL,
25181                                 DYNAMIC_TYPE_TMP_BUFFER);
25182                         if (rawKey == NULL) {
25183                             WOLFSSL_MSG("Memory error");
25184                             wc_FreeRsaKey(rsa);
25185                         #ifdef WOLFSSL_SMALL_STACK
25186                             XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
25187                         #endif
25188                             return WOLFSSL_FAILURE;
25189                         }
25190                         XMEMSET(rawKey, 0, rawLen);
25191                         mp_to_unsigned_bin(&rsa->e, rawKey);
25192                         if ((word32)rawLen <= sizeof(word32)) {
25193                             idx = *(word32*)rawKey;
25194                         #ifdef BIG_ENDIAN_ORDER
25195                             idx = ByteReverseWord32(idx);
25196                         #endif
25197                         }
25198                         XSNPRINTF(tmp, sizeof(tmp) - 1,
25199                             "\n                Exponent: %d (0x%x)\n",idx, idx);
25200                         if (wolfSSL_BIO_write(bio, tmp,
25201                                                       (int)XSTRLEN(tmp)) <= 0) {
25202                             XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25203                             wc_FreeRsaKey(rsa);
25204                         #ifdef WOLFSSL_SMALL_STACK
25205                             XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
25206                         #endif
25207                             return WOLFSSL_FAILURE;
25208                         }
25209                         XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25210                         wc_FreeRsaKey(rsa);
25211                     #ifdef WOLFSSL_SMALL_STACK
25212                         XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
25213                     #endif
25214                     }
25215                 #endif /* HAVE_USER_RSA */
25216                     break;
25217             #endif /* NO_RSA */
25218 
25219             #ifdef HAVE_ECC
25220                 case ECDSAk:
25221                     {
25222                         word32 i;
25223                     #ifdef WOLFSSL_SMALL_STACK
25224                         ecc_key *ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL,
25225                                 DYNAMIC_TYPE_ECC);
25226                         if (ecc == NULL)
25227                             return WOLFSSL_FAILURE;
25228                     #else
25229                         ecc_key ecc[1];
25230                     #endif
25231 
25232                         if (wolfSSL_BIO_write(bio,
25233                                 "            Public Key Algorithm: EC\n",
25234                    (int)XSTRLEN("            Public Key Algorithm: EC\n")) <= 0) {
25235                         #ifdef WOLFSSL_SMALL_STACK
25236                             XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
25237                         #endif
25238                             return WOLFSSL_FAILURE;
25239                         }
25240                         if (wc_ecc_init_ex(ecc, x509->heap, INVALID_DEVID)
25241                                 != 0) {
25242                         #ifdef WOLFSSL_SMALL_STACK
25243                             XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
25244                         #endif
25245                             return WOLFSSL_FAILURE;
25246                         }
25247 
25248                         i = 0;
25249                         if (wc_EccPublicKeyDecode(x509->pubKey.buffer, &i,
25250                                               ecc, x509->pubKey.length) != 0) {
25251                             wc_ecc_free(ecc);
25252                         #ifdef WOLFSSL_SMALL_STACK
25253                             XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
25254                         #endif
25255                             return WOLFSSL_FAILURE;
25256                         }
25257                         XSNPRINTF(tmp, sizeof(tmp) - 1, "%s%s: (%d bit)\n%s\n",
25258                                 "                 ", "Public-Key",
25259                                 8 * wc_ecc_size(ecc),
25260                                 "                 pub:");
25261                         tmp[sizeof(tmp) - 1] = '\0';
25262                         if (wolfSSL_BIO_write(bio, tmp,
25263                                                       (int)XSTRLEN(tmp)) <= 0) {
25264                             wc_ecc_free(ecc);
25265                         #ifdef WOLFSSL_SMALL_STACK
25266                             XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
25267                         #endif
25268                             return WOLFSSL_FAILURE;
25269                         }
25270                         XSNPRINTF(tmp, sizeof(tmp) - 1,"                     ");
25271                         {
25272                             word32 derSz;
25273                             byte*  der;
25274 
25275                             derSz = wc_ecc_size(ecc) * WOLFSSL_BIT_SIZE;
25276                             der = (byte*)XMALLOC(derSz, x509->heap,
25277                                     DYNAMIC_TYPE_TMP_BUFFER);
25278                             if (der == NULL) {
25279                                 wc_ecc_free(ecc);
25280                             #ifdef WOLFSSL_SMALL_STACK
25281                                 XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
25282                             #endif
25283                                 return WOLFSSL_FAILURE;
25284                             }
25285                             PRIVATE_KEY_UNLOCK();
25286                             if (wc_ecc_export_x963(ecc, der, &derSz) != 0) {
25287                                 PRIVATE_KEY_LOCK();
25288                                 wc_ecc_free(ecc);
25289                             #ifdef WOLFSSL_SMALL_STACK
25290                                 XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
25291                             #endif
25292                                 XFREE(der, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
25293                                 return WOLFSSL_FAILURE;
25294                             }
25295                             PRIVATE_KEY_LOCK();
25296                             for (i = 0; i < derSz; i++) {
25297                                 char val[5];
25298                                 int valSz = 5;
25299 
25300                                 if (i == 0) {
25301                                     XSNPRINTF(val, valSz - 1, "%02x", der[i]);
25302                                 }
25303                                 else if ((i % 15) == 0) {
25304                                     tmp[sizeof(tmp) - 1] = '\0';
25305                                     if (wolfSSL_BIO_write(bio, tmp,
25306                                                 (int)XSTRLEN(tmp)) <= 0) {
25307                                         wc_ecc_free(ecc);
25308                                     #ifdef WOLFSSL_SMALL_STACK
25309                                         XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
25310                                     #endif
25311                                         XFREE(der, x509->heap,
25312                                                 DYNAMIC_TYPE_TMP_BUFFER);
25313                                         return WOLFSSL_FAILURE;
25314                                     }
25315                                     XSNPRINTF(tmp, sizeof(tmp) - 1,
25316                                         ":\n                     ");
25317                                     XSNPRINTF(val, valSz - 1, "%02x", der[i]);
25318                                 }
25319                                 else {
25320                                     XSNPRINTF(val, valSz - 1, ":%02x", der[i]);
25321                                 }
25322                                 XSTRNCAT(tmp, val, valSz);
25323                             }
25324 
25325                             /* print out remaining modulus values */
25326                             if ((i > 0) && (((i - 1) % 15) != 0)) {
25327                                 tmp[sizeof(tmp) - 1] = '\0';
25328                                 if (wolfSSL_BIO_write(bio, tmp,
25329                                                       (int)XSTRLEN(tmp)) <= 0) {
25330                                     wc_ecc_free(ecc);
25331                                 #ifdef WOLFSSL_SMALL_STACK
25332                                     XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
25333                                 #endif
25334                                     XFREE(der, x509->heap,
25335                                                 DYNAMIC_TYPE_TMP_BUFFER);
25336                                     return WOLFSSL_FAILURE;
25337                                 }
25338                             }
25339 
25340                             XFREE(der, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
25341                         }
25342                         XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s%s: %s\n",
25343                                 "                ", "ASN1 OID",
25344                                 ecc->dp->name);
25345                         if (wolfSSL_BIO_write(bio, tmp,
25346                                                       (int)XSTRLEN(tmp)) <= 0) {
25347                             wc_ecc_free(ecc);
25348                         #ifdef WOLFSSL_SMALL_STACK
25349                             XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
25350                         #endif
25351                             return WOLFSSL_FAILURE;
25352                         }
25353                     #ifdef WOLFSSL_SMALL_STACK
25354                         XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
25355                     #endif
25356                         wc_ecc_free(ecc);
25357                     }
25358                     break;
25359             #endif /* HAVE_ECC */
25360                 default:
25361                     WOLFSSL_MSG("Unknown key type");
25362                     return WOLFSSL_FAILURE;
25363             }
25364         }
25365 
25366         /* print out extensions */
25367         if (wolfSSL_BIO_write(bio, "        X509v3 extensions:\n",
25368                       (int)XSTRLEN("        X509v3 extensions:\n")) <= 0) {
25369             return WOLFSSL_FAILURE;
25370         }
25371 
25372         /* print subject key id */
25373         if (x509->subjKeyIdSet && x509->subjKeyId != NULL &&
25374                 x509->subjKeyIdSz > 0) {
25375             char tmp[100];
25376             word32 i;
25377             char val[5];
25378             int valSz = 5;
25379 
25380 
25381             if (wolfSSL_BIO_write(bio,
25382                         "            X509v3 Subject Key Identifier: \n",
25383            (int)XSTRLEN("            X509v3 Subject Key Identifier: \n"))
25384                  <= 0) {
25385                 return WOLFSSL_FAILURE;
25386             }
25387 
25388             XSNPRINTF(tmp, sizeof(tmp) - 1, "                ");
25389             for (i = 0; i < sizeof(tmp) && i < (x509->subjKeyIdSz - 1); i++) {
25390                 XSNPRINTF(val, valSz - 1, "%02X:", x509->subjKeyId[i]);
25391                 XSTRNCAT(tmp, val, valSz);
25392             }
25393             XSNPRINTF(val, valSz - 1, "%02X\n", x509->subjKeyId[i]);
25394             XSTRNCAT(tmp, val, valSz);
25395             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
25396                 return WOLFSSL_FAILURE;
25397             }
25398         }
25399 
25400         /* printf out authority key id */
25401         if (x509->authKeyIdSet && x509->authKeyId != NULL &&
25402                 x509->authKeyIdSz > 0) {
25403             char tmp[100];
25404             word32 i;
25405             char val[5];
25406             int valSz = 5;
25407             int len = 0;
25408 
25409             if (wolfSSL_BIO_write(bio,
25410                         "            X509v3 Authority Key Identifier: \n",
25411            (int)XSTRLEN("            X509v3 Authority Key Identifier: \n"))
25412                  <= 0) {
25413                 return WOLFSSL_FAILURE;
25414             }
25415 
25416             XSNPRINTF(tmp, sizeof(tmp) - 1, "                keyid");
25417             for (i = 0; i < x509->authKeyIdSz; i++) {
25418                 /* check if buffer is almost full */
25419                 if (XSTRLEN(tmp) >= sizeof(tmp) - valSz) {
25420                     if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
25421                         return WOLFSSL_FAILURE;
25422                     }
25423                     tmp[0] = '\0';
25424                 }
25425                 XSNPRINTF(val, valSz - 1, ":%02X", x509->authKeyId[i]);
25426                 XSTRNCAT(tmp, val, valSz);
25427             }
25428             len = (int)XSTRLEN("\n");
25429             XSTRNCAT(tmp, "\n", len + 1);
25430             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
25431                 return WOLFSSL_FAILURE;
25432             }
25433         }
25434 
25435         /* print basic constraint */
25436         if (x509->basicConstSet) {
25437             char tmp[100];
25438 
25439             if (wolfSSL_BIO_write(bio,
25440                         "\n            X509v3 Basic Constraints: \n",
25441            (int)XSTRLEN("\n            X509v3 Basic Constraints: \n"))
25442                  <= 0) {
25443                 return WOLFSSL_FAILURE;
25444             }
25445             XSNPRINTF(tmp, sizeof(tmp),
25446                     "                CA:%s\n",
25447                     (x509->isCa)? "TRUE": "FALSE");
25448             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
25449                 return WOLFSSL_FAILURE;
25450             }
25451         }
25452 
25453         /* print out signature */
25454         if (x509->sig.length > 0) {
25455             unsigned char* sig;
25456             int sigSz;
25457             int i;
25458             char tmp[100];
25459             int sigOid = wolfSSL_X509_get_signature_type(x509);
25460 
25461             if (wolfSSL_BIO_write(bio,
25462                                 "    Signature Algorithm: ",
25463                    (int)XSTRLEN("    Signature Algorithm: ")) <= 0) {
25464                 return WOLFSSL_FAILURE;
25465             }
25466             XSNPRINTF(tmp, sizeof(tmp) - 1,"%s\n", GetSigName(sigOid));
25467             tmp[sizeof(tmp) - 1] = '\0';
25468             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
25469                 return WOLFSSL_FAILURE;
25470             }
25471 
25472             sigSz = (int)x509->sig.length;
25473             sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25474             if (sig == NULL) {
25475                 return WOLFSSL_FAILURE;
25476             }
25477 
25478             if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) {
25479                 XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25480                 return WOLFSSL_FAILURE;
25481             }
25482             XSNPRINTF(tmp, sizeof(tmp) - 1,"        ");
25483             tmp[sizeof(tmp) - 1] = '\0';
25484             for (i = 0; i < sigSz; i++) {
25485                 char val[5];
25486                 int valSz = 5;
25487 
25488                 if (i == 0) {
25489                     XSNPRINTF(val, valSz - 1, "%02x", sig[i]);
25490                 }
25491                 else if (((i % 18) == 0)) {
25492                     tmp[sizeof(tmp) - 1] = '\0';
25493                     if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp))
25494                             <= 0) {
25495                         XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25496                         return WOLFSSL_FAILURE;
25497                     }
25498                     XSNPRINTF(tmp, sizeof(tmp) - 1,
25499                             ":\n        ");
25500                     XSNPRINTF(val, valSz - 1, "%02x", sig[i]);
25501                 }
25502                 else {
25503                     XSNPRINTF(val, valSz - 1, ":%02x", sig[i]);
25504                 }
25505                 XSTRNCAT(tmp, val, valSz);
25506             }
25507             XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25508 
25509             /* print out remaining sig values */
25510             if ((i > 0) && (((i - 1) % 18) != 0)) {
25511                     tmp[sizeof(tmp) - 1] = '\0';
25512                     if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp))
25513                             <= 0) {
25514                         return WOLFSSL_FAILURE;
25515                     }
25516             }
25517         }
25518 
25519         /* done with print out */
25520         if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
25521             return WOLFSSL_FAILURE;
25522         }
25523 
25524         return WOLFSSL_SUCCESS;
25525     }
wolfSSL_X509_print(WOLFSSL_BIO * bio,WOLFSSL_X509 * x509)25526     int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
25527     {
25528         return wolfSSL_X509_print_ex(bio, x509, 0, 0);
25529     }
25530 
25531 #ifndef NO_FILESYSTEM
wolfSSL_X509_print_fp(XFILE fp,WOLFSSL_X509 * x509)25532     int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509)
25533     {
25534         WOLFSSL_BIO* bio;
25535         int ret;
25536 
25537         WOLFSSL_ENTER("wolfSSL_X509_print_fp");
25538 
25539         if (!fp || !x509) {
25540             WOLFSSL_MSG("Bad parameter");
25541             return WOLFSSL_FAILURE;
25542         }
25543 
25544         if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()))) {
25545             WOLFSSL_MSG("wolfSSL_BIO_new wolfSSL_BIO_s_file error");
25546             return WOLFSSL_FAILURE;
25547         }
25548 
25549         if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
25550             WOLFSSL_MSG("wolfSSL_BIO_set_fp error");
25551             wolfSSL_BIO_free(bio);
25552             return WOLFSSL_FAILURE;
25553         }
25554 
25555         ret = wolfSSL_X509_print(bio, x509);
25556 
25557         wolfSSL_BIO_free(bio);
25558 
25559         return ret;
25560     }
25561 #endif /* NO_FILESYSTEM */
25562 
25563 #endif /* XSNPRINTF */
25564 
wolfSSL_X509_signature_print(WOLFSSL_BIO * bp,const WOLFSSL_X509_ALGOR * sigalg,const WOLFSSL_ASN1_STRING * sig)25565     int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp,
25566             const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig)
25567     {
25568         (void)sig;
25569 
25570         WOLFSSL_ENTER("wolfSSL_X509_signature_print");
25571 
25572         if (!bp || !sigalg) {
25573             WOLFSSL_MSG("Bad parameter");
25574             return WOLFSSL_FAILURE;
25575         }
25576 
25577         if (wolfSSL_BIO_puts(bp, "    Signature Algorithm: ") <= 0) {
25578             WOLFSSL_MSG("wolfSSL_BIO_puts error");
25579             return WOLFSSL_FAILURE;
25580         }
25581 
25582         if (wolfSSL_i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) {
25583             WOLFSSL_MSG("wolfSSL_i2a_ASN1_OBJECT error");
25584             return WOLFSSL_FAILURE;
25585         }
25586 
25587         return WOLFSSL_SUCCESS;
25588     }
25589 #endif /* !NO_BIO */
25590 
25591 #ifndef NO_WOLFSSL_STUB
wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING ** psig,const WOLFSSL_X509_ALGOR ** palg,const WOLFSSL_X509 * x509)25592     void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig,
25593             const WOLFSSL_X509_ALGOR **palg, const WOLFSSL_X509 *x509)
25594     {
25595         (void)psig;
25596         (void)palg;
25597         (void)x509;
25598         WOLFSSL_STUB("wolfSSL_X509_get0_signature");
25599     }
25600 #endif
25601 
25602 #endif /* OPENSSL_EXTRA */
25603 
25604 #endif /* !NO_CERTS */
25605 
25606 #ifdef OPENSSL_EXTRA
25607 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
25608 /* return authentication NID corresponding to cipher suite
25609  * @param cipher a pointer to WOLFSSL_CIPHER
25610  * return NID if found, NID_undef if not found
25611  */
wolfSSL_CIPHER_get_auth_nid(const WOLFSSL_CIPHER * cipher)25612 int wolfSSL_CIPHER_get_auth_nid(const WOLFSSL_CIPHER* cipher)
25613 {
25614     static const struct authnid {
25615         const char* alg_name;
25616         const int  nid;
25617     } authnid_tbl[] = {
25618         {"RSA",     NID_auth_rsa},
25619         {"PSK",     NID_auth_psk},
25620         {"SRP",     NID_auth_srp},
25621         {"ECDSA",   NID_auth_ecdsa},
25622         {"None",    NID_auth_null},
25623         {NULL,      NID_undef}
25624     };
25625 
25626     const struct authnid* sa;
25627     const char* authStr;
25628     char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
25629 
25630     if (GetCipherSegment(cipher, n) == NULL) {
25631         WOLFSSL_MSG("no suitable cipher name found");
25632         return NID_undef;
25633     }
25634 
25635     authStr = GetCipherAuthStr(n);
25636 
25637     if (authStr != NULL) {
25638         for(sa = authnid_tbl; sa->alg_name != NULL; sa++) {
25639             if (XSTRNCMP(sa->alg_name, authStr, XSTRLEN(sa->alg_name)) == 0) {
25640                 return sa->nid;
25641             }
25642         }
25643     }
25644 
25645     return NID_undef;
25646 }
25647 /* return cipher NID corresponding to cipher suite
25648  * @param cipher a pointer to WOLFSSL_CIPHER
25649  * return NID if found, NID_undef if not found
25650  */
wolfSSL_CIPHER_get_cipher_nid(const WOLFSSL_CIPHER * cipher)25651 int wolfSSL_CIPHER_get_cipher_nid(const WOLFSSL_CIPHER* cipher)
25652 {
25653     static const struct ciphernid {
25654         const char* alg_name;
25655         const int  nid;
25656     } ciphernid_tbl[] = {
25657         {"AESGCM(256)",             NID_aes_256_gcm},
25658         {"AESGCM(128)",             NID_aes_128_gcm},
25659         {"AESCCM(128)",             NID_aes_128_ccm},
25660         {"AES(128)",                NID_aes_128_cbc},
25661         {"AES(256)",                NID_aes_256_cbc},
25662         {"CAMELLIA(256)",           NID_camellia_256_cbc},
25663         {"CAMELLIA(128)",           NID_camellia_128_cbc},
25664         {"RC4",                     NID_rc4},
25665         {"3DES",                    NID_des_ede3_cbc},
25666         {"CHACHA20/POLY1305(256)",  NID_chacha20_poly1305},
25667         {"None",                    NID_undef},
25668         {"IDEA",                    NID_idea_cbc},
25669         {"RABBIT",                  NID_undef},
25670         {"HC128",                   NID_undef},
25671         {NULL,                      NID_undef}
25672     };
25673 
25674     const struct ciphernid* c;
25675     const char* encStr;
25676     char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
25677 
25678     WOLFSSL_ENTER("wolfSSL_CIPHER_get_cipher_nid");
25679 
25680     if (GetCipherSegment(cipher, n) == NULL) {
25681         WOLFSSL_MSG("no suitable cipher name found");
25682         return NID_undef;
25683     }
25684 
25685     encStr = GetCipherEncStr(n);
25686 
25687     if (encStr != NULL) {
25688         for(c = ciphernid_tbl; c->alg_name != NULL; c++) {
25689             if (XSTRNCMP(c->alg_name, encStr, XSTRLEN(c->alg_name)) == 0) {
25690                 return c->nid;
25691             }
25692         }
25693     }
25694 
25695     return NID_undef;
25696 }
25697 /* return digest NID corresponding to cipher suite
25698  * @param cipher a pointer to WOLFSSL_CIPHER
25699  * return NID if found, NID_undef if not found
25700  */
wolfSSL_CIPHER_get_digest_nid(const WOLFSSL_CIPHER * cipher)25701 int wolfSSL_CIPHER_get_digest_nid(const WOLFSSL_CIPHER* cipher)
25702 {
25703     static const struct macnid {
25704         const char* alg_name;
25705         const int  nid;
25706     } macnid_tbl[] = {
25707         {"SHA1",    NID_sha1},
25708         {"SHA256",  NID_sha256},
25709         {"SHA384",  NID_sha384},
25710         {NULL,      NID_undef}
25711     };
25712 
25713     const struct macnid* mc;
25714     const char* name;
25715     const char* macStr;
25716     char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
25717     (void)name;
25718 
25719     WOLFSSL_ENTER("wolfSSL_CIPHER_get_digest_nid");
25720 
25721     if ((name = GetCipherSegment(cipher, n)) == NULL) {
25722         WOLFSSL_MSG("no suitable cipher name found");
25723         return NID_undef;
25724     }
25725 
25726     /* in MD5 case, NID will be NID_md5 */
25727     if (XSTRSTR(name, "MD5") != NULL) {
25728         return NID_md5;
25729     }
25730 
25731     macStr = GetCipherMacStr(n);
25732 
25733     if (macStr != NULL) {
25734         for(mc = macnid_tbl; mc->alg_name != NULL; mc++) {
25735             if (XSTRNCMP(mc->alg_name, macStr, XSTRLEN(mc->alg_name)) == 0) {
25736                 return mc->nid;
25737             }
25738         }
25739     }
25740 
25741     return NID_undef;
25742 }
25743 /* return key exchange NID corresponding to cipher suite
25744  * @param cipher a pointer to WOLFSSL_CIPHER
25745  * return NID if found, NID_undef if not found
25746  */
wolfSSL_CIPHER_get_kx_nid(const WOLFSSL_CIPHER * cipher)25747 int wolfSSL_CIPHER_get_kx_nid(const WOLFSSL_CIPHER* cipher)
25748 {
25749 static const struct kxnid {
25750         const char* name;
25751         const int  nid;
25752     } kxnid_table[] = {
25753         {"ECDHEPSK",  NID_kx_ecdhe_psk},
25754         {"ECDH",      NID_kx_ecdhe},
25755         {"DHEPSK",    NID_kx_dhe_psk},
25756         {"DH",        NID_kx_dhe},
25757         {"RSAPSK",    NID_kx_rsa_psk},
25758         {"SRP",       NID_kx_srp},
25759         {"EDH",       NID_kx_dhe},
25760         {"RSA",       NID_kx_rsa},
25761         {NULL,        NID_undef}
25762     };
25763 
25764     const struct kxnid* k;
25765     const char* name;
25766     const char* keaStr;
25767     char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
25768     (void)name;
25769 
25770     WOLFSSL_ENTER("wolfSSL_CIPHER_get_kx_nid");
25771 
25772     if ((name = GetCipherSegment(cipher, n)) == NULL) {
25773         WOLFSSL_MSG("no suitable cipher name found");
25774         return NID_undef;
25775     }
25776 
25777     /* in TLS 1.3 case, NID will be NID_kx_any */
25778     if (XSTRNCMP(name, "TLS13", 5) == 0) {
25779         return NID_kx_any;
25780     }
25781 
25782     keaStr = GetCipherKeaStr(n);
25783 
25784     if (keaStr != NULL) {
25785         for(k = kxnid_table; k->name != NULL; k++) {
25786             if (XSTRNCMP(k->name, keaStr, XSTRLEN(k->name)) == 0) {
25787                 printf("k->name %s k->nid %d\n", k->name, k->nid);
25788                 return k->nid;
25789             }
25790         }
25791     }
25792 
25793     return NID_undef;
25794 }
25795 /* check if cipher suite is AEAD
25796  * @param cipher a pointer to WOLFSSL_CIPHER
25797  * return 1 if cipher is AEAD, 0 otherwise
25798  */
wolfSSL_CIPHER_is_aead(const WOLFSSL_CIPHER * cipher)25799 int wolfSSL_CIPHER_is_aead(const WOLFSSL_CIPHER* cipher)
25800 {
25801     char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
25802 
25803     WOLFSSL_ENTER("wolfSSL_CIPHER_is_aead");
25804 
25805     if (GetCipherSegment(cipher, n) == NULL) {
25806         WOLFSSL_MSG("no suitable cipher name found");
25807         return NID_undef;
25808     }
25809 
25810     return IsCipherAEAD(n);
25811 }
25812 /* Creates cipher->description based on cipher->offset
25813  * cipher->offset is set in wolfSSL_get_ciphers_compat when it is added
25814  * to a stack of ciphers.
25815  * @param [in] cipher: A cipher from a stack of ciphers.
25816  * return WOLFSSL_SUCCESS if cipher->description is set, else WOLFSSL_FAILURE
25817  */
wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER * cipher)25818 int wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER* cipher)
25819 {
25820     int strLen;
25821     unsigned long offset;
25822     char* dp;
25823     const char* name;
25824     const char *keaStr, *authStr, *encStr, *macStr, *protocol;
25825     char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
25826     unsigned char len = MAX_DESCRIPTION_SZ-1;
25827     const CipherSuiteInfo* cipher_names;
25828     ProtocolVersion pv;
25829     WOLFSSL_ENTER("wolfSSL_sk_CIPHER_description");
25830 
25831     if (cipher == NULL)
25832         return WOLFSSL_FAILURE;
25833 
25834     dp = cipher->description;
25835     if (dp == NULL)
25836         return WOLFSSL_FAILURE;
25837 
25838     cipher_names = GetCipherNames();
25839 
25840     offset = cipher->offset;
25841     if (offset >= (unsigned long)GetCipherNamesSize())
25842         return WOLFSSL_FAILURE;
25843     pv.major = cipher_names[offset].major;
25844     pv.minor = cipher_names[offset].minor;
25845     protocol = wolfSSL_internal_get_version(&pv);
25846 
25847     if ((name = GetCipherSegment(cipher, n)) == NULL) {
25848         WOLFSSL_MSG("no suitable cipher name found");
25849         return WOLFSSL_FAILURE;
25850     }
25851 
25852     /* keaStr */
25853     keaStr = GetCipherKeaStr(n);
25854     /* authStr */
25855     authStr = GetCipherAuthStr(n);
25856     /* encStr */
25857     encStr = GetCipherEncStr(n);
25858     if ((cipher->bits = SetCipherBits(encStr)) == WOLFSSL_FAILURE) {
25859        WOLFSSL_MSG("Cipher Bits Not Set.");
25860     }
25861     /* macStr */
25862     macStr = GetCipherMacStr(n);
25863 
25864 
25865     /* Build up the string by copying onto the end. */
25866     XSTRNCPY(dp, name, len);
25867     dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
25868     len -= (int)strLen; dp += strLen;
25869 
25870     XSTRNCPY(dp, " ", len);
25871     dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
25872     len -= (int)strLen; dp += strLen;
25873     XSTRNCPY(dp, protocol, len);
25874     dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
25875     len -= (int)strLen; dp += strLen;
25876 
25877     XSTRNCPY(dp, " Kx=", len);
25878     dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
25879     len -= (int)strLen; dp += strLen;
25880     XSTRNCPY(dp, keaStr, len);
25881     dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
25882     len -= (int)strLen; dp += strLen;
25883 
25884     XSTRNCPY(dp, " Au=", len);
25885     dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
25886     len -= (int)strLen; dp += strLen;
25887     XSTRNCPY(dp, authStr, len);
25888     dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
25889     len -= (int)strLen; dp += strLen;
25890 
25891     XSTRNCPY(dp, " Enc=", len);
25892     dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
25893     len -= (int)strLen; dp += strLen;
25894     XSTRNCPY(dp, encStr, len);
25895     dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
25896     len -= (int)strLen; dp += strLen;
25897 
25898     XSTRNCPY(dp, " Mac=", len);
25899     dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
25900     len -= (int)strLen; dp += strLen;
25901     XSTRNCPY(dp, macStr, len);
25902     dp[len-1] = '\0';
25903 
25904     return WOLFSSL_SUCCESS;
25905 }
25906 #endif /* OPENSSL_ALL || WOLFSSL_QT */
25907 
wolfssl_kea_to_string(int kea)25908 static WC_INLINE const char* wolfssl_kea_to_string(int kea)
25909 {
25910     const char* keaStr;
25911 
25912     switch (kea) {
25913         case no_kea:
25914             keaStr = "None";
25915             break;
25916 #ifndef NO_RSA
25917         case rsa_kea:
25918             keaStr = "RSA";
25919             break;
25920 #endif
25921 #ifndef NO_DH
25922         case diffie_hellman_kea:
25923             keaStr = "DHE";
25924             break;
25925 #endif
25926         case fortezza_kea:
25927             keaStr = "FZ";
25928             break;
25929 #ifndef NO_PSK
25930         case psk_kea:
25931             keaStr = "PSK";
25932             break;
25933     #ifndef NO_DH
25934         case dhe_psk_kea:
25935             keaStr = "DHEPSK";
25936             break;
25937     #endif
25938     #ifdef HAVE_ECC
25939         case ecdhe_psk_kea:
25940             keaStr = "ECDHEPSK";
25941             break;
25942     #endif
25943 #endif
25944 #ifdef HAVE_ECC
25945         case ecc_diffie_hellman_kea:
25946             keaStr = "ECDHE";
25947             break;
25948         case ecc_static_diffie_hellman_kea:
25949             keaStr = "ECDH";
25950             break;
25951 #endif
25952         default:
25953             keaStr = "unknown";
25954             break;
25955     }
25956 
25957     return keaStr;
25958 }
25959 
wolfssl_sigalg_to_string(int sig_algo)25960 static WC_INLINE const char* wolfssl_sigalg_to_string(int sig_algo)
25961 {
25962     const char* authStr;
25963 
25964     switch (sig_algo) {
25965         case anonymous_sa_algo:
25966             authStr = "None";
25967             break;
25968 #ifndef NO_RSA
25969         case rsa_sa_algo:
25970             authStr = "RSA";
25971             break;
25972     #ifdef WC_RSA_PSS
25973         case rsa_pss_sa_algo:
25974             authStr = "RSA-PSS";
25975             break;
25976     #endif
25977 #endif
25978 #ifndef NO_DSA
25979         case dsa_sa_algo:
25980             authStr = "DSA";
25981             break;
25982 #endif
25983 #ifdef HAVE_ECC
25984         case ecc_dsa_sa_algo:
25985             authStr = "ECDSA";
25986             break;
25987 #endif
25988 #ifdef HAVE_ED25519
25989         case ed25519_sa_algo:
25990             authStr = "Ed25519";
25991             break;
25992 #endif
25993 #ifdef HAVE_ED448
25994         case ed448_sa_algo:
25995             authStr = "Ed448";
25996             break;
25997 #endif
25998         default:
25999             authStr = "unknown";
26000             break;
26001     }
26002 
26003     return authStr;
26004 }
26005 
wolfssl_cipher_to_string(int cipher,int key_size)26006 static WC_INLINE const char* wolfssl_cipher_to_string(int cipher, int key_size)
26007 {
26008     const char* encStr;
26009 
26010     (void)key_size;
26011 
26012     switch (cipher) {
26013         case wolfssl_cipher_null:
26014             encStr = "None";
26015             break;
26016 #ifndef NO_RC4
26017         case wolfssl_rc4:
26018             encStr = "RC4(128)";
26019             break;
26020 #endif
26021 #ifndef NO_DES3
26022         case wolfssl_triple_des:
26023             encStr = "3DES(168)";
26024             break;
26025 #endif
26026 #ifdef HAVE_IDEA
26027         case wolfssl_idea:
26028             encStr = "IDEA(128)";
26029             break;
26030 #endif
26031 #ifndef NO_AES
26032         case wolfssl_aes:
26033             if (key_size == 128)
26034                 encStr = "AES(128)";
26035             else if (key_size == 256)
26036                 encStr = "AES(256)";
26037             else
26038                 encStr = "AES(?)";
26039             break;
26040     #ifdef HAVE_AESGCM
26041         case wolfssl_aes_gcm:
26042             if (key_size == 128)
26043                 encStr = "AESGCM(128)";
26044             else if (key_size == 256)
26045                 encStr = "AESGCM(256)";
26046             else
26047                 encStr = "AESGCM(?)";
26048             break;
26049     #endif
26050     #ifdef HAVE_AESCCM
26051         case wolfssl_aes_ccm:
26052             if (key_size == 128)
26053                 encStr = "AESCCM(128)";
26054             else if (key_size == 256)
26055                 encStr = "AESCCM(256)";
26056             else
26057                 encStr = "AESCCM(?)";
26058             break;
26059     #endif
26060 #endif
26061 #ifdef HAVE_CHACHA
26062         case wolfssl_chacha:
26063             encStr = "CHACHA20/POLY1305(256)";
26064             break;
26065 #endif
26066 #ifdef HAVE_CAMELLIA
26067         case wolfssl_camellia:
26068             if (key_size == 128)
26069                 encStr = "Camellia(128)";
26070             else if (key_size == 256)
26071                 encStr = "Camellia(256)";
26072             else
26073                 encStr = "Camellia(?)";
26074             break;
26075 #endif
26076 #if defined(HAVE_HC128) && !defined(NO_HC128)
26077         case wolfssl_hc128:
26078             encStr = "HC128(128)";
26079             break;
26080 #endif
26081 #if defined(HAVE_RABBIT) && !defined(NO_RABBIT)
26082         case wolfssl_rabbit:
26083             encStr = "RABBIT(128)";
26084             break;
26085 #endif
26086         default:
26087             encStr = "unknown";
26088             break;
26089     }
26090 
26091     return encStr;
26092 }
26093 
wolfssl_mac_to_string(int mac)26094 static WC_INLINE const char* wolfssl_mac_to_string(int mac)
26095 {
26096     const char* macStr;
26097 
26098     switch (mac) {
26099         case no_mac:
26100             macStr = "None";
26101             break;
26102 #ifndef NO_MD5
26103         case md5_mac:
26104             macStr = "MD5";
26105             break;
26106 #endif
26107 #ifndef NO_SHA
26108         case sha_mac:
26109             macStr = "SHA1";
26110             break;
26111 #endif
26112 #ifdef HAVE_SHA224
26113         case sha224_mac:
26114             macStr = "SHA224";
26115             break;
26116 #endif
26117 #ifndef NO_SHA256
26118         case sha256_mac:
26119             macStr = "SHA256";
26120             break;
26121 #endif
26122 #ifdef HAVE_SHA384
26123         case sha384_mac:
26124             macStr = "SHA384";
26125             break;
26126 #endif
26127 #ifdef HAVE_SHA512
26128         case sha512_mac:
26129             macStr = "SHA512";
26130             break;
26131 #endif
26132         default:
26133             macStr = "unknown";
26134             break;
26135     }
26136 
26137     return macStr;
26138 }
26139 
wolfSSL_CIPHER_description(const WOLFSSL_CIPHER * cipher,char * in,int len)26140 char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
26141                                  int len)
26142 {
26143     char *ret = in;
26144     const char *keaStr, *authStr, *encStr, *macStr;
26145     size_t strLen;
26146     WOLFSSL_ENTER("wolfSSL_CIPHER_description");
26147 
26148     if (cipher == NULL || in == NULL)
26149         return NULL;
26150 
26151 #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
26152     /* if cipher is in the stack from wolfSSL_get_ciphers_compat then
26153      * Return the description based on cipher_names[cipher->offset]
26154      */
26155     if (cipher->in_stack == TRUE) {
26156         wolfSSL_sk_CIPHER_description((WOLFSSL_CIPHER*)cipher);
26157         XSTRNCPY(in,cipher->description,len);
26158         return ret;
26159     }
26160 #endif
26161 
26162     /* Get the cipher description based on the SSL session cipher */
26163     keaStr = wolfssl_kea_to_string(cipher->ssl->specs.kea);
26164     authStr = wolfssl_sigalg_to_string(cipher->ssl->specs.sig_algo);
26165     encStr = wolfssl_cipher_to_string(cipher->ssl->specs.bulk_cipher_algorithm,
26166                                       cipher->ssl->specs.key_size);
26167     macStr = wolfssl_mac_to_string(cipher->ssl->specs.mac_algorithm);
26168 
26169     /* Build up the string by copying onto the end. */
26170     XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), len);
26171     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
26172 
26173     XSTRNCPY(in, " ", len);
26174     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
26175     XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), len);
26176     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
26177 
26178     XSTRNCPY(in, " Kx=", len);
26179     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
26180     XSTRNCPY(in, keaStr, len);
26181     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
26182 
26183     XSTRNCPY(in, " Au=", len);
26184     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
26185     XSTRNCPY(in, authStr, len);
26186     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
26187 
26188     XSTRNCPY(in, " Enc=", len);
26189     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
26190     XSTRNCPY(in, encStr, len);
26191     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
26192 
26193     XSTRNCPY(in, " Mac=", len);
26194     in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
26195     XSTRNCPY(in, macStr, len);
26196     in[len-1] = '\0';
26197 
26198     return ret;
26199 }
26200 
26201 #ifndef NO_WOLFSSL_STUB
wolfSSL_OCSP_parse_url(char * url,char ** host,char ** port,char ** path,int * ssl)26202 int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
26203                    int* ssl)
26204 {
26205     (void)url;
26206     (void)host;
26207     (void)port;
26208     (void)path;
26209     (void)ssl;
26210     WOLFSSL_STUB("OCSP_parse_url");
26211     return 0;
26212 }
26213 #endif
26214 
26215 #ifndef NO_MD4
26216 
wolfSSL_MD4_Init(WOLFSSL_MD4_CTX * md4)26217 void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
26218 {
26219     /* make sure we have a big enough buffer */
26220     typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
26221     (void) sizeof(ok);
26222 
26223     WOLFSSL_ENTER("MD4_Init");
26224     wc_InitMd4((Md4*)md4);
26225 }
26226 
26227 
wolfSSL_MD4_Update(WOLFSSL_MD4_CTX * md4,const void * data,unsigned long len)26228 void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
26229                        unsigned long len)
26230 {
26231     WOLFSSL_ENTER("MD4_Update");
26232     wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len);
26233 }
26234 
26235 
wolfSSL_MD4_Final(unsigned char * digest,WOLFSSL_MD4_CTX * md4)26236 void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
26237 {
26238     WOLFSSL_ENTER("MD4_Final");
26239     wc_Md4Final((Md4*)md4, digest);
26240 }
26241 
26242 #endif /* NO_MD4 */
26243 
26244 #ifndef NO_WOLFSSL_STUB
wolfSSL_RAND_screen(void)26245 void wolfSSL_RAND_screen(void)
26246 {
26247     WOLFSSL_STUB("RAND_screen");
26248 }
26249 #endif
26250 
26251 
26252 
wolfSSL_RAND_load_file(const char * fname,long len)26253 int wolfSSL_RAND_load_file(const char* fname, long len)
26254 {
26255     (void)fname;
26256     /* wolfCrypt provides enough entropy internally or will report error */
26257     if (len == -1)
26258         return 1024;
26259     else
26260         return (int)len;
26261 }
26262 
26263 
26264 #ifndef NO_WOLFSSL_STUB
wolfSSL_COMP_zlib(void)26265 WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
26266 {
26267     WOLFSSL_STUB("COMP_zlib");
26268     return 0;
26269 }
26270 #endif
26271 
26272 #ifndef NO_WOLFSSL_STUB
wolfSSL_COMP_rle(void)26273 WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
26274 {
26275     WOLFSSL_STUB("COMP_rle");
26276     return 0;
26277 }
26278 #endif
26279 
26280 #ifndef NO_WOLFSSL_STUB
wolfSSL_COMP_add_compression_method(int method,void * data)26281 int wolfSSL_COMP_add_compression_method(int method, void* data)
26282 {
26283     (void)method;
26284     (void)data;
26285     WOLFSSL_STUB("COMP_add_compression_method");
26286     return 0;
26287 }
26288 #endif
26289 
26290 /*  wolfSSL_set_dynlock_create_callback
26291  *  CRYPTO_set_dynlock_create_callback has been deprecated since openSSL 1.0.1.
26292  *  This function exists for compatibility purposes because wolfSSL satisfies
26293  *  thread safety without relying on the callback.
26294  */
wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value * (* f)(const char *,int))26295 void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
26296                                                           const char*, int))
26297 {
26298     WOLFSSL_STUB("CRYPTO_set_dynlock_create_callback");
26299     (void)f;
26300 }
26301 /*  wolfSSL_set_dynlock_lock_callback
26302  *  CRYPTO_set_dynlock_lock_callback has been deprecated since openSSL 1.0.1.
26303  *  This function exists for compatibility purposes because wolfSSL satisfies
26304  *  thread safety without relying on the callback.
26305  */
wolfSSL_set_dynlock_lock_callback(void (* f)(int,WOLFSSL_dynlock_value *,const char *,int))26306 void wolfSSL_set_dynlock_lock_callback(
26307              void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
26308 {
26309     WOLFSSL_STUB("CRYPTO_set_set_dynlock_lock_callback");
26310     (void)f;
26311 }
26312 /*  wolfSSL_set_dynlock_destroy_callback
26313  *  CRYPTO_set_dynlock_destroy_callback has been deprecated since openSSL 1.0.1.
26314  *  This function exists for compatibility purposes because wolfSSL satisfies
26315  *  thread safety without relying on the callback.
26316  */
wolfSSL_set_dynlock_destroy_callback(void (* f)(WOLFSSL_dynlock_value *,const char *,int))26317 void wolfSSL_set_dynlock_destroy_callback(
26318                   void (*f)(WOLFSSL_dynlock_value*, const char*, int))
26319 {
26320     WOLFSSL_STUB("CRYPTO_set_set_dynlock_destroy_callback");
26321     (void)f;
26322 }
26323 
26324 
26325 #endif /* OPENSSL_EXTRA */
26326 
26327 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
wolfSSL_X509_verify_cert_error_string(long err)26328 const char* wolfSSL_X509_verify_cert_error_string(long err)
26329 {
26330     return wolfSSL_ERR_reason_error_string(err);
26331 }
26332 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
26333 
26334 #ifdef OPENSSL_EXTRA
26335 
26336 #ifndef NO_WOLFSSL_STUB
wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP * lookup,const char * dir,long len)26337 int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
26338                                long len)
26339 {
26340     (void)lookup;
26341     (void)dir;
26342     (void)len;
26343     WOLFSSL_STUB("X509_LOOKUP_add_dir");
26344     return 0;
26345 }
26346 #endif
26347 
wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP * lookup,const char * file,long type)26348 int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
26349                                  const char* file, long type)
26350 {
26351 #if !defined(NO_FILESYSTEM) && \
26352     (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
26353     int           ret = WOLFSSL_FAILURE;
26354     XFILE         fp;
26355     long          sz;
26356     byte*         pem = NULL;
26357     byte*         curr = NULL;
26358     byte*         prev = NULL;
26359     WOLFSSL_X509* x509;
26360     const char* header = NULL;
26361     const char* footer = NULL;
26362 
26363     if (type != X509_FILETYPE_PEM)
26364         return WS_RETURN_CODE(BAD_FUNC_ARG,WOLFSSL_FAILURE);
26365 
26366     fp = XFOPEN(file, "rb");
26367     if (fp == XBADFILE)
26368         return WS_RETURN_CODE(BAD_FUNC_ARG,WOLFSSL_FAILURE);
26369 
26370     if(XFSEEK(fp, 0, XSEEK_END) != 0) {
26371         XFCLOSE(fp);
26372         return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
26373     }
26374     sz = XFTELL(fp);
26375     XREWIND(fp);
26376 
26377     if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
26378         WOLFSSL_MSG("X509_LOOKUP_load_file size error");
26379         goto end;
26380     }
26381 
26382     pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_PEM);
26383     if (pem == NULL) {
26384         ret = MEMORY_ERROR;
26385         goto end;
26386     }
26387 
26388     /* Read in file which may be CRLs or certificates. */
26389     if (XFREAD(pem, (size_t)sz, 1, fp) != 1)
26390         goto end;
26391 
26392     prev = curr = pem;
26393     do {
26394         /* get PEM header and footer based on type */
26395         if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
26396                 XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
26397 #ifdef HAVE_CRL
26398             WOLFSSL_CERT_MANAGER* cm = lookup->store->cm;
26399 
26400             if (cm->crl == NULL) {
26401                 if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
26402                     WOLFSSL_MSG("Enable CRL failed");
26403                     goto end;
26404                 }
26405             }
26406 
26407             ret = BufferLoadCRL(cm->crl, curr, sz, WOLFSSL_FILETYPE_PEM,
26408                 NO_VERIFY);
26409             if (ret != WOLFSSL_SUCCESS)
26410                 goto end;
26411 #endif
26412             curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
26413         }
26414         else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
26415                 XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
26416             x509 = wolfSSL_X509_load_certificate_buffer(curr, (int)sz,
26417                                                         WOLFSSL_FILETYPE_PEM);
26418             if (x509 == NULL)
26419                  goto end;
26420             ret = wolfSSL_X509_STORE_add_cert(lookup->store, x509);
26421             wolfSSL_X509_free(x509);
26422             if (ret != WOLFSSL_SUCCESS)
26423                 goto end;
26424             curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
26425         }
26426         else
26427             goto end;
26428 
26429         if (curr == NULL)
26430             goto end;
26431 
26432         curr++;
26433         sz -= (long)(curr - prev);
26434         prev = curr;
26435     }
26436     while (ret == WOLFSSL_SUCCESS);
26437 
26438 end:
26439     if (pem != NULL)
26440         XFREE(pem, 0, DYNAMIC_TYPE_PEM);
26441     XFCLOSE(fp);
26442     return WS_RETURN_CODE(ret,WOLFSSL_FAILURE);
26443 #else
26444     (void)lookup;
26445     (void)file;
26446     (void)type;
26447     return WS_RETURN_CODE(WOLFSSL_FAILURE,WOLFSSL_FAILURE);
26448 #endif
26449 }
26450 
wolfSSL_X509_LOOKUP_hash_dir(void)26451 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
26452 {
26453     /* Method implementation in functions. */
26454     static WOLFSSL_X509_LOOKUP_METHOD meth = { 1 };
26455     return &meth;
26456 }
26457 
wolfSSL_X509_LOOKUP_file(void)26458 WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
26459 {
26460     /* Method implementation in functions. */
26461     static WOLFSSL_X509_LOOKUP_METHOD meth = { 0 };
26462     return &meth;
26463 }
26464 
26465 /* set directory path to load certificate or CRL which have the hash.N form */
26466 /* for late use                                                             */
26467 /* @param ctx    a pointer to WOLFSSL_BY_DIR structure                      */
26468 /* @param argc   directory path                                             */
26469 /* @param argl   file type, either WOLFSSL_FILETYPE_PEM or                  */
26470 /*                                          WOLFSSL_FILETYPE_ASN1           */
26471 /* @return WOLFSSL_SUCCESS on successful, othewise negative or zero         */
x509AddCertDir(WOLFSSL_BY_DIR * ctx,const char * argc,long argl)26472 static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl)
26473 {
26474     WOLFSSL_ENTER("x509AddCertDir");
26475 
26476     (void)argl;
26477 #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
26478     WOLFSSL_BY_DIR_entry *entry;
26479     size_t pathLen;
26480     int i, num;
26481     const char* c;
26482 #ifdef WOLFSSL_SMALL_STACK
26483     char *buf;
26484 #else
26485     char  buf[MAX_FILENAME_SZ];
26486 #endif
26487 
26488     pathLen = 0;
26489     c = argc;
26490     /* sanity check, zero length */
26491     if (ctx == NULL || c == NULL || *c == '\0')
26492         return WOLFSSL_FAILURE;
26493 
26494 #ifdef WOLFSSL_SMALL_STACK
26495     buf = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_OPENSSL);
26496     if (buf == NULL) {
26497         WOLFSSL_LEAVE("x509AddCertDir", MEMORY_E);
26498         return MEMORY_E;
26499     }
26500 #endif
26501 
26502     XMEMSET(buf, 0, MAX_FILENAME_SZ);
26503 
26504     do {
26505         if (*c == SEPARATOR_CHAR || *c == '\0') {
26506 
26507             num = wolfSSL_sk_BY_DIR_entry_num(ctx->dir_entry);
26508 
26509             for (i=0; i<num; i++) {
26510 
26511                 entry = wolfSSL_sk_BY_DIR_entry_value(ctx->dir_entry, i);
26512 
26513                 if (XSTRLEN(entry->dir_name) == pathLen &&
26514                     XSTRNCMP(entry->dir_name, buf, pathLen) == 0) {
26515                     WOLFSSL_MSG("dir entry found");
26516                     break;
26517                 }
26518             }
26519 
26520             if (num == -1 || i == num) {
26521                 WOLFSSL_MSG("no entry found");
26522 
26523                 if (ctx->dir_entry == NULL) {
26524                     ctx->dir_entry = wolfSSL_sk_BY_DIR_entry_new_null();
26525 
26526                     if (ctx->dir_entry == NULL) {
26527                         WOLFSSL_MSG("failed to allocate dir_entry");
26528                         #ifdef WOLFSSL_SMALL_STACK
26529                             XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
26530                         #endif
26531                         return 0;
26532                     }
26533                 }
26534 
26535                 entry = wolfSSL_BY_DIR_entry_new();
26536                 if (entry == NULL) {
26537                     WOLFSSL_MSG("failed to allocate dir entry");
26538                     #ifdef WOLFSSL_SMALL_STACK
26539                         XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
26540                     #endif
26541                     return 0;
26542                 }
26543                 entry->dir_type = (int)argl;
26544                 entry->dir_name = (char*)XMALLOC(pathLen + 1/* \0 termination*/
26545                                                 , NULL, DYNAMIC_TYPE_OPENSSL);
26546                 entry->hashes = wolfSSL_sk_BY_DIR_HASH_new_null();
26547                 if (entry->dir_name == NULL || entry->hashes == NULL) {
26548                     WOLFSSL_MSG("failed to allocate dir name");
26549                     wolfSSL_BY_DIR_entry_free(entry);
26550                     #ifdef WOLFSSL_SMALL_STACK
26551                         XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
26552                     #endif
26553                     return 0;
26554                 }
26555 
26556                 XSTRNCPY(entry->dir_name, buf, pathLen);
26557                 entry->dir_name[pathLen] = '\0';
26558 
26559                 if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry)
26560                                                     != WOLFSSL_SUCCESS) {
26561                     wolfSSL_BY_DIR_entry_free(entry);
26562                     #ifdef WOLFSSL_SMALL_STACK
26563                         XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
26564                     #endif
26565                     return 0;
26566                 }
26567             }
26568             /* skip separator */
26569             if (*c == SEPARATOR_CHAR) c++;
26570 
26571             pathLen = 0;
26572             XMEMSET(buf, 0, MAX_FILENAME_SZ);
26573         }
26574         buf[pathLen++] = *c;
26575 
26576     } while(*c++ != '\0');
26577 
26578 #ifdef WOLFSSL_SMALL_STACK
26579     XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
26580 #endif
26581 
26582     return WOLFSSL_SUCCESS;
26583 #else
26584     (void)ctx;
26585     (void)argc;
26586     return WOLFSSL_NOT_IMPLEMENTED;
26587 #endif
26588 }
26589 
26590 /* set additional data to X509_LOOKUP                                   */
26591 /* @param ctx    a pointer to X509_LOOKUP structure                     */
26592 /* @param cmd    control command :                                      */
26593 /*               X509_L_FILE_LOAD, X509_L_ADD_DIR X509_L_ADD_STORE or   */
26594 /*               X509_L_LOAD_STORE                                      */
26595 /* @param argc   arguments for the control command                      */
26596 /* @param argl   arguments for the control command                      */
26597 /* @param **ret  return value of the control command                    */
26598 /* @return WOLFSSL_SUCCESS on successful, othewise WOLFSSL_FAILURE      */
26599 /* note: WOLFSSL_X509_L_ADD_STORE and WOLFSSL_X509_L_LOAD_STORE have not*/
26600 /*       yet implemented. It retutns WOLFSSL_NOT_IMPLEMENTED            */
26601 /*       when those control commands are passed.                        */
wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP * ctx,int cmd,const char * argc,long argl,char ** ret)26602 int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd,
26603         const char *argc, long argl, char **ret)
26604 {
26605     int lret = WOLFSSL_FAILURE;
26606 
26607     WOLFSSL_ENTER("wolfSSL_X509_LOOKUP_ctrl");
26608 #if !defined(NO_FILESYSTEM)
26609     if (ctx != NULL) {
26610         switch (cmd) {
26611         case WOLFSSL_X509_L_FILE_LOAD:
26612             /* expects to return a number of processed cert or crl file */
26613             lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, (int)argl) > 0 ?
26614                             WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
26615             break;
26616         case WOLFSSL_X509_L_ADD_DIR:
26617             /* store directory loaction to use it later */
26618 #if !defined(NO_WOLFSSL_DIR)
26619             lret = x509AddCertDir(ctx->dirs, argc, argl);
26620 #else
26621             (void)x509AddCertDir;
26622             lret = WOLFSSL_NOT_IMPLEMENTED;
26623 #endif
26624             break;
26625         case WOLFSSL_X509_L_ADD_STORE:
26626         case WOLFSSL_X509_L_LOAD_STORE:
26627             return WOLFSSL_NOT_IMPLEMENTED;
26628 
26629         default:
26630             break;
26631         }
26632     }
26633     (void)ret;
26634 #else
26635     (void)ctx;
26636     (void)argc;
26637     (void)argl;
26638     (void)ret;
26639     (void)cmd;
26640     (void)x509AddCertDir;
26641     lret = WOLFSSL_NOT_IMPLEMENTED;
26642 #endif
26643     return lret;
26644 }
26645 
26646 
26647 #if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN)
26648 static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
26649         unsigned char* der, int* derSz, int includeSig);
26650 #endif
26651 
26652 #ifndef NO_CERTS
26653 #ifdef WOLFSSL_CERT_GEN
26654 #ifndef NO_BIO
26655 /* Converts the X509 to DER format and outputs it into bio.
26656  *
26657  * bio  is the structure to hold output DER
26658  * x509 certificate to create DER from
26659  * req  if set then a CSR is generated
26660  *
26661  * returns WOLFSSL_SUCCESS on success
26662  */
loadX509orX509REQFromBio(WOLFSSL_BIO * bio,WOLFSSL_X509 * x509,int req)26663 static int loadX509orX509REQFromBio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int req)
26664 {
26665     int ret = WOLFSSL_FAILURE;
26666     /* Get large buffer to hold cert der */
26667     int derSz = X509_BUFFER_SZ;
26668 #ifdef WOLFSSL_SMALL_STACK
26669     byte* der;
26670 #else
26671     byte der[X509_BUFFER_SZ];
26672 #endif
26673     WOLFSSL_ENTER("wolfSSL_i2d_X509_bio");
26674 
26675     if (bio == NULL || x509 == NULL) {
26676         return WOLFSSL_FAILURE;
26677     }
26678 
26679 #ifdef WOLFSSL_SMALL_STACK
26680     der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26681     if (!der) {
26682         WOLFSSL_MSG("malloc failed");
26683         return WOLFSSL_FAILURE;
26684     }
26685 #endif
26686 
26687     if (wolfssl_x509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) {
26688         goto cleanup;
26689     }
26690 
26691     if (wolfSSL_BIO_write(bio, der, derSz) != derSz) {
26692         goto cleanup;
26693     }
26694 
26695     ret = WOLFSSL_SUCCESS;
26696 cleanup:
26697     #ifdef WOLFSSL_SMALL_STACK
26698     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26699     #endif
26700 
26701     return ret;
26702 }
26703 
26704 /* Converts the X509 to DER format and outputs it into bio.
26705  *
26706  * bio  is the structure to hold output DER
26707  * x509 certificate to create DER from
26708  *
26709  * returns WOLFSSL_SUCCESS on success
26710  */
wolfSSL_i2d_X509_bio(WOLFSSL_BIO * bio,WOLFSSL_X509 * x509)26711 int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
26712 {
26713     return loadX509orX509REQFromBio(bio, x509, 0);
26714 }
26715 
26716 #ifdef WOLFSSL_CERT_REQ
wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO * bio,WOLFSSL_X509 * x509)26717 int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
26718 {
26719     return loadX509orX509REQFromBio(bio, x509, 1);
26720 }
26721 #endif /* WOLFSSL_CERT_REQ */
26722 #endif /* !NO_BIO */
26723 #endif /* WOLFSSL_CERT_GEN */
26724 
26725 /* Converts an internal structure to a DER buffer
26726  *
26727  * x509 structure to get DER buffer from
26728  * out  buffer to hold result. If NULL then *out is NULL then a new buffer is
26729  *      created.
26730  *
26731  * returns the size of the DER result on success
26732  */
wolfSSL_i2d_X509(WOLFSSL_X509 * x509,unsigned char ** out)26733 int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
26734 {
26735     const unsigned char* der;
26736     int derSz = 0;
26737 
26738     WOLFSSL_ENTER("wolfSSL_i2d_X509");
26739 
26740     if (x509 == NULL) {
26741         WOLFSSL_LEAVE("wolfSSL_i2d_X509", BAD_FUNC_ARG);
26742         return BAD_FUNC_ARG;
26743     }
26744 
26745     der = wolfSSL_X509_get_der(x509, &derSz);
26746     if (der == NULL) {
26747         WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
26748         return MEMORY_E;
26749     }
26750 
26751     if (out != NULL && *out == NULL) {
26752         *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
26753         if (*out == NULL) {
26754             WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
26755             return MEMORY_E;
26756         }
26757     }
26758 
26759     if (out != NULL)
26760         XMEMCPY(*out, der, derSz);
26761 
26762     WOLFSSL_LEAVE("wolfSSL_i2d_X509", derSz);
26763     return derSz;
26764 }
26765 
26766 #ifndef NO_BIO
26767 /**
26768  * Converts the DER from bio and creates a WOLFSSL_X509 structure from it.
26769  * @param bio  is the structure holding DER
26770  * @param x509 certificate to create from DER. Can be NULL
26771  * @param req  1 for a CSR and 0 for a x509 cert
26772  * @return pointer to WOLFSSL_X509 structure on success and NULL on fail
26773  */
d2i_X509orX509REQ_bio(WOLFSSL_BIO * bio,WOLFSSL_X509 ** x509,int req)26774 static WOLFSSL_X509* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio,
26775                                             WOLFSSL_X509** x509, int req)
26776 {
26777     WOLFSSL_X509* localX509 = NULL;
26778     byte* mem  = NULL;
26779     int    size;
26780 
26781     WOLFSSL_ENTER("wolfSSL_d2i_X509_bio");
26782 
26783     if (bio == NULL) {
26784         WOLFSSL_MSG("Bad Function Argument bio is NULL");
26785         return NULL;
26786     }
26787 
26788     size = wolfSSL_BIO_get_len(bio);
26789     if (size <= 0) {
26790         WOLFSSL_MSG("wolfSSL_BIO_get_len error. Possibly no pending data.");
26791 #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
26792         /* EOF ASN1 file */
26793         WOLFSSL_ERROR(ASN1_R_HEADER_TOO_LONG);
26794 #endif
26795         return NULL;
26796     }
26797 
26798     if (!(mem = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL))) {
26799         WOLFSSL_MSG("malloc error");
26800         return NULL;
26801     }
26802 
26803     if ((size = wolfSSL_BIO_read(bio, mem, size)) == 0) {
26804         WOLFSSL_MSG("wolfSSL_BIO_read error");
26805         XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
26806         return NULL;
26807     }
26808 
26809     if (req) {
26810 #ifdef WOLFSSL_CERT_REQ
26811         localX509 = wolfSSL_X509_REQ_d2i(NULL, mem, size);
26812 #else
26813         WOLFSSL_MSG("CSR not compiled in");
26814 #endif
26815     }
26816     else {
26817         localX509 = wolfSSL_X509_d2i(NULL, mem, size);
26818     }
26819     if (localX509 == NULL) {
26820         WOLFSSL_MSG("wolfSSL_X509_d2i error");
26821         XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
26822         return NULL;
26823     }
26824 
26825     if (x509 != NULL) {
26826         *x509 = localX509;
26827     }
26828 
26829     XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
26830     return localX509;
26831 }
26832 
wolfSSL_d2i_X509_bio(WOLFSSL_BIO * bio,WOLFSSL_X509 ** x509)26833 WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
26834 {
26835     return d2i_X509orX509REQ_bio(bio, x509, 0);
26836 }
26837 
26838 #ifdef WOLFSSL_CERT_REQ
wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO * bio,WOLFSSL_X509 ** x509)26839 WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
26840 {
26841     return d2i_X509orX509REQ_bio(bio, x509, 1);
26842 }
26843 #endif
26844 #endif /* !NO_BIO */
26845 
26846 
26847 #if !defined(NO_ASN) && !defined(NO_PWDBASED)
26848 /* Copies unencrypted DER key buffer into "der". If "der" is null then the size
26849  * of buffer needed is returned. If *der == NULL then it allocates a buffer.
26850  * NOTE: This also advances the "der" pointer to be at the end of buffer.
26851  *
26852  * Returns size of key buffer on success
26853  */
wolfSSL_i2d_PrivateKey(const WOLFSSL_EVP_PKEY * key,unsigned char ** der)26854 int wolfSSL_i2d_PrivateKey(const WOLFSSL_EVP_PKEY* key, unsigned char** der)
26855 {
26856     return wolfSSL_EVP_PKEY_get_der(key, der);
26857 }
26858 
wolfSSL_i2d_PublicKey(const WOLFSSL_EVP_PKEY * key,unsigned char ** der)26859 int wolfSSL_i2d_PublicKey(const WOLFSSL_EVP_PKEY *key, unsigned char **der)
26860 {
26861     return wolfSSL_EVP_PKEY_get_der(key, der);
26862 }
26863 #endif /* !NO_ASN && !NO_PWDBASED */
26864 
26865 
26866 
26867 
26868 #endif /* !NO_CERTS */
26869 #endif /* OPENSSL_EXTRA */
26870 
26871 #ifdef OPENSSL_EXTRA
26872 #ifndef NO_CERTS
26873 /* Use the public key to verify the signature. Note: this only verifies
26874  * the certificate signature.
26875  * returns WOLFSSL_SUCCESS on successful signature verification */
verifyX509orX509REQ(WOLFSSL_X509 * x509,WOLFSSL_EVP_PKEY * pkey,int req)26876 static int verifyX509orX509REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, int req)
26877 {
26878     int ret;
26879     const byte* der;
26880     int derSz = 0;
26881     int type;
26882 
26883     (void)req;
26884 
26885     if (x509 == NULL || pkey == NULL) {
26886         return WOLFSSL_FATAL_ERROR;
26887     }
26888 
26889     der = wolfSSL_X509_get_der(x509, &derSz);
26890     if (der == NULL) {
26891         WOLFSSL_MSG("Error getting WOLFSSL_X509 DER");
26892         return WOLFSSL_FATAL_ERROR;
26893     }
26894 
26895     switch (pkey->type) {
26896         case EVP_PKEY_RSA:
26897             type = RSAk;
26898             break;
26899 
26900         case EVP_PKEY_EC:
26901             type = ECDSAk;
26902             break;
26903 
26904         case EVP_PKEY_DSA:
26905             type = DSAk;
26906             break;
26907 
26908         default:
26909             WOLFSSL_MSG("Unknown pkey key type");
26910             return WOLFSSL_FATAL_ERROR;
26911     }
26912 
26913 #ifdef WOLFSSL_CERT_REQ
26914     if (req)
26915         ret = CheckCSRSignaturePubKey(der, derSz, x509->heap,
26916                 (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
26917     else
26918 #endif
26919         ret = CheckCertSignaturePubKey(der, derSz, x509->heap,
26920                 (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
26921     if (ret == 0) {
26922         return WOLFSSL_SUCCESS;
26923     }
26924     return WOLFSSL_FAILURE;
26925 }
26926 
wolfSSL_X509_verify(WOLFSSL_X509 * x509,WOLFSSL_EVP_PKEY * pkey)26927 int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
26928 {
26929     return verifyX509orX509REQ(x509, pkey, 0);
26930 }
26931 
26932 #ifdef WOLFSSL_CERT_REQ
wolfSSL_X509_REQ_verify(WOLFSSL_X509 * x509,WOLFSSL_EVP_PKEY * pkey)26933 int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
26934 {
26935     return verifyX509orX509REQ(x509, pkey, 1);
26936 }
26937 #endif /* WOLFSSL_CERT_REQ */
26938 #endif /* !NO_CERTS */
26939 
26940 #if !defined(NO_FILESYSTEM)
wolfSSL_d2i_X509_fp_ex(XFILE file,void ** x509,int type)26941 static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
26942 {
26943     void *newx509 = NULL;
26944     byte *fileBuffer = NULL;
26945     long sz = 0;
26946 
26947     /* init variable */
26948     if (x509)
26949         *x509 = NULL;
26950 
26951     /* argument check */
26952     if (file == XBADFILE) {
26953         return NULL;
26954     }
26955 
26956     /* determine file size */
26957     if (XFSEEK(file, 0, XSEEK_END) != 0) {
26958         return NULL;
26959     }
26960     sz = XFTELL(file);
26961     XREWIND(file);
26962 
26963     if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
26964         WOLFSSL_MSG("d2i_X509_fp_ex file size error");
26965         return NULL;
26966     }
26967 
26968     fileBuffer = (byte *)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
26969     if (fileBuffer != NULL) {
26970         if ((long)XFREAD(fileBuffer, 1, sz, file) != sz) {
26971             WOLFSSL_MSG("File read failed");
26972             goto err_exit;
26973         }
26974         if (type == CERT_TYPE) {
26975             newx509 = (void *)wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
26976         }
26977     #ifdef HAVE_CRL
26978         else if (type == CRL_TYPE) {
26979             newx509 = (void *)wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz);
26980         }
26981     #endif
26982     #if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
26983         else if (type == PKCS12_TYPE) {
26984             if ((newx509 = wc_PKCS12_new()) == NULL) {
26985                 goto err_exit;
26986             }
26987             if (wc_d2i_PKCS12(fileBuffer, (int)sz, (WC_PKCS12*)newx509) < 0) {
26988                 goto err_exit;
26989             }
26990         }
26991     #endif
26992         else {
26993             goto err_exit;
26994         }
26995         if (newx509 == NULL) {
26996             WOLFSSL_MSG("X509 failed");
26997             goto err_exit;
26998         }
26999     }
27000 
27001     if (x509)
27002         *x509 = newx509;
27003 
27004     goto _exit;
27005 
27006 err_exit:
27007 #if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
27008     if ((newx509 != NULL) && (type == PKCS12_TYPE)) {
27009         wc_PKCS12_free((WC_PKCS12*)newx509);
27010         newx509 = NULL;
27011     }
27012 #endif
27013 _exit:
27014     if (fileBuffer != NULL)
27015         XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
27016 
27017     return newx509;
27018 }
27019 
wolfSSL_d2i_X509_fp(XFILE fp,WOLFSSL_X509 ** x509)27020 WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509)
27021 {
27022     WOLFSSL_ENTER("wolfSSL_d2i_X509_fp");
27023     return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE);
27024 }
27025 /* load certificate or CRL file, and add it to the STORE           */
27026 /* @param ctx    a pointer to X509_LOOKUP structure                */
27027 /* @param file   file name to load                                 */
27028 /* @param type   WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1     */
27029 /* @return a number of loading CRL or certificate, otherwise zero  */
wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP * ctx,const char * file,int type)27030 WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx,
27031     const char *file, int type)
27032 {
27033     STACK_OF(WOLFSSL_X509_INFO) *info;
27034     WOLFSSL_X509_INFO *info_tmp;
27035     WOLFSSL_BIO *bio;
27036     WOLFSSL_X509 *x509 = NULL;
27037 
27038     int i;
27039     int cnt = 0;
27040     int num = 0;
27041 
27042     WOLFSSL_ENTER("wolfSSL_X509_load_cert_crl_file");
27043 
27044     /* stanity check */
27045     if (ctx == NULL || file == NULL) {
27046         WOLFSSL_MSG("bad arguments");
27047         return 0;
27048     }
27049 
27050     if (type != WOLFSSL_FILETYPE_PEM) {
27051         x509 = wolfSSL_X509_load_certificate_file(file, type);
27052         if (x509 != NULL) {
27053             if (wolfSSL_X509_STORE_add_cert(ctx->store, x509)
27054                                     == WOLFSSL_SUCCESS) {
27055                 cnt++;
27056             } else {
27057                 WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert error");
27058             }
27059             wolfSSL_X509_free(x509);
27060             x509 = NULL;
27061         } else {
27062             WOLFSSL_MSG("wolfSSL_X509_load_certificate_file error");
27063         }
27064 
27065     } else {
27066 #if defined(OPENSSL_ALL) && !defined(NO_BIO)
27067         bio = wolfSSL_BIO_new_file(file, "rb");
27068         if(!bio) {
27069             WOLFSSL_MSG("wolfSSL_BIO_new error");
27070             return cnt;
27071         }
27072 
27073         info = wolfSSL_PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
27074 
27075         wolfSSL_BIO_free(bio);
27076 
27077         if (!info) {
27078             WOLFSSL_MSG("wolfSSL_PEM_X509_INFO_read_bio error");
27079             return cnt;
27080         }
27081         num = wolfSSL_sk_X509_INFO_num(info);
27082         for (i=0; i < num; i++) {
27083             info_tmp = wolfSSL_sk_X509_INFO_value(info, i);
27084 
27085             if (info_tmp->x509) {
27086                 if(wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509) ==
27087                     WOLFSSL_SUCCESS) {
27088                     cnt ++;
27089                 } else {
27090                     WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
27091                 }
27092             }
27093 #ifdef HAVE_CRL
27094             if (info_tmp->crl) {
27095                 if(wolfSSL_X509_STORE_add_crl(ctx->store, info_tmp->crl) ==
27096                     WOLFSSL_SUCCESS) {
27097                     cnt ++;
27098                 } else {
27099                     WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
27100                 }
27101             }
27102 #endif
27103         }
27104         wolfSSL_sk_X509_INFO_pop_free(info, wolfSSL_X509_INFO_free);
27105 #else
27106     (void)i;
27107     (void)cnt;
27108     (void)num;
27109     (void)info_tmp;
27110     (void)info;
27111     (void)bio;
27112 #endif /* OPENSSL_ALL && !NO_BIO */
27113     }
27114 
27115     WOLFSSL_LEAVE("wolfSSL_X509_load_ceretificate_crl_file", cnt);
27116     return cnt;
27117 }
27118 #endif /* !NO_FILESYSTEM */
27119 
27120 
27121 #ifdef HAVE_CRL
27122 
27123 #ifndef NO_BIO
wolfSSL_d2i_X509_CRL_bio(WOLFSSL_BIO * bp,WOLFSSL_X509_CRL ** x)27124 WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_bio(WOLFSSL_BIO *bp,
27125                                                     WOLFSSL_X509_CRL **x)
27126 {
27127     int derSz;
27128     byte* der = NULL;
27129     WOLFSSL_X509_CRL* crl = NULL;
27130 
27131     if (bp == NULL)
27132         return NULL;
27133 
27134     if ((derSz = wolfSSL_BIO_get_len(bp)) > 0) {
27135         der = (byte*)XMALLOC(derSz, 0, DYNAMIC_TYPE_DER);
27136         if (der != NULL) {
27137             if (wolfSSL_BIO_read(bp, der, derSz) == derSz) {
27138                 crl = wolfSSL_d2i_X509_CRL(x, der, derSz);
27139             }
27140         }
27141     }
27142 
27143     if (der != NULL) {
27144         XFREE(der, 0, DYNAMIC_TYPE_DER);
27145     }
27146 
27147     return crl;
27148 }
27149 #endif
27150 
27151 #ifndef NO_FILESYSTEM
wolfSSL_d2i_X509_CRL_fp(XFILE fp,WOLFSSL_X509_CRL ** crl)27152 WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE fp, WOLFSSL_X509_CRL **crl)
27153 {
27154     WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_fp");
27155     return (WOLFSSL_X509_CRL *)wolfSSL_d2i_X509_fp_ex(fp, (void **)crl, CRL_TYPE);
27156 }
27157 
27158 #ifndef NO_BIO
27159 /* Read CRL file, and add it to store and corresponding cert manager    */
27160 /* @param ctx   a pointer of X509_LOOKUP back to the X509_STORE         */
27161 /* @param file  a file to read                                          */
27162 /* @param type  WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1           */
27163 /* @return WOLFSSL_SUCCESS(1) on successful, othewise WOLFSSL_FAILURE(0)*/
wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP * ctx,const char * file,int type)27164 WOLFSSL_API int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx,
27165                                              const char *file, int type)
27166 {
27167     int ret = WOLFSSL_FAILURE;
27168     int count = 0;
27169     WOLFSSL_BIO *bio = NULL;
27170     WOLFSSL_X509_CRL *crl = NULL;
27171 
27172     WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
27173 
27174     if (ctx == NULL || file == NULL)
27175         return ret;
27176 
27177     if ((bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file())) == NULL)
27178         return ret;
27179 
27180     if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
27181         wolfSSL_BIO_free(bio);
27182         return ret;
27183     }
27184 
27185     if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
27186         wolfSSL_BIO_free(bio);
27187         return ret;
27188     }
27189 
27190     if (type == WOLFSSL_FILETYPE_PEM) {
27191         do {
27192             crl = wolfSSL_PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
27193             if (crl == NULL) {
27194                 if (count <= 0) {
27195                     WOLFSSL_MSG("Load crl failed");
27196                 }
27197                 break;
27198             }
27199 
27200             ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
27201             if (ret == WOLFSSL_FAILURE) {
27202                 WOLFSSL_MSG("Adding crl failed");
27203                 break;
27204             }
27205             count++;
27206             wolfSSL_X509_CRL_free(crl);
27207             crl = NULL;
27208         }   while(crl == NULL);
27209 
27210         ret = count;
27211     } else if (type == WOLFSSL_FILETYPE_ASN1) {
27212         crl = wolfSSL_d2i_X509_CRL_bio(bio, NULL);
27213         if (crl == NULL) {
27214             WOLFSSL_MSG("Load crl failed");
27215         } else {
27216             ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
27217             if (ret == WOLFSSL_FAILURE) {
27218                 WOLFSSL_MSG("Adding crl failed");
27219             } else {
27220                 ret = 1;/* handled a file */
27221             }
27222         }
27223     } else {
27224         WOLFSSL_MSG("Invalid file type");
27225     }
27226 
27227     wolfSSL_X509_CRL_free(crl);
27228     wolfSSL_BIO_free(bio);
27229 
27230     WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
27231     return ret;
27232 }
27233 #endif /* !NO_BIO */
27234 #endif /* !NO_FILESYSTEM */
27235 
27236 
wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL ** crl,const unsigned char * in,int len)27237 WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl,
27238         const unsigned char* in, int len)
27239 {
27240     WOLFSSL_X509_CRL *newcrl = NULL;
27241     int ret = WOLFSSL_SUCCESS;
27242 
27243     WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL");
27244 
27245     if (in == NULL) {
27246         WOLFSSL_MSG("Bad argument value");
27247     } else {
27248         newcrl =(WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), NULL,
27249                 DYNAMIC_TYPE_CRL);
27250         if (newcrl == NULL){
27251             WOLFSSL_MSG("New CRL allocation failed");
27252         } else {
27253             ret = InitCRL(newcrl, NULL);
27254             if (ret < 0) {
27255                 WOLFSSL_MSG("Init tmp CRL failed");
27256             } else {
27257                 ret = BufferLoadCRL(newcrl, in, len, WOLFSSL_FILETYPE_ASN1,
27258                     NO_VERIFY);
27259                 if (ret != WOLFSSL_SUCCESS) {
27260                     WOLFSSL_MSG("Buffer Load CRL failed");
27261                 } else {
27262                     if (crl) {
27263                         *crl = newcrl;
27264                     }
27265                 }
27266             }
27267         }
27268     }
27269 
27270     if((ret != WOLFSSL_SUCCESS) && (newcrl != NULL)) {
27271         wolfSSL_X509_CRL_free(newcrl);
27272         newcrl = NULL;
27273     }
27274 
27275     return newcrl;
27276 }
27277 #endif /* HAVE_CRL */
27278 #endif /* OPENSSL_EXTRA */
27279 
27280 #if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL * crl)27281 void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl)
27282 {
27283     WOLFSSL_ENTER("wolfSSL_X509_CRL_free");
27284 
27285     if (crl)
27286         FreeCRL(crl, 1);
27287 }
27288 #endif /* HAVE_CRL && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
27289 
27290 #ifdef OPENSSL_EXTRA
27291 #ifndef NO_WOLFSSL_STUB
wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL * crl)27292 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
27293 {
27294     (void)crl;
27295     WOLFSSL_STUB("X509_CRL_get_lastUpdate");
27296     return 0;
27297 }
27298 #endif
27299 #ifndef NO_WOLFSSL_STUB
wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL * crl)27300 WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
27301 {
27302     (void)crl;
27303     WOLFSSL_STUB("X509_CRL_get_nextUpdate");
27304     return 0;
27305 }
27306 #endif
27307 
27308 
27309 #ifndef NO_WOLFSSL_STUB
wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL * crl,WOLFSSL_EVP_PKEY * key)27310 int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
27311 {
27312     (void)crl;
27313     (void)key;
27314     WOLFSSL_STUB("X509_CRL_verify");
27315     return 0;
27316 }
27317 #endif
27318 #endif /* OPENSSL_EXTRA */
27319 
27320 #ifdef OPENSSL_EXTRA
27321 
27322 
wolfSSL_X509_VERIFY_PARAM_new(void)27323 WOLFSSL_X509_VERIFY_PARAM* wolfSSL_X509_VERIFY_PARAM_new(void)
27324 {
27325     WOLFSSL_X509_VERIFY_PARAM *param = NULL;
27326     param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
27327             sizeof(WOLFSSL_X509_VERIFY_PARAM), NULL, DYNAMIC_TYPE_OPENSSL);
27328     if (param != NULL)
27329         XMEMSET(param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM ));
27330 
27331     return(param);
27332 }
27333 
27334 
wolfSSL_X509_VERIFY_PARAM_free(WOLFSSL_X509_VERIFY_PARAM * param)27335 void wolfSSL_X509_VERIFY_PARAM_free(WOLFSSL_X509_VERIFY_PARAM *param)
27336 {
27337     if (param != NULL)
27338         XFREE(param, NULL, DYNAMIC_TYPE_OPENSSL);
27339 }
27340 
27341 
27342 /* Sets flags by OR'ing with existing value. */
wolfSSL_X509_VERIFY_PARAM_set_flags(WOLFSSL_X509_VERIFY_PARAM * param,unsigned long flags)27343 int wolfSSL_X509_VERIFY_PARAM_set_flags(WOLFSSL_X509_VERIFY_PARAM *param,
27344         unsigned long flags)
27345 {
27346     int ret = WOLFSSL_FAILURE;
27347 
27348     if (param != NULL) {
27349         param->flags |= flags;
27350         ret = WOLFSSL_SUCCESS;
27351     }
27352 
27353     return ret;
27354 }
27355 
27356 
wolfSSL_X509_VERIFY_PARAM_get_flags(WOLFSSL_X509_VERIFY_PARAM * param)27357 int wolfSSL_X509_VERIFY_PARAM_get_flags(WOLFSSL_X509_VERIFY_PARAM *param)
27358 {
27359     int ret = 0;
27360 
27361     if (param != NULL) {
27362         ret = (int)param->flags;
27363     }
27364 
27365     return ret;
27366 }
27367 
27368 
wolfSSL_X509_VERIFY_PARAM_clear_flags(WOLFSSL_X509_VERIFY_PARAM * param,unsigned long flags)27369 int wolfSSL_X509_VERIFY_PARAM_clear_flags(WOLFSSL_X509_VERIFY_PARAM *param,
27370         unsigned long flags)
27371 {
27372     int ret = WOLFSSL_FAILURE;
27373 
27374     if (param != NULL) {
27375         param->flags &= ~flags;
27376         ret = WOLFSSL_SUCCESS;
27377     }
27378 
27379     return ret;
27380 }
27381 
27382 
27383 /* inherits properties of param "to" to param "from"
27384 *
27385 * WOLFSSL_VPARAM_DEFAULT          any values in "src" is copied
27386 *                                 if "src" value is new for "to".
27387 * WOLFSSL_VPARAM_OVERWRITE        all values of "form" are copied to "to"
27388 * WOLFSSL_VPARAM_RESET_FLAGS      the flag values are copied, not Ored
27389 * WOLFSSL_VPARAM_LOCKED           don't copy any values
27390 * WOLFSSL_VPARAM_ONCE             the current inherit_flags is zerroed
27391 */
wolfSSL_X509_VERIFY_PARAM_inherit(WOLFSSL_X509_VERIFY_PARAM * to,const WOLFSSL_X509_VERIFY_PARAM * from)27392 static int wolfSSL_X509_VERIFY_PARAM_inherit(WOLFSSL_X509_VERIFY_PARAM *to,
27393                                          const WOLFSSL_X509_VERIFY_PARAM *from)
27394 {
27395     int ret = WOLFSSL_FAILURE;
27396     int isOverWrite = 0;
27397     int isDefault = 0;
27398     unsigned int flags;
27399 
27400     /* sanity check */
27401     if (!to || !from) {
27402         /* be compatible to openssl return value */
27403         return WOLFSSL_SUCCESS;
27404     }
27405     flags = to->inherit_flags | from->inherit_flags;
27406 
27407     if (flags & WOLFSSL_VPARAM_LOCKED) {
27408         return WOLFSSL_SUCCESS;
27409     }
27410 
27411     if (flags & WOLFSSL_VPARAM_ONCE) {
27412         to->inherit_flags = 0;
27413     }
27414 
27415     isOverWrite = (flags & WOLFSSL_VPARAM_OVERWRITE);
27416     isDefault = (flags & WOLFSSL_VPARAM_DEFAULT);
27417 
27418     /* copy check_time if check time is not set */
27419     if ((to->flags & WOLFSSL_USE_CHECK_TIME) == 0 || isOverWrite) {
27420            to->check_time = from->check_time;
27421            to->flags &= ~WOLFSSL_USE_CHECK_TIME;
27422     }
27423     /* host name */
27424     if (isOverWrite ||
27425         (from->hostName[0] != 0 && (to->hostName[0] == 0 || isDefault))) {
27426             if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_host(to, from->hostName,
27427                 (int)XSTRLEN(from->hostName))))
27428                 return ret;
27429         to->hostFlags = from->hostFlags;
27430     }
27431     /* ip ascii */
27432     if (isOverWrite ||
27433         (from->ipasc[0] != 0 && (to->ipasc[0] == 0 || isDefault))) {
27434 
27435             if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(to, from->ipasc)))
27436                 return ret;
27437     }
27438 
27439     if (flags & WOLFSSL_VPARAM_RESET_FLAGS)
27440         to->flags = 0;
27441 
27442     to->flags |= from->flags;
27443 
27444     return ret;
27445 }
27446 /******************************************************************************
27447 * wolfSSL_X509_VERIFY_PARAM_set1_host - sets the DNS hostname to name
27448 * hostnames is cleared if name is NULL or empty.
27449 *
27450 * RETURNS:
27451 *
27452 */
wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM * pParam,const char * name,unsigned int nameSz)27453 int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam,
27454                                          const char* name,
27455                                          unsigned int nameSz)
27456 {
27457     unsigned int sz = 0;
27458 
27459     if (pParam == NULL)
27460         return WOLFSSL_FAILURE;
27461 
27462     XMEMSET(pParam->hostName, 0, WOLFSSL_HOST_NAME_MAX);
27463 
27464     if (name == NULL)
27465         return WOLFSSL_SUCCESS;
27466 
27467     sz = (unsigned int)XSTRLEN(name);
27468 
27469     /* If name is NULL-terminated, namelen can be set to zero. */
27470     if (nameSz == 0 || nameSz > sz)
27471         nameSz = sz;
27472 
27473     if (nameSz > 0 && name[nameSz - 1] == '\0')
27474         nameSz--;
27475 
27476     if (nameSz > WOLFSSL_HOST_NAME_MAX-1)
27477         nameSz = WOLFSSL_HOST_NAME_MAX-1;
27478 
27479     if (nameSz > 0)
27480         XMEMCPY(pParam->hostName, name, nameSz);
27481 
27482     pParam->hostName[nameSz] = '\0';
27483 
27484     return WOLFSSL_SUCCESS;
27485 }
27486 /******************************************************************************
27487 * wolfSSL_CTX_set1_param - set a pointer to the SSL verification parameters
27488 *
27489 * RETURNS:
27490 *   WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
27491 *   Note: Returns WOLFSSL_SUCCESS, in case either parameter is NULL,
27492 *   same as openssl.
27493 */
wolfSSL_CTX_set1_param(WOLFSSL_CTX * ctx,WOLFSSL_X509_VERIFY_PARAM * vpm)27494 int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PARAM *vpm)
27495 {
27496     if (ctx == NULL || vpm == NULL)
27497         return WOLFSSL_SUCCESS;
27498 
27499     return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, vpm);
27500 }
27501 
27502 /******************************************************************************
27503 * wolfSSL_CTX/_get0_param - return a pointer to the SSL verification parameters
27504 *
27505 * RETURNS:
27506 * returns pointer to the SSL verification parameters on success,
27507 * otherwise returns NULL
27508 */
wolfSSL_CTX_get0_param(WOLFSSL_CTX * ctx)27509 WOLFSSL_X509_VERIFY_PARAM* wolfSSL_CTX_get0_param(WOLFSSL_CTX* ctx)
27510 {
27511     if (ctx == NULL) {
27512         return NULL;
27513     }
27514 
27515     return ctx->param;
27516 }
27517 
wolfSSL_get0_param(WOLFSSL * ssl)27518 WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl)
27519 {
27520     if (ssl == NULL) {
27521         return NULL;
27522     }
27523     return ssl->param;
27524 }
27525 
27526 /* Set VERIFY PARAM from "from" pointer to "to" pointer */
wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM * to,const WOLFSSL_X509_VERIFY_PARAM * from)27527 int wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM *to,
27528                                    const WOLFSSL_X509_VERIFY_PARAM *from)
27529 {
27530     int ret = WOLFSSL_FAILURE;
27531     unsigned int _inherit_flags;
27532 
27533     if (!to) {
27534         return ret;
27535     }
27536     /* keeps the inherit flags for save */
27537     _inherit_flags = to->inherit_flags;
27538 
27539     /* Ored DEFAULT inherit flag proerty to copy "from" contents to "to"
27540     *  contents
27541     */
27542     to->inherit_flags |= WOLFSSL_VPARAM_DEFAULT;
27543 
27544     ret = wolfSSL_X509_VERIFY_PARAM_inherit(to, from);
27545 
27546     /* restore inherit flag */
27547     to->inherit_flags = _inherit_flags;
27548 
27549     return ret;
27550 }
27551 
27552 /* Set the host flag in the X509_VERIFY_PARAM structure */
wolfSSL_X509_VERIFY_PARAM_set_hostflags(WOLFSSL_X509_VERIFY_PARAM * param,unsigned int flags)27553 void wolfSSL_X509_VERIFY_PARAM_set_hostflags(WOLFSSL_X509_VERIFY_PARAM* param,
27554                                              unsigned int flags)
27555 {
27556     if (param != NULL) {
27557         param->hostFlags = flags;
27558     }
27559 }
27560 
27561 /* Sets the expected IP address to ipasc.
27562  *
27563  * param is a pointer to the X509_VERIFY_PARAM structure
27564  * ipasc is a NULL-terminated string with N.N.N.N for IPv4 and
27565  *       HH:HH ... HH:HH for IPv6. There is no validation performed on the
27566  *       parameter, and it must be an exact match with the IP in the cert.
27567  *
27568  * return 1 for success and 0 for failure*/
wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(WOLFSSL_X509_VERIFY_PARAM * param,const char * ipasc)27569 int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(WOLFSSL_X509_VERIFY_PARAM *param,
27570         const char *ipasc)
27571 {
27572     int ret = WOLFSSL_FAILURE;
27573 
27574     if (param != NULL) {
27575         if (ipasc == NULL) {
27576             param->ipasc[0] = '\0';
27577         }
27578         else {
27579             XSTRNCPY(param->ipasc, ipasc, WOLFSSL_MAX_IPSTR - 1);
27580             param->ipasc[WOLFSSL_MAX_IPSTR-1] = '\0';
27581         }
27582         ret = WOLFSSL_SUCCESS;
27583     }
27584 
27585     return ret;
27586 }
27587 /* Sets the expected IP address to ip(asc)
27588  *          by re-constructing IP address in ascii
27589  * @param  param is a pointer to the X509_VERIFY_PARAM structure
27590  * @param  ip    in binary format of ip address
27591  * @param  iplen size of ip, 4 for ipv4, 16 for ipv6
27592  * @return 1 for success and 0 for failure
27593  */
wolfSSL_X509_VERIFY_PARAM_set1_ip(WOLFSSL_X509_VERIFY_PARAM * param,const unsigned char * ip,size_t iplen)27594 int wolfSSL_X509_VERIFY_PARAM_set1_ip(WOLFSSL_X509_VERIFY_PARAM* param,
27595     const unsigned char* ip, size_t iplen)
27596 {
27597     int ret = WOLFSSL_FAILURE;
27598 #ifndef NO_FILESYSTEM
27599     char* buf = NULL;
27600     char* p = NULL;
27601     word32 val = 0;
27602     int i;
27603     const size_t max_ipv6_len = 40;
27604     byte write_zero = 0;
27605 #endif
27606 
27607     /* sanity check */
27608     if (param == NULL || (iplen != 0 && iplen != 4 && iplen != 16)) {
27609         WOLFSSL_MSG("bad function arg");
27610         return ret;
27611     }
27612 #ifndef NO_FILESYSTEM
27613     if (iplen == 4) {
27614         /* ipv4 www.xxx.yyy.zzz max 15 length + Null termination */
27615         buf = (char*)XMALLOC(16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27616 
27617         if (!buf) {
27618             WOLFSSL_MSG("failed malloc");
27619             return ret;
27620         }
27621 
27622         XSPRINTF(buf, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
27623         buf[15] = '\0';
27624     }
27625     else if (iplen == 16) {
27626         /* ipv6 normal address scheme
27627         *   y1:y2:y3:y4:y5:y6:y7:y8, len(yx):4, len(y1-y8):32. len(":"):7
27628         *   Max len is 32 + 7 + 1(Termination) = 40 bytes
27629         *
27630         *   ipv6 dual address
27631         *   Or y1:y2:y3:y4:y:y6:x.x.x.x yx is 4, y1-y6 is 24, ":" is 6
27632         *   x.x.x.x is 15.
27633         *   Max len is 24 + 6 + 15 + 1(Termination) = 46 bytes
27634         *
27635         *   Expect data in ip[16]
27636         *   e.g (aaaa):(bbbb):(cccc):....(hhhh)
27637         *   (aaaa) = (ip[0<<8)|ip[1]
27638         *   ......
27639         *   (hhhh) = (ip[14]<<8)|(ip[15])
27640         *
27641         *   e.g ::(gggg):(hhhh)
27642         *   ip[0]-[11] = 0
27643         *   (gggg) = (ip[12]<<8) |(ip[13])
27644         *   (hhhh) = (ip[14]<<8) |(ip[15])
27645         *
27646         *   Because it is not able to know which ivp6 scheme uses from data to
27647         *   reconstruct IP address, this function assumes
27648         *   ivp6 normal address scheme, not dual adress scheme,
27649         *   to re-construct IP address in ascii.
27650         */
27651         buf = (char*)XMALLOC(max_ipv6_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27652 
27653         if (!buf) {
27654             WOLFSSL_MSG("failed malloc");
27655             return ret;
27656         }
27657         p = buf;
27658         for (i = 0; i < 16; i += 2) {
27659            val = (((word32)(ip[i]<<8)) | (ip[i+1])) & 0xFFFF;
27660            if (val == 0){
27661                if (!write_zero) {
27662                     *p = ':';
27663                }
27664                p++;
27665                *p = '\0';
27666                write_zero = 1;
27667            }
27668            else {
27669                if (i != 0)
27670                 *p++ = ':';
27671                XSPRINTF(p, "%x", val);
27672            }
27673            /* sanity check */
27674            if (XSTRLEN(buf) > max_ipv6_len) {
27675                WOLFSSL_MSG("The target ip adress exceeds buffer length(40)");
27676                XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27677                buf = NULL;
27678                break;
27679            }
27680            /* move the pointer to the last */
27681            /* XSTRLEN includes NULL because of XSPRINTF use */
27682            p = buf + (XSTRLEN(buf));
27683         }
27684         /* termination */
27685         if(i == 16 && buf) {
27686             p--;
27687             if ((*p) == ':') {
27688             /* when the last character is :, the followig segments are zero
27689              * Therefore, adding : and null termination
27690              */
27691                  p++;
27692                  *p++ = ':';
27693                 *p = '\0';
27694             }
27695         }
27696     }
27697     else {
27698         WOLFSSL_MSG("iplen is zero, do nothing");
27699         return WOLFSSL_SUCCESS;
27700     }
27701 
27702     if (buf) {
27703          /* set address to ip asc */
27704         ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, buf);
27705         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27706     }
27707 #else
27708     (void)param;
27709     (void)ip;
27710     (void)iplen;
27711 #endif
27712 
27713     return ret;
27714 }
27715 
27716 #ifndef NO_WOLFSSL_STUB
wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT * obj)27717 void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
27718 {
27719     (void)obj;
27720     WOLFSSL_STUB("X509_OBJECT_free_contents");
27721 }
27722 #endif
27723 
27724 #ifndef NO_ASN_TIME
wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME * asnTime)27725 int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
27726 {
27727     return wolfSSL_X509_cmp_time(asnTime, NULL);
27728 }
27729 
27730 /* Converts a WOLFSSL_ASN1_TIME to a struct tm. Returns WOLFSSL_SUCCESS on
27731  * success and WOLFSSL_FAILURE on failure. */
Asn1TimeToTm(WOLFSSL_ASN1_TIME * asnTime,struct tm * tm)27732 static int Asn1TimeToTm(WOLFSSL_ASN1_TIME* asnTime, struct tm* tm)
27733 {
27734     unsigned char* asn1TimeBuf;
27735     int asn1TimeBufLen;
27736     int i = 0;
27737     int bytesNeeded = 10;
27738 
27739     if (asnTime == NULL) {
27740         WOLFSSL_MSG("asnTime is NULL");
27741         return WOLFSSL_FAILURE;
27742     }
27743     if (tm == NULL) {
27744         WOLFSSL_MSG("tm is NULL");
27745         return WOLFSSL_FAILURE;
27746     }
27747 
27748     asn1TimeBuf = wolfSSL_ASN1_TIME_get_data(asnTime);
27749     if (asn1TimeBuf == NULL) {
27750         WOLFSSL_MSG("Failed to get WOLFSSL_ASN1_TIME buffer.");
27751         return WOLFSSL_FAILURE;
27752     }
27753     asn1TimeBufLen = wolfSSL_ASN1_TIME_get_length(asnTime);
27754     if (asn1TimeBufLen <= 0) {
27755         WOLFSSL_MSG("Failed to get WOLFSSL_ASN1_TIME buffer length.");
27756         return WOLFSSL_FAILURE;
27757     }
27758     XMEMSET(tm, 0, sizeof(struct tm));
27759 
27760     /* Convert ASN1_time to struct tm */
27761     /* Check type */
27762     if (asnTime->type == ASN_UTC_TIME) {
27763         /* 2-digit year */
27764         bytesNeeded += 2;
27765         if (bytesNeeded > asn1TimeBufLen) {
27766             WOLFSSL_MSG("WOLFSSL_ASN1_TIME buffer length is invalid.");
27767             return WOLFSSL_FAILURE;
27768         }
27769 
27770         tm->tm_year = (asn1TimeBuf[i] - '0') * 10; i++;
27771         tm->tm_year += asn1TimeBuf[i] - '0'; i++;
27772         if (tm->tm_year < 70) {
27773             tm->tm_year += 100;
27774         }
27775     }
27776     else if (asnTime->type == ASN_GENERALIZED_TIME) {
27777         /* 4-digit year */
27778         bytesNeeded += 4;
27779         if (bytesNeeded > asn1TimeBufLen) {
27780             WOLFSSL_MSG("WOLFSSL_ASN1_TIME buffer length is invalid.");
27781             return WOLFSSL_FAILURE;
27782         }
27783 
27784         tm->tm_year = (asn1TimeBuf[i] - '0') * 1000; i++;
27785         tm->tm_year += (asn1TimeBuf[i] - '0') * 100; i++;
27786         tm->tm_year += (asn1TimeBuf[i] - '0') * 10; i++;
27787         tm->tm_year += asn1TimeBuf[i] - '0'; i++;
27788         tm->tm_year -= 1900;
27789     }
27790     else {
27791         WOLFSSL_MSG("asnTime->type is invalid.");
27792         return WOLFSSL_FAILURE;
27793     }
27794 
27795     tm->tm_mon = (asn1TimeBuf[i] - '0') * 10; i++;
27796     tm->tm_mon += (asn1TimeBuf[i] - '0') - 1; i++; /* January is 0 not 1 */
27797     tm->tm_mday = (asn1TimeBuf[i] - '0') * 10; i++;
27798     tm->tm_mday += (asn1TimeBuf[i] - '0'); i++;
27799     tm->tm_hour = (asn1TimeBuf[i] - '0') * 10; i++;
27800     tm->tm_hour += (asn1TimeBuf[i] - '0'); i++;
27801     tm->tm_min = (asn1TimeBuf[i] - '0') * 10; i++;
27802     tm->tm_min += (asn1TimeBuf[i] - '0'); i++;
27803     tm->tm_sec = (asn1TimeBuf[i] - '0') * 10; i++;
27804     tm->tm_sec += (asn1TimeBuf[i] - '0');
27805 
27806 #ifdef XMKTIME
27807     /* Call XMKTIME on tm to get the tm_wday and tm_yday fields populated. */
27808     XMKTIME(tm);
27809 #endif
27810 
27811     return WOLFSSL_SUCCESS;
27812 }
27813 
27814 /* return -1 if asnTime is earlier than or equal to cmpTime, and 1 otherwise
27815  * return 0 on error
27816  */
wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME * asnTime,time_t * cmpTime)27817 int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime)
27818 {
27819     int ret = WOLFSSL_FAILURE;
27820     time_t tmpTime, *pTime = &tmpTime;
27821     struct tm ts, *tmpTs, *ct;
27822 #if defined(NEED_TMP_TIME)
27823     /* for use with gmtime_r */
27824     struct tm tmpTimeStorage;
27825 
27826     tmpTs = &tmpTimeStorage;
27827 #else
27828     tmpTs = NULL;
27829 #endif
27830     (void)tmpTs;
27831 
27832     if (asnTime == NULL) {
27833         return WOLFSSL_FAILURE;
27834     }
27835 
27836     if (cmpTime == NULL) {
27837         /* Use current time */
27838         *pTime = XTIME(0);
27839     }
27840     else {
27841         pTime = cmpTime;
27842     }
27843 
27844     if (Asn1TimeToTm((WOLFSSL_ASN1_TIME*)asnTime, &ts) != WOLFSSL_SUCCESS) {
27845         WOLFSSL_MSG("Failed to convert WOLFSSL_ASN1_TIME to struct tm.");
27846         return WOLFSSL_FAILURE;
27847     }
27848 
27849     /* Convert to time struct*/
27850     ct = XGMTIME(pTime, tmpTs);
27851 
27852     if (ct == NULL)
27853         return GETTIME_ERROR;
27854 
27855     /* DateGreaterThan returns 1 for >; 0 for <= */
27856     ret = DateGreaterThan(&ts, ct) ? 1 : -1;
27857 
27858     return ret;
27859 }
27860 #endif /* !NO_ASN_TIME */
27861 
27862 #if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
27863     !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME * asnTime,int offset_day,long offset_sec,time_t * in_tm)27864 WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME *asnTime,
27865     int offset_day, long offset_sec, time_t *in_tm)
27866 {
27867     /* get current time if in_tm is null */
27868     time_t t = in_tm ? *in_tm : XTIME(0);
27869     return wolfSSL_ASN1_TIME_adj(asnTime, t, offset_day, offset_sec);
27870 }
27871 
wolfSSL_X509_time_adj(WOLFSSL_ASN1_TIME * asnTime,long offset_sec,time_t * in_tm)27872 WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj(WOLFSSL_ASN1_TIME *asnTime,
27873     long offset_sec, time_t *in_tm)
27874 {
27875     return wolfSSL_X509_time_adj_ex(asnTime, 0, offset_sec, in_tm);
27876 }
27877 
wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME * s,long adj)27878 WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj)
27879 {
27880     return wolfSSL_X509_time_adj(s, adj, NULL);
27881 }
27882 #endif
27883 
27884 #ifndef NO_WOLFSSL_STUB
wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED * revoked)27885 int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked)
27886 {
27887     (void)revoked;
27888     WOLFSSL_STUB("sk_X509_REVOKED_num");
27889     return 0;
27890 }
27891 #endif
27892 
27893 #ifndef NO_WOLFSSL_STUB
wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL * crl)27894 WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
27895 {
27896     (void)crl;
27897     WOLFSSL_STUB("X509_CRL_get_REVOKED");
27898     return 0;
27899 }
27900 #endif
27901 
27902 #ifndef NO_WOLFSSL_STUB
wolfSSL_sk_X509_REVOKED_value(WOLFSSL_X509_REVOKED * revoked,int value)27903 WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
27904                                     WOLFSSL_X509_REVOKED* revoked, int value)
27905 {
27906     (void)revoked;
27907     (void)value;
27908     WOLFSSL_STUB("sk_X509_REVOKED_value");
27909     return 0;
27910 }
27911 #endif
27912 
27913 #endif /* OPENSSL_EXTRA */
27914 
27915 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
27916 /* Used to create a new WOLFSSL_ASN1_INTEGER structure.
27917  * returns a pointer to new structure on success and NULL on failure
27918  */
wolfSSL_ASN1_INTEGER_new(void)27919 WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_new(void)
27920 {
27921     WOLFSSL_ASN1_INTEGER* a;
27922 
27923     a = (WOLFSSL_ASN1_INTEGER*)XMALLOC(sizeof(WOLFSSL_ASN1_INTEGER), NULL,
27924                                        DYNAMIC_TYPE_OPENSSL);
27925     if (a == NULL) {
27926         return NULL;
27927     }
27928 
27929     XMEMSET(a, 0, sizeof(WOLFSSL_ASN1_INTEGER));
27930     a->data    = a->intData;
27931     a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
27932     a->length  = 0;
27933     return a;
27934 }
27935 
27936 
27937 /* free's internal elements of WOLFSSL_ASN1_INTEGER and free's "in" itself */
wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER * in)27938 void wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER* in)
27939 {
27940     if (in != NULL) {
27941         if (in->isDynamic) {
27942             XFREE(in->data, NULL, DYNAMIC_TYPE_OPENSSL);
27943         }
27944         XFREE(in, NULL, DYNAMIC_TYPE_OPENSSL);
27945     }
27946 }
27947 
27948 
27949 /* Duplicate all WOLFSSL_ASN1_INTEGER members from src to dup
27950  *  src : WOLFSSL_ASN1_INTEGER to duplicate
27951  *  Returns pointer to duplicate WOLFSSL_ASN1_INTEGER
27952  */
wolfSSL_ASN1_INTEGER_dup(const WOLFSSL_ASN1_INTEGER * src)27953 WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_dup(const WOLFSSL_ASN1_INTEGER* src)
27954 {
27955     WOLFSSL_ASN1_INTEGER* copy;
27956     WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_dup");
27957     if (!src)
27958         return NULL;
27959 
27960     copy = wolfSSL_ASN1_INTEGER_new();
27961 
27962     if (copy == NULL)
27963         return NULL;
27964 
27965     copy->negative  = src->negative;
27966     copy->dataMax   = src->dataMax;
27967     copy->isDynamic = src->isDynamic;
27968 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
27969     copy->length    = src->length;
27970 #endif
27971     XSTRNCPY((char*)copy->intData,(const char*)src->intData,WOLFSSL_ASN1_INTEGER_MAX);
27972 
27973     if (copy->isDynamic && src->data && copy->dataMax) {
27974         copy->data = (unsigned char*)
27975             XMALLOC(src->dataMax,NULL,DYNAMIC_TYPE_OPENSSL);
27976         if (copy->data == NULL) {
27977             wolfSSL_ASN1_INTEGER_free(copy);
27978             return NULL;
27979         }
27980         XMEMCPY(copy->data, src->data, copy->dataMax);
27981     }
27982     return copy;
27983 }
27984 
27985 
27986 /* sets the value of WOLFSSL_ASN1_INTEGER a to the long value v. */
wolfSSL_ASN1_INTEGER_set(WOLFSSL_ASN1_INTEGER * a,long v)27987 int wolfSSL_ASN1_INTEGER_set(WOLFSSL_ASN1_INTEGER *a, long v)
27988 {
27989     int ret = WOLFSSL_SUCCESS; /* return 1 for success and 0 for failure */
27990     int j;
27991     unsigned int i = 0;
27992     unsigned char tmp[sizeof(long)+1] = {0};
27993     int pad = 0;
27994 
27995     if (a != NULL) {
27996         /* dynamically create data buffer, +2 for type and length */
27997         a->data = (unsigned char*)XMALLOC((sizeof(long)+1) + 2, NULL,
27998                 DYNAMIC_TYPE_OPENSSL);
27999         if (a->data == NULL) {
28000             wolfSSL_ASN1_INTEGER_free(a);
28001             ret = WOLFSSL_FAILURE;
28002         }
28003         else {
28004             a->dataMax   = (int)(sizeof(long)+1) + 2;
28005             a->isDynamic = 1;
28006         }
28007     }
28008     else {
28009         /* Invalid parameter */
28010         ret = WOLFSSL_FAILURE;
28011     }
28012 
28013 
28014     if (ret != WOLFSSL_FAILURE) {
28015         /* Set type */
28016         a->data[i++] = ASN_INTEGER;
28017 
28018         /* Check for negative */
28019         if (v < 0) {
28020             a->negative = 1;
28021             v *= -1;
28022         }
28023 
28024         /* Create char buffer */
28025         for (j = 0; j < (int)sizeof(long); j++) {
28026             if (v == 0) {
28027                 break;
28028             }
28029             tmp[j] = (unsigned char)(v & 0xff);
28030             v >>= 8;
28031         }
28032 
28033         /* 0 pad to indicate positive number when top bit set. */
28034         if ((!a->negative) && (j > 0) && (tmp[j-1] & 0x80)) {
28035             pad = 1;
28036         }
28037         /* Set length */
28038         a->data[i++] = (unsigned char)(((j == 0) ? ++j : j) + pad);
28039         /* +2 for type and length */
28040         a->length = j + pad + 2;
28041 
28042         /* Add padding if required. */
28043         if (pad) {
28044             a->data[i++] = 0;
28045         }
28046         /* Copy to data */
28047         for (; j > 0; j--) {
28048             a->data[i++] = tmp[j-1];
28049         }
28050     }
28051 
28052     return ret;
28053 }
28054 
28055 
wolfSSL_X509_get_serialNumber(WOLFSSL_X509 * x509)28056 WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
28057 {
28058     WOLFSSL_ASN1_INTEGER* a;
28059     int i = 0;
28060 
28061     WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber");
28062 
28063     if (x509 == NULL) {
28064         WOLFSSL_MSG("NULL function argument");
28065         return NULL;
28066     }
28067 
28068     if (x509->serialNumber != NULL)
28069        return x509->serialNumber;
28070 
28071     a = wolfSSL_ASN1_INTEGER_new();
28072     if (a == NULL)
28073         return NULL;
28074 
28075     /* Make sure there is space for the data, ASN.1 type and length. */
28076     if (x509->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
28077         /* dynamically create data buffer, +2 for type and length */
28078         a->data = (unsigned char*)XMALLOC(x509->serialSz + 2, NULL,
28079                 DYNAMIC_TYPE_OPENSSL);
28080         if (a->data == NULL) {
28081             wolfSSL_ASN1_INTEGER_free(a);
28082             return NULL;
28083         }
28084         a->dataMax   = x509->serialSz + 2;
28085         a->isDynamic = 1;
28086     } else {
28087         /* Use array instead of dynamic memory */
28088         a->data    = a->intData;
28089         a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
28090     }
28091 
28092     #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
28093         XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
28094         a->length = x509->serialSz;
28095     #else
28096         a->data[i++] = ASN_INTEGER;
28097         i += SetLength(x509->serialSz, a->data + i);
28098         XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
28099         a->length = x509->serialSz + 2;
28100     #endif
28101 
28102     x509->serialNumber = a;
28103 
28104     return a;
28105 }
28106 
28107 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
28108 
28109 #if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \
28110     defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
28111 #ifndef NO_ASN_TIME
28112 #ifndef NO_BIO
wolfSSL_ASN1_TIME_print(WOLFSSL_BIO * bio,const WOLFSSL_ASN1_TIME * asnTime)28113 int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
28114 {
28115     char buf[MAX_TIME_STRING_SZ];
28116     int  ret = WOLFSSL_SUCCESS;
28117 
28118     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_print");
28119 
28120     if (bio == NULL || asnTime == NULL) {
28121         WOLFSSL_MSG("NULL function argument");
28122         return WOLFSSL_FAILURE;
28123     }
28124 
28125     if (wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)asnTime, buf,
28126                 sizeof(buf)) == NULL) {
28127         XMEMSET(buf, 0, MAX_TIME_STRING_SZ);
28128         XSTRNCPY(buf, "Bad time value", sizeof(buf)-1);
28129         ret = WOLFSSL_FAILURE;
28130     }
28131 
28132     if (wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf)) <= 0) {
28133         WOLFSSL_MSG("Unable to write to bio");
28134         return WOLFSSL_FAILURE;
28135     }
28136 
28137     return ret;
28138 }
28139 #endif /* !NO_BIO */
28140 
wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME * t,char * buf,int len)28141 char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, char* buf, int len)
28142 {
28143     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_string");
28144 
28145     if (t == NULL || buf == NULL || len < 5) {
28146         WOLFSSL_MSG("Bad argument");
28147         return NULL;
28148     }
28149 
28150     if (t->length > len) {
28151         WOLFSSL_MSG("Length of date is longer then buffer");
28152         return NULL;
28153     }
28154 
28155     if (!GetTimeString(t->data, t->type, buf, len)) {
28156         return NULL;
28157     }
28158 
28159     return buf;
28160 }
28161 
wolfSSL_ASN1_TIME_to_tm(const WOLFSSL_ASN1_TIME * asnTime,struct tm * tm)28162 int wolfSSL_ASN1_TIME_to_tm(const WOLFSSL_ASN1_TIME* asnTime, struct tm* tm)
28163 {
28164     time_t currentTime;
28165     struct tm *tmpTs;
28166 #if defined(NEED_TMP_TIME)
28167     /* for use with gmtime_r */
28168     struct tm tmpTimeStorage;
28169     tmpTs = &tmpTimeStorage;
28170 #else
28171     tmpTs = NULL;
28172 #endif
28173     (void)tmpTs;
28174 
28175     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_tm");
28176 
28177     /* If asnTime is NULL, then the current time is converted. */
28178     if (asnTime == NULL) {
28179         if (tm == NULL) {
28180             WOLFSSL_MSG("asnTime and tm are both NULL");
28181             return WOLFSSL_FAILURE;
28182         }
28183 
28184         currentTime = XTIME(0);
28185         if (currentTime <= 0) {
28186             WOLFSSL_MSG("Failed to get current time.");
28187             return WOLFSSL_FAILURE;
28188         }
28189 
28190         tm = XGMTIME(&currentTime, tmpTs);
28191         if (tm == NULL) {
28192             WOLFSSL_MSG("Failed to convert current time to UTC.");
28193             return WOLFSSL_FAILURE;
28194         }
28195 
28196         return WOLFSSL_SUCCESS;
28197     }
28198 
28199     /* If tm is NULL this function performs a format check on asnTime only. */
28200     if (tm == NULL) {
28201         return wolfSSL_ASN1_TIME_check(asnTime);
28202     }
28203 
28204     return Asn1TimeToTm((WOLFSSL_ASN1_TIME*)asnTime, tm);
28205 }
28206 #endif /* !NO_ASN_TIME */
28207 #endif /* WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
28208     OPENSSL_EXTRA*/
28209 
28210 
28211 #ifdef OPENSSL_EXTRA
28212 
28213 #ifndef NO_WOLFSSL_STUB
wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER * a,const WOLFSSL_ASN1_INTEGER * b)28214 int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a,
28215                             const WOLFSSL_ASN1_INTEGER* b)
28216 {
28217     (void)a;
28218     (void)b;
28219     WOLFSSL_STUB("ASN1_INTEGER_cmp");
28220     return 0;
28221 }
28222 #endif
28223 
wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER * a)28224 long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* a)
28225 {
28226     long ret = 1;
28227     WOLFSSL_BIGNUM* bn = NULL;
28228 
28229     WOLFSSL_ENTER("ASN1_INTEGER_get");
28230 
28231     if (a == NULL) {
28232         /* OpenSSL returns 0 when a is NULL and -1 if there is an error. Quoting
28233          * the documentation:
28234          *
28235          * "ASN1_INTEGER_get() also returns the value of a but it returns 0 if a
28236          * is NULL and -1 on error (which is ambiguous because -1 is a
28237          * legitimate value for an ASN1_INTEGER). New applications should use
28238          * ASN1_INTEGER_get_int64() instead."
28239          * */
28240         ret = 0;
28241     }
28242 
28243     if (ret > 0) {
28244         bn = wolfSSL_ASN1_INTEGER_to_BN(a, NULL);
28245         if (bn == NULL) {
28246             ret = -1;
28247         }
28248     }
28249     if (ret > 0) {
28250         ret = wolfSSL_BN_get_word(bn);
28251         if (a->negative == 1) {
28252             ret = -ret;
28253         }
28254     }
28255 
28256     if (bn != NULL) {
28257         wolfSSL_BN_free(bn);
28258     }
28259 
28260     WOLFSSL_LEAVE("ASN1_INTEGER_get", (int)ret);
28261 
28262     return ret;
28263 }
28264 
28265 #endif /* OPENSSL_EXTRA */
28266 
28267 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
28268 /* Gets an index to store SSL structure at.
28269  *
28270  * Returns positive index on success and negative values on failure
28271  */
wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)28272 int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
28273 {
28274     WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
28275 
28276     /* store SSL at index 0 */
28277     return 0;
28278 }
28279 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
28280 
28281 #ifdef OPENSSL_EXTRA
28282 /* Sets a function callback that will send information about the state of all
28283  * WOLFSSL objects that have been created by the WOLFSSL_CTX structure passed
28284  * in.
28285  *
28286  * ctx WOLFSSL_CTX structure to set callback function in
28287  * f   callback function to use
28288  */
wolfSSL_CTX_set_info_callback(WOLFSSL_CTX * ctx,void (* f)(const WOLFSSL * ssl,int type,int val))28289 void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
28290        void (*f)(const WOLFSSL* ssl, int type, int val))
28291 {
28292     WOLFSSL_ENTER("wolfSSL_CTX_set_info_callback");
28293     if (ctx == NULL) {
28294         WOLFSSL_MSG("Bad function argument");
28295     }
28296     else {
28297         ctx->CBIS = f;
28298     }
28299 }
28300 
28301 
wolfSSL_ERR_peek_error(void)28302 unsigned long wolfSSL_ERR_peek_error(void)
28303 {
28304     WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
28305 
28306     return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL);
28307 }
28308 
wolfSSL_ERR_GET_LIB(unsigned long err)28309 int wolfSSL_ERR_GET_LIB(unsigned long err)
28310 {
28311     unsigned long value;
28312 
28313     value = (err & 0xFFFFFFL);
28314     switch (value) {
28315     case -SSL_R_HTTP_REQUEST:
28316         return ERR_LIB_SSL;
28317     case PEM_R_NO_START_LINE:
28318     case PEM_R_PROBLEMS_GETTING_PASSWORD:
28319     case PEM_R_BAD_PASSWORD_READ:
28320     case PEM_R_BAD_DECRYPT:
28321         return ERR_LIB_PEM;
28322     case EVP_R_BAD_DECRYPT:
28323     case EVP_R_BN_DECODE_ERROR:
28324     case EVP_R_DECODE_ERROR:
28325     case EVP_R_PRIVATE_KEY_DECODE_ERROR:
28326         return ERR_LIB_EVP;
28327     case ASN1_R_HEADER_TOO_LONG:
28328         return ERR_LIB_ASN1;
28329     default:
28330         return 0;
28331     }
28332 }
28333 
28334 /* This function is to find global error values that are the same through out
28335  * all library version. With wolfSSL having only one set of error codes the
28336  * return value is pretty straight forward. The only thing needed is all wolfSSL
28337  * error values are typically negative.
28338  *
28339  * Returns the error reason
28340  */
wolfSSL_ERR_GET_REASON(unsigned long err)28341 int wolfSSL_ERR_GET_REASON(unsigned long err)
28342 {
28343     int ret = (int)err;
28344 
28345     WOLFSSL_ENTER("wolfSSL_ERR_GET_REASON");
28346 
28347 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
28348     /* Nginx looks for this error to know to stop parsing certificates. */
28349     if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE))
28350         return PEM_R_NO_START_LINE;
28351     if (err == ((ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST))
28352         return SSL_R_HTTP_REQUEST;
28353 #endif
28354 #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
28355     if (err == ((ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG))
28356         return ASN1_R_HEADER_TOO_LONG;
28357 #endif
28358 
28359     /* check if error value is in range of wolfSSL errors */
28360     ret = 0 - ret; /* setting as negative value */
28361     /* wolfCrypt range is less than MAX (-100)
28362        wolfSSL range is MIN (-300) and lower */
28363     if (ret < MAX_CODE_E && ret > MIN_CODE_E) {
28364         return ret;
28365     }
28366     else {
28367         WOLFSSL_MSG("Not in range of typical error values");
28368         ret = (int)err;
28369     }
28370 
28371     return ret;
28372 }
28373 
28374 /* returns a string that describes the alert
28375  *
28376  * alertID the alert value to look up
28377  */
wolfSSL_alert_type_string_long(int alertID)28378 const char* wolfSSL_alert_type_string_long(int alertID)
28379 {
28380     WOLFSSL_ENTER("wolfSSL_alert_type_string_long");
28381 
28382     return AlertTypeToString(alertID);
28383 }
28384 
28385 
wolfSSL_alert_desc_string_long(int alertID)28386 const char* wolfSSL_alert_desc_string_long(int alertID)
28387 {
28388     WOLFSSL_ENTER("wolfSSL_alert_desc_string_long");
28389 
28390     return AlertTypeToString(alertID);
28391 }
28392 
28393 /* Gets the current state of the WOLFSSL structure
28394  *
28395  * ssl WOLFSSL structure to get state of
28396  *
28397  * Returns a human readable string of the WOLFSSL structure state
28398  */
wolfSSL_state_string_long(const WOLFSSL * ssl)28399 const char* wolfSSL_state_string_long(const WOLFSSL* ssl)
28400 {
28401 
28402     static const char* OUTPUT_STR[14][6][3] = {
28403         {
28404             {"SSLv3 Initialization","SSLv3 Initialization","SSLv3 Initialization"},
28405             {"TLSv1 Initialization","TLSv2 Initialization","TLSv2 Initialization"},
28406             {"TLSv1_1 Initialization","TLSv1_1 Initialization","TLSv1_1 Initialization"},
28407             {"TLSv1_2 Initialization","TLSv1_2 Initialization","TLSv1_2 Initialization"},
28408             {"DTLSv1 Initialization","DTLSv1 Initialization","DTLSv1 Initialization"},
28409             {"DTLSv1_2 Initialization","DTLSv1_2 Initialization","DTLSv1_2 Initialization"},
28410         },
28411         {
28412             {"SSLv3 read Server Hello Verify Request",
28413              "SSLv3 write Server Hello Verify Request",
28414              "SSLv3 Server Hello Verify Request"},
28415             {"TLSv1 read Server Hello Verify Request",
28416              "TLSv1 write Server Hello Verify Request",
28417              "TLSv1 Server Hello Verify Request"},
28418             {"TLSv1_1 read Server Hello Verify Request",
28419             "TLSv1_1 write Server Hello Verify Request",
28420              "TLSv1_1 Server Hello Verify Request"},
28421             {"TLSv1_2 read Server Hello Verify Request",
28422             "TLSv1_2 write Server Hello Verify Request",
28423              "TLSv1_2 Server Hello Verify Request"},
28424             {"DTLSv1 read Server Hello Verify Request",
28425              "DTLSv1 write Server Hello Verify Request",
28426              "DTLSv1 Server Hello Verify Request"},
28427             {"DTLSv1_2 read Server Hello Verify Request",
28428              "DTLSv1_2 write Server Hello Verify Request",
28429              "DTLSv1_2 Server Hello Verify Request"},
28430         },
28431         {
28432             {"SSLv3 read Server Hello",
28433              "SSLv3 write Server Hello",
28434              "SSLv3 Server Hello"},
28435             {"TLSv1 read Server Hello",
28436              "TLSv1 write Server Hello",
28437              "TLSv1 Server Hello"},
28438             {"TLSv1_1 read Server Hello",
28439             "TLSv1_1 write Server Hello",
28440              "TLSv1_1 Server Hello"},
28441             {"TLSv1_2 read Server Hello",
28442             "TLSv1_2 write Server Hello",
28443              "TLSv1_2 Server Hello"},
28444             {"DTLSv1 read Server Hello",
28445             "DTLSv1 write Server Hello",
28446              "DTLSv1 Server Hello"},
28447             {"DTLSv1_2 read Server Hello"
28448              "DTLSv1_2 write Server Hello",
28449              "DTLSv1_2 Server Hello",
28450             },
28451         },
28452         {
28453             {"SSLv3 read Server Session Ticket",
28454              "SSLv3 write Server Session Ticket",
28455              "SSLv3 Server Session Ticket"},
28456             {"TLSv1 read Server Session Ticket",
28457              "TLSv1 write Server Session Ticket",
28458              "TLSv1 Server Session Ticket"},
28459             {"TLSv1_1 read Server Session Ticket",
28460              "TLSv1_1 write Server Session Ticket",
28461              "TLSv1_1 Server Session Ticket"},
28462             {"TLSv1_2 read Server Session Ticket",
28463              "TLSv1_2 write Server Session Ticket",
28464              "TLSv1_2 Server Session Ticket"},
28465             {"DTLSv1 read Server Session Ticket",
28466              "DTLSv1 write Server Session Ticket",
28467              "DTLSv1 Server Session Ticket"},
28468             {"DTLSv1_2 read Server Session Ticket",
28469              "DTLSv1_2 write Server Session Ticket",
28470              "DTLSv1_2 Server Session Ticket"},
28471         },
28472         {
28473             {"SSLv3 read Server Cert",
28474              "SSLv3 write Server Cert",
28475              "SSLv3 Server Cert"},
28476             {"TLSv1 read Server Cert",
28477              "TLSv1 write Server Cert",
28478              "TLSv1 Server Cert"},
28479             {"TLSv1_1 read Server Cert",
28480              "TLSv1_1 write Server Cert",
28481              "TLSv1_1 Server Cert"},
28482             {"TLSv1_2 read Server Cert",
28483              "TLSv1_2 write Server Cert",
28484              "TLSv1_2 Server Cert"},
28485             {"DTLSv1 read Server Cert",
28486              "DTLSv1 write Server Cert",
28487              "DTLSv1 Server Cert"},
28488             {"DTLSv1_2 read Server Cert",
28489              "DTLSv1_2 write Server Cert",
28490              "DTLSv1_2 Server Cert"},
28491         },
28492         {
28493             {"SSLv3 read Server Key Exchange",
28494              "SSLv3 write Server Key Exchange",
28495              "SSLv3 Server Key Exchange"},
28496             {"TLSv1 read Server Key Exchange",
28497              "TLSv1 write Server Key Exchange",
28498              "TLSv1 Server Key Exchange"},
28499             {"TLSv1_1 read Server Key Exchange",
28500              "TLSv1_1 write Server Key Exchange",
28501              "TLSv1_1 Server Key Exchange"},
28502             {"TLSv1_2 read Server Key Exchange",
28503              "TLSv1_2 write Server Key Exchange",
28504              "TLSv1_2 Server Key Exchange"},
28505             {"DTLSv1 read Server Key Exchange",
28506              "DTLSv1 write Server Key Exchange",
28507              "DTLSv1 Server Key Exchange"},
28508             {"DTLSv1_2 read Server Key Exchange",
28509              "DTLSv1_2 write Server Key Exchange",
28510              "DTLSv1_2 Server Key Exchange"},
28511         },
28512         {
28513             {"SSLv3 read Server Hello Done",
28514              "SSLv3 write Server Hello Done",
28515              "SSLv3 Server Hello Done"},
28516             {"TLSv1 read Server Hello Done",
28517              "TLSv1 write Server Hello Done",
28518              "TLSv1 Server Hello Done"},
28519             {"TLSv1_1 read Server Hello Done",
28520              "TLSv1_1 write Server Hello Done",
28521              "TLSv1_1 Server Hello Done"},
28522             {"TLSv1_2 read Server Hello Done",
28523              "TLSv1_2 write Server Hello Done",
28524              "TLSv1_2 Server Hello Done"},
28525             {"DTLSv1 read Server Hello Done",
28526              "DTLSv1 write Server Hello Done",
28527              "DTLSv1 Server Hello Done"},
28528             {"DTLSv1_2 read Server Hello Done",
28529              "DTLSv1_2 write Server Hello Done",
28530              "DTLSv1_2 Server Hello Done"},
28531         },
28532         {
28533             {"SSLv3 read Server Change CipherSpec",
28534              "SSLv3 write Server Change CipherSpec",
28535              "SSLv3 Server Change CipherSpec"},
28536             {"TLSv1 read Server Change CipherSpec",
28537              "TLSv1 write Server Change CipherSpec",
28538              "TLSv1 Server Change CipherSpec"},
28539             {"TLSv1_1 read Server Change CipherSpec",
28540              "TLSv1_1 write Server Change CipherSpec",
28541              "TLSv1_1 Server Change CipherSpec"},
28542             {"TLSv1_2 read Server Change CipherSpec",
28543              "TLSv1_2 write Server Change CipherSpec",
28544              "TLSv1_2 Server Change CipherSpec"},
28545             {"DTLSv1 read Server Change CipherSpec",
28546              "DTLSv1 write Server Change CipherSpec",
28547              "DTLSv1 Server Change CipherSpec"},
28548             {"DTLSv1_2 read Server Change CipherSpec",
28549              "DTLSv1_2 write Server Change CipherSpec",
28550              "DTLSv1_2 Server Change CipherSpec"},
28551         },
28552         {
28553             {"SSLv3 read Server Finished",
28554              "SSLv3 write Server Finished",
28555              "SSLv3 Server Finished"},
28556             {"TLSv1 read Server Finished",
28557              "TLSv1 write Server Finished",
28558              "TLSv1 Server Finished"},
28559             {"TLSv1_1 read Server Finished",
28560              "TLSv1_1 write Server Finished",
28561              "TLSv1_1 Server Finished"},
28562             {"TLSv1_2 read Server Finished",
28563              "TLSv1_2 write Server Finished",
28564              "TLSv1_2 Server Finished"},
28565             {"DTLSv1 read Server Finished",
28566              "DTLSv1 write Server Finished",
28567              "DTLSv1 Server Finished"},
28568             {"DTLSv1_2 read Server Finished",
28569              "DTLSv1_2 write Server Finished",
28570              "DTLSv1_2 Server Finished"},
28571         },
28572         {
28573             {"SSLv3 read Client Hello",
28574              "SSLv3 write Client Hello",
28575              "SSLv3 Client Hello"},
28576             {"TLSv1 read Client Hello",
28577              "TLSv1 write Client Hello",
28578              "TLSv1 Client Hello"},
28579             {"TLSv1_1 read Client Hello",
28580              "TLSv1_1 write Client Hello",
28581              "TLSv1_1 Client Hello"},
28582             {"TLSv1_2 read Client Hello",
28583              "TLSv1_2 write Client Hello",
28584              "TLSv1_2 Client Hello"},
28585             {"DTLSv1 read Client Hello",
28586              "DTLSv1 write Client Hello",
28587              "DTLSv1 Client Hello"},
28588             {"DTLSv1_2 read Client Hello",
28589              "DTLSv1_2 write Client Hello",
28590              "DTLSv1_2 Client Hello"},
28591         },
28592         {
28593             {"SSLv3 read Client Key Exchange",
28594              "SSLv3 write Client Key Exchange",
28595              "SSLv3 Client Key Exchange"},
28596             {"TLSv1 read Client Key Exchange",
28597              "TLSv1 write Client Key Exchange",
28598              "TLSv1 Client Key Exchange"},
28599             {"TLSv1_1 read Client Key Exchange",
28600              "TLSv1_1 write Client Key Exchange",
28601              "TLSv1_1 Client Key Exchange"},
28602             {"TLSv1_2 read Client Key Exchange",
28603              "TLSv1_2 write Client Key Exchange",
28604              "TLSv1_2 Client Key Exchange"},
28605             {"DTLSv1 read Client Key Exchange",
28606              "DTLSv1 write Client Key Exchange",
28607              "DTLSv1 Client Key Exchange"},
28608             {"DTLSv1_2 read Client Key Exchange",
28609              "DTLSv1_2 write Client Key Exchange",
28610              "DTLSv1_2 Client Key Exchange"},
28611         },
28612         {
28613             {"SSLv3 read Client Change CipherSpec",
28614              "SSLv3 write Client Change CipherSpec",
28615              "SSLv3 Client Change CipherSpec"},
28616             {"TLSv1 read Client Change CipherSpec",
28617              "TLSv1 write Client Change CipherSpec",
28618              "TLSv1 Client Change CipherSpec"},
28619             {"TLSv1_1 read Client Change CipherSpec",
28620              "TLSv1_1 write Client Change CipherSpec",
28621              "TLSv1_1 Client Change CipherSpec"},
28622             {"TLSv1_2 read Client Change CipherSpec",
28623              "TLSv1_2 write Client Change CipherSpec",
28624              "TLSv1_2 Client Change CipherSpec"},
28625             {"DTLSv1 read Client Change CipherSpec",
28626              "DTLSv1 write Client Change CipherSpec",
28627              "DTLSv1 Client Change CipherSpec"},
28628             {"DTLSv1_2 read Client Change CipherSpec",
28629              "DTLSv1_2 write Client Change CipherSpec",
28630              "DTLSv1_2 Client Change CipherSpec"},
28631         },
28632         {
28633             {"SSLv3 read Client Finished",
28634              "SSLv3 write Client Finished",
28635              "SSLv3 Client Finished"},
28636             {"TLSv1 read Client Finished",
28637              "TLSv1 write Client Finished",
28638              "TLSv1 Client Finished"},
28639             {"TLSv1_1 read Client Finished",
28640              "TLSv1_1 write Client Finished",
28641              "TLSv1_1 Client Finished"},
28642             {"TLSv1_2 read Client Finished",
28643              "TLSv1_2 write Client Finished",
28644              "TLSv1_2 Client Finished"},
28645             {"DTLSv1 read Client Finished",
28646              "DTLSv1 write Client Finished",
28647              "DTLSv1 Client Finished"},
28648             {"DTLSv1_2 read Client Finished",
28649              "DTLSv1_2 write Client Finished",
28650              "DTLSv1_2 Client Finished"},
28651         },
28652         {
28653             {"SSLv3 Handshake Done",
28654              "SSLv3 Handshake Done",
28655              "SSLv3 Handshake Done"},
28656             {"TLSv1 Handshake Done",
28657              "TLSv1 Handshake Done",
28658              "TLSv1 Handshake Done"},
28659             {"TLSv1_1 Handshake Done",
28660              "TLSv1_1 Handshake Done",
28661              "TLSv1_1 Handshake Done"},
28662             {"TLSv1_2 Handshake Done",
28663              "TLSv1_2 Handshake Done",
28664              "TLSv1_2 Handshake Done"},
28665             {"DTLSv1 Handshake Done",
28666              "DTLSv1 Handshake Done",
28667              "DTLSv1 Handshake Done"},
28668             {"DTLSv1_2 Handshake Done"
28669              "DTLSv1_2 Handshake Done"
28670              "DTLSv1_2 Handshake Done"}
28671         }
28672     };
28673     enum ProtocolVer {
28674         SSL_V3 = 0,
28675         TLS_V1,
28676         TLS_V1_1,
28677         TLS_V1_2,
28678         DTLS_V1,
28679         DTLS_V1_2,
28680         UNKNOWN = 100
28681     };
28682 
28683     enum IOMode {
28684         SS_READ = 0,
28685         SS_WRITE,
28686         SS_NEITHER
28687     };
28688 
28689     enum SslState {
28690         ss_null_state = 0,
28691         ss_server_helloverify,
28692         ss_server_hello,
28693         ss_sessionticket,
28694         ss_server_cert,
28695         ss_server_keyexchange,
28696         ss_server_hellodone,
28697         ss_server_changecipherspec,
28698         ss_server_finished,
28699         ss_client_hello,
28700         ss_client_keyexchange,
28701         ss_client_changecipherspec,
28702         ss_client_finished,
28703         ss_handshake_done
28704     };
28705 
28706     int protocol = 0;
28707     int cbmode = 0;
28708     int state = 0;
28709 
28710     WOLFSSL_ENTER("wolfSSL_state_string_long");
28711     if (ssl == NULL) {
28712         WOLFSSL_MSG("Null argument passed in");
28713         return NULL;
28714     }
28715 
28716     /* Get state of callback */
28717     if (ssl->cbmode == SSL_CB_MODE_WRITE){
28718         cbmode =  SS_WRITE;
28719     } else if (ssl->cbmode == SSL_CB_MODE_READ){
28720         cbmode =  SS_READ;
28721     } else {
28722         cbmode =  SS_NEITHER;
28723     }
28724 
28725     /* Get protocol version */
28726     switch (ssl->version.major){
28727         case SSLv3_MAJOR:
28728             switch (ssl->version.minor){
28729                 case TLSv1_MINOR:
28730                     protocol = TLS_V1;
28731                     break;
28732                 case TLSv1_1_MINOR:
28733                     protocol = TLS_V1_1;
28734                     break;
28735                 case TLSv1_2_MINOR:
28736                     protocol = TLS_V1_2;
28737                     break;
28738                 case SSLv3_MINOR:
28739                     protocol = SSL_V3;
28740                     break;
28741                 default:
28742                     protocol = UNKNOWN;
28743             }
28744             break;
28745         case DTLS_MAJOR:
28746             switch (ssl->version.minor){
28747         case DTLS_MINOR:
28748             protocol = DTLS_V1;
28749             break;
28750         case DTLSv1_2_MINOR:
28751             protocol = DTLS_V1_2;
28752             break;
28753         default:
28754             protocol = UNKNOWN;
28755     }
28756     break;
28757     default:
28758         protocol = UNKNOWN;
28759     }
28760 
28761     /* accept process */
28762     if (ssl->cbmode == SSL_CB_MODE_READ){
28763         state = ssl->cbtype;
28764         switch (state) {
28765             case hello_verify_request:
28766                 state = ss_server_helloverify;
28767                 break;
28768             case session_ticket:
28769                 state = ss_sessionticket;
28770                 break;
28771             case server_hello:
28772                 state = ss_server_hello;
28773                 break;
28774             case server_hello_done:
28775                 state = ss_server_hellodone;
28776                 break;
28777             case certificate:
28778                 state = ss_server_cert;
28779                 break;
28780             case server_key_exchange:
28781                 state = ss_server_keyexchange;
28782                 break;
28783             case client_hello:
28784                 state = ss_client_hello;
28785                 break;
28786             case client_key_exchange:
28787                 state = ss_client_keyexchange;
28788                 break;
28789             case finished:
28790                 if (ssl->options.side == WOLFSSL_SERVER_END)
28791                     state = ss_client_finished;
28792                 else if (ssl->options.side == WOLFSSL_CLIENT_END)
28793                     state = ss_server_finished;
28794                 else {
28795                     WOLFSSL_MSG("Unknown State");
28796                     state = ss_null_state;
28797                 }
28798                 break;
28799             default:
28800                 WOLFSSL_MSG("Unknown State");
28801                 state = ss_null_state;
28802         }
28803     } else {
28804         /* Send process */
28805         if (ssl->options.side == WOLFSSL_SERVER_END)
28806             state = ssl->options.serverState;
28807         else
28808             state = ssl->options.clientState;
28809 
28810         switch(state){
28811             case SERVER_HELLOVERIFYREQUEST_COMPLETE:
28812                 state = ss_server_helloverify;
28813                 break;
28814             case SERVER_HELLO_COMPLETE:
28815                 state = ss_server_hello;
28816                 break;
28817             case SERVER_CERT_COMPLETE:
28818                 state = ss_server_cert;
28819                 break;
28820             case SERVER_KEYEXCHANGE_COMPLETE:
28821                 state = ss_server_keyexchange;
28822                 break;
28823             case SERVER_HELLODONE_COMPLETE:
28824                 state = ss_server_hellodone;
28825                 break;
28826             case SERVER_CHANGECIPHERSPEC_COMPLETE:
28827                 state = ss_server_changecipherspec;
28828                 break;
28829             case SERVER_FINISHED_COMPLETE:
28830                 state = ss_server_finished;
28831                 break;
28832             case CLIENT_HELLO_COMPLETE:
28833                 state = ss_client_hello;
28834                 break;
28835             case CLIENT_KEYEXCHANGE_COMPLETE:
28836                 state = ss_client_keyexchange;
28837                 break;
28838             case CLIENT_CHANGECIPHERSPEC_COMPLETE:
28839                 state = ss_client_changecipherspec;
28840                 break;
28841             case CLIENT_FINISHED_COMPLETE:
28842                 state = ss_client_finished;
28843                 break;
28844             case HANDSHAKE_DONE:
28845                 state = ss_handshake_done;
28846                 break;
28847             default:
28848                 WOLFSSL_MSG("Unknown State");
28849                 state = ss_null_state;
28850         }
28851     }
28852 
28853     if (protocol == UNKNOWN)
28854         return NULL;
28855     else
28856         return OUTPUT_STR[state][protocol][cbmode];
28857 }
28858 
28859 /*
28860  * Sets default PEM callback password if null is passed into
28861  * the callback parameter of a PEM_read_bio_* function.
28862  *
28863  * Returns callback phrase size on success or WOLFSSL_FAILURE otherwise.
28864  */
wolfSSL_PEM_def_callback(char * name,int num,int w,void * key)28865 int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key)
28866 {
28867     int sz;
28868     (void)w;
28869     WOLFSSL_ENTER("wolfSSL_PEM_def_callback");
28870 
28871     /* We assume that the user passes a default password as userdata */
28872     if (key) {
28873         sz = (int)XSTRLEN((const char*)key);
28874         sz = (sz > num) ? num : sz;
28875         XMEMCPY(name, key, sz);
28876         return sz;
28877     } else {
28878         WOLFSSL_MSG("Error, default password cannot be created.");
28879         return WOLFSSL_FAILURE;
28880     }
28881 }
28882 
28883 #endif /* OPENSSL_EXTRA */
28884 
wolf_set_options(long old_op,long op)28885 static long wolf_set_options(long old_op, long op)
28886 {
28887     /* if SSL_OP_ALL then turn all bug workarounds on */
28888     if ((op & SSL_OP_ALL) == SSL_OP_ALL) {
28889         WOLFSSL_MSG("\tSSL_OP_ALL");
28890     }
28891 
28892     /* by default cookie exchange is on with DTLS */
28893     if ((op & SSL_OP_COOKIE_EXCHANGE) == SSL_OP_COOKIE_EXCHANGE) {
28894         WOLFSSL_MSG("\tSSL_OP_COOKIE_EXCHANGE : on by default");
28895     }
28896 
28897     if ((op & WOLFSSL_OP_NO_SSLv2) == WOLFSSL_OP_NO_SSLv2) {
28898         WOLFSSL_MSG("\tWOLFSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2");
28899     }
28900 
28901 #ifdef SSL_OP_NO_TLSv1_3
28902     if ((op & SSL_OP_NO_TLSv1_3) == SSL_OP_NO_TLSv1_3) {
28903         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_3");
28904     }
28905 #endif
28906 
28907     if ((op & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
28908         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2");
28909     }
28910 
28911     if ((op & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
28912         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_1");
28913     }
28914 
28915     if ((op & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
28916         WOLFSSL_MSG("\tSSL_OP_NO_TLSv1");
28917     }
28918 
28919     if ((op & WOLFSSL_OP_NO_SSLv3) == WOLFSSL_OP_NO_SSLv3) {
28920         WOLFSSL_MSG("\tSSL_OP_NO_SSLv3");
28921     }
28922 
28923     if ((op & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) ==
28924             WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
28925         WOLFSSL_MSG("\tWOLFSSL_OP_CIPHER_SERVER_PREFERENCE");
28926     }
28927 
28928     if ((op & WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION) {
28929     #ifdef HAVE_LIBZ
28930         WOLFSSL_MSG("SSL_OP_NO_COMPRESSION");
28931     #else
28932         WOLFSSL_MSG("SSL_OP_NO_COMPRESSION: compression not compiled in");
28933     #endif
28934     }
28935 
28936     return old_op | op;
28937 }
28938 
28939 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
wolfSSL_set_options(WOLFSSL * ssl,long op)28940 long wolfSSL_set_options(WOLFSSL* ssl, long op)
28941 {
28942     word16 haveRSA = 1;
28943     word16 havePSK = 0;
28944     int    keySz   = 0;
28945 
28946     WOLFSSL_ENTER("wolfSSL_set_options");
28947 
28948     if (ssl == NULL) {
28949         return 0;
28950     }
28951 
28952     ssl->options.mask = wolf_set_options(ssl->options.mask, op);
28953 
28954 #ifdef SSL_OP_NO_TLSv1_3
28955     if ((ssl->options.mask & SSL_OP_NO_TLSv1_3) == SSL_OP_NO_TLSv1_3) {
28956         if (ssl->version.minor == TLSv1_3_MINOR)
28957             ssl->version.minor = TLSv1_2_MINOR;
28958     }
28959 #endif
28960 
28961     if ((ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) {
28962         if (ssl->version.minor == TLSv1_2_MINOR)
28963             ssl->version.minor = TLSv1_1_MINOR;
28964     }
28965 
28966     if ((ssl->options.mask & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) {
28967         if (ssl->version.minor == TLSv1_1_MINOR)
28968             ssl->version.minor = TLSv1_MINOR;
28969     }
28970 
28971     if ((ssl->options.mask & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) {
28972         if (ssl->version.minor == TLSv1_MINOR)
28973             ssl->version.minor = SSLv3_MINOR;
28974     }
28975 
28976     if ((ssl->options.mask & WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION) {
28977     #ifdef HAVE_LIBZ
28978         ssl->options.usingCompression = 0;
28979     #endif
28980     }
28981 
28982     /* in the case of a version change the cipher suites should be reset */
28983 #ifndef NO_PSK
28984     havePSK = ssl->options.havePSK;
28985 #endif
28986 #ifdef NO_RSA
28987     haveRSA = 0;
28988 #endif
28989 #ifndef NO_CERTS
28990     keySz = ssl->buffers.keySz;
28991 #endif
28992 
28993     if (ssl->suites != NULL && ssl->options.side != WOLFSSL_NEITHER_END)
28994         InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
28995                    ssl->options.haveDH, ssl->options.haveECDSAsig,
28996                    ssl->options.haveECC, ssl->options.haveStaticECC,
28997                    ssl->options.haveFalconSig, ssl->options.haveAnon,
28998                    ssl->options.side);
28999 
29000     return ssl->options.mask;
29001 }
29002 
29003 
wolfSSL_get_options(const WOLFSSL * ssl)29004 long wolfSSL_get_options(const WOLFSSL* ssl)
29005 {
29006     WOLFSSL_ENTER("wolfSSL_get_options");
29007     if(ssl == NULL)
29008         return WOLFSSL_FAILURE;
29009     return ssl->options.mask;
29010 }
29011 
29012 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
29013 
29014 #if defined(HAVE_SECURE_RENEGOTIATION) \
29015         || defined(HAVE_SERVER_RENEGOTIATION_INFO)
29016 /* clears the counter for number of renegotiations done
29017  * returns the current count before it is cleared */
wolfSSL_clear_num_renegotiations(WOLFSSL * s)29018 long wolfSSL_clear_num_renegotiations(WOLFSSL *s)
29019 {
29020     long total;
29021 
29022     WOLFSSL_ENTER("wolfSSL_clear_num_renegotiations");
29023     if (s == NULL)
29024         return 0;
29025 
29026     total = s->secure_rene_count;
29027     s->secure_rene_count = 0;
29028     return total;
29029 }
29030 
29031 
29032 /* return the number of renegotiations since wolfSSL_new */
wolfSSL_total_renegotiations(WOLFSSL * s)29033 long wolfSSL_total_renegotiations(WOLFSSL *s)
29034 {
29035     WOLFSSL_ENTER("wolfSSL_total_renegotiations");
29036     return wolfSSL_num_renegotiations(s);
29037 }
29038 
29039 
29040 /* return the number of renegotiations since wolfSSL_new */
wolfSSL_num_renegotiations(WOLFSSL * s)29041 long wolfSSL_num_renegotiations(WOLFSSL* s)
29042 {
29043     if (s == NULL) {
29044         return 0;
29045     }
29046 
29047     return s->secure_rene_count;
29048 }
29049 
29050 
29051 /* Is there a renegotiation currently in progress? */
wolfSSL_SSL_renegotiate_pending(WOLFSSL * s)29052 int  wolfSSL_SSL_renegotiate_pending(WOLFSSL *s)
29053 {
29054     return s && s->options.handShakeDone &&
29055             s->options.handShakeState != HANDSHAKE_DONE ? 1 : 0;
29056 }
29057 #endif /* HAVE_SECURE_RENEGOTIATION || HAVE_SERVER_RENEGOTIATION_INFO */
29058 
29059 #ifdef OPENSSL_EXTRA
29060 
wolfSSL_clear_options(WOLFSSL * ssl,long opt)29061 long wolfSSL_clear_options(WOLFSSL* ssl, long opt)
29062 {
29063     WOLFSSL_ENTER("SSL_clear_options");
29064     if(ssl == NULL)
29065         return WOLFSSL_FAILURE;
29066     ssl->options.mask &= ~opt;
29067     return ssl->options.mask;
29068 }
29069 
29070 
29071 #ifndef NO_DH
wolfSSL_set_tmp_dh(WOLFSSL * ssl,WOLFSSL_DH * dh)29072 long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh)
29073 {
29074     int pSz, gSz;
29075     byte *p, *g;
29076     int ret = 0;
29077 
29078     WOLFSSL_ENTER("wolfSSL_set_tmp_dh");
29079 
29080     if (!ssl || !dh)
29081         return BAD_FUNC_ARG;
29082 
29083     /* Get needed size for p and g */
29084     pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
29085     gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
29086 
29087     if (pSz <= 0 || gSz <= 0)
29088         return WOLFSSL_FATAL_ERROR;
29089 
29090     p = (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
29091     if (!p)
29092         return MEMORY_E;
29093 
29094     g = (byte*)XMALLOC(gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
29095     if (!g) {
29096         XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
29097         return MEMORY_E;
29098     }
29099 
29100     pSz = wolfSSL_BN_bn2bin(dh->p, p);
29101     gSz = wolfSSL_BN_bn2bin(dh->g, g);
29102 
29103     if (pSz >= 0 && gSz >= 0) /* Conversion successful */
29104         ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
29105 
29106     XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
29107     XFREE(g, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
29108 
29109     return pSz > 0 && gSz > 0 ? ret : WOLFSSL_FATAL_ERROR;
29110 }
29111 #endif /* !NO_DH */
29112 
29113 
29114 #ifdef HAVE_PK_CALLBACKS
wolfSSL_set_tlsext_debug_arg(WOLFSSL * ssl,void * arg)29115 long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
29116 {
29117     if (ssl == NULL) {
29118         return WOLFSSL_FAILURE;
29119     }
29120 
29121     ssl->loggingCtx = arg;
29122     return WOLFSSL_SUCCESS;
29123 }
29124 #endif /* HAVE_PK_CALLBACKS */
29125 
29126 #if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)
SSL_SESSION_get0_id_context(const WOLFSSL_SESSION * sess,unsigned int * sid_ctx_length)29127 const unsigned char *SSL_SESSION_get0_id_context(const WOLFSSL_SESSION *sess, unsigned int *sid_ctx_length)
29128 {
29129     const byte *c = wolfSSL_SESSION_get_id((WOLFSSL_SESSION *)sess, sid_ctx_length);
29130     return c;
29131 }
29132 #endif
29133 
29134 /*** TBD ***/
29135 #ifndef NO_WOLFSSL_STUB
wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK * st)29136 WOLFSSL_API int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* st)
29137 {
29138     (void)st;
29139     WOLFSSL_STUB("wolfSSL_sk_SSL_COMP_zero");
29140     /* wolfSSL_set_options(ssl, SSL_OP_NO_COMPRESSION); */
29141     return WOLFSSL_FAILURE;
29142 }
29143 #endif
29144 
29145 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
wolfSSL_set_tlsext_status_type(WOLFSSL * s,int type)29146 long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type)
29147 {
29148     WOLFSSL_ENTER("wolfSSL_set_tlsext_status_type");
29149 
29150     if (s == NULL){
29151         return BAD_FUNC_ARG;
29152     }
29153 
29154     if (type == TLSEXT_STATUSTYPE_ocsp){
29155         int r = TLSX_UseCertificateStatusRequest(&s->extensions, (byte)type, 0, s,
29156                                                              s->heap, s->devId);
29157         return (long)r;
29158     } else {
29159         WOLFSSL_MSG(
29160        "SSL_set_tlsext_status_type only supports TLSEXT_STATUSTYPE_ocsp type.");
29161         return SSL_FAILURE;
29162     }
29163 
29164 }
29165 
wolfSSL_get_tlsext_status_type(WOLFSSL * s)29166 long wolfSSL_get_tlsext_status_type(WOLFSSL *s)
29167 {
29168     TLSX* extension;
29169 
29170     if (s == NULL)
29171         return WOLFSSL_FATAL_ERROR;
29172     extension = TLSX_Find(s->extensions, TLSX_STATUS_REQUEST);
29173     return extension != NULL ? TLSEXT_STATUSTYPE_ocsp : WOLFSSL_FATAL_ERROR;
29174 }
29175 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
29176 
29177 #ifndef NO_WOLFSSL_STUB
wolfSSL_get_tlsext_status_exts(WOLFSSL * s,void * arg)29178 WOLFSSL_API long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg)
29179 {
29180     (void)s;
29181     (void)arg;
29182     WOLFSSL_STUB("wolfSSL_get_tlsext_status_exts");
29183     return WOLFSSL_FAILURE;
29184 }
29185 #endif
29186 
29187 /*** TBD ***/
29188 #ifndef NO_WOLFSSL_STUB
wolfSSL_set_tlsext_status_exts(WOLFSSL * s,void * arg)29189 WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg)
29190 {
29191     (void)s;
29192     (void)arg;
29193     WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts");
29194     return WOLFSSL_FAILURE;
29195 }
29196 #endif
29197 
29198 /*** TBD ***/
29199 #ifndef NO_WOLFSSL_STUB
wolfSSL_get_tlsext_status_ids(WOLFSSL * s,void * arg)29200 WOLFSSL_API long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg)
29201 {
29202     (void)s;
29203     (void)arg;
29204     WOLFSSL_STUB("wolfSSL_get_tlsext_status_ids");
29205     return WOLFSSL_FAILURE;
29206 }
29207 #endif
29208 
29209 /*** TBD ***/
29210 #ifndef NO_WOLFSSL_STUB
wolfSSL_set_tlsext_status_ids(WOLFSSL * s,void * arg)29211 WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg)
29212 {
29213     (void)s;
29214     (void)arg;
29215     WOLFSSL_STUB("wolfSSL_set_tlsext_status_ids");
29216     return WOLFSSL_FAILURE;
29217 }
29218 #endif
29219 
29220 /*** TBD ***/
29221 #ifndef NO_WOLFSSL_STUB
SSL_SESSION_set1_id(WOLFSSL_SESSION * s,const unsigned char * sid,unsigned int sid_len)29222 WOLFSSL_API int SSL_SESSION_set1_id(WOLFSSL_SESSION *s, const unsigned char *sid, unsigned int sid_len)
29223 {
29224     (void)s;
29225     (void)sid;
29226     (void)sid_len;
29227     WOLFSSL_STUB("SSL_SESSION_set1_id");
29228     return WOLFSSL_FAILURE;
29229 }
29230 #endif
29231 
29232 #ifndef NO_WOLFSSL_STUB
29233 /*** TBD ***/
SSL_SESSION_set1_id_context(WOLFSSL_SESSION * s,const unsigned char * sid_ctx,unsigned int sid_ctx_len)29234 WOLFSSL_API int SSL_SESSION_set1_id_context(WOLFSSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len)
29235 {
29236     (void)s;
29237     (void)sid_ctx;
29238     (void)sid_ctx_len;
29239     WOLFSSL_STUB("SSL_SESSION_set1_id_context");
29240     return WOLFSSL_FAILURE;
29241 }
29242 #endif
29243 
29244 #if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) \
29245     || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
wolfSSL_X509_ALGOR_new(void)29246 WOLFSSL_X509_ALGOR* wolfSSL_X509_ALGOR_new(void)
29247 {
29248     WOLFSSL_X509_ALGOR* ret;
29249     ret = (WOLFSSL_X509_ALGOR*)XMALLOC(sizeof(WOLFSSL_X509_ALGOR), NULL,
29250                                        DYNAMIC_TYPE_OPENSSL);
29251     if (ret) {
29252         XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ALGOR));
29253     }
29254     return ret;
29255 }
29256 
wolfSSL_X509_ALGOR_free(WOLFSSL_X509_ALGOR * alg)29257 void wolfSSL_X509_ALGOR_free(WOLFSSL_X509_ALGOR *alg)
29258 {
29259     if (alg) {
29260         wolfSSL_ASN1_OBJECT_free(alg->algorithm);
29261         wolfSSL_ASN1_TYPE_free(alg->parameter);
29262         XFREE(alg, NULL, DYNAMIC_TYPE_OPENSSL);
29263     }
29264 }
29265 
29266 /* Returns X509_ALGOR struct with signature algorithm */
wolfSSL_X509_get0_tbs_sigalg(const WOLFSSL_X509 * x509)29267 const WOLFSSL_X509_ALGOR* wolfSSL_X509_get0_tbs_sigalg(const WOLFSSL_X509 *x509)
29268 {
29269     WOLFSSL_ENTER("X509_get0_tbs_sigalg");
29270 
29271     if (x509 == NULL) {
29272         WOLFSSL_MSG("x509 struct NULL error");
29273         return NULL;
29274     }
29275 
29276     return &x509->algor;
29277 }
29278 
29279 /* Sets paobj pointer to X509_ALGOR signature algorithm */
wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT ** paobj,int * pptype,const void ** ppval,const WOLFSSL_X509_ALGOR * algor)29280 void wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT **paobj, int *pptype,
29281                             const void **ppval, const WOLFSSL_X509_ALGOR *algor)
29282 {
29283     WOLFSSL_ENTER("X509_ALGOR_get0");
29284 
29285     if (!algor) {
29286         WOLFSSL_MSG("algor object is NULL");
29287         return;
29288     }
29289 
29290     if (paobj)
29291         *paobj = algor->algorithm;
29292     if (ppval && algor->parameter)
29293         *ppval = algor->parameter->value.ptr;
29294     if (pptype) {
29295         if (algor->parameter) {
29296             *pptype = algor->parameter->type;
29297         }
29298         else {
29299             /* Default to V_ASN1_OBJECT */
29300             *pptype = V_ASN1_OBJECT;
29301         }
29302     }
29303 }
29304 
29305 /**
29306  * Populate algor members.
29307  *
29308  * @param algor The object to be set
29309  * @param aobj The value to be set in algor->algorithm
29310  * @param ptype The type of algor->parameter
29311  * @param pval The value of algor->parameter
29312  * @return WOLFSSL_SUCCESS on success
29313  *         WOLFSSL_FAILURE on missing parameters or bad malloc
29314  */
wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR * algor,WOLFSSL_ASN1_OBJECT * aobj,int ptype,void * pval)29315 int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor, WOLFSSL_ASN1_OBJECT *aobj,
29316                             int ptype, void *pval)
29317 {
29318     if (!algor) {
29319         return WOLFSSL_FAILURE;
29320     }
29321     if (aobj) {
29322         algor->algorithm = aobj;
29323     }
29324 
29325     if (!algor->parameter) {
29326         algor->parameter = wolfSSL_ASN1_TYPE_new();
29327         if (!algor->parameter) {
29328             return WOLFSSL_FAILURE;
29329         }
29330     }
29331 
29332     wolfSSL_ASN1_TYPE_set(algor->parameter, ptype, pval);
29333 
29334     return WOLFSSL_SUCCESS;
29335 }
29336 
29337 /**
29338  * Set `a` in a smart way.
29339  *
29340  * @param a Object to set
29341  * @param type The type of object in value
29342  * @param value Object to set
29343  */
wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE * a,int type,void * value)29344 void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value)
29345 {
29346     if (!a) {
29347         return;
29348     }
29349     switch (type) {
29350         case V_ASN1_NULL:
29351             a->value.ptr = (char *)value;
29352             break;
29353         case V_ASN1_SEQUENCE:
29354             a->value.asn1_string = (WOLFSSL_ASN1_STRING*)value;
29355             break;
29356         case V_ASN1_OBJECT:
29357             a->value.object = (WOLFSSL_ASN1_OBJECT*)value;
29358             break;
29359         case V_ASN1_UTCTIME:
29360             a->value.utctime = (WOLFSSL_ASN1_TIME*)value;
29361             break;
29362         case V_ASN1_GENERALIZEDTIME:
29363             a->value.generalizedtime = (WOLFSSL_ASN1_TIME*)value;
29364             break;
29365         default:
29366             WOLFSSL_MSG("Unknown or unsupported ASN1_TYPE");
29367             return;
29368     }
29369     a->type = type;
29370 }
29371 
29372 /**
29373  * Allocate a new WOLFSSL_ASN1_TYPE object.
29374  *
29375  * @return New zero'ed WOLFSSL_ASN1_TYPE object
29376  */
wolfSSL_ASN1_TYPE_new(void)29377 WOLFSSL_ASN1_TYPE* wolfSSL_ASN1_TYPE_new(void)
29378 {
29379     WOLFSSL_ASN1_TYPE* ret = (WOLFSSL_ASN1_TYPE*)XMALLOC(sizeof(WOLFSSL_ASN1_TYPE),
29380                                                         NULL, DYNAMIC_TYPE_OPENSSL);
29381     if (!ret)
29382         return NULL;
29383     XMEMSET(ret, 0, sizeof(WOLFSSL_ASN1_TYPE));
29384     return ret;
29385 }
29386 
29387 /**
29388  * Free WOLFSSL_ASN1_TYPE and all its members.
29389  *
29390  * @param at Object to free
29391  */
wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE * at)29392 void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at)
29393 {
29394     if (at) {
29395         switch (at->type) {
29396             case V_ASN1_OBJECT:
29397                 wolfSSL_ASN1_OBJECT_free(at->value.object);
29398                 break;
29399             case V_ASN1_UTCTIME:
29400             #ifndef NO_ASN_TIME
29401                 wolfSSL_ASN1_TIME_free(at->value.utctime);
29402             #endif
29403                 break;
29404             case V_ASN1_GENERALIZEDTIME:
29405             #ifndef NO_ASN_TIME
29406                 wolfSSL_ASN1_TIME_free(at->value.generalizedtime);
29407             #endif
29408                 break;
29409             case V_ASN1_UTF8STRING:
29410             case V_ASN1_PRINTABLESTRING:
29411             case V_ASN1_T61STRING:
29412             case V_ASN1_IA5STRING:
29413             case V_ASN1_UNIVERSALSTRING:
29414             case V_ASN1_SEQUENCE:
29415                 wolfSSL_ASN1_STRING_free(at->value.asn1_string);
29416                 break;
29417             default:
29418                 WOLFSSL_MSG("Unknown or unsupported ASN1_TYPE");
29419                 break;
29420         }
29421         XFREE(at, NULL, DYNAMIC_TYPE_OPENSSL);
29422     }
29423 }
29424 
29425 /**
29426  * Allocate a new WOLFSSL_X509_PUBKEY object.
29427  *
29428  * @return New zero'ed WOLFSSL_X509_PUBKEY object
29429  */
wolfSSL_X509_PUBKEY_new(void)29430 WOLFSSL_X509_PUBKEY *wolfSSL_X509_PUBKEY_new(void)
29431 {
29432     WOLFSSL_X509_PUBKEY *ret;
29433     ret = (WOLFSSL_X509_PUBKEY*)XMALLOC(sizeof(WOLFSSL_X509_PUBKEY), NULL,
29434                                         DYNAMIC_TYPE_OPENSSL);
29435     if (!ret) {
29436         return NULL;
29437     }
29438     XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PUBKEY));
29439     ret->algor = wolfSSL_X509_ALGOR_new();
29440     if (!ret->algor) {
29441         wolfSSL_X509_PUBKEY_free(ret);
29442         return NULL;
29443     }
29444     return ret;
29445 }
29446 
29447 /**
29448  * Free WOLFSSL_X509_PUBKEY and all its members.
29449  *
29450  * @param at Object to free
29451  */
wolfSSL_X509_PUBKEY_free(WOLFSSL_X509_PUBKEY * x)29452 void wolfSSL_X509_PUBKEY_free(WOLFSSL_X509_PUBKEY *x)
29453 {
29454     if (x) {
29455         if (x->algor) {
29456             wolfSSL_X509_ALGOR_free(x->algor);
29457         }
29458         if (x->pkey) {
29459             wolfSSL_EVP_PKEY_free(x->pkey);
29460         }
29461         XFREE(x, NULL, DYNAMIC_TYPE_OPENSSL);
29462     }
29463 }
29464 
29465 /* Returns X509_PUBKEY structure containing X509_ALGOR and EVP_PKEY */
wolfSSL_X509_get_X509_PUBKEY(const WOLFSSL_X509 * x509)29466 WOLFSSL_X509_PUBKEY* wolfSSL_X509_get_X509_PUBKEY(const WOLFSSL_X509* x509)
29467 {
29468     WOLFSSL_ENTER("X509_get_X509_PUBKEY");
29469 
29470     if (x509 == NULL) {
29471         WOLFSSL_MSG("x509 struct NULL error");
29472         return NULL;
29473     }
29474 
29475     return (WOLFSSL_X509_PUBKEY*)&x509->key;
29476 }
29477 
29478 /* Sets ppkalg pointer to X509_PUBKEY algorithm. Returns WOLFSSL_SUCCESS on
29479     success or WOLFSSL_FAILURE on error. */
wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT ** ppkalg,const unsigned char ** pk,int * ppklen,WOLFSSL_X509_ALGOR ** pa,WOLFSSL_X509_PUBKEY * pub)29480 int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg,
29481      const unsigned char **pk, int *ppklen, WOLFSSL_X509_ALGOR **pa,
29482      WOLFSSL_X509_PUBKEY *pub)
29483 {
29484     WOLFSSL_ENTER("X509_PUBKEY_get0_param");
29485 
29486     if (!pub || !pub->pubKeyOID) {
29487         WOLFSSL_MSG("X509_PUBKEY struct not populated");
29488         return WOLFSSL_FAILURE;
29489     }
29490 
29491     if (!pub->algor) {
29492         if (!(pub->algor = wolfSSL_X509_ALGOR_new())) {
29493             return WOLFSSL_FAILURE;
29494         }
29495         pub->algor->algorithm = wolfSSL_OBJ_nid2obj(pub->pubKeyOID);
29496         if (pub->algor->algorithm == NULL) {
29497             WOLFSSL_MSG("Failed to create object from NID");
29498             return WOLFSSL_FAILURE;
29499         }
29500     }
29501 
29502     if (pa)
29503         *pa = pub->algor;
29504     if (ppkalg)
29505         *ppkalg = pub->algor->algorithm;
29506     if (pk)
29507         *pk = (unsigned char*)pub->pkey->pkey.ptr;
29508     if (ppklen)
29509         *ppklen = pub->pkey->pkey_sz;
29510 
29511     return WOLFSSL_SUCCESS;
29512 }
29513 
29514 /* Returns a pointer to the pkey when passed a key */
wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY * key)29515 WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key)
29516 {
29517     WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get");
29518     if (key == NULL || key->pkey == NULL) {
29519         WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_FUNC_ARG);
29520         return NULL;
29521     }
29522     if (wolfSSL_EVP_PKEY_up_ref(key->pkey) != WOLFSSL_SUCCESS) {
29523         WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_MUTEX_E);
29524         return NULL;
29525     }
29526     WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", WOLFSSL_SUCCESS);
29527     return key->pkey;
29528 }
29529 
wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY ** x,WOLFSSL_EVP_PKEY * key)29530 int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
29531 {
29532     WOLFSSL_X509_PUBKEY *pk = NULL;
29533     int ptype;
29534     void *pval;
29535 #ifndef NO_DSA
29536     WOLFSSL_ASN1_STRING *str;
29537 #endif
29538 #ifdef HAVE_ECC
29539     int nid;
29540     const WOLFSSL_EC_GROUP *group;
29541 #endif
29542 
29543     WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_set");
29544 
29545     if (!x || !key) {
29546         return WOLFSSL_FAILURE;
29547     }
29548 
29549     if (!(pk = wolfSSL_X509_PUBKEY_new())) {
29550         return WOLFSSL_FAILURE;
29551     }
29552 
29553     switch (key->type) {
29554 #ifndef NO_RSA
29555     case EVP_PKEY_RSA:
29556         pval = NULL;
29557         ptype = V_ASN1_NULL;
29558         pk->pubKeyOID = RSAk;
29559         break;
29560 #endif
29561 #ifndef NO_DSA
29562     case EVP_PKEY_DSA:
29563         if (!key->dsa->p || !key->dsa->q || !key->dsa->g)
29564             goto error;
29565 
29566         str = wolfSSL_ASN1_STRING_new();
29567         if (str == NULL)
29568             goto error;
29569 
29570         str->length = wolfSSL_i2d_DSAparams(key->dsa, (unsigned char **)&str->data);
29571         if (str->length <= 0)
29572             goto error;
29573         str->isDynamic = 1;
29574 
29575         pval = str;
29576         ptype = V_ASN1_SEQUENCE;
29577         pk->pubKeyOID = DSAk;
29578         break;
29579 #endif
29580 #ifdef HAVE_ECC
29581     case EVP_PKEY_EC:
29582         group = wolfSSL_EC_KEY_get0_group(key->ecc);
29583         if (!group)
29584             goto error;
29585 
29586         nid = wolfSSL_EC_GROUP_get_curve_name(group);
29587         if (nid == WOLFSSL_FAILURE) {
29588             /* TODO: Add support for no nid case */
29589             WOLFSSL_MSG("nid not found");
29590             goto error;
29591         }
29592 
29593         pval = wolfSSL_OBJ_nid2obj(nid);
29594         if (!pval)
29595             goto error;
29596 
29597         ptype = V_ASN1_OBJECT;
29598         pk->pubKeyOID = ECDSAk;
29599         break;
29600 #endif
29601     default:
29602         WOLFSSL_MSG("Unknown key type");
29603         goto error;
29604     }
29605 
29606     if (!wolfSSL_X509_ALGOR_set0(pk->algor, wolfSSL_OBJ_nid2obj(key->type), ptype, pval)) {
29607         WOLFSSL_MSG("Failed to create algorithm object");
29608         if (ptype == V_ASN1_OBJECT)
29609             ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
29610         else
29611             ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
29612         goto error;
29613     }
29614 
29615     if (!wolfSSL_EVP_PKEY_up_ref(key)) {
29616         WOLFSSL_MSG("Failed to up key reference");
29617         goto error;
29618     }
29619     pk->pkey = key;
29620 
29621     wolfSSL_X509_PUBKEY_free(*x);
29622     *x = pk;
29623     return WOLFSSL_SUCCESS;
29624 error:
29625     if (pk) {
29626         wolfSSL_X509_PUBKEY_free(pk);
29627     }
29628     return WOLFSSL_FAILURE;
29629 }
29630 
29631 #endif /* OPENSSL_ALL || WOLFSSL_APACHE_HTTPD || WOLFSSL_HAPROXY*/
29632 
29633 #ifndef NO_WOLFSSL_STUB
29634 /*** TBD ***/
wolfSSL_get_privatekey(const WOLFSSL * ssl)29635 WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_get_privatekey(const WOLFSSL *ssl)
29636 {
29637     (void)ssl;
29638     WOLFSSL_STUB("SSL_get_privatekey");
29639     return NULL;
29640 }
29641 #endif
29642 
29643 /**
29644  * Get a textual representation of given WOLFSSL_ASN1_OBJECT then write it to
29645  * buf at most buf_len bytes.
29646  *
29647  * params
29648  * - buf: buffer where the textual representation is to be written to
29649  * - buf_len: buffer size in bytes
29650  * - a: WOLFSSL_ASN1_OBJECT
29651  *
29652  * return the string length written on success, WOLFSSL_FAILURE on failure.
29653  */
wolfSSL_i2t_ASN1_OBJECT(char * buf,int buf_len,WOLFSSL_ASN1_OBJECT * a)29654 WOLFSSL_API int wolfSSL_i2t_ASN1_OBJECT(char *buf, int buf_len,
29655                                                 WOLFSSL_ASN1_OBJECT *a)
29656 {
29657     WOLFSSL_ENTER("wolfSSL_i2t_ASN1_OBJECT");
29658     return wolfSSL_OBJ_obj2txt(buf, buf_len, a, 0);
29659 }
29660 
wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT ** a,const unsigned char ** der,long length)29661 WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a,
29662                                              const unsigned char **der,
29663                                              long length)
29664 {
29665     const unsigned char *d;
29666     long len;
29667     int tag, cls;
29668     WOLFSSL_ASN1_OBJECT* ret = NULL;
29669 
29670     WOLFSSL_ENTER("wolfSSL_d2i_ASN1_OBJECT");
29671 
29672     if (!der || !*der || length <= 0) {
29673         WOLFSSL_MSG("Bad parameter");
29674         return NULL;
29675     }
29676 
29677     d = *der;
29678 
29679     if (wolfSSL_ASN1_get_object(&d, &len, &tag, &cls, length) & 0x80) {
29680         WOLFSSL_MSG("wolfSSL_ASN1_get_object error");
29681         return NULL;
29682     }
29683     /* d now points to value */
29684 
29685     if (tag != ASN_OBJECT_ID) {
29686         WOLFSSL_MSG("Not an ASN object");
29687         return NULL;
29688     }
29689 
29690     ret = wolfSSL_c2i_ASN1_OBJECT(a, &d, len);
29691     if (ret)
29692         *der = d;
29693     return ret;
29694 }
29695 
29696 /**
29697  * Parse an ASN1 encoded input and output information about the parsed object
29698  * @param in    ASN1 encoded data. *in is moved to the value of the ASN1 object
29699  * @param len   Length of parsed ASN1 object
29700  * @param tag   Tag value of parsed ASN1 object
29701  * @param cls   Class of parsed ASN1 object
29702  * @param inLen Length of *in buffer
29703  * @return int  Depends on which bits are set in the returned int:
29704  *              0x80 an error occurred during parsing
29705  *              0x20 parsed object is constructed
29706  *              0x01 the parsed object length is infinite
29707  */
wolfSSL_ASN1_get_object(const unsigned char ** in,long * len,int * tag,int * cls,long inLen)29708 int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag,
29709                             int *cls, long inLen)
29710 {
29711     word32 inOutIdx = 0;
29712     int l;
29713     byte t;
29714     int ret = 0x80;
29715 
29716     WOLFSSL_ENTER("wolfSSL_ASN1_get_object");
29717 
29718     if (!in || !*in || !len || !tag || !cls || inLen == 0) {
29719         WOLFSSL_MSG("Bad parameter");
29720         return ret;
29721     }
29722 
29723     if (GetASNTag(*in, &inOutIdx, &t, (word32)inLen) != 0) {
29724         WOLFSSL_MSG("GetASNTag error");
29725         return ret;
29726     }
29727 
29728     if (GetLength(*in, &inOutIdx, &l, (word32)inLen) < 0) {
29729         WOLFSSL_MSG("GetLength error");
29730         return ret;
29731     }
29732 
29733     *tag = t & 0x1F; /* Tag number is 5 lsb */
29734     *cls = t & 0xC0; /* Class is 2 msb */
29735     *len = l;
29736     ret = t & ASN_CONSTRUCTED;
29737 
29738     if (l > (int)(inLen - inOutIdx)) {
29739         /* Still return other values but indicate error in msb */
29740         ret |= 0x80;
29741     }
29742 
29743     *in += inOutIdx;
29744     return ret;
29745 }
29746 
wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT ** a,const unsigned char ** pp,long len)29747 WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a,
29748         const unsigned char **pp, long len)
29749 {
29750     WOLFSSL_ASN1_OBJECT* ret = NULL;
29751 
29752     WOLFSSL_ENTER("wolfSSL_c2i_ASN1_OBJECT");
29753 
29754     if (!pp || !*pp || len <= 0) {
29755         WOLFSSL_MSG("Bad parameter");
29756         return NULL;
29757     }
29758 
29759     if (!(ret = wolfSSL_ASN1_OBJECT_new())) {
29760         WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new error");
29761         return NULL;
29762     }
29763 
29764     ret->obj = (const unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
29765     if (!ret->obj) {
29766         WOLFSSL_MSG("error allocating asn data memory");
29767         wolfSSL_ASN1_OBJECT_free(ret);
29768         return NULL;
29769     }
29770 
29771     XMEMCPY((byte*)ret->obj, *pp, len);
29772     ret->objSz = (unsigned int)len;
29773     ret->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
29774 
29775     *pp += len;
29776 
29777     if (a)
29778         *a = ret;
29779     return ret;
29780 }
29781 
29782 #ifndef NO_BIO
29783 /* Return number of bytes written to BIO on success. 0 on failure. */
wolfSSL_i2a_ASN1_OBJECT(WOLFSSL_BIO * bp,WOLFSSL_ASN1_OBJECT * a)29784 WOLFSSL_API int wolfSSL_i2a_ASN1_OBJECT(WOLFSSL_BIO *bp,
29785                                         WOLFSSL_ASN1_OBJECT *a)
29786 {
29787     int length = 0;
29788     word32 idx = 0;
29789     const char null_str[] = "NULL";
29790 
29791     WOLFSSL_ENTER("wolfSSL_i2a_ASN1_OBJECT");
29792 
29793     if (bp == NULL)
29794         return WOLFSSL_FAILURE;
29795 
29796     if (a == NULL) {
29797         /* Write "NULL" */
29798         if (wolfSSL_BIO_write(bp, null_str, (int)XSTRLEN(null_str)) ==
29799                 (int)XSTRLEN(null_str)) {
29800             return (int)XSTRLEN(null_str);
29801         }
29802         else {
29803             return WOLFSSL_FAILURE;
29804         }
29805     }
29806 
29807 
29808     if ((a->obj == NULL) || (a->obj[idx++] != ASN_OBJECT_ID)) {
29809         WOLFSSL_MSG("Bad ASN1 Object");
29810         return WOLFSSL_FAILURE;
29811     }
29812 
29813     if (GetLength((const byte*)a->obj, &idx, &length,
29814                    a->objSz) < 0 || length < 0) {
29815         return WOLFSSL_FAILURE;
29816     }
29817 
29818     if (wolfSSL_BIO_write(bp, a->obj + idx, length) == (int)length) {
29819         return length;
29820     }
29821 
29822     return WOLFSSL_FAILURE;
29823 }
29824 #endif /* !NO_BIO */
29825 
29826 /* Returns object data for an ASN1_OBJECT */
29827 /* If pp is NULL then only the size is returned */
29828 /* If pp has pointer to pointer then its used directly */
29829 /* If pp has pointer to pointer that is NULL then new variable is allocated */
29830 /* Failure returns WOLFSSL_FAILURE (0) */
wolfSSL_i2d_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT * a,unsigned char ** pp)29831 int wolfSSL_i2d_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT *a, unsigned char **pp)
29832 {
29833     byte *p;
29834 
29835     WOLFSSL_ENTER("wolfSSL_i2d_ASN1_OBJECT");
29836 
29837     if (!a || !a->obj) {
29838         WOLFSSL_MSG("Bad parameters");
29839         return WOLFSSL_FAILURE;
29840     }
29841 
29842     if (!pp)
29843         return a->objSz;
29844 
29845     if (*pp)
29846         p = *pp;
29847     else {
29848         p = (byte*)XMALLOC(a->objSz, NULL, DYNAMIC_TYPE_OPENSSL);
29849         if (!p) {
29850             WOLFSSL_MSG("Bad malloc");
29851             return WOLFSSL_FAILURE;
29852         }
29853     }
29854 
29855     XMEMCPY(p, a->obj, a->objSz);
29856     *pp = p + a->objSz;
29857     return a->objSz;
29858 }
29859 
29860 #if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
wolfSSL_get_finished(const WOLFSSL * ssl,void * buf,size_t count)29861 WOLFSSL_API size_t wolfSSL_get_finished(const WOLFSSL *ssl, void *buf, size_t count)
29862 {
29863     WOLFSSL_ENTER("SSL_get_finished");
29864     byte len = 0;
29865 
29866     if (!ssl || !buf || count < TLS_FINISHED_SZ) {
29867         WOLFSSL_MSG("Bad parameter");
29868         return WOLFSSL_FAILURE;
29869     }
29870 
29871     if (ssl->options.side == WOLFSSL_SERVER_END) {
29872         len = ssl->serverFinished_len;
29873         XMEMCPY(buf, ssl->serverFinished, len);
29874     }
29875     else {
29876         len = ssl->clientFinished_len;
29877         XMEMCPY(buf, ssl->clientFinished, len);
29878     }
29879     return len;
29880 }
29881 
wolfSSL_get_peer_finished(const WOLFSSL * ssl,void * buf,size_t count)29882 WOLFSSL_API size_t wolfSSL_get_peer_finished(const WOLFSSL *ssl, void *buf, size_t count)
29883 {
29884     byte len = 0;
29885     WOLFSSL_ENTER("SSL_get_peer_finished");
29886 
29887     if (!ssl || !buf || count < TLS_FINISHED_SZ) {
29888         WOLFSSL_MSG("Bad parameter");
29889         return WOLFSSL_FAILURE;
29890     }
29891 
29892     if (ssl->options.side == WOLFSSL_CLIENT_END) {
29893         len = ssl->serverFinished_len;
29894         XMEMCPY(buf, ssl->serverFinished, len);
29895     }
29896     else {
29897         len = ssl->clientFinished_len;
29898         XMEMCPY(buf, ssl->clientFinished, len);
29899     }
29900 
29901     return len;
29902 }
29903 #endif /* WOLFSSL_HAPROXY */
29904 
29905 #ifndef NO_WOLFSSL_STUB
29906 /*** TBD ***/
SSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX * ctx,WOLFSSL_DH * (* dh)(WOLFSSL * ssl,int is_export,int keylength))29907 WOLFSSL_API void SSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx, WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength))
29908 {
29909     (void)ctx;
29910     (void)dh;
29911     WOLFSSL_STUB("SSL_CTX_set_tmp_dh_callback");
29912 }
29913 #endif
29914 
29915 #ifndef NO_WOLFSSL_STUB
29916 /*** TBD ***/
WOLF_STACK_OF(SSL_COMP)29917 WOLFSSL_API WOLF_STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
29918 {
29919     WOLFSSL_STUB("SSL_COMP_get_compression_methods");
29920     return NULL;
29921 }
29922 #endif
29923 
29924 
wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF (WOLFSSL_CIPHER)* p)29925 int wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF(WOLFSSL_CIPHER)* p)
29926 {
29927     WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_num");
29928     if (p == NULL) {
29929         return WOLFSSL_FATAL_ERROR;
29930     }
29931     return (int)p->num;
29932 }
29933 
wolfSSL_sk_SSL_CIPHER_value(WOLFSSL_STACK * sk,int i)29934 WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(WOLFSSL_STACK* sk, int i)
29935 {
29936     WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_value");
29937     return (WOLFSSL_CIPHER*)wolfSSL_sk_value(sk, i);
29938 }
29939 
29940 #if !defined(NETOS)
ERR_load_SSL_strings(void)29941 WOLFSSL_API void ERR_load_SSL_strings(void)
29942 {
29943 
29944 }
29945 #endif
29946 
29947 #ifdef HAVE_OCSP
wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL * s,unsigned char ** resp)29948 WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp)
29949 {
29950     if (s == NULL || resp == NULL)
29951         return 0;
29952 
29953     *resp = s->ocspResp;
29954     return s->ocspRespSz;
29955 }
29956 
wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL * s,unsigned char * resp,int len)29957 WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, int len)
29958 {
29959     if (s == NULL)
29960         return WOLFSSL_FAILURE;
29961 
29962     s->ocspResp   = resp;
29963     s->ocspRespSz = len;
29964 
29965     return WOLFSSL_SUCCESS;
29966 }
29967 #endif /* HAVE_OCSP */
29968 
29969 #ifdef HAVE_MAX_FRAGMENT
29970 #ifndef NO_WOLFSSL_CLIENT
29971 /**
29972  * Set max fragment tls extension
29973  * @param c a pointer to WOLFSSL_CTX object
29974  * @param mode maximum fragment length mode
29975  * @return 1 on success, otherwise 0 or negative error code
29976  */
wolfSSL_CTX_set_tlsext_max_fragment_length(WOLFSSL_CTX * c,unsigned char mode)29977 WOLFSSL_API int wolfSSL_CTX_set_tlsext_max_fragment_length(WOLFSSL_CTX *c,
29978                                                             unsigned char mode)
29979 {
29980     if (c == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
29981         return BAD_FUNC_ARG;
29982 
29983     return wolfSSL_CTX_UseMaxFragment(c, mode);
29984 }
29985 /**
29986  * Set max fragment tls extension
29987  * @param c a pointer to WOLFSSL object
29988  * @param mode maximum fragment length mode
29989  * @return 1 on success, otherwise 0 or negative error code
29990  */
wolfSSL_set_tlsext_max_fragment_length(WOLFSSL * s,unsigned char mode)29991 WOLFSSL_API int wolfSSL_set_tlsext_max_fragment_length(WOLFSSL *s,
29992                                                             unsigned char mode)
29993 {
29994     if (s == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
29995         return BAD_FUNC_ARG;
29996 
29997     return wolfSSL_UseMaxFragment(s, mode);
29998 }
29999 #endif /* NO_WOLFSSL_CLIENT */
30000 #endif /* HAVE_MAX_FRAGMENT */
30001 
30002 #endif /* OPENSSL_EXTRA */
30003 
30004 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
wolfSSL_get_verify_result(const WOLFSSL * ssl)30005 long wolfSSL_get_verify_result(const WOLFSSL *ssl)
30006 {
30007     if (ssl == NULL) {
30008         return WOLFSSL_FAILURE;
30009     }
30010 
30011     return ssl->peerVerifyRet;
30012 }
30013 #endif
30014 
30015 #ifdef OPENSSL_EXTRA
30016 
30017 #ifndef NO_WOLFSSL_STUB
30018 /* shows the number of accepts attempted by CTX in it's lifetime */
wolfSSL_CTX_sess_accept(WOLFSSL_CTX * ctx)30019 long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
30020 {
30021     WOLFSSL_STUB("wolfSSL_CTX_sess_accept");
30022     (void)ctx;
30023     return 0;
30024 }
30025 #endif
30026 
30027 #ifndef NO_WOLFSSL_STUB
30028 /* shows the number of connects attempted CTX in it's lifetime */
wolfSSL_CTX_sess_connect(WOLFSSL_CTX * ctx)30029 long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
30030 {
30031     WOLFSSL_STUB("wolfSSL_CTX_sess_connect");
30032     (void)ctx;
30033     return 0;
30034 }
30035 #endif
30036 
30037 
30038 #ifndef NO_WOLFSSL_STUB
30039 /* shows the number of accepts completed by CTX in it's lifetime */
wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX * ctx)30040 long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
30041 {
30042     WOLFSSL_STUB("wolfSSL_CTX_sess_accept_good");
30043     (void)ctx;
30044     return 0;
30045 }
30046 #endif
30047 
30048 
30049 #ifndef NO_WOLFSSL_STUB
30050 /* shows the number of connects completed by CTX in it's lifetime */
wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX * ctx)30051 long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
30052 {
30053     WOLFSSL_STUB("wolfSSL_CTX_sess_connect_good");
30054     (void)ctx;
30055     return 0;
30056 }
30057 #endif
30058 
30059 
30060 #ifndef NO_WOLFSSL_STUB
30061 /* shows the number of renegotiation accepts attempted by CTX */
wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX * ctx)30062 long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
30063 {
30064     WOLFSSL_STUB("wolfSSL_CTX_sess_accept_renegotiate");
30065     (void)ctx;
30066     return 0;
30067 }
30068 #endif
30069 
30070 
30071 #ifndef NO_WOLFSSL_STUB
30072 /* shows the number of renegotiation accepts attempted by CTX */
wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX * ctx)30073 long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
30074 {
30075     WOLFSSL_STUB("wolfSSL_CTX_sess_connect_renegotiate");
30076     (void)ctx;
30077     return 0;
30078 }
30079 #endif
30080 
30081 
30082 #ifndef NO_WOLFSSL_STUB
wolfSSL_CTX_sess_hits(WOLFSSL_CTX * ctx)30083 long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
30084 {
30085     WOLFSSL_STUB("wolfSSL_CTX_sess_hits");
30086     (void)ctx;
30087     return 0;
30088 }
30089 #endif
30090 
30091 
30092 #ifndef NO_WOLFSSL_STUB
wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX * ctx)30093 long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
30094 {
30095     WOLFSSL_STUB("wolfSSL_CTX_sess_cb_hits");
30096     (void)ctx;
30097     return 0;
30098 }
30099 #endif
30100 
30101 
30102 #ifndef NO_WOLFSSL_STUB
wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX * ctx)30103 long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
30104 {
30105     WOLFSSL_STUB("wolfSSL_CTX_sess_cache_full");
30106     (void)ctx;
30107     return 0;
30108 }
30109 #endif
30110 
30111 
30112 #ifndef NO_WOLFSSL_STUB
wolfSSL_CTX_sess_misses(WOLFSSL_CTX * ctx)30113 long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
30114 {
30115     WOLFSSL_STUB("wolfSSL_CTX_sess_misses");
30116     (void)ctx;
30117     return 0;
30118 }
30119 #endif
30120 
30121 
30122 #ifndef NO_WOLFSSL_STUB
wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX * ctx)30123 long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
30124 {
30125     WOLFSSL_STUB("wolfSSL_CTX_sess_timeouts");
30126     (void)ctx;
30127     return 0;
30128 }
30129 #endif
30130 
30131 
30132 /* Return the total number of sessions */
wolfSSL_CTX_sess_number(WOLFSSL_CTX * ctx)30133 long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
30134 {
30135     word32 total = 0;
30136 
30137     WOLFSSL_ENTER("wolfSSL_CTX_sess_number");
30138     (void)ctx;
30139 
30140 #if defined(WOLFSSL_SESSION_STATS) && !defined(NO_SESSION_CACHE)
30141     if (wolfSSL_get_session_stats(NULL, &total, NULL, NULL) != WOLFSSL_SUCCESS) {
30142         WOLFSSL_MSG("Error getting session stats");
30143     }
30144 #else
30145     WOLFSSL_MSG("Please use macro WOLFSSL_SESSION_STATS for session stats");
30146 #endif
30147 
30148     return (long)total;
30149 }
30150 
30151 
30152 #ifndef NO_CERTS
wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX * ctx,WOLFSSL_X509 * x509)30153 long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
30154 {
30155     byte* chain = NULL;
30156     long  chainSz = 0;
30157     int   derSz;
30158     const byte* der;
30159     int   ret;
30160     int   idx = 0;
30161     DerBuffer *derBuffer = NULL;
30162 
30163     WOLFSSL_ENTER("wolfSSL_CTX_add_extra_chain_cert");
30164 
30165     if (ctx == NULL || x509 == NULL) {
30166         WOLFSSL_MSG("Bad Argument");
30167         return WOLFSSL_FAILURE;
30168     }
30169 
30170     der = wolfSSL_X509_get_der(x509, &derSz);
30171     if (der == NULL || derSz <= 0) {
30172         WOLFSSL_MSG("Error getting X509 DER");
30173         return WOLFSSL_FAILURE;
30174     }
30175 
30176     if (ctx->certificate == NULL) {
30177         WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
30178 
30179         /* Process buffer makes first certificate the leaf. */
30180         ret = ProcessBuffer(ctx, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
30181                             NULL, NULL, 1, GET_VERIFY_SETTING_CTX(ctx));
30182         if (ret != WOLFSSL_SUCCESS) {
30183             WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
30184             return WOLFSSL_FAILURE;
30185         }
30186     }
30187     else {
30188         /* TODO: Do this elsewhere. */
30189         ret = AllocDer(&derBuffer, derSz, CERT_TYPE, ctx->heap);
30190         if (ret != 0) {
30191             WOLFSSL_MSG("Memory Error");
30192             return WOLFSSL_FAILURE;
30193         }
30194         XMEMCPY(derBuffer->buffer, der, derSz);
30195         ret = AddCA(ctx->cm, &derBuffer, WOLFSSL_USER_CA,
30196             GET_VERIFY_SETTING_CTX(ctx));
30197         if (ret != WOLFSSL_SUCCESS) {
30198             WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
30199             return WOLFSSL_FAILURE;
30200         }
30201 
30202         /* adding cert to existing chain */
30203         if (ctx->certChain != NULL && ctx->certChain->length > 0) {
30204             chainSz += ctx->certChain->length;
30205         }
30206         chainSz += OPAQUE24_LEN + derSz;
30207 
30208         chain = (byte*)XMALLOC(chainSz, ctx->heap, DYNAMIC_TYPE_DER);
30209         if (chain == NULL) {
30210             WOLFSSL_MSG("Memory Error");
30211             return WOLFSSL_FAILURE;
30212         }
30213 
30214         if (ctx->certChain != NULL && ctx->certChain->length > 0) {
30215             XMEMCPY(chain, ctx->certChain->buffer, ctx->certChain->length);
30216             idx = ctx->certChain->length;
30217         }
30218         c32to24(derSz, chain + idx);
30219         idx += OPAQUE24_LEN;
30220         XMEMCPY(chain + idx, der, derSz);
30221         idx += derSz;
30222 #ifdef WOLFSSL_TLS13
30223         ctx->certChainCnt++;
30224 #endif
30225 
30226         FreeDer(&ctx->certChain);
30227         ret = AllocDer(&ctx->certChain, idx, CERT_TYPE, ctx->heap);
30228         if (ret == 0) {
30229             XMEMCPY(ctx->certChain->buffer, chain, idx);
30230         }
30231     }
30232 
30233     /* on success WOLFSSL_X509 memory is responsibility of ctx */
30234     wolfSSL_X509_free(x509);
30235     if (chain != NULL)
30236         XFREE(chain, ctx->heap, DYNAMIC_TYPE_DER);
30237 
30238     return WOLFSSL_SUCCESS;
30239 }
30240 
30241 
wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX * ctx,void * arg)30242 long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg)
30243 {
30244     if (ctx == NULL || ctx->cm == NULL) {
30245         return WOLFSSL_FAILURE;
30246     }
30247 
30248     ctx->cm->ocspIOCtx = arg;
30249     return WOLFSSL_SUCCESS;
30250 }
30251 
30252 #endif /* NO_CERTS */
30253 
30254 
30255 /* Get the session cache mode for CTX
30256  *
30257  * ctx  WOLFSSL_CTX struct to get cache mode from
30258  *
30259  * Returns a bit mask that has the session cache mode */
wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX * ctx)30260 WOLFSSL_API long wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX* ctx)
30261 {
30262     long m = 0;
30263 
30264     WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
30265 
30266     if (ctx == NULL) {
30267         return m;
30268     }
30269 
30270     if (ctx->sessionCacheOff != 1) {
30271         m |= SSL_SESS_CACHE_SERVER;
30272     }
30273 
30274     if (ctx->sessionCacheFlushOff == 1) {
30275         m |= SSL_SESS_CACHE_NO_AUTO_CLEAR;
30276     }
30277 
30278 #ifdef HAVE_EXT_CACHE
30279     if (ctx->internalCacheOff == 1) {
30280         m |= SSL_SESS_CACHE_NO_INTERNAL_STORE;
30281     }
30282 #endif
30283 
30284     return m;
30285 }
30286 
30287 
wolfSSL_get_read_ahead(const WOLFSSL * ssl)30288 int wolfSSL_get_read_ahead(const WOLFSSL* ssl)
30289 {
30290     if (ssl == NULL) {
30291         return WOLFSSL_FAILURE;
30292     }
30293 
30294     return ssl->readAhead;
30295 }
30296 
30297 
wolfSSL_set_read_ahead(WOLFSSL * ssl,int v)30298 int wolfSSL_set_read_ahead(WOLFSSL* ssl, int v)
30299 {
30300     if (ssl == NULL) {
30301         return WOLFSSL_FAILURE;
30302     }
30303 
30304     ssl->readAhead = (byte)v;
30305 
30306     return WOLFSSL_SUCCESS;
30307 }
30308 
30309 
wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX * ctx)30310 int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx)
30311 {
30312     if (ctx == NULL) {
30313         return WOLFSSL_FAILURE;
30314     }
30315 
30316     return ctx->readAhead;
30317 }
30318 
30319 
wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX * ctx,int v)30320 int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v)
30321 {
30322     if (ctx == NULL) {
30323         return WOLFSSL_FAILURE;
30324     }
30325 
30326     ctx->readAhead = (byte)v;
30327 
30328     return WOLFSSL_SUCCESS;
30329 }
30330 
30331 
wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX * ctx,void * arg)30332 long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx,
30333         void* arg)
30334 {
30335     if (ctx == NULL) {
30336         return WOLFSSL_FAILURE;
30337     }
30338 
30339     ctx->userPRFArg = arg;
30340     return WOLFSSL_SUCCESS;
30341 }
30342 
30343 
30344 #ifndef NO_DES3
30345 /* 0 on success */
wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock * myDes,WOLFSSL_DES_key_schedule * key)30346 int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes,
30347                                                WOLFSSL_DES_key_schedule* key)
30348 {
30349 #ifdef WOLFSSL_CHECK_DESKEY
30350     return wolfSSL_DES_set_key_checked(myDes, key);
30351 #else
30352     wolfSSL_DES_set_key_unchecked(myDes, key);
30353     return 0;
30354 #endif
30355 }
30356 
30357 
30358 
30359 /* return true in fail case (1) */
DES_check(word32 mask,word32 mask2,unsigned char * key)30360 static int DES_check(word32 mask, word32 mask2, unsigned char* key)
30361 {
30362     word32 value[2];
30363 
30364     /* sanity check on length made in wolfSSL_DES_set_key_checked */
30365     value[0] = mask;
30366     value[1] = mask2;
30367     return (XMEMCMP(value, key, sizeof(value)) == 0)? 1: 0;
30368 }
30369 
30370 
30371 /* check that the key is odd parity and is not a weak key
30372  * returns -1 if parity is wrong, -2 if weak/null key and 0 on success */
wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock * myDes,WOLFSSL_DES_key_schedule * key)30373 int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes,
30374                                                WOLFSSL_DES_key_schedule* key)
30375 {
30376     if (myDes == NULL || key == NULL) {
30377         WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked");
30378         return -2;
30379     }
30380     else {
30381         word32 sz = sizeof(WOLFSSL_DES_key_schedule);
30382 
30383         /* sanity check before call to DES_check */
30384         if (sz != (sizeof(word32) * 2)) {
30385             WOLFSSL_MSG("Unexpected WOLFSSL_DES_key_schedule size");
30386             return -2;
30387         }
30388 
30389         /* check odd parity */
30390         if (wolfSSL_DES_check_key_parity(myDes) != 1) {
30391             WOLFSSL_MSG("Odd parity test fail");
30392             return -1;
30393         }
30394 
30395         if (wolfSSL_DES_is_weak_key(myDes) == 1) {
30396             WOLFSSL_MSG("Weak key found");
30397             return -2;
30398         }
30399 
30400         /* passed tests, now copy over key */
30401         XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
30402 
30403         return 0;
30404     }
30405 }
30406 
30407 
30408 /* check is not weak. Weak key list from Nist "Recommendation for the Triple
30409  * Data Encryption Algorithm (TDEA) Block Cipher"
30410  *
30411  * returns 1 if is weak 0 if not
30412  */
wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock * key)30413 int wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock* key)
30414 {
30415     word32 mask, mask2;
30416 
30417     WOLFSSL_ENTER("wolfSSL_DES_is_weak_key");
30418 
30419     if (key == NULL) {
30420         WOLFSSL_MSG("NULL key passed in");
30421         return 1;
30422     }
30423 
30424     mask = 0x01010101; mask2 = 0x01010101;
30425     if (DES_check(mask, mask2, *key)) {
30426         WOLFSSL_MSG("Weak key found");
30427         return 1;
30428     }
30429 
30430     mask = 0xFEFEFEFE; mask2 = 0xFEFEFEFE;
30431     if (DES_check(mask, mask2, *key)) {
30432         WOLFSSL_MSG("Weak key found");
30433         return 1;
30434     }
30435 
30436     mask = 0xE0E0E0E0; mask2 = 0xF1F1F1F1;
30437     if (DES_check(mask, mask2, *key)) {
30438         WOLFSSL_MSG("Weak key found");
30439         return 1;
30440     }
30441 
30442     mask = 0x1F1F1F1F; mask2 = 0x0E0E0E0E;
30443     if (DES_check(mask, mask2, *key)) {
30444         WOLFSSL_MSG("Weak key found");
30445         return 1;
30446     }
30447 
30448     /* semi-weak *key check (list from same Nist paper) */
30449     mask  = 0x011F011F; mask2 = 0x010E010E;
30450     if (DES_check(mask, mask2, *key) ||
30451        DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
30452         WOLFSSL_MSG("Weak key found");
30453         return 1;
30454     }
30455 
30456     mask  = 0x01E001E0; mask2 = 0x01F101F1;
30457     if (DES_check(mask, mask2, *key) ||
30458        DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
30459         WOLFSSL_MSG("Weak key found");
30460         return 1;
30461     }
30462 
30463     mask  = 0x01FE01FE; mask2 = 0x01FE01FE;
30464     if (DES_check(mask, mask2, *key) ||
30465        DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
30466         WOLFSSL_MSG("Weak key found");
30467         return 1;
30468     }
30469 
30470     mask  = 0x1FE01FE0; mask2 = 0x0EF10EF1;
30471     if (DES_check(mask, mask2, *key) ||
30472        DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
30473         WOLFSSL_MSG("Weak key found");
30474         return 1;
30475     }
30476 
30477     mask  = 0x1FFE1FFE; mask2 = 0x0EFE0EFE;
30478     if (DES_check(mask, mask2, *key) ||
30479        DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
30480         WOLFSSL_MSG("Weak key found");
30481         return 1;
30482     }
30483 
30484     return 0;
30485 }
30486 
30487 
wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock * myDes,WOLFSSL_DES_key_schedule * key)30488 void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes,
30489                                                WOLFSSL_DES_key_schedule* key)
30490 {
30491     if (myDes != NULL && key != NULL) {
30492         XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
30493     }
30494 }
30495 
30496 
30497 /* Sets the parity of the DES key for use */
wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock * myDes)30498 void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes)
30499 {
30500     word32 i;
30501     word32 sz = sizeof(WOLFSSL_DES_cblock);
30502 
30503     WOLFSSL_ENTER("wolfSSL_DES_set_odd_parity");
30504 
30505     for (i = 0; i < sz; i++) {
30506         unsigned char c = (*myDes)[i];
30507         if ((
30508             ((c >> 1) & 0x01) ^
30509             ((c >> 2) & 0x01) ^
30510             ((c >> 3) & 0x01) ^
30511             ((c >> 4) & 0x01) ^
30512             ((c >> 5) & 0x01) ^
30513             ((c >> 6) & 0x01) ^
30514             ((c >> 7) & 0x01)) == (c & 0x01)) {
30515             WOLFSSL_MSG("Flipping parity bit");
30516             (*myDes)[i] = c ^ 0x01;
30517         }
30518     }
30519 }
30520 
wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock * myDes)30521 int wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock *myDes)
30522 {
30523     word32 i;
30524     word32 sz = sizeof(WOLFSSL_DES_cblock);
30525 
30526     WOLFSSL_ENTER("wolfSSL_DES_check_key_parity");
30527 
30528     for (i = 0; i < sz; i++) {
30529         unsigned char c = (*myDes)[i];
30530         if ((
30531             ((c >> 1) & 0x01) ^
30532             ((c >> 2) & 0x01) ^
30533             ((c >> 3) & 0x01) ^
30534             ((c >> 4) & 0x01) ^
30535             ((c >> 5) & 0x01) ^
30536             ((c >> 6) & 0x01) ^
30537             ((c >> 7) & 0x01)) == (c & 0x01)) {
30538             return 0;
30539         }
30540     }
30541     return 1;
30542 }
30543 
30544 #ifdef WOLFSSL_DES_ECB
30545 /* Encrypt or decrypt input message desa with key and get output in desb.
30546  * if enc is DES_ENCRYPT,input message is encrypted or
30547  * if enc is DES_DECRYPT,input message is decrypted.
30548  * */
wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock * desa,WOLFSSL_DES_cblock * desb,WOLFSSL_DES_key_schedule * key,int enc)30549 void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa,
30550              WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int enc)
30551 {
30552     Des myDes;
30553 
30554     WOLFSSL_ENTER("wolfSSL_DES_ecb_encrypt");
30555 
30556     if (desa == NULL || key == NULL || desb == NULL ||
30557         (enc != DES_ENCRYPT && enc != DES_DECRYPT)) {
30558         WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_ecb_encrypt");
30559     } else {
30560         if (wc_Des_SetKey(&myDes, (const byte*) key,
30561                            (const byte*) NULL, !enc) != 0) {
30562             WOLFSSL_MSG("wc_Des_SetKey return error.");
30563             return;
30564         }
30565         if (enc){
30566             if (wc_Des_EcbEncrypt(&myDes, (byte*) desb, (const byte*) desa,
30567                         sizeof(WOLFSSL_DES_cblock)) != 0){
30568                 WOLFSSL_MSG("wc_Des_EcbEncrypt return error.");
30569             }
30570         } else {
30571             if (wc_Des_EcbDecrypt(&myDes, (byte*) desb, (const byte*) desa,
30572                         sizeof(WOLFSSL_DES_cblock)) != 0){
30573                 WOLFSSL_MSG("wc_Des_EcbDecrpyt return error.");
30574             }
30575         }
30576     }
30577 }
30578 #endif
30579 #endif /* NO_DES3 */
30580 
30581 #ifndef NO_RC4
30582 /* Set the key state for Arc4 structure.
30583  *
30584  * key  Arc4 structure to use
30585  * len  length of data buffer
30586  * data initial state to set Arc4 structure
30587  */
wolfSSL_RC4_set_key(WOLFSSL_RC4_KEY * key,int len,const unsigned char * data)30588 void wolfSSL_RC4_set_key(WOLFSSL_RC4_KEY* key, int len,
30589         const unsigned char* data)
30590 {
30591     typedef char rc4_test[sizeof(WOLFSSL_RC4_KEY) >= sizeof(Arc4) ? 1 : -1];
30592     (void)sizeof(rc4_test);
30593 
30594     WOLFSSL_ENTER("wolfSSL_RC4_set_key");
30595 
30596     if (key == NULL || len < 0) {
30597         WOLFSSL_MSG("bad argument passed in");
30598         return;
30599     }
30600 
30601     XMEMSET(key, 0, sizeof(WOLFSSL_RC4_KEY));
30602     wc_Arc4SetKey((Arc4*)key, data, (word32)len);
30603 }
30604 
30605 
30606 /* Encrypt/decrypt with Arc4 structure.
30607  *
30608  * len length of buffer to encrypt/decrypt (in/out)
30609  * in  buffer to encrypt/decrypt
30610  * out results of encryption/decryption
30611  */
wolfSSL_RC4(WOLFSSL_RC4_KEY * key,size_t len,const unsigned char * in,unsigned char * out)30612 void wolfSSL_RC4(WOLFSSL_RC4_KEY* key, size_t len,
30613         const unsigned char* in, unsigned char* out)
30614 {
30615     WOLFSSL_ENTER("wolfSSL_RC4");
30616 
30617     if (key == NULL || in == NULL || out == NULL) {
30618         WOLFSSL_MSG("Bad argument passed in");
30619         return;
30620     }
30621 
30622     wc_Arc4Process((Arc4*)key, out, in, (word32)len);
30623 }
30624 #endif /* NO_RC4 */
30625 
30626 #ifndef NO_AES
30627 
30628 #ifdef WOLFSSL_AES_DIRECT
30629 /* AES encrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input.
30630  *
30631  * input  Data to encrypt
30632  * output Encrypted data after done
30633  * key    AES key to use for encryption
30634  */
wolfSSL_AES_encrypt(const unsigned char * input,unsigned char * output,AES_KEY * key)30635 void wolfSSL_AES_encrypt(const unsigned char* input, unsigned char* output,
30636         AES_KEY *key)
30637 {
30638     WOLFSSL_ENTER("wolfSSL_AES_encrypt");
30639 
30640     if (input == NULL || output == NULL || key == NULL) {
30641         WOLFSSL_MSG("Null argument passed in");
30642         return;
30643     }
30644 
30645     wc_AesEncryptDirect((Aes*)key, output, input);
30646 }
30647 
30648 
30649 /* AES decrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input.
30650  *
30651  * input  Data to decrypt
30652  * output Decrypted data after done
30653  * key    AES key to use for encryption
30654  */
wolfSSL_AES_decrypt(const unsigned char * input,unsigned char * output,AES_KEY * key)30655 void wolfSSL_AES_decrypt(const unsigned char* input, unsigned char* output,
30656         AES_KEY *key)
30657 {
30658     WOLFSSL_ENTER("wolfSSL_AES_decrypt");
30659 
30660     if (input == NULL || output == NULL || key == NULL) {
30661         WOLFSSL_MSG("Null argument passed in");
30662         return;
30663     }
30664 
30665     wc_AesDecryptDirect((Aes*)key, output, input);
30666 }
30667 #endif /* WOLFSSL_AES_DIRECT */
30668 
30669 /* Setup of an AES key to use for encryption.
30670  *
30671  * key  key in bytes to use for encryption
30672  * bits size of key in bits
30673  * aes  AES structure to initialize
30674  */
wolfSSL_AES_set_encrypt_key(const unsigned char * key,const int bits,AES_KEY * aes)30675 int wolfSSL_AES_set_encrypt_key(const unsigned char *key, const int bits,
30676         AES_KEY *aes)
30677 {
30678     typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1];
30679     (void)sizeof(aes_test);
30680 
30681     WOLFSSL_ENTER("wolfSSL_AES_set_encrypt_key");
30682 
30683     if (key == NULL || aes == NULL) {
30684         WOLFSSL_MSG("Null argument passed in");
30685         return -1;
30686     }
30687 
30688     XMEMSET(aes, 0, sizeof(AES_KEY));
30689     if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_ENCRYPTION) != 0) {
30690         WOLFSSL_MSG("Error in setting AES key");
30691         return -1;
30692     }
30693     return 0;
30694 }
30695 
30696 
30697 /* Setup of an AES key to use for decryption.
30698  *
30699  * key  key in bytes to use for decryption
30700  * bits size of key in bits
30701  * aes  AES structure to initialize
30702  */
wolfSSL_AES_set_decrypt_key(const unsigned char * key,const int bits,AES_KEY * aes)30703 int wolfSSL_AES_set_decrypt_key(const unsigned char *key, const int bits,
30704         AES_KEY *aes)
30705 {
30706     typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1];
30707     (void)sizeof(aes_test);
30708 
30709     WOLFSSL_ENTER("wolfSSL_AES_set_decrypt_key");
30710 
30711     if (key == NULL || aes == NULL) {
30712         WOLFSSL_MSG("Null argument passed in");
30713         return -1;
30714     }
30715 
30716     XMEMSET(aes, 0, sizeof(AES_KEY));
30717     if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_DECRYPTION) != 0) {
30718         WOLFSSL_MSG("Error in setting AES key");
30719         return -1;
30720     }
30721     return 0;
30722 }
30723 
30724 
30725 #ifdef HAVE_AES_ECB
30726 /* Encrypt/decrypt a 16 byte block of data using the key passed in.
30727  *
30728  * in  buffer to encrypt/decrypt
30729  * out buffer to hold result of encryption/decryption
30730  * key AES structure to use with encryption/decryption
30731  * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
30732  */
wolfSSL_AES_ecb_encrypt(const unsigned char * in,unsigned char * out,AES_KEY * key,const int enc)30733 void wolfSSL_AES_ecb_encrypt(const unsigned char *in, unsigned char* out,
30734                              AES_KEY *key, const int enc)
30735 {
30736     Aes* aes;
30737 
30738     WOLFSSL_ENTER("wolfSSL_AES_ecb_encrypt");
30739 
30740     if (key == NULL || in == NULL || out == NULL) {
30741         WOLFSSL_MSG("Error, Null argument passed in");
30742         return;
30743     }
30744 
30745     aes = (Aes*)key;
30746     if (enc == AES_ENCRYPT) {
30747         if (wc_AesEcbEncrypt(aes, out, in, AES_BLOCK_SIZE) != 0) {
30748             WOLFSSL_MSG("Error with AES CBC encrypt");
30749         }
30750     }
30751     else {
30752     #ifdef HAVE_AES_DECRYPT
30753         if (wc_AesEcbDecrypt(aes, out, in, AES_BLOCK_SIZE) != 0) {
30754             WOLFSSL_MSG("Error with AES CBC decrypt");
30755         }
30756     #else
30757         WOLFSSL_MSG("AES decryption not compiled in");
30758     #endif
30759     }
30760 }
30761 #endif /* HAVE_AES_ECB */
30762 
30763 #ifdef HAVE_AES_CBC
30764 /* Encrypt data using key and iv passed in. iv gets updated to most recent iv
30765  * state after encryption/decryption.
30766  *
30767  * in  buffer to encrypt/decrypt
30768  * out buffer to hold result of encryption/decryption
30769  * len length of input buffer
30770  * key AES structure to use with encryption/decryption
30771  * iv  iv to use with operation
30772  * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
30773  */
wolfSSL_AES_cbc_encrypt(const unsigned char * in,unsigned char * out,size_t len,AES_KEY * key,unsigned char * iv,const int enc)30774 void wolfSSL_AES_cbc_encrypt(const unsigned char *in, unsigned char* out,
30775         size_t len, AES_KEY *key, unsigned char* iv, const int enc)
30776 {
30777     Aes* aes;
30778 
30779     WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
30780 
30781     if (key == NULL || in == NULL || out == NULL || iv == NULL || len == 0) {
30782         WOLFSSL_MSG("Error, Null argument passed in");
30783         return;
30784     }
30785 
30786     aes = (Aes*)key;
30787     if (wc_AesSetIV(aes, (const byte*)iv) != 0) {
30788         WOLFSSL_MSG("Error with setting iv");
30789         return;
30790     }
30791 
30792     if (enc) {
30793         if (wc_AesCbcEncrypt(aes, out, in, (word32)len) != 0) {
30794             WOLFSSL_MSG("Error with AES CBC encrypt");
30795         }
30796     }
30797     else {
30798         if (wc_AesCbcDecrypt(aes, out, in, (word32)len) != 0) {
30799             WOLFSSL_MSG("Error with AES CBC decrypt");
30800         }
30801     }
30802 
30803     /* to be compatible copy iv to iv buffer after completing operation */
30804     XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE);
30805 }
30806 #endif /* HAVE_AES_CBC */
30807 
30808 
30809 /* Encrypt data using CFB mode with key and iv passed in. iv gets updated to
30810  * most recent iv state after encryption/decryption.
30811  *
30812  * in  buffer to encrypt/decrypt
30813  * out buffer to hold result of encryption/decryption
30814  * len length of input buffer
30815  * key AES structure to use with encryption/decryption
30816  * iv  iv to use with operation
30817  * num contains the amount of block used
30818  * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
30819  */
wolfSSL_AES_cfb128_encrypt(const unsigned char * in,unsigned char * out,size_t len,AES_KEY * key,unsigned char * iv,int * num,const int enc)30820 void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out,
30821         size_t len, AES_KEY *key, unsigned char* iv, int* num,
30822         const int enc)
30823 {
30824 #ifndef WOLFSSL_AES_CFB
30825     WOLFSSL_MSG("CFB mode not enabled please use macro WOLFSSL_AES_CFB");
30826     (void)in;
30827     (void)out;
30828     (void)len;
30829     (void)key;
30830     (void)iv;
30831     (void)num;
30832     (void)enc;
30833 
30834     return;
30835 #else
30836     Aes* aes;
30837 
30838     WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
30839     if (key == NULL || in == NULL || out == NULL || iv == NULL) {
30840         WOLFSSL_MSG("Error, Null argument passed in");
30841         return;
30842     }
30843 
30844     aes = (Aes*)key;
30845     if (wc_AesSetIV(aes, (const byte*)iv) != 0) {
30846         WOLFSSL_MSG("Error with setting iv");
30847         return;
30848     }
30849 
30850     if (enc == AES_ENCRYPT) {
30851         if (wc_AesCfbEncrypt(aes, out, in, (word32)len) != 0) {
30852             WOLFSSL_MSG("Error with AES CBC encrypt");
30853         }
30854     }
30855     else {
30856         if (wc_AesCfbDecrypt(aes, out, in, (word32)len) != 0) {
30857             WOLFSSL_MSG("Error with AES CBC decrypt");
30858         }
30859     }
30860 
30861     /* to be compatible copy iv to iv buffer after completing operation */
30862     XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE);
30863 
30864     /* store number of left over bytes to num */
30865     *num = (aes->left)? AES_BLOCK_SIZE - aes->left : 0;
30866 #endif /* WOLFSSL_AES_CFB */
30867 }
30868 
30869 /* wc_AesKey*Wrap_ex API not available in FIPS and SELFTEST */
30870 #if defined(HAVE_AES_KEYWRAP) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
wolfSSL_AES_wrap_key(AES_KEY * key,const unsigned char * iv,unsigned char * out,const unsigned char * in,unsigned int inlen)30871 int wolfSSL_AES_wrap_key(AES_KEY *key, const unsigned char *iv,
30872                  unsigned char *out,
30873                  const unsigned char *in, unsigned int inlen)
30874 {
30875     int ret;
30876 
30877     WOLFSSL_ENTER("wolfSSL_AES_wrap_key");
30878 
30879     if (out == NULL || in == NULL) {
30880         WOLFSSL_MSG("Error, Null argument passed in");
30881         return WOLFSSL_FAILURE;
30882     }
30883 
30884     ret = wc_AesKeyWrap_ex((Aes*)key, in, inlen, out, inlen + KEYWRAP_BLOCK_SIZE, iv);
30885 
30886     return ret < 0 ? WOLFSSL_FAILURE : ret;
30887 }
30888 
wolfSSL_AES_unwrap_key(AES_KEY * key,const unsigned char * iv,unsigned char * out,const unsigned char * in,unsigned int inlen)30889 int wolfSSL_AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
30890                    unsigned char *out,
30891                    const unsigned char *in, unsigned int inlen)
30892 {
30893     int ret;
30894 
30895     WOLFSSL_ENTER("wolfSSL_AES_wrap_key");
30896 
30897     if (out == NULL || in == NULL) {
30898         WOLFSSL_MSG("Error, Null argument passed in");
30899         return WOLFSSL_FAILURE;
30900     }
30901 
30902     ret = wc_AesKeyUnWrap_ex((Aes*)key, in, inlen, out, inlen + KEYWRAP_BLOCK_SIZE, iv);
30903 
30904     return ret < 0 ? WOLFSSL_FAILURE : ret;
30905 }
30906 #endif /* HAVE_AES_KEYWRAP && !HAVE_FIPS && !HAVE_SELFTEST */
30907 #endif /* NO_AES */
30908 
30909 #ifdef HAVE_CTS
30910 /*
30911  * Ciphertext stealing interface compatible with RFC2040 and RFC3962.
30912  */
wolfSSL_CRYPTO_cts128_encrypt(const unsigned char * in,unsigned char * out,size_t len,const void * key,unsigned char * iv,WOLFSSL_CBC128_CB cbc)30913 size_t wolfSSL_CRYPTO_cts128_encrypt(const unsigned char *in,
30914         unsigned char *out, size_t len, const void *key,
30915         unsigned char *iv, WOLFSSL_CBC128_CB cbc)
30916 {
30917     byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ];
30918     int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ;
30919     WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_encrypt");
30920 
30921     if (in == NULL || out == NULL || len < WOLFSSL_CTS128_BLOCK_SZ ||
30922             cbc == NULL) {
30923         WOLFSSL_MSG("Bad parameter");
30924         return WOLFSSL_FAILURE;
30925     }
30926 
30927     if (lastBlkLen == 0)
30928         lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ;
30929 
30930     /* Encrypt data up to last block */
30931     (*cbc)(in, out, len - lastBlkLen, key, iv, 1);
30932 
30933     /* Move to last block */
30934     in += len - lastBlkLen;
30935     out += len - lastBlkLen;
30936 
30937     /* RFC2040: Pad Pn with zeros at the end to create P of length BB. */
30938     XMEMCPY(lastBlk, in, lastBlkLen);
30939     XMEMSET(lastBlk + lastBlkLen, 0, WOLFSSL_CTS128_BLOCK_SZ - lastBlkLen);
30940     /* RFC2040: Select the first Ln bytes of En-1 to create Cn */
30941     XMEMCPY(out, out - WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
30942     (*cbc)(lastBlk, out - WOLFSSL_CTS128_BLOCK_SZ, WOLFSSL_CTS128_BLOCK_SZ,
30943             key, iv, 1);
30944 
30945     return len;
30946 }
30947 
wolfSSL_CRYPTO_cts128_decrypt(const unsigned char * in,unsigned char * out,size_t len,const void * key,unsigned char * iv,WOLFSSL_CBC128_CB cbc)30948 size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in,
30949         unsigned char *out, size_t len, const void *key,
30950         unsigned char *iv, WOLFSSL_CBC128_CB cbc)
30951 {
30952     byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ];
30953     byte prevBlk[WOLFSSL_CTS128_BLOCK_SZ];
30954     int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ;
30955     WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_decrypt");
30956 
30957     if (in == NULL || out == NULL || len <= WOLFSSL_CTS128_BLOCK_SZ ||
30958             cbc == NULL) {
30959         WOLFSSL_MSG("Bad parameter");
30960         return WOLFSSL_FAILURE;
30961     }
30962 
30963     if (lastBlkLen == 0)
30964         lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ;
30965 
30966     /* Decrypt up to last two blocks */
30967     (*cbc)(in, out, len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ, key, iv, 0);
30968 
30969     /* Move to last two blocks */
30970     in += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ;
30971     out += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ;
30972 
30973     /* RFC2040: Decrypt Cn-1 to create Dn.
30974      * Use 0 buffer as IV to do straight decryption.
30975      * This places the Cn-1 block at lastBlk */
30976     XMEMSET(lastBlk, 0, WOLFSSL_CTS128_BLOCK_SZ);
30977     (*cbc)(in, prevBlk, WOLFSSL_CTS128_BLOCK_SZ, key, lastBlk, 0);
30978     /* RFC2040: Append the tail (BB minus Ln) bytes of Xn to Cn
30979      *          to create En. */
30980     XMEMCPY(prevBlk, in + WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
30981     /* Cn and Cn-1 can now be decrypted */
30982     (*cbc)(prevBlk, out, WOLFSSL_CTS128_BLOCK_SZ, key, iv, 0);
30983     (*cbc)(lastBlk, lastBlk, WOLFSSL_CTS128_BLOCK_SZ, key, iv, 0);
30984     XMEMCPY(out + WOLFSSL_CTS128_BLOCK_SZ, lastBlk, lastBlkLen);
30985     return len;
30986 }
30987 #endif /* HAVE_CTS */
30988 
30989 #ifndef NO_ASN_TIME
30990 #ifndef NO_BIO
wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO * bio,const WOLFSSL_ASN1_UTCTIME * a)30991 int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
30992 {
30993     WOLFSSL_ENTER("ASN1_UTCTIME_print");
30994     if (bio == NULL || a == NULL) {
30995         return WOLFSSL_FAILURE;
30996     }
30997     if (a->type != ASN_UTC_TIME) {
30998         WOLFSSL_MSG("Error, not UTC_TIME");
30999         return WOLFSSL_FAILURE;
31000     }
31001 
31002     return wolfSSL_ASN1_TIME_print(bio, a);
31003 }
31004 
31005 #endif /* !NO_BIO */
31006 
31007 /* Checks the ASN1 syntax of "a"
31008  * returns WOLFSSL_SUCCESS (1)  if correct otherwise WOLFSSL_FAILURE (0) */
wolfSSL_ASN1_TIME_check(const WOLFSSL_ASN1_TIME * a)31009 int wolfSSL_ASN1_TIME_check(const WOLFSSL_ASN1_TIME* a)
31010 {
31011     char buf[MAX_TIME_STRING_SZ];
31012 
31013     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_check");
31014 
31015     /* if can parse the WOLFSSL_ASN1_TIME passed in then consider syntax good */
31016     if (wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)a, buf,
31017                 MAX_TIME_STRING_SZ) == NULL) {
31018         return WOLFSSL_FAILURE;
31019     }
31020     return WOLFSSL_SUCCESS;
31021 }
31022 
wolfSSL_ASN1_TIME_diff(int * days,int * secs,const WOLFSSL_ASN1_TIME * from,const WOLFSSL_ASN1_TIME * to)31023 int wolfSSL_ASN1_TIME_diff(int *days, int *secs, const WOLFSSL_ASN1_TIME *from,
31024     const WOLFSSL_ASN1_TIME *to)
31025 {
31026 #if defined(XMKTIME) && defined(XDIFFTIME)
31027     const int SECS_PER_DAY = 24 * 60 * 60;
31028     struct tm fromTm_s, *fromTm = &fromTm_s;
31029     struct tm toTm_s, *toTm = &toTm_s;
31030     time_t fromSecs;
31031     time_t toSecs;
31032     double diffSecs;
31033     struct tm *tmpTs;
31034 #if defined(NEED_TMP_TIME)
31035     /* for use with gmtime_r */
31036     struct tm tmpTimeStorage;
31037     tmpTs = &tmpTimeStorage;
31038 #else
31039     tmpTs = NULL;
31040 #endif
31041     (void)tmpTs;
31042 
31043     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_diff");
31044 
31045     if (days == NULL) {
31046         WOLFSSL_MSG("days is NULL");
31047         return WOLFSSL_FAILURE;
31048     }
31049     if (secs == NULL) {
31050         WOLFSSL_MSG("secs is NULL");
31051         return WOLFSSL_FAILURE;
31052     }
31053 
31054     if (from == NULL && to == NULL) {
31055         *days = 0;
31056         *secs = 0;
31057         return WOLFSSL_SUCCESS;
31058     }
31059 
31060     if (from == NULL) {
31061         fromSecs = XTIME(0);
31062         fromTm = XGMTIME(&fromSecs, tmpTs);
31063         if (fromTm == NULL) {
31064             WOLFSSL_MSG("XGMTIME for from time failed.");
31065             return WOLFSSL_FAILURE;
31066         }
31067     }
31068     else if (wolfSSL_ASN1_TIME_to_tm(from, fromTm) != WOLFSSL_SUCCESS) {
31069         WOLFSSL_MSG("Failed to convert from time to struct tm.");
31070         return WOLFSSL_FAILURE;
31071     }
31072 
31073     fromSecs = XMKTIME(fromTm);
31074     if (fromSecs <= 0) {
31075         WOLFSSL_MSG("XMKTIME for from time failed.");
31076         return WOLFSSL_FAILURE;
31077     }
31078 
31079     if (to == NULL) {
31080         toSecs = XTIME(0);
31081         toTm = XGMTIME(&toSecs, tmpTs);
31082         if (toTm == NULL) {
31083             WOLFSSL_MSG("XGMTIME for to time failed.");
31084             return WOLFSSL_FAILURE;
31085         }
31086     }
31087     else if (wolfSSL_ASN1_TIME_to_tm(to, toTm) != WOLFSSL_SUCCESS) {
31088         WOLFSSL_MSG("Failed to convert to time to struct tm.");
31089         return WOLFSSL_FAILURE;
31090     }
31091 
31092     toSecs = XMKTIME(toTm);
31093     if (toSecs <= 0) {
31094         WOLFSSL_MSG("XMKTIME for to time failed.");
31095         return WOLFSSL_FAILURE;
31096     }
31097 
31098     diffSecs = XDIFFTIME(toSecs, fromSecs);
31099     *days = (int) (diffSecs / SECS_PER_DAY);
31100     *secs = (int) (diffSecs - (((double)*days) * SECS_PER_DAY));
31101 
31102     return WOLFSSL_SUCCESS;
31103 #else
31104     return WOLFSSL_FAILURE;
31105 #endif /* XMKTIME && XDIFFTIME */
31106 }
31107 #endif /* !NO_ASN_TIME */
31108 
31109 #ifndef NO_WOLFSSL_STUB
wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME * s,time_t t)31110 WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t)
31111 {
31112     WOLFSSL_STUB("wolfSSL_ASN1_TIME_set");
31113     (void)s;
31114     (void)t;
31115     return s;
31116 }
31117 #endif /* !NO_WOLFSSL_STUB */
31118 
wolfSSL_ASN1_TIME_set_string(WOLFSSL_ASN1_TIME * s,const char * str)31119 int wolfSSL_ASN1_TIME_set_string(WOLFSSL_ASN1_TIME *s, const char *str)
31120 {
31121     int slen;
31122     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_set_string");
31123 
31124     if (!str) {
31125         WOLFSSL_MSG("Bad parameter");
31126         return WOLFSSL_FAILURE;
31127     }
31128     slen = (int)XSTRLEN(str)+1;
31129     if (slen > CTC_DATE_SIZE) {
31130         WOLFSSL_MSG("Date string too long");
31131         return WOLFSSL_FAILURE;
31132     }
31133     if (s) {
31134         XMEMCPY(s->data, str, slen);
31135         s->length = slen - 1; /* do not include null terminator in length */
31136         s->type = slen == ASN_UTC_TIME_SIZE ? V_ASN1_UTCTIME :
31137             V_ASN1_GENERALIZEDTIME;
31138     }
31139     return WOLFSSL_SUCCESS;
31140 }
31141 
31142 #ifndef NO_BIO
31143 
31144 /* Return the month as a string.
31145  *
31146  * n  The number of the month as a two characters (1 based).
31147  * returns the month as a string.
31148  */
MonthStr(const char * n)31149 static WC_INLINE const char* MonthStr(const char* n)
31150 {
31151     static const char monthStr[12][4] = {
31152             "Jan", "Feb", "Mar", "Apr", "May", "Jun",
31153             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
31154     return monthStr[(n[0] - '0') * 10 + (n[1] - '0') - 1];
31155 }
31156 
wolfSSL_ASN1_GENERALIZEDTIME_print(WOLFSSL_BIO * bio,const WOLFSSL_ASN1_GENERALIZEDTIME * asnTime)31157 int wolfSSL_ASN1_GENERALIZEDTIME_print(WOLFSSL_BIO* bio,
31158     const WOLFSSL_ASN1_GENERALIZEDTIME* asnTime)
31159 {
31160     const char* p;
31161     WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_print");
31162 
31163     if (bio == NULL || asnTime == NULL)
31164         return BAD_FUNC_ARG;
31165 
31166     if (asnTime->type != ASN_GENERALIZED_TIME) {
31167         WOLFSSL_MSG("Error, not GENERALIZED_TIME");
31168         return WOLFSSL_FAILURE;
31169     }
31170     p = (const char *)(asnTime->data);
31171     /* GetTimeString not always available. */
31172     if (wolfSSL_BIO_write(bio, MonthStr(p + 4), 3) <= 0)
31173         return WOLFSSL_FAILURE;
31174     if (wolfSSL_BIO_write(bio, " ", 1) <= 0)
31175         return WOLFSSL_FAILURE;
31176 
31177     /* Day */
31178     if (wolfSSL_BIO_write(bio, p + 6, 2) <= 0)
31179         return WOLFSSL_FAILURE;
31180     if (wolfSSL_BIO_write(bio, " ", 1) <= 0)
31181         return WOLFSSL_FAILURE;
31182 
31183     /* Hour */
31184     if (wolfSSL_BIO_write(bio, p + 8, 2) <= 0)
31185         return WOLFSSL_FAILURE;
31186     if (wolfSSL_BIO_write(bio, ":", 1) <= 0)
31187         return WOLFSSL_FAILURE;
31188 
31189     /* Min */
31190     if (wolfSSL_BIO_write(bio, p + 10, 2) <= 0)
31191         return WOLFSSL_FAILURE;
31192     if (wolfSSL_BIO_write(bio, ":", 1) <= 0)
31193         return WOLFSSL_FAILURE;
31194 
31195     /* Secs */
31196     if (wolfSSL_BIO_write(bio, p + 12, 2) <= 0)
31197         return WOLFSSL_FAILURE;
31198     if (wolfSSL_BIO_write(bio, " ", 1) <= 0)
31199         return WOLFSSL_FAILURE;
31200     if (wolfSSL_BIO_write(bio, p, 4) <= 0)
31201         return WOLFSSL_FAILURE;
31202 
31203     return 0;
31204 }
31205 #endif /* !NO_BIO */
31206 
wolfSSL_ASN1_GENERALIZEDTIME_free(WOLFSSL_ASN1_TIME * asn1Time)31207 void wolfSSL_ASN1_GENERALIZEDTIME_free(WOLFSSL_ASN1_TIME* asn1Time)
31208 {
31209     WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_free");
31210     if (asn1Time == NULL)
31211         return;
31212     XMEMSET(asn1Time->data, 0, sizeof(asn1Time->data));
31213 }
31214 
31215 #endif /* OPENSSL_EXTRA */
31216 
31217 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
wolfSSL_sk_num(const WOLFSSL_STACK * sk)31218 int wolfSSL_sk_num(const WOLFSSL_STACK* sk)
31219 {
31220     WOLFSSL_ENTER("wolfSSL_sk_num");
31221     if (sk == NULL)
31222         return 0;
31223     return (int)sk->num;
31224 }
31225 
wolfSSL_sk_value(const WOLFSSL_STACK * sk,int i)31226 void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i)
31227 {
31228     WOLFSSL_ENTER("wolfSSL_sk_value");
31229 
31230     for (; sk != NULL && i > 0; i--)
31231         sk = sk->next;
31232     if (sk == NULL)
31233         return NULL;
31234 
31235     switch (sk->type) {
31236         case STACK_TYPE_X509:
31237             return (void*)sk->data.x509;
31238         case STACK_TYPE_GEN_NAME:
31239             return (void*)sk->data.gn;
31240         case STACK_TYPE_BIO:
31241             return (void*)sk->data.bio;
31242         case STACK_TYPE_OBJ:
31243             return (void*)sk->data.obj;
31244         case STACK_TYPE_STRING:
31245             return (void*)sk->data.string;
31246         case STACK_TYPE_CIPHER:
31247             return (void*)&sk->data.cipher;
31248         case STACK_TYPE_ACCESS_DESCRIPTION:
31249             return (void*)sk->data.access;
31250         case STACK_TYPE_X509_EXT:
31251             return (void*)sk->data.ext;
31252         case STACK_TYPE_NULL:
31253             return (void*)sk->data.generic;
31254         case STACK_TYPE_X509_NAME:
31255             return (void*)sk->data.name;
31256         case STACK_TYPE_CONF_VALUE:
31257             return (void*)sk->data.conf;
31258         case STACK_TYPE_X509_INFO:
31259             return (void*)sk->data.info;
31260         case STACK_TYPE_BY_DIR_entry:
31261             return (void*)sk->data.dir_entry;
31262         case STACK_TYPE_BY_DIR_hash:
31263             return (void*)sk->data.dir_hash;
31264         case STACK_TYPE_X509_OBJ:
31265             return (void*)sk->data.x509_obj;
31266         case STACK_TYPE_DIST_POINT:
31267             return (void*)sk->data.dp;
31268         case STACK_TYPE_X509_CRL:
31269             return (void*)sk->data.crl;
31270         default:
31271             return (void*)sk->data.generic;
31272     }
31273 }
31274 
31275 /* copies over data of "in" to "out" */
wolfSSL_CIPHER_copy(WOLFSSL_CIPHER * in,WOLFSSL_CIPHER * out)31276 static void wolfSSL_CIPHER_copy(WOLFSSL_CIPHER* in, WOLFSSL_CIPHER* out)
31277 {
31278     if (in == NULL || out == NULL)
31279         return;
31280 
31281     *out = *in;
31282 }
31283 
wolfSSL_sk_dup(WOLFSSL_STACK * sk)31284 WOLFSSL_STACK* wolfSSL_sk_dup(WOLFSSL_STACK* sk)
31285 {
31286 
31287     WOLFSSL_STACK* ret = NULL;
31288     WOLFSSL_STACK* last = NULL;
31289 
31290     WOLFSSL_ENTER("wolfSSL_sk_dup");
31291 
31292     while (sk) {
31293         WOLFSSL_STACK* cur = wolfSSL_sk_new_node(sk->heap);
31294 
31295         if (!cur) {
31296             WOLFSSL_MSG("wolfSSL_sk_new_node error");
31297             goto error;
31298         }
31299 
31300         if (!ret) {
31301             /* Set first node */
31302             ret = cur;
31303         }
31304 
31305         if (last) {
31306             last->next = cur;
31307         }
31308 
31309         XMEMCPY(cur, sk, sizeof(WOLFSSL_STACK));
31310 
31311         /* We will allocate new memory for this */
31312         XMEMSET(&cur->data, 0, sizeof(cur->data));
31313         cur->next = NULL;
31314 
31315         switch (sk->type) {
31316             case STACK_TYPE_X509:
31317                 if (!sk->data.x509)
31318                     break;
31319                 cur->data.x509 = wolfSSL_X509_dup(sk->data.x509);
31320                 if (!cur->data.x509) {
31321                     WOLFSSL_MSG("wolfSSL_X509_dup error");
31322                     goto error;
31323                 }
31324                 break;
31325             case STACK_TYPE_CIPHER:
31326                 wolfSSL_CIPHER_copy(&sk->data.cipher, &cur->data.cipher);
31327                 break;
31328             case STACK_TYPE_GEN_NAME:
31329                 if (!sk->data.gn)
31330                     break;
31331                 cur->data.gn = wolfSSL_GENERAL_NAME_dup(sk->data.gn);
31332                 if (!cur->data.gn) {
31333                     WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
31334                     goto error;
31335                 }
31336                 break;
31337             case STACK_TYPE_OBJ:
31338                 if (!sk->data.obj)
31339                     break;
31340                 cur->data.obj = wolfSSL_ASN1_OBJECT_dup(sk->data.obj);
31341                 if (!cur->data.obj) {
31342                     WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup error");
31343                     goto error;
31344                 }
31345                 break;
31346             case STACK_TYPE_BIO:
31347             case STACK_TYPE_STRING:
31348             case STACK_TYPE_ACCESS_DESCRIPTION:
31349             case STACK_TYPE_X509_EXT:
31350             case STACK_TYPE_NULL:
31351             case STACK_TYPE_X509_NAME:
31352             case STACK_TYPE_CONF_VALUE:
31353             case STACK_TYPE_X509_INFO:
31354             case STACK_TYPE_BY_DIR_entry:
31355             case STACK_TYPE_BY_DIR_hash:
31356             case STACK_TYPE_X509_OBJ:
31357             case STACK_TYPE_DIST_POINT:
31358             case STACK_TYPE_X509_CRL:
31359             default:
31360                 WOLFSSL_MSG("Unsupported stack type");
31361                 goto error;
31362         }
31363 
31364         sk = sk->next;
31365         last = cur;
31366     }
31367     return ret;
31368 
31369 error:
31370     if (ret) {
31371         wolfSSL_sk_GENERAL_NAME_free(ret);
31372     }
31373     return NULL;
31374 }
31375 
31376 /* Free the just the stack structure */
wolfSSL_sk_free(WOLFSSL_STACK * sk)31377 void wolfSSL_sk_free(WOLFSSL_STACK* sk)
31378 {
31379     WOLFSSL_ENTER("wolfSSL_sk_free");
31380 
31381     while (sk != NULL) {
31382         WOLFSSL_STACK* next = sk->next;
31383         XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
31384         sk = next;
31385     }
31386 }
31387 
31388 /* Frees each node in the stack and frees the stack.
31389  */
wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK * sk,void (* f)(void *))31390 void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk,
31391     void (*f) (void*))
31392 {
31393     WOLFSSL_ENTER("wolfSSL_sk_GENERIC_pop_free");
31394     wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
31395 }
31396 
31397 /* return 1 on success 0 on fail */
wolfSSL_sk_GENERIC_push(WOLFSSL_STACK * sk,void * generic)31398 int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK* sk, void* generic)
31399 {
31400     WOLFSSL_ENTER("wolfSSL_sk_GENERIC_push");
31401 
31402     return wolfSSL_sk_push(sk, generic);
31403 }
wolfSSL_sk_GENERIC_free(WOLFSSL_STACK * sk)31404 void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk)
31405 {
31406     wolfSSL_sk_free(sk);
31407 }
31408 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
31409 
31410 #ifdef OPENSSL_EXTRA
31411 
31412 /* Free all nodes in a stack including the pushed objects */
wolfSSL_sk_pop_free(WOLF_STACK_OF (WOLFSSL_ASN1_OBJECT)* sk,wolfSSL_sk_freefunc func)31413 void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
31414                                                        wolfSSL_sk_freefunc func)
31415 {
31416     WOLFSSL_ENTER("wolfSSL_sk_pop_free");
31417 
31418     if (sk == NULL) {
31419         /* pop_free can be called with NULL, do not print bad argument */
31420         return;
31421     }
31422     #if defined(WOLFSSL_QT)
31423     /* In Qt v15.5, it calls OPENSSL_sk_free(xxx, OPENSSL_sk_free).
31424     *  By using OPENSSL_sk_free for free causes access violation.
31425     *  Therefore, switching free func to wolfSSL_ACCESS_DESCRIPTION_free
31426     *  is needed even the func isn't NULL.
31427     */
31428     if (sk->type == STACK_TYPE_ACCESS_DESCRIPTION) {
31429         func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free;
31430     }
31431     #endif
31432     if (func == NULL) {
31433         switch(sk->type) {
31434             case STACK_TYPE_ACCESS_DESCRIPTION:
31435             #if defined(OPENSSL_ALL)
31436                 func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free;
31437             #endif
31438                 break;
31439             case STACK_TYPE_X509:
31440                 func = (wolfSSL_sk_freefunc)wolfSSL_X509_free;
31441                 break;
31442             case STACK_TYPE_X509_OBJ:
31443             #ifdef OPENSSL_ALL
31444                 func = (wolfSSL_sk_freefunc)wolfSSL_X509_OBJECT_free;
31445             #endif
31446                 break;
31447             case STACK_TYPE_OBJ:
31448                 func = (wolfSSL_sk_freefunc)wolfSSL_ASN1_OBJECT_free;
31449                 break;
31450             case STACK_TYPE_DIST_POINT:
31451                 func = (wolfSSL_sk_freefunc)wolfSSL_DIST_POINT_free;
31452                 break;
31453             case STACK_TYPE_GEN_NAME:
31454                 func = (wolfSSL_sk_freefunc)wolfSSL_GENERAL_NAME_free;
31455                 break;
31456             #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
31457                 defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
31458             case STACK_TYPE_STRING:
31459                 func = (wolfSSL_sk_freefunc)wolfSSL_WOLFSSL_STRING_free;
31460                 break;
31461             #endif
31462             case STACK_TYPE_X509_NAME:
31463             #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
31464                 && !defined(WOLFCRYPT_ONLY)
31465                 func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_free;
31466             #endif
31467                 break;
31468             case STACK_TYPE_X509_EXT:
31469             #ifdef OPENSSL_ALL
31470                 func = (wolfSSL_sk_freefunc)wolfSSL_X509_EXTENSION_free;
31471             #endif
31472                 break;
31473             case STACK_TYPE_CONF_VALUE:
31474             #ifdef OPENSSL_ALL
31475                 func = (wolfSSL_sk_freefunc)wolfSSL_X509V3_conf_free;
31476             #endif
31477                 break;
31478             case STACK_TYPE_X509_INFO:
31479             #if defined(OPENSSL_ALL)
31480                 func = (wolfSSL_sk_freefunc)wolfSSL_X509_INFO_free;
31481             #endif
31482                 break;
31483             case STACK_TYPE_BIO:
31484                 func = (wolfSSL_sk_freefunc)wolfSSL_BIO_vfree;
31485                 break;
31486             case STACK_TYPE_BY_DIR_entry:
31487 #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
31488                 func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_entry_free;
31489 #endif
31490                 break;
31491             case STACK_TYPE_BY_DIR_hash:
31492 #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
31493                 func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_HASH_free;
31494 #endif
31495                 break;
31496             case STACK_TYPE_X509_CRL:
31497 #if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
31498                 func = (wolfSSL_sk_freefunc)wolfSSL_X509_CRL_free;
31499 #endif
31500                 break;
31501             case STACK_TYPE_CIPHER:
31502             case STACK_TYPE_NULL:
31503             default:
31504                 break;
31505         }
31506     }
31507 
31508     while (sk != NULL) {
31509         WOLFSSL_STACK* next = sk->next;
31510 
31511         if (func != NULL) {
31512             if (sk->type == STACK_TYPE_CIPHER)
31513                 func(&sk->data.cipher);
31514             else
31515                 func(sk->data.generic);
31516         }
31517         XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
31518         sk = next;
31519     }
31520 }
31521 #endif /* OPENSSL_EXTRA */
31522 
31523 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
31524 /* Creates and returns a new null stack. */
wolfSSL_sk_new_null(void)31525 WOLFSSL_STACK* wolfSSL_sk_new_null(void)
31526 {
31527     WOLFSSL_STACK* sk;
31528     WOLFSSL_ENTER("wolfSSL_sk_new_null");
31529 
31530     sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
31531                                  DYNAMIC_TYPE_OPENSSL);
31532     if (sk == NULL) {
31533         WOLFSSL_MSG("WOLFSSL_STACK memory error");
31534         return NULL;
31535     }
31536 
31537     XMEMSET(sk, 0, sizeof(WOLFSSL_STACK));
31538     sk->type = STACK_TYPE_NULL;
31539 
31540     return sk;
31541 }
31542 
wolfSSL_BASIC_CONSTRAINTS_new(void)31543 WOLFSSL_BASIC_CONSTRAINTS* wolfSSL_BASIC_CONSTRAINTS_new(void)
31544 {
31545     WOLFSSL_BASIC_CONSTRAINTS* bc;
31546     bc = (WOLFSSL_BASIC_CONSTRAINTS*)
31547           XMALLOC(sizeof(WOLFSSL_BASIC_CONSTRAINTS), NULL,
31548           DYNAMIC_TYPE_X509_EXT);
31549     if (bc == NULL) {
31550         WOLFSSL_MSG("Failed to malloc basic constraints");
31551         return NULL;
31552     }
31553     XMEMSET(bc, 0, sizeof(WOLFSSL_BASIC_CONSTRAINTS));
31554     return bc;
31555 }
31556 
31557 /* frees the wolfSSL_BASIC_CONSTRAINTS object */
wolfSSL_BASIC_CONSTRAINTS_free(WOLFSSL_BASIC_CONSTRAINTS * bc)31558 void wolfSSL_BASIC_CONSTRAINTS_free(WOLFSSL_BASIC_CONSTRAINTS *bc)
31559 {
31560     WOLFSSL_ENTER("wolfSSL_BASIC_CONSTRAINTS_free");
31561     if (bc == NULL) {
31562         WOLFSSL_MSG("Argument is NULL");
31563         return;
31564     }
31565     if (bc->pathlen) {
31566         wolfSSL_ASN1_INTEGER_free(bc->pathlen);
31567     }
31568     XFREE(bc, NULL, DYNAMIC_TYPE_OPENSSL);
31569 }
31570 
wolfSSL_AUTHORITY_KEYID_new(void)31571 WOLFSSL_AUTHORITY_KEYID* wolfSSL_AUTHORITY_KEYID_new(void)
31572 {
31573     WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)XMALLOC(
31574           sizeof(WOLFSSL_AUTHORITY_KEYID), NULL, DYNAMIC_TYPE_OPENSSL);
31575     if (!akey) {
31576         WOLFSSL_MSG("Issue creating WOLFSSL_AUTHORITY_KEYID struct");
31577         return NULL;
31578     }
31579     XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
31580     return akey;
31581 }
31582 
31583 /* frees the wolfSSL_AUTHORITY_KEYID object */
wolfSSL_AUTHORITY_KEYID_free(WOLFSSL_AUTHORITY_KEYID * id)31584 void wolfSSL_AUTHORITY_KEYID_free(WOLFSSL_AUTHORITY_KEYID *id)
31585 {
31586     WOLFSSL_ENTER("wolfSSL_AUTHORITY_KEYID_free");
31587     if(id == NULL) {
31588         WOLFSSL_MSG("Argument is NULL");
31589         return;
31590     }
31591     if (id->keyid) {
31592         wolfSSL_ASN1_STRING_free(id->keyid);
31593     }
31594     if (id->issuer) {
31595         wolfSSL_ASN1_OBJECT_free(id->issuer);
31596     }
31597     if (id->serial) {
31598         wolfSSL_ASN1_INTEGER_free(id->serial);
31599     }
31600     XFREE(id, NULL, DYNAMIC_TYPE_OPENSSL);
31601 }
31602 
wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF (WOLFSSL_COMP)* sk)31603 int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* sk)
31604 {
31605     if (sk == NULL)
31606         return 0;
31607     return (int)sk->num;
31608 }
31609 
31610 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
31611 
31612 #if !defined(NO_SESSION_CACHE) && (defined(OPENSSL_EXTRA) || \
31613         defined(HAVE_EXT_CACHE))
31614 /* stunnel 4.28 needs
31615  *
31616  * Callback that is called if a session tries to resume but could not find
31617  * the session to resume it.
31618  */
wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX * ctx,WOLFSSL_SESSION * (* f)(WOLFSSL *,const unsigned char *,int,int *))31619 void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
31620                     WOLFSSL_SESSION*(*f)(WOLFSSL*, const unsigned char*, int, int*))
31621 {
31622     if (ctx == NULL)
31623         return;
31624 
31625 #ifdef HAVE_EXT_CACHE
31626     ctx->get_sess_cb = f;
31627 #else
31628     (void)f;
31629 #endif
31630 }
31631 
wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX * ctx,int (* f)(WOLFSSL *,WOLFSSL_SESSION *))31632 void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
31633                              int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
31634 {
31635     if (ctx == NULL)
31636         return;
31637 
31638 #ifdef HAVE_EXT_CACHE
31639     ctx->new_sess_cb = f;
31640 #else
31641     (void)f;
31642 #endif
31643 }
31644 
wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX * ctx,void (* f)(WOLFSSL_CTX *,WOLFSSL_SESSION *))31645 void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
31646                                                         WOLFSSL_SESSION*))
31647 {
31648     if (ctx == NULL)
31649         return;
31650 
31651 #ifdef HAVE_EXT_CACHE
31652     ctx->rem_sess_cb = f;
31653 #else
31654     (void)f;
31655 #endif
31656 }
31657 
31658 
31659 /*
31660  *
31661  * Note: It is expected that the importing and exporting function have been
31662  *       built with the same settings. For example if session tickets was
31663  *       enabled with the wolfSSL library exporting a session then it is
31664  *       expected to be turned on with the wolfSSL library importing the session.
31665  */
wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION * sess,unsigned char ** p)31666 int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
31667 {
31668     int size = 0;
31669 #ifdef HAVE_EXT_CACHE
31670     int idx = 0;
31671 #ifdef SESSION_CERTS
31672     int i;
31673 #endif
31674     unsigned char *data;
31675 
31676     sess = GetSessionPtr(sess);
31677     if (sess == NULL) {
31678         return BAD_FUNC_ARG;
31679     }
31680 
31681     /* side | bornOn | timeout | sessionID len | sessionID | masterSecret |
31682      * haveEMS  */
31683     size += OPAQUE8_LEN + OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN +
31684             sess->sessionIDSz + SECRET_LEN + OPAQUE8_LEN;
31685 #ifdef SESSION_CERTS
31686     /* Peer chain */
31687     size += OPAQUE8_LEN;
31688     for (i = 0; i < sess->chain.count; i++)
31689         size += OPAQUE16_LEN + sess->chain.certs[i].length;
31690 #endif
31691 #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
31692                                defined(HAVE_SESSION_TICKET))
31693     /* Protocol version */
31694     size += OPAQUE16_LEN;
31695 #endif
31696 #if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
31697                         (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
31698     /* cipher suite */
31699     size += OPAQUE16_LEN;
31700 #endif
31701 #ifndef NO_CLIENT_CACHE
31702     /* ServerID len | ServerID */
31703     size += OPAQUE16_LEN + sess->idLen;
31704 #endif
31705 #ifdef OPENSSL_EXTRA
31706     /* session context ID len | session context ID */
31707     size += OPAQUE8_LEN + sess->sessionCtxSz;
31708 #endif
31709 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
31710     /* peerVerifyRet */
31711     size += OPAQUE8_LEN;
31712 #endif
31713 #ifdef WOLFSSL_TLS13
31714     /* namedGroup */
31715     size += OPAQUE16_LEN;
31716 #endif
31717 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
31718 #ifdef WOLFSSL_TLS13
31719     /* ticketSeen | ticketAdd */
31720     size += OPAQUE32_LEN + OPAQUE32_LEN;
31721     /* ticketNonce */
31722     size += OPAQUE8_LEN + sess->ticketNonce.len;
31723 #endif
31724 #ifdef WOLFSSL_EARLY_DATA
31725     size += OPAQUE32_LEN;
31726 #endif
31727 #endif
31728 #ifdef HAVE_SESSION_TICKET
31729     /* ticket len | ticket */
31730     size += OPAQUE16_LEN + sess->ticketLen;
31731 #endif
31732 
31733     if (p != NULL) {
31734         if (*p == NULL)
31735             *p = (unsigned char*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL);
31736         if (*p == NULL)
31737             return 0;
31738         data = *p;
31739 
31740         data[idx++] = sess->side;
31741         c32toa(sess->bornOn, data + idx); idx += OPAQUE32_LEN;
31742         c32toa(sess->timeout, data + idx); idx += OPAQUE32_LEN;
31743         data[idx++] = sess->sessionIDSz;
31744         XMEMCPY(data + idx, sess->sessionID, sess->sessionIDSz);
31745         idx += sess->sessionIDSz;
31746         XMEMCPY(data + idx, sess->masterSecret, SECRET_LEN); idx += SECRET_LEN;
31747         data[idx++] = (byte)sess->haveEMS;
31748 #ifdef SESSION_CERTS
31749         data[idx++] = (byte)sess->chain.count;
31750         for (i = 0; i < sess->chain.count; i++) {
31751             c16toa((word16)sess->chain.certs[i].length, data + idx);
31752             idx += OPAQUE16_LEN;
31753             XMEMCPY(data + idx, sess->chain.certs[i].buffer,
31754                     sess->chain.certs[i].length);
31755             idx += sess->chain.certs[i].length;
31756         }
31757 #endif
31758 #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
31759                                defined(HAVE_SESSION_TICKET))
31760         data[idx++] = sess->version.major;
31761         data[idx++] = sess->version.minor;
31762 #endif
31763 #if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
31764                         (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
31765         data[idx++] = sess->cipherSuite0;
31766         data[idx++] = sess->cipherSuite;
31767 #endif
31768 #ifndef NO_CLIENT_CACHE
31769         c16toa(sess->idLen, data + idx); idx += OPAQUE16_LEN;
31770         XMEMCPY(data + idx, sess->serverID, sess->idLen);
31771         idx += sess->idLen;
31772 #endif
31773 #ifdef OPENSSL_EXTRA
31774         data[idx++] = sess->sessionCtxSz;
31775         XMEMCPY(data + idx, sess->sessionCtx, sess->sessionCtxSz);
31776         idx += sess->sessionCtxSz;
31777 #endif
31778 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
31779         data[idx++] = sess->peerVerifyRet;
31780 #endif
31781 #ifdef WOLFSSL_TLS13
31782         c16toa(sess->namedGroup, data + idx);
31783         idx += OPAQUE16_LEN;
31784 #endif
31785 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
31786 #ifdef WOLFSSL_TLS13
31787     c32toa(sess->ticketSeen, data + idx);
31788     idx += OPAQUE32_LEN;
31789     c32toa(sess->ticketAdd, data + idx);
31790     idx += OPAQUE32_LEN;
31791     data[idx++] = sess->ticketNonce.len;
31792     XMEMCPY(data + idx, sess->ticketNonce.data, sess->ticketNonce.len);
31793     idx += sess->ticketNonce.len;
31794 #endif
31795 #ifdef WOLFSSL_EARLY_DATA
31796         c32toa(sess->maxEarlyDataSz, data + idx);
31797         idx += OPAQUE32_LEN;
31798 #endif
31799 #endif
31800 #ifdef HAVE_SESSION_TICKET
31801         c16toa(sess->ticketLen, data + idx); idx += OPAQUE16_LEN;
31802         XMEMCPY(data + idx, sess->ticket, sess->ticketLen);
31803         idx += sess->ticketLen;
31804 #endif
31805     }
31806 #endif
31807 
31808     (void)sess;
31809     (void)p;
31810 #ifdef HAVE_EXT_CACHE
31811     (void)idx;
31812 #endif
31813 
31814     return size;
31815 }
31816 
31817 
31818 /* TODO: no function to free new session.
31819  *
31820  * Note: It is expected that the importing and exporting function have been
31821  *       built with the same settings. For example if session tickets was
31822  *       enabled with the wolfSSL library exporting a session then it is
31823  *       expected to be turned on with the wolfSSL library importing the session.
31824  */
wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION ** sess,const unsigned char ** p,long i)31825 WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
31826                                 const unsigned char** p, long i)
31827 {
31828     WOLFSSL_SESSION* s = NULL;
31829     int ret = 0;
31830 #if defined(HAVE_EXT_CACHE)
31831     int idx;
31832     byte* data;
31833 #ifdef SESSION_CERTS
31834     int j;
31835     word16 length;
31836 #endif
31837 #endif /* HAVE_EXT_CACHE */
31838 
31839     (void)p;
31840     (void)i;
31841     (void)ret;
31842 
31843     if (sess != NULL) {
31844         s = GetSessionPtr(*sess);
31845     }
31846 
31847 #ifdef HAVE_EXT_CACHE
31848     if (p == NULL || *p == NULL)
31849         return NULL;
31850 
31851     if (s == NULL) {
31852         s = wolfSSL_SESSION_new();
31853         if (s == NULL)
31854             return NULL;
31855 #ifdef HAVE_SESSION_TICKET
31856         s->ticketLenAlloc = 0;
31857 #endif
31858     }
31859 
31860     idx = 0;
31861     data = (byte*)*p;
31862 
31863     /* side | bornOn | timeout | sessionID len */
31864     if (i < OPAQUE8_LEN + OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN) {
31865         ret = BUFFER_ERROR;
31866         goto end;
31867     }
31868     s->side = data[idx++];
31869     ato32(data + idx, &s->bornOn); idx += OPAQUE32_LEN;
31870     ato32(data + idx, &s->timeout); idx += OPAQUE32_LEN;
31871     s->sessionIDSz = data[idx++];
31872 
31873     /* sessionID | secret | haveEMS */
31874     if (i - idx < s->sessionIDSz + SECRET_LEN + OPAQUE8_LEN) {
31875         ret = BUFFER_ERROR;
31876         goto end;
31877     }
31878     XMEMCPY(s->sessionID, data + idx, s->sessionIDSz);
31879     idx  += s->sessionIDSz;
31880     XMEMCPY(s->masterSecret, data + idx, SECRET_LEN); idx += SECRET_LEN;
31881     s->haveEMS = data[idx++];
31882 
31883 #ifdef SESSION_CERTS
31884     /* Certificate chain */
31885     if (i - idx == 0) {
31886         ret = BUFFER_ERROR;
31887         goto end;
31888     }
31889     s->chain.count = data[idx++];
31890     for (j = 0; j < s->chain.count; j++) {
31891         if (i - idx < OPAQUE16_LEN) {
31892             ret = BUFFER_ERROR;
31893             goto end;
31894         }
31895         ato16(data + idx, &length); idx += OPAQUE16_LEN;
31896         s->chain.certs[j].length = length;
31897         if (i - idx < length) {
31898             ret = BUFFER_ERROR;
31899             goto end;
31900         }
31901         XMEMCPY(s->chain.certs[j].buffer, data + idx, length);
31902         idx += length;
31903     }
31904 #endif
31905 #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
31906                                defined(HAVE_SESSION_TICKET))
31907     /* Protocol Version */
31908     if (i - idx < OPAQUE16_LEN) {
31909         ret = BUFFER_ERROR;
31910         goto end;
31911     }
31912     s->version.major = data[idx++];
31913     s->version.minor = data[idx++];
31914 #endif
31915 #if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
31916                         (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
31917     /* Cipher suite */
31918     if (i - idx < OPAQUE16_LEN) {
31919         ret = BUFFER_ERROR;
31920         goto end;
31921     }
31922     s->cipherSuite0 = data[idx++];
31923     s->cipherSuite = data[idx++];
31924 #endif
31925 #ifndef NO_CLIENT_CACHE
31926     /* ServerID len */
31927     if (i - idx < OPAQUE16_LEN) {
31928         ret = BUFFER_ERROR;
31929         goto end;
31930     }
31931     ato16(data + idx, &s->idLen); idx += OPAQUE16_LEN;
31932 
31933     /* ServerID */
31934     if (i - idx < s->idLen) {
31935         ret = BUFFER_ERROR;
31936         goto end;
31937     }
31938     XMEMCPY(s->serverID, data + idx, s->idLen); idx += s->idLen;
31939 #endif
31940 #ifdef OPENSSL_EXTRA
31941     /* byte for length of session context ID */
31942     if (i - idx < OPAQUE8_LEN) {
31943         ret = BUFFER_ERROR;
31944         goto end;
31945     }
31946     s->sessionCtxSz = data[idx++];
31947 
31948     /* app session context ID */
31949     if (i - idx < s->sessionCtxSz) {
31950         ret = BUFFER_ERROR;
31951         goto end;
31952     }
31953     XMEMCPY(s->sessionCtx, data + idx, s->sessionCtxSz); idx += s->sessionCtxSz;
31954 #endif
31955 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
31956     /* byte for peerVerifyRet */
31957     if (i - idx < OPAQUE8_LEN) {
31958         ret = BUFFER_ERROR;
31959         goto end;
31960     }
31961     s->peerVerifyRet = data[idx++];
31962 #endif
31963 #ifdef WOLFSSL_TLS13
31964     if (i - idx < OPAQUE16_LEN) {
31965         ret = BUFFER_ERROR;
31966         goto end;
31967     }
31968     ato16(data + idx, &s->namedGroup);
31969     idx += OPAQUE16_LEN;
31970 #endif
31971 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
31972 #ifdef WOLFSSL_TLS13
31973     if (i - idx < (OPAQUE32_LEN * 2)) {
31974         ret = BUFFER_ERROR;
31975         goto end;
31976     }
31977     ato32(data + idx, &s->ticketSeen);
31978     idx += OPAQUE32_LEN;
31979     ato32(data + idx, &s->ticketAdd);
31980     idx += OPAQUE32_LEN;
31981     if (i - idx < OPAQUE8_LEN) {
31982         ret = BUFFER_ERROR;
31983         goto end;
31984     }
31985     s->ticketNonce.len = data[idx++];
31986 
31987     if (i - idx < s->ticketNonce.len) {
31988         ret = BUFFER_ERROR;
31989         goto end;
31990     }
31991     XMEMCPY(s->ticketNonce.data, data + idx, s->ticketNonce.len);
31992     idx += s->ticketNonce.len;
31993 #endif
31994 #ifdef WOLFSSL_EARLY_DATA
31995     if (i - idx < OPAQUE32_LEN) {
31996         ret = BUFFER_ERROR;
31997         goto end;
31998     }
31999     ato32(data + idx, &s->maxEarlyDataSz);
32000     idx += OPAQUE32_LEN;
32001 #endif
32002 #endif
32003 #ifdef HAVE_SESSION_TICKET
32004     /* ticket len */
32005     if (i - idx < OPAQUE16_LEN) {
32006         ret = BUFFER_ERROR;
32007         goto end;
32008     }
32009     ato16(data + idx, &s->ticketLen); idx += OPAQUE16_LEN;
32010 
32011     /* Dispose of ol dynamic ticket and ensure space for new ticket. */
32012     if (s->ticketLenAlloc > 0) {
32013         XFREE(s->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
32014     }
32015     if (s->ticketLen <= SESSION_TICKET_LEN)
32016         s->ticket = s->_staticTicket;
32017     else {
32018         s->ticket = (byte*)XMALLOC(s->ticketLen, NULL,
32019                                    DYNAMIC_TYPE_SESSION_TICK);
32020         if (s->ticket == NULL) {
32021             ret = MEMORY_ERROR;
32022             goto end;
32023         }
32024         s->ticketLenAlloc = (word16)s->ticketLen;
32025     }
32026 
32027     /* ticket */
32028     if (i - idx < s->ticketLen) {
32029         ret = BUFFER_ERROR;
32030         goto end;
32031     }
32032     XMEMCPY(s->ticket, data + idx, s->ticketLen); idx += s->ticketLen;
32033 #endif
32034     (void)idx;
32035 
32036     if (sess != NULL)
32037         *sess = s;
32038 
32039     *p += idx;
32040 
32041 end:
32042     if (ret != 0 && (sess == NULL || *sess != s)) {
32043         wolfSSL_SESSION_free(s);
32044         s = NULL;
32045     }
32046 #endif /* HAVE_EXT_CACHE */
32047     return s;
32048 }
32049 
32050 /* Check if there is a session ticket associated with this WOLFSSL_SESSION.
32051  *
32052  * sess - pointer to WOLFSSL_SESSION struct
32053  *
32054  * Returns 1 if has session ticket, otherwise 0 */
wolfSSL_SESSION_has_ticket(const WOLFSSL_SESSION * sess)32055 int wolfSSL_SESSION_has_ticket(const WOLFSSL_SESSION* sess)
32056 {
32057     WOLFSSL_ENTER("wolfSSL_SESSION_has_ticket");
32058     sess = GetSessionPtr(sess);
32059 #ifdef HAVE_SESSION_TICKET
32060     if (sess) {
32061         if ((sess->ticketLen > 0) && (sess->ticket != NULL)) {
32062             return WOLFSSL_SUCCESS;
32063         }
32064     }
32065 #endif
32066     return WOLFSSL_FAILURE;
32067 }
32068 
wolfSSL_SESSION_get_ticket_lifetime_hint(const WOLFSSL_SESSION * sess)32069 unsigned long wolfSSL_SESSION_get_ticket_lifetime_hint(
32070                   const WOLFSSL_SESSION* sess)
32071 {
32072     WOLFSSL_ENTER("wolfSSL_SESSION_get_ticket_lifetime_hint");
32073     sess = GetSessionPtr(sess);
32074     if (sess) {
32075         return sess->timeout;
32076     }
32077     return 0;
32078 }
32079 
wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION * sess)32080 long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
32081 {
32082     long timeout = 0;
32083     WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
32084     sess = GetSessionPtr(sess);
32085     if (sess)
32086         timeout = sess->timeout;
32087     return timeout;
32088 }
32089 
32090 
wolfSSL_SESSION_get_time(const WOLFSSL_SESSION * sess)32091 long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
32092 {
32093     long bornOn = 0;
32094     WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
32095     sess = GetSessionPtr(sess);
32096     if (sess)
32097         bornOn = sess->bornOn;
32098     return bornOn;
32099 }
32100 
wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION * ses,long t)32101 long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
32102 {
32103     word32 tmptime;
32104 
32105     ses = GetSessionPtr(ses);
32106     if (ses == NULL || t < 0) {
32107         return BAD_FUNC_ARG;
32108     }
32109 
32110     tmptime = t & 0xFFFFFFFF;
32111     ses->timeout = tmptime;
32112 
32113     return WOLFSSL_SUCCESS;
32114 }
32115 
32116 #endif /* !NO_SESSION_CACHE && OPENSSL_EXTRA || HAVE_EXT_CACHE */
32117 
32118 
32119 #ifdef KEEP_PEER_CERT
wolfSSL_X509_get_subjectCN(WOLFSSL_X509 * x509)32120 char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
32121 {
32122     if (x509 == NULL)
32123         return NULL;
32124 
32125     return x509->subjectCN;
32126 }
32127 #endif /* KEEP_PEER_CERT */
32128 
32129 #ifdef OPENSSL_EXTRA
32130 
32131 #if defined(HAVE_EX_DATA) && !defined(NO_FILESYSTEM)
wolfSSL_cmp_peer_cert_to_file(WOLFSSL * ssl,const char * fname)32132 int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
32133 {
32134     int ret = WOLFSSL_FATAL_ERROR;
32135 
32136     WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
32137     if (ssl != NULL && fname != NULL)
32138     {
32139     #ifdef WOLFSSL_SMALL_STACK
32140         byte           staticBuffer[1]; /* force heap usage */
32141     #else
32142         byte           staticBuffer[FILE_BUFFER_SIZE];
32143     #endif
32144         byte*          myBuffer  = staticBuffer;
32145         int            dynamic   = 0;
32146         XFILE          file;
32147         long           sz        = 0;
32148         WOLFSSL_CTX*   ctx       = ssl->ctx;
32149         WOLFSSL_X509*  peer_cert = &ssl->peerCert;
32150         DerBuffer*     fileDer = NULL;
32151 
32152         file = XFOPEN(fname, "rb");
32153         if (file == XBADFILE)
32154             return WOLFSSL_BAD_FILE;
32155 
32156         if (XFSEEK(file, 0, XSEEK_END) != 0) {
32157             XFCLOSE(file);
32158             return WOLFSSL_BAD_FILE;
32159         }
32160         sz = XFTELL(file);
32161         XREWIND(file);
32162 
32163         if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
32164             WOLFSSL_MSG("cmp_peer_cert_to_file size error");
32165             XFCLOSE(file);
32166             return WOLFSSL_BAD_FILE;
32167         }
32168 
32169         if (sz > (long)sizeof(staticBuffer)) {
32170             WOLFSSL_MSG("Getting dynamic buffer");
32171             myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
32172             dynamic = 1;
32173         }
32174 
32175         if ((myBuffer != NULL) &&
32176             (sz > 0) &&
32177             (XFREAD(myBuffer, 1, sz, file) == (size_t)sz) &&
32178             (PemToDer(myBuffer, (long)sz, CERT_TYPE,
32179                       &fileDer, ctx->heap, NULL, NULL) == 0) &&
32180             (fileDer->length != 0) &&
32181             (fileDer->length == peer_cert->derCert->length) &&
32182             (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer,
32183                                                 fileDer->length) == 0))
32184         {
32185             ret = 0;
32186         }
32187 
32188         FreeDer(&fileDer);
32189 
32190         if (dynamic)
32191             XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
32192 
32193         XFCLOSE(file);
32194     }
32195 
32196     return ret;
32197 }
32198 #endif
32199 #endif /* OPENSSL_EXTRA */
32200 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
32201 const WOLFSSL_ObjectInfo wolfssl_object_info[] = {
32202 #ifndef NO_CERTS
32203     /* oidCertExtType */
32204     { NID_basic_constraints, BASIC_CA_OID, oidCertExtType, "basicConstraints",
32205                                                 "X509v3 Basic Constraints"},
32206     { NID_subject_alt_name, ALT_NAMES_OID, oidCertExtType, "subjectAltName",
32207                                          "X509v3 Subject Alternative Name"},
32208     { NID_crl_distribution_points, CRL_DIST_OID, oidCertExtType, "crlDistributionPoints",
32209                                           "X509v3 CRL Distribution Points"},
32210     { NID_info_access, AUTH_INFO_OID, oidCertExtType, "authorityInfoAccess",
32211                                             "Authority Information Access"},
32212     { NID_authority_key_identifier, AUTH_KEY_OID, oidCertExtType,
32213                "authorityKeyIdentifier", "X509v3 Authority Key Identifier"},
32214     { NID_subject_key_identifier, SUBJ_KEY_OID, oidCertExtType,
32215                    "subjectKeyIdentifier", "X509v3 Subject Key Identifier"},
32216     { NID_key_usage, KEY_USAGE_OID, oidCertExtType, "keyUsage",
32217                                                         "X509v3 Key Usage"},
32218     { NID_inhibit_any_policy, INHIBIT_ANY_OID, oidCertExtType,
32219                            "inhibitAnyPolicy", "X509v3 Inhibit Any Policy"},
32220     { NID_ext_key_usage, KEY_USAGE_OID, oidCertExtType,
32221                            "extendedKeyUsage", "X509v3 Extended Key Usage"},
32222     { NID_name_constraints, NAME_CONS_OID, oidCertExtType,
32223                               "nameConstraints", "X509v3 Name Constraints"},
32224     { NID_certificate_policies, CERT_POLICY_OID, oidCertExtType,
32225                       "certificatePolicies", "X509v3 Certificate Policies"},
32226 
32227     /* oidCertAuthInfoType */
32228     { NID_ad_OCSP, AIA_OCSP_OID, oidCertAuthInfoType, "OCSP",
32229                                             "OCSP"},
32230     { NID_ad_ca_issuers, AIA_CA_ISSUER_OID, oidCertAuthInfoType,
32231                                                  "caIssuers", "CA Issuers"},
32232 
32233     /* oidCertPolicyType */
32234     { NID_any_policy, CP_ANY_OID, oidCertPolicyType, "anyPolicy",
32235                                                        "X509v3 Any Policy"},
32236 
32237     /* oidCertAltNameType */
32238     { NID_hw_name_oid, HW_NAME_OID, oidCertAltNameType, "Hardware name",""},
32239 
32240     /* oidCertKeyUseType */
32241     { NID_anyExtendedKeyUsage, EKU_ANY_OID, oidCertKeyUseType,
32242                            "anyExtendedKeyUsage", "Any Extended Key Usage"},
32243     { EKU_SERVER_AUTH_OID, EKU_SERVER_AUTH_OID, oidCertKeyUseType,
32244                              "serverAuth", "TLS Web Server Authentication"},
32245     { EKU_CLIENT_AUTH_OID, EKU_CLIENT_AUTH_OID, oidCertKeyUseType,
32246                              "clientAuth", "TLS Web Client Authentication"},
32247     { EKU_OCSP_SIGN_OID, EKU_OCSP_SIGN_OID, oidCertKeyUseType,
32248                                              "OCSPSigning", "OCSP Signing"},
32249 
32250     /* oidCertNameType */
32251     { NID_commonName, NID_commonName, oidCertNameType, "CN", "commonName"},
32252     { NID_surname, NID_surname, oidCertNameType, "SN", "surname"},
32253     { NID_serialNumber, NID_serialNumber, oidCertNameType, "serialNumber",
32254                                                             "serialNumber"},
32255     { NID_countryName, NID_countryName, oidCertNameType, "C", "countryName"},
32256     { NID_localityName, NID_localityName, oidCertNameType, "L", "localityName"},
32257     { NID_stateOrProvinceName, NID_stateOrProvinceName, oidCertNameType, "ST",
32258                                                         "stateOrProvinceName"},
32259     { NID_streetAddress, NID_streetAddress, oidCertNameType, "street",
32260                                                         "streetAddress"},
32261     { NID_organizationName, NID_organizationName, oidCertNameType, "O",
32262                                                         "organizationName"},
32263     { NID_organizationalUnitName, NID_organizationalUnitName, oidCertNameType,
32264                                                 "OU", "organizationalUnitName"},
32265     { NID_emailAddress, NID_emailAddress, oidCertNameType, "emailAddress",
32266                                                             "emailAddress"},
32267     { NID_domainComponent, NID_domainComponent, oidCertNameType, "DC",
32268                                                             "domainComponent"},
32269     { NID_favouriteDrink, NID_favouriteDrink, oidCertNameType, "favouriteDrink",
32270                                                             "favouriteDrink"},
32271     { NID_businessCategory, NID_businessCategory, oidCertNameType, "businessCategory",
32272                                                             "businessCategory"},
32273     { NID_jurisdictionCountryName, NID_jurisdictionCountryName, oidCertNameType, "jurisdictionC",
32274                                                             "jurisdictionCountryName"},
32275     { NID_jurisdictionStateOrProvinceName, NID_jurisdictionStateOrProvinceName,
32276             oidCertNameType, "jurisdictionST", "jurisdictionStateOrProvinceName"},
32277     { NID_postalCode, NID_postalCode, oidCertNameType, "postalCode", "postalCode"},
32278 
32279 #ifdef WOLFSSL_CERT_REQ
32280     { NID_pkcs9_challengePassword, CHALLENGE_PASSWORD_OID,
32281             oidCsrAttrType, "challengePassword", "challengePassword"},
32282     { NID_pkcs9_contentType, PKCS9_CONTENT_TYPE_OID,
32283         oidCsrAttrType, "contentType", "contentType" },
32284 #endif
32285 #endif
32286 #ifdef OPENSSL_EXTRA /* OPENSSL_EXTRA_X509_SMALL only needs the above */
32287         /* oidHashType */
32288     #ifdef WOLFSSL_MD2
32289         { NID_md2, MD2h, oidHashType, "MD2", "md2"},
32290     #endif
32291     #ifdef WOLFSSL_MD5
32292         { NID_md5, MD5h, oidHashType, "MD5", "md5"},
32293     #endif
32294     #ifndef NO_SHA
32295         { NID_sha1, SHAh, oidHashType, "SHA1", "sha1"},
32296     #endif
32297     #ifdef WOLFSSL_SHA224
32298         { NID_sha224, SHA224h, oidHashType, "SHA224", "sha224"},
32299     #endif
32300     #ifndef NO_SHA256
32301         { NID_sha256, SHA256h, oidHashType, "SHA256", "sha256"},
32302     #endif
32303     #ifdef WOLFSSL_SHA384
32304         { NID_sha384, SHA384h, oidHashType, "SHA384", "sha384"},
32305     #endif
32306     #ifdef WOLFSSL_SHA512
32307         { NID_sha512, SHA512h, oidHashType, "SHA512", "sha512"},
32308     #endif
32309     #ifdef WOLFSSL_SHA3
32310         #ifndef WOLFSSL_NOSHA3_224
32311         { NID_sha3_224, SHA3_224h, oidHashType, "SHA3-224", "sha3-224"},
32312         #endif
32313         #ifndef WOLFSSL_NOSHA3_256
32314         { NID_sha3_256, SHA3_256h, oidHashType, "SHA3-256", "sha3-256"},
32315         #endif
32316         #ifndef WOLFSSL_NOSHA3_384
32317         { NID_sha3_384, SHA3_384h, oidHashType, "SHA3-384", "sha3-384"},
32318         #endif
32319         #ifndef WOLFSSL_NOSHA3_512
32320         { NID_sha3_512, SHA3_512h, oidHashType, "SHA3-512", "sha3-512"},
32321         #endif
32322     #endif /* WOLFSSL_SHA3 */
32323         /* oidSigType */
32324     #ifndef NO_DSA
32325         #ifndef NO_SHA
32326         { NID_dsaWithSHA1, CTC_SHAwDSA, oidSigType, "DSA-SHA1", "dsaWithSHA1"},
32327         { NID_dsa_with_SHA256, CTC_SHA256wDSA, oidSigType, "dsa_with_SHA256",
32328                                                         "dsa_with_SHA256"},
32329         #endif
32330     #endif /* NO_DSA */
32331     #ifndef NO_RSA
32332         #ifdef WOLFSSL_MD2
32333         { NID_md2WithRSAEncryption, CTC_MD2wRSA, oidSigType, "RSA-MD2",
32334                                                         "md2WithRSAEncryption"},
32335         #endif
32336         #ifndef NO_MD5
32337         { NID_md5WithRSAEncryption, CTC_MD5wRSA, oidSigType, "RSA-MD5",
32338                                                         "md5WithRSAEncryption"},
32339         #endif
32340         #ifndef NO_SHA
32341         { NID_sha1WithRSAEncryption, CTC_SHAwRSA, oidSigType, "RSA-SHA1",
32342                                                        "sha1WithRSAEncryption"},
32343         #endif
32344         #ifdef WOLFSSL_SHA224
32345         { NID_sha224WithRSAEncryption, CTC_SHA224wRSA, oidSigType, "RSA-SHA224",
32346                                                      "sha224WithRSAEncryption"},
32347         #endif
32348         #ifndef NO_SHA256
32349         { NID_sha256WithRSAEncryption, CTC_SHA256wRSA, oidSigType, "RSA-SHA256",
32350                                                      "sha256WithRSAEncryption"},
32351         #endif
32352         #ifdef WOLFSSL_SHA384
32353         { NID_sha384WithRSAEncryption, CTC_SHA384wRSA, oidSigType, "RSA-SHA384",
32354                                                      "sha384WithRSAEncryption"},
32355         #endif
32356         #ifdef WOLFSSL_SHA512
32357         { NID_sha512WithRSAEncryption, CTC_SHA512wRSA, oidSigType, "RSA-SHA512",
32358                                                      "sha512WithRSAEncryption"},
32359         #endif
32360         #ifdef WOLFSSL_SHA3
32361         #ifndef WOLFSSL_NOSHA3_224
32362         { NID_RSA_SHA3_224, CTC_SHA3_224wRSA, oidSigType, "RSA-SHA3-224",
32363                                                      "sha3-224WithRSAEncryption"},
32364         #endif
32365         #ifndef WOLFSSL_NOSHA3_256
32366         { NID_RSA_SHA3_256, CTC_SHA3_256wRSA, oidSigType, "RSA-SHA3-256",
32367                                                      "sha3-256WithRSAEncryption"},
32368         #endif
32369         #ifndef WOLFSSL_NOSHA3_384
32370         { NID_RSA_SHA3_384, CTC_SHA3_384wRSA, oidSigType, "RSA-SHA3-384",
32371                                                      "sha3-384WithRSAEncryption"},
32372         #endif
32373         #ifndef WOLFSSL_NOSHA3_512
32374         { NID_RSA_SHA3_512, CTC_SHA3_512wRSA, oidSigType, "RSA-SHA3-512",
32375                                                      "sha3-512WithRSAEncryption"},
32376         #endif
32377         #endif
32378     #endif /* NO_RSA */
32379     #ifdef HAVE_ECC
32380         #ifndef NO_SHA
32381         { NID_ecdsa_with_SHA1, CTC_SHAwECDSA, oidSigType, "ecdsa-with-SHA1", "shaWithECDSA"},
32382         #endif
32383         #ifdef WOLFSSL_SHA224
32384         { NID_ecdsa_with_SHA224, CTC_SHA224wECDSA, oidSigType, "ecdsa-with-SHA224","sha224WithECDSA"},
32385         #endif
32386         #ifndef NO_SHA256
32387         { NID_ecdsa_with_SHA256, CTC_SHA256wECDSA, oidSigType, "ecdsa-with-SHA256","sha256WithECDSA"},
32388         #endif
32389         #ifdef WOLFSSL_SHA384
32390         { NID_ecdsa_with_SHA384, CTC_SHA384wECDSA, oidSigType, "ecdsa-with-SHA384","sha384WithECDSA"},
32391         #endif
32392         #ifdef WOLFSSL_SHA512
32393         { NID_ecdsa_with_SHA512, CTC_SHA512wECDSA, oidSigType, "ecdsa-with-SHA512","sha512WithECDSA"},
32394         #endif
32395         #ifdef WOLFSSL_SHA3
32396         #ifndef WOLFSSL_NOSHA3_224
32397         { NID_ecdsa_with_SHA3_224, CTC_SHA3_224wECDSA, oidSigType, "id-ecdsa-with-SHA3-224",
32398                 "ecdsa_with_SHA3-224"},
32399         #endif
32400         #ifndef WOLFSSL_NOSHA3_256
32401         { NID_ecdsa_with_SHA3_256, CTC_SHA3_256wECDSA, oidSigType, "id-ecdsa-with-SHA3-256",
32402                 "ecdsa_with_SHA3-256"},
32403         #endif
32404         #ifndef WOLFSSL_NOSHA3_384
32405         { NID_ecdsa_with_SHA3_384, CTC_SHA3_384wECDSA, oidSigType, "id-ecdsa-with-SHA3-384",
32406                 "ecdsa_with_SHA3-384"},
32407         #endif
32408         #ifndef WOLFSSL_NOSHA3_512
32409         { NID_ecdsa_with_SHA3_512, CTC_SHA3_512wECDSA, oidSigType, "id-ecdsa-with-SHA3-512",
32410                 "ecdsa_with_SHA3-512"},
32411         #endif
32412         #endif
32413     #endif /* HAVE_ECC */
32414 
32415         /* oidKeyType */
32416     #ifndef NO_DSA
32417         { NID_dsa, DSAk, oidKeyType, "DSA", "dsaEncryption"},
32418     #endif /* NO_DSA */
32419     #ifndef NO_RSA
32420         { NID_rsaEncryption, RSAk, oidKeyType, "rsaEncryption", "rsaEncryption"},
32421     #endif /* NO_RSA */
32422     #ifdef HAVE_ECC
32423         { NID_X9_62_id_ecPublicKey, ECDSAk, oidKeyType, "id-ecPublicKey",
32424                                                         "id-ecPublicKey"},
32425     #endif /* HAVE_ECC */
32426     #ifndef NO_DH
32427         { NID_dhKeyAgreement, DHk, oidKeyType, "dhKeyAgreement", "dhKeyAgreement"},
32428     #endif
32429     #ifdef HAVE_ED448
32430         { NID_ED448, ED448k,  oidKeyType, "ED448", "ED448"},
32431     #endif
32432     #ifdef HAVE_ED25519
32433         { NID_ED25519, ED25519k,  oidKeyType, "ED25519", "ED25519"},
32434     #endif
32435     #ifdef HAVE_PQC
32436         { CTC_FALCON_LEVEL1, FALCON_LEVEL1k,  oidKeyType, "Falcon Level 1",
32437                                                           "Falcon Level 1"},
32438         { CTC_FALCON_LEVEL5, FALCON_LEVEL5k,  oidKeyType, "Falcon Level 5",
32439                                                           "Falcon Level 5"},
32440     #endif
32441 
32442         /* oidCurveType */
32443     #ifdef HAVE_ECC
32444         { NID_X9_62_prime192v1, ECC_SECP192R1_OID, oidCurveType, "prime192v1", "prime192v1"},
32445         { NID_X9_62_prime192v2, ECC_PRIME192V2_OID, oidCurveType, "prime192v2", "prime192v2"},
32446         { NID_X9_62_prime192v3, ECC_PRIME192V3_OID, oidCurveType, "prime192v3", "prime192v3"},
32447 
32448         { NID_X9_62_prime239v1, ECC_PRIME239V1_OID, oidCurveType, "prime239v1", "prime239v1"},
32449         { NID_X9_62_prime239v2, ECC_PRIME239V2_OID, oidCurveType, "prime239v2", "prime239v2"},
32450         { NID_X9_62_prime239v3, ECC_PRIME239V3_OID, oidCurveType, "prime239v3", "prime239v3"},
32451 
32452         { NID_X9_62_prime256v1, ECC_SECP256R1_OID, oidCurveType, "prime256v1", "prime256v1"},
32453 
32454         { NID_secp112r1, ECC_SECP112R1_OID,  oidCurveType, "secp112r1", "secp112r1"},
32455         { NID_secp112r2, ECC_SECP112R2_OID,  oidCurveType, "secp112r2", "secp112r2"},
32456 
32457         { NID_secp128r1, ECC_SECP128R1_OID,  oidCurveType, "secp128r1", "secp128r1"},
32458         { NID_secp128r2, ECC_SECP128R2_OID,  oidCurveType, "secp128r2", "secp128r2"},
32459 
32460         { NID_secp160r1, ECC_SECP160R1_OID,  oidCurveType, "secp160r1", "secp160r1"},
32461         { NID_secp160r2, ECC_SECP160R2_OID,  oidCurveType, "secp160r2", "secp160r2"},
32462 
32463         { NID_secp224r1, ECC_SECP224R1_OID,  oidCurveType, "secp224r1", "secp224r1"},
32464         { NID_secp384r1, ECC_SECP384R1_OID,  oidCurveType, "secp384r1", "secp384r1"},
32465         { NID_secp521r1, ECC_SECP521R1_OID,  oidCurveType, "secp521r1", "secp521r1"},
32466 
32467         { NID_secp160k1, ECC_SECP160K1_OID,  oidCurveType, "secp160k1", "secp160k1"},
32468         { NID_secp192k1, ECC_SECP192K1_OID,  oidCurveType, "secp192k1", "secp192k1"},
32469         { NID_secp224k1, ECC_SECP224K1_OID,  oidCurveType, "secp224k1", "secp224k1"},
32470         { NID_secp256k1, ECC_SECP256K1_OID,  oidCurveType, "secp256k1", "secp256k1"},
32471 
32472         { NID_brainpoolP160r1, ECC_BRAINPOOLP160R1_OID,  oidCurveType, "brainpoolP160r1", "brainpoolP160r1"},
32473         { NID_brainpoolP192r1, ECC_BRAINPOOLP192R1_OID,  oidCurveType, "brainpoolP192r1", "brainpoolP192r1"},
32474         { NID_brainpoolP224r1, ECC_BRAINPOOLP224R1_OID,  oidCurveType, "brainpoolP224r1", "brainpoolP224r1"},
32475         { NID_brainpoolP256r1, ECC_BRAINPOOLP256R1_OID,  oidCurveType, "brainpoolP256r1", "brainpoolP256r1"},
32476         { NID_brainpoolP320r1, ECC_BRAINPOOLP320R1_OID,  oidCurveType, "brainpoolP320r1", "brainpoolP320r1"},
32477         { NID_brainpoolP384r1, ECC_BRAINPOOLP384R1_OID,  oidCurveType, "brainpoolP384r1", "brainpoolP384r1"},
32478         { NID_brainpoolP512r1, ECC_BRAINPOOLP512R1_OID,  oidCurveType, "brainpoolP512r1", "brainpoolP512r1"},
32479     #endif /* HAVE_ECC */
32480 
32481         /* oidBlkType */
32482     #ifdef WOLFSSL_AES_128
32483         { AES128CBCb, AES128CBCb, oidBlkType, "AES-128-CBC", "aes-128-cbc"},
32484     #endif
32485     #ifdef WOLFSSL_AES_192
32486         { AES192CBCb, AES192CBCb, oidBlkType, "AES-192-CBC", "aes-192-cbc"},
32487     #endif
32488     #ifdef WOLFSSL_AES_256
32489         { AES256CBCb, AES256CBCb, oidBlkType, "AES-256-CBC", "aes-256-cbc"},
32490     #endif
32491     #ifndef NO_DES3
32492         { NID_des, DESb, oidBlkType, "DES-CBC", "des-cbc"},
32493         { NID_des3, DES3b, oidBlkType, "DES-EDE3-CBC", "des-ede3-cbc"},
32494     #endif /* !NO_DES3 */
32495 
32496         /* oidOcspType */
32497     #ifdef HAVE_OCSP
32498         { NID_id_pkix_OCSP_basic, OCSP_BASIC_OID, oidOcspType, "basicOCSPResponse",
32499                                                          "Basic OCSP Response"},
32500         { OCSP_NONCE_OID, OCSP_NONCE_OID, oidOcspType, "Nonce",
32501                                                                   "OCSP Nonce"},
32502     #endif /* HAVE_OCSP */
32503 
32504     #ifndef NO_PWDBASED
32505         /* oidKdfType */
32506         { PBKDF2_OID, PBKDF2_OID, oidKdfType, "PBKDFv2", "PBKDF2"},
32507 
32508         /* oidPBEType */
32509         { PBE_SHA1_RC4_128, PBE_SHA1_RC4_128, oidPBEType,
32510                                  "PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4"},
32511         { PBE_SHA1_DES, PBE_SHA1_DES, oidPBEType, "PBE-SHA1-DES",
32512                                                        "pbeWithSHA1AndDES-CBC"},
32513         { PBE_SHA1_DES3, PBE_SHA1_DES3, oidPBEType, "PBE-SHA1-3DES",
32514                                             "pbeWithSHA1And3-KeyTripleDES-CBC"},
32515     #endif
32516 
32517         /* oidKeyWrapType */
32518     #ifdef WOLFSSL_AES_128
32519         { AES128_WRAP, AES128_WRAP, oidKeyWrapType, "AES-128 wrap", "aes128-wrap"},
32520     #endif
32521     #ifdef WOLFSSL_AES_192
32522         { AES192_WRAP, AES192_WRAP, oidKeyWrapType, "AES-192 wrap", "aes192-wrap"},
32523     #endif
32524     #ifdef WOLFSSL_AES_256
32525         { AES256_WRAP, AES256_WRAP, oidKeyWrapType, "AES-256 wrap", "aes256-wrap"},
32526     #endif
32527 
32528     #ifndef NO_PKCS7
32529         #ifndef NO_DH
32530         /* oidCmsKeyAgreeType */
32531             #ifndef NO_SHA
32532         { dhSinglePass_stdDH_sha1kdf_scheme, dhSinglePass_stdDH_sha1kdf_scheme,
32533                 oidCmsKeyAgreeType, "dhSinglePass-stdDH-sha1kdf-scheme", "dhSinglePass-stdDH-sha1kdf-scheme"},
32534             #endif
32535             #ifdef WOLFSSL_SHA224
32536         { dhSinglePass_stdDH_sha224kdf_scheme,
32537                 dhSinglePass_stdDH_sha224kdf_scheme, oidCmsKeyAgreeType,
32538                 "dhSinglePass-stdDH-sha224kdf-scheme", "dhSinglePass-stdDH-sha224kdf-scheme"},
32539             #endif
32540             #ifndef NO_SHA256
32541         { dhSinglePass_stdDH_sha256kdf_scheme,
32542                         dhSinglePass_stdDH_sha256kdf_scheme, oidCmsKeyAgreeType,
32543                         "dhSinglePass-stdDH-sha256kdf-scheme", "dhSinglePass-stdDH-sha256kdf-scheme"},
32544             #endif
32545             #ifdef WOLFSSL_SHA384
32546         { dhSinglePass_stdDH_sha384kdf_scheme,
32547                         dhSinglePass_stdDH_sha384kdf_scheme, oidCmsKeyAgreeType,
32548                         "dhSinglePass-stdDH-sha384kdf-scheme", "dhSinglePass-stdDH-sha384kdf-scheme"},
32549             #endif
32550             #ifdef WOLFSSL_SHA512
32551         { dhSinglePass_stdDH_sha512kdf_scheme,
32552                         dhSinglePass_stdDH_sha512kdf_scheme, oidCmsKeyAgreeType,
32553                         "dhSinglePass-stdDH-sha512kdf-scheme", "dhSinglePass-stdDH-sha512kdf-scheme"},
32554             #endif
32555         #endif
32556     #endif
32557     #if defined(WOLFSSL_APACHE_HTTPD)
32558         /* "1.3.6.1.5.5.7.8.7" */
32559         { NID_id_on_dnsSRV, NID_id_on_dnsSRV, oidCertNameType,
32560             WOLFSSL_SN_DNS_SRV, WOLFSSL_LN_DNS_SRV },
32561 
32562         /* "1.3.6.1.4.1.311.20.2.3" */
32563         { NID_ms_upn, WOLFSSL_MS_UPN_SUM, oidCertExtType, WOLFSSL_SN_MS_UPN,
32564             WOLFSSL_LN_MS_UPN },
32565 
32566         /* "1.3.6.1.5.5.7.1.24" */
32567         { NID_tlsfeature, WOLFSSL_TLS_FEATURE_SUM, oidTlsExtType,
32568             WOLFSSL_SN_TLS_FEATURE, WOLFSSL_LN_TLS_FEATURE },
32569     #endif
32570 #endif /* OPENSSL_EXTRA */
32571 };
32572 
32573 #define WOLFSSL_OBJECT_INFO_SZ \
32574                 (sizeof(wolfssl_object_info) / sizeof(*wolfssl_object_info))
32575 const size_t wolfssl_object_info_sz = WOLFSSL_OBJECT_INFO_SZ;
32576 #endif
32577 #if defined(OPENSSL_EXTRA) && \
32578     !defined(NO_RSA) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
WOLFSSL_RSA_GetRNG(WOLFSSL_RSA * rsa,WC_RNG ** tmpRNG,int * initTmpRng)32579 WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG, int *initTmpRng)
32580 {
32581     WC_RNG* rng = NULL;
32582 
32583     if (!rsa || !initTmpRng) {
32584         return NULL;
32585     }
32586     *initTmpRng = 0;
32587 
32588 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \
32589     !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING)
32590     rng = ((RsaKey*)rsa->internal)->rng;
32591 #endif
32592     if (tmpRNG != NULL
32593     #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \
32594         !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING)
32595         && rng == NULL
32596     #endif
32597         ) {
32598         if (*tmpRNG == NULL) {
32599 #ifdef WOLFSSL_SMALL_STACK
32600             *tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
32601             if (*tmpRNG == NULL)
32602                 return NULL;
32603 #else
32604             WOLFSSL_MSG("*tmpRNG is null");
32605             return NULL;
32606 #endif
32607         }
32608 
32609         if (wc_InitRng(*tmpRNG) == 0) {
32610             rng = *tmpRNG;
32611             *initTmpRng = 1;
32612         }
32613         else {
32614             WOLFSSL_MSG("Bad RNG Init, trying global");
32615             if (initGlobalRNG == 0)
32616                 WOLFSSL_MSG("Global RNG no Init");
32617             else
32618                 rng = &globalRNG;
32619 #ifdef WOLFSSL_SMALL_STACK
32620             if (*tmpRNG)
32621                 XFREE(*tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
32622             *tmpRNG = NULL;
32623 #endif
32624         }
32625     }
32626     return rng;
32627 }
32628 #endif
32629 
32630 
32631 
32632 #ifdef OPENSSL_EXTRA
32633 
wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM * bn,WOLFSSL_ASN1_INTEGER * ai)32634 WOLFSSL_ASN1_INTEGER* wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM *bn, WOLFSSL_ASN1_INTEGER *ai)
32635 {
32636     WOLFSSL_ASN1_INTEGER* a;
32637     int len;
32638     const int extraTagSz = MAX_LENGTH_SZ + 1;
32639     byte intTag[MAX_LENGTH_SZ + 1];
32640     int idx = 0;
32641     WOLFSSL_ENTER("wolfSSL_BN_to_ASN1_INTEGER");
32642 
32643     if (ai == NULL) {
32644         a = wolfSSL_ASN1_INTEGER_new();
32645 
32646         if (a == NULL)
32647             return NULL;
32648 
32649         a->type = V_ASN1_INTEGER;
32650     }
32651     else {
32652         a = ai;
32653     }
32654     if (a) {
32655         if (wolfSSL_BN_is_negative(bn) && !wolfSSL_BN_is_zero(bn)) {
32656             a->type |= V_ASN1_NEG_INTEGER;
32657             a->negative = 1;
32658         }
32659 
32660         len = wolfSSL_BN_num_bytes(bn);
32661         if (len == 0)
32662             len = 1;
32663 
32664         /* allocate buffer */
32665         if (len + extraTagSz > (int)sizeof(a->intData)) {
32666             /* create new data buffer and copy over */
32667             a->data = (byte*)XMALLOC(len + extraTagSz, NULL,
32668                     DYNAMIC_TYPE_OPENSSL);
32669             if (a->data == NULL) {
32670                 if (a != ai)
32671                     wolfSSL_ASN1_INTEGER_free(a);
32672                 return NULL;
32673             }
32674             a->isDynamic = 1;
32675         }
32676         else {
32677             XMEMSET(a->intData, 0, sizeof(a->intData));
32678             a->data = a->intData;
32679         }
32680 
32681         /* populate data */
32682         if (wolfSSL_BN_is_zero(bn)) {
32683             a->data[0] = 0;
32684         }
32685         else {
32686             len = wolfSSL_BN_bn2bin(bn, a->data);
32687             if (len < 0) {
32688                 wolfSSL_ASN1_INTEGER_free(a);
32689                 return NULL;
32690             }
32691         }
32692         a->length = len;
32693 
32694         /* Write ASN tag */
32695         idx = SetASNInt(a->length, a->data[0], intTag);
32696         XMEMMOVE(a->data + idx, a->data, a->length);
32697         XMEMCPY(a->data, intTag, idx);
32698         a->dataMax = a->length += idx;
32699     }
32700 
32701     return a;
32702 }
32703 
32704 #ifdef OPENSSL_ALL
wolfSSL_ASN1_item_new(const WOLFSSL_ASN1_ITEM * tpl)32705 void *wolfSSL_ASN1_item_new(const WOLFSSL_ASN1_ITEM *tpl)
32706 {
32707     void *ret = NULL;
32708     const WOLFSSL_ASN1_TEMPLATE *member = NULL;
32709     size_t i;
32710     WOLFSSL_ENTER("wolfSSL_ASN1_item_new");
32711     if (!tpl) {
32712         return NULL;
32713     }
32714     if (!(ret = (void *)XMALLOC(tpl->size, NULL, DYNAMIC_TYPE_OPENSSL))) {
32715         return NULL;
32716     }
32717     XMEMSET(ret, 0, tpl->size);
32718     for (member = tpl->members, i = 0; i < tpl->mcount;
32719             member++, i++) {
32720         switch (member->type) {
32721             case WOLFSSL_X509_ALGOR_ASN1:
32722             {
32723                 WOLFSSL_X509_ALGOR* algor = wolfSSL_X509_ALGOR_new();
32724                 if (!algor) {
32725                     goto error;
32726                 }
32727                 *(WOLFSSL_X509_ALGOR**)(((byte*)ret) + member->offset) = algor;
32728                 break;
32729             }
32730             case WOLFSSL_ASN1_BIT_STRING_ASN1:
32731             {
32732                 WOLFSSL_ASN1_BIT_STRING* bit_str = wolfSSL_ASN1_BIT_STRING_new();
32733                 if (!bit_str) {
32734                     goto error;
32735                 }
32736                 *(WOLFSSL_ASN1_BIT_STRING**)(((byte*)ret) + member->offset) = bit_str;
32737                 break;
32738             }
32739             default:
32740                 WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_new");
32741                 goto error;
32742         }
32743     }
32744     return ret;
32745 error:
32746     wolfSSL_ASN1_item_free(ret, tpl);
32747     return NULL;
32748 }
32749 
wolfSSL_ASN1_item_free(void * val,const WOLFSSL_ASN1_ITEM * tpl)32750 void wolfSSL_ASN1_item_free(void *val, const WOLFSSL_ASN1_ITEM *tpl)
32751 {
32752     const WOLFSSL_ASN1_TEMPLATE *member = NULL;
32753     size_t i;
32754     WOLFSSL_ENTER("wolfSSL_ASN1_item_free");
32755     if (val) {
32756         for (member = tpl->members, i = 0; i < tpl->mcount;
32757                 member++, i++) {
32758             switch (member->type) {
32759                 case WOLFSSL_X509_ALGOR_ASN1:
32760                 {
32761                     WOLFSSL_X509_ALGOR* algor = *(WOLFSSL_X509_ALGOR**)
32762                                                  (((byte*)val) + member->offset);
32763                     if (algor) {
32764                         wolfSSL_X509_ALGOR_free(algor);
32765                     }
32766                     break;
32767                 }
32768                 case WOLFSSL_ASN1_BIT_STRING_ASN1:
32769                 {
32770                     WOLFSSL_ASN1_BIT_STRING* bit_str = *(WOLFSSL_ASN1_BIT_STRING**)
32771                                                         (((byte*)val) + member->offset);
32772                     if (bit_str) {
32773                         wolfSSL_ASN1_BIT_STRING_free(bit_str);
32774                     }
32775                     break;
32776                 }
32777                 default:
32778                     WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_free");
32779             }
32780         }
32781         XFREE(val, NULL, DYNAMIC_TYPE_OPENSSL);
32782     }
32783 }
32784 
32785 #define bufLenOrNull(buf, len) (buf ? buf + len : NULL)
32786 
i2dProcessMembers(const void * src,byte * buf,const WOLFSSL_ASN1_TEMPLATE * members,size_t mcount)32787 static int i2dProcessMembers(const void *src, byte *buf,
32788                           const WOLFSSL_ASN1_TEMPLATE *members, size_t mcount)
32789 {
32790     const WOLFSSL_ASN1_TEMPLATE *member = NULL;
32791     int len = 0, ret;
32792     size_t i;
32793     WOLFSSL_ENTER("processMembers");
32794     for (member = members, i = 0; i < mcount; member++, i++) {
32795         switch (member->type) {
32796             case WOLFSSL_X509_ALGOR_ASN1:
32797             {
32798                 word32 oid = 0;
32799                 word32 idx = 0;
32800                 const WOLFSSL_X509_ALGOR* algor = *(const WOLFSSL_X509_ALGOR**)
32801                                                    (((byte*)src) + member->offset);
32802                 if (!algor->algorithm) {
32803                     WOLFSSL_LEAVE("processMembers", WOLFSSL_FAILURE);
32804                     return WOLFSSL_FAILURE;
32805                 }
32806 
32807                 if (GetObjectId(algor->algorithm->obj, &idx, &oid,
32808                         algor->algorithm->grp, algor->algorithm->objSz) < 0) {
32809                     WOLFSSL_MSG("Issue getting OID of object");
32810                     return -1;
32811                 }
32812 
32813                 ret = SetAlgoID(oid, bufLenOrNull(buf, len),
32814                                 algor->algorithm->grp, 0);
32815                 if (!ret) {
32816                     return WOLFSSL_FAILURE;
32817                 }
32818                 len += ret;
32819                 break;
32820             }
32821             case WOLFSSL_ASN1_BIT_STRING_ASN1:
32822             {
32823                 const WOLFSSL_ASN1_BIT_STRING* bit_str;
32824                 bit_str = *(const WOLFSSL_ASN1_BIT_STRING**)
32825                            (((byte*)src) + member->offset);
32826                 len += SetBitString(bit_str->length, 0, bufLenOrNull(buf, len));
32827                 if (buf && bit_str->data) {
32828                     XMEMCPY(buf + len, bit_str->data, bit_str->length);
32829                 }
32830                 len += bit_str->length;
32831                 break;
32832             }
32833             default:
32834                 WOLFSSL_MSG("Type not support in processMembers");
32835                 WOLFSSL_LEAVE("processMembers", WOLFSSL_FAILURE);
32836                 return WOLFSSL_FAILURE;
32837         }
32838     }
32839     WOLFSSL_LEAVE("processMembers", len);
32840     return len;
32841 }
32842 
wolfSSL_ASN1_item_i2d(const void * src,byte ** dest,const WOLFSSL_ASN1_ITEM * tpl)32843 int wolfSSL_ASN1_item_i2d(const void *src, byte **dest,
32844                           const WOLFSSL_ASN1_ITEM *tpl)
32845 {
32846     int len = 0;
32847     byte *buf = NULL;
32848 
32849     WOLFSSL_ENTER("wolfSSL_ASN1_item_i2d");
32850 
32851     if (!src || !tpl) {
32852         WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", WOLFSSL_FAILURE);
32853         return WOLFSSL_FAILURE;
32854     }
32855 
32856     if (dest && !*dest) {
32857         len = wolfSSL_ASN1_item_i2d(src, NULL, tpl);
32858         if (!len) {
32859             goto error;
32860         }
32861         buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
32862         if (!buf) {
32863             goto error;
32864         }
32865         len = 0;
32866     }
32867 
32868     switch (tpl->type) {
32869         case ASN_SEQUENCE:
32870         {
32871             int seq_len = i2dProcessMembers(src, NULL, tpl->members,
32872                                          tpl->mcount);
32873             if (!seq_len) {
32874                 goto error;
32875             }
32876             len += SetSequence(seq_len, bufLenOrNull(buf, len));
32877             if (buf &&
32878                     i2dProcessMembers(src, bufLenOrNull(buf, len), tpl->members,
32879                                    tpl->mcount) != seq_len) {
32880                 WOLFSSL_MSG("Inconsistent sequence length");
32881                 goto error;
32882             }
32883             len += seq_len;
32884             break;
32885         }
32886         default:
32887             WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_i2d");
32888             goto error;
32889     }
32890 
32891     if (dest && !*dest) {
32892         *dest = buf;
32893     }
32894     else if (dest && *dest && buf) {
32895         /* *dest length is not checked because the user is responsible
32896          * for providing a long enough buffer */
32897         XMEMCPY(*dest, buf, len);
32898     }
32899 
32900     WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", len);
32901     return len;
32902 error:
32903     if (buf) {
32904         XFREE(buf, NULL, DYNAMIC_TYPE_ASN1);
32905     }
32906     WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", WOLFSSL_FAILURE);
32907     return WOLFSSL_FAILURE;
32908 }
32909 #endif /* OPENSSL_ALL */
32910 
32911 #ifndef NO_DH
32912 
InitwolfSSL_DH(WOLFSSL_DH * dh)32913 static void InitwolfSSL_DH(WOLFSSL_DH* dh)
32914 {
32915     if (dh) {
32916         XMEMSET(dh, 0, sizeof(WOLFSSL_DH));
32917     }
32918 }
32919 
32920 
wolfSSL_DH_new(void)32921 WOLFSSL_DH* wolfSSL_DH_new(void)
32922 {
32923     WOLFSSL_DH* external;
32924     DhKey*     key;
32925 
32926     WOLFSSL_ENTER("wolfSSL_DH_new");
32927 
32928     key = (DhKey*) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
32929     if (key == NULL) {
32930         WOLFSSL_MSG("wolfSSL_DH_new malloc DhKey failure");
32931         return NULL;
32932     }
32933 
32934     external = (WOLFSSL_DH*) XMALLOC(sizeof(WOLFSSL_DH), NULL,
32935                                     DYNAMIC_TYPE_DH);
32936     if (external == NULL) {
32937         WOLFSSL_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
32938         XFREE(key, NULL, DYNAMIC_TYPE_DH);
32939         return NULL;
32940     }
32941 
32942     InitwolfSSL_DH(external);
32943     if (wc_InitDhKey(key) != 0) {
32944         WOLFSSL_MSG("wolfSSL_DH_new InitDhKey failure");
32945         XFREE(key, NULL, DYNAMIC_TYPE_DH);
32946         XFREE(external, NULL, DYNAMIC_TYPE_DH);
32947         return NULL;
32948     }
32949     external->internal = key;
32950     external->priv_key = wolfSSL_BN_new();
32951     external->pub_key = wolfSSL_BN_new();
32952 
32953     return external;
32954 }
32955 
wolfSSL_DH_free(WOLFSSL_DH * dh)32956 void wolfSSL_DH_free(WOLFSSL_DH* dh)
32957 {
32958     WOLFSSL_ENTER("wolfSSL_DH_free");
32959 
32960     if (dh) {
32961         if (dh->internal) {
32962             wc_FreeDhKey((DhKey*)dh->internal);
32963             XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
32964             dh->internal = NULL;
32965         }
32966         wolfSSL_BN_free(dh->priv_key);
32967         wolfSSL_BN_free(dh->pub_key);
32968         wolfSSL_BN_free(dh->g);
32969         wolfSSL_BN_free(dh->p);
32970         wolfSSL_BN_free(dh->q);
32971         InitwolfSSL_DH(dh);  /* set back to NULLs for safety */
32972 
32973         XFREE(dh, NULL, DYNAMIC_TYPE_DH);
32974     }
32975 }
32976 
SetDhInternal(WOLFSSL_DH * dh)32977 int SetDhInternal(WOLFSSL_DH* dh)
32978 {
32979     int            ret = WOLFSSL_FATAL_ERROR;
32980     int            pSz = 1024;
32981     int            gSz = 1024;
32982 #ifdef WOLFSSL_DH_EXTRA
32983     int            privSz = 256; /* Up to 2048-bit */
32984     int            pubSz  = 256;
32985 #endif
32986 #ifdef WOLFSSL_SMALL_STACK
32987     unsigned char* p   = NULL;
32988     unsigned char* g   = NULL;
32989     #ifdef WOLFSSL_DH_EXTRA
32990         unsigned char* priv_key = NULL;
32991         unsigned char* pub_key = NULL;
32992     #endif
32993 #else
32994     unsigned char  p[1024];
32995     unsigned char  g[1024];
32996     #ifdef WOLFSSL_DH_EXTRA
32997         unsigned char priv_key[256];
32998         unsigned char pub_key[256];
32999     #endif
33000 #endif
33001 
33002     WOLFSSL_ENTER("SetDhInternal");
33003 
33004     if (dh == NULL || dh->p == NULL || dh->g == NULL)
33005         WOLFSSL_MSG("Bad function arguments");
33006     else if (wolfSSL_BN_bn2bin(dh->p, NULL) > pSz)
33007         WOLFSSL_MSG("Bad p internal size");
33008     else if (wolfSSL_BN_bn2bin(dh->g, NULL) > gSz)
33009         WOLFSSL_MSG("Bad g internal size");
33010 #ifdef WOLFSSL_DH_EXTRA
33011     else if (wolfSSL_BN_bn2bin(dh->priv_key, NULL) > privSz)
33012         WOLFSSL_MSG("Bad private key internal size");
33013     else if (wolfSSL_BN_bn2bin(dh->pub_key, NULL) > privSz)
33014         WOLFSSL_MSG("Bad public key internal size");
33015 #endif
33016     else {
33017     #ifdef WOLFSSL_SMALL_STACK
33018         p = (unsigned char*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33019         g = (unsigned char*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33020         #ifdef WOLFSSL_DH_EXTRA
33021             priv_key = (unsigned char*)XMALLOC(privSz, NULL,
33022                 DYNAMIC_TYPE_PRIVATE_KEY);
33023             pub_key  = (unsigned char*)XMALLOC(pubSz, NULL,
33024                 DYNAMIC_TYPE_PUBLIC_KEY);
33025         #endif
33026 
33027         if (p == NULL || g == NULL) {
33028             XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33029             XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33030             return ret;
33031         }
33032     #endif /* WOLFSSL_SMALL_STACK */
33033 
33034         /* Free so that mp_init's don't leak */
33035         wc_FreeDhKey((DhKey*)dh->internal);
33036 
33037     #ifdef WOLFSSL_DH_EXTRA
33038         privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv_key);
33039         pubSz  = wolfSSL_BN_bn2bin(dh->pub_key,  pub_key);
33040         if (privSz <= 0) {
33041             WOLFSSL_MSG("No private key size.");
33042         }
33043         if (pubSz <= 0) {
33044             WOLFSSL_MSG("No public key size.");
33045         }
33046         if (privSz > 0 || pubSz > 0) {
33047             ret = wc_DhImportKeyPair((DhKey*)dh->internal, priv_key, privSz,
33048                                      pub_key, pubSz);
33049             if (ret == 0) {
33050                 ret = WOLFSSL_SUCCESS;
33051             }
33052             else {
33053                 WOLFSSL_MSG("Failed setting private or public key.");
33054                 ret = WOLFSSL_FAILURE;
33055             }
33056         }
33057     #endif /* WOLFSSL_DH_EXTRA */
33058 
33059         pSz = wolfSSL_BN_bn2bin(dh->p, p);
33060         gSz = wolfSSL_BN_bn2bin(dh->g, g);
33061 
33062         if (pSz <= 0 || gSz <= 0)
33063             WOLFSSL_MSG("Bad BN2bin set");
33064         else if (wc_DhSetKey((DhKey*)dh->internal, p, pSz, g, gSz) < 0)
33065             WOLFSSL_MSG("Bad DH SetKey");
33066         else {
33067             dh->inSet = 1;
33068             ret = WOLFSSL_SUCCESS;
33069         }
33070 
33071     #ifdef WOLFSSL_SMALL_STACK
33072         XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33073         XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33074         #ifdef WOLFSSL_DH_EXTRA
33075             XFREE(priv_key, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
33076             XFREE(pub_key,  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33077         #endif
33078     #endif
33079     }
33080 
33081     return ret;
33082 }
33083 
33084 #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) \
33085     || defined(WOLFSSL_OPENSSH)) || defined(OPENSSL_EXTRA)
33086 
33087 #ifdef WOLFSSL_DH_EXTRA
wolfSSL_DH_dup(WOLFSSL_DH * dh)33088 WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh)
33089 {
33090     WOLFSSL_DH* ret = NULL;
33091 
33092     WOLFSSL_ENTER("wolfSSL_DH_dup");
33093 
33094     if (!dh) {
33095         WOLFSSL_MSG("Bad parameter");
33096         return NULL;
33097     }
33098 
33099     if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS){
33100         WOLFSSL_MSG("Bad DH set internal");
33101         return NULL;
33102     }
33103 
33104     if (!(ret = wolfSSL_DH_new())) {
33105         WOLFSSL_MSG("wolfSSL_DH_new error");
33106         return NULL;
33107     }
33108 
33109     if (wc_DhKeyCopy((DhKey*)dh->internal, (DhKey*)ret->internal) != MP_OKAY) {
33110         WOLFSSL_MSG("wc_DhKeyCopy error");
33111         wolfSSL_DH_free(ret);
33112         return NULL;
33113     }
33114     ret->inSet = 1;
33115 
33116     if (SetDhExternal(ret) != WOLFSSL_SUCCESS) {
33117         WOLFSSL_MSG("SetDhExternal error");
33118         wolfSSL_DH_free(ret);
33119         return NULL;
33120     }
33121 
33122     return ret;
33123 }
33124 #endif /* WOLFSSL_DH_EXTRA */
33125 
33126 /* Set the members of DhKey into WOLFSSL_DH
33127  * Specify elements to set via the 2nd parmeter
33128  */
SetDhExternal_ex(WOLFSSL_DH * dh,int elm)33129 int SetDhExternal_ex(WOLFSSL_DH *dh, int elm)
33130 {
33131     DhKey *key;
33132     WOLFSSL_MSG("Entering SetDhExternal_ex");
33133 
33134     if (dh == NULL || dh->internal == NULL) {
33135         WOLFSSL_MSG("dh key NULL error");
33136         return WOLFSSL_FATAL_ERROR;
33137     }
33138 
33139     key = (DhKey*)dh->internal;
33140 
33141     if (elm & ELEMENT_P) {
33142         if (SetIndividualExternal(&dh->p, &key->p) != WOLFSSL_SUCCESS) {
33143             WOLFSSL_MSG("dh param p error");
33144             return WOLFSSL_FATAL_ERROR;
33145         }
33146     }
33147     if (elm & ELEMENT_Q) {
33148         if (SetIndividualExternal(&dh->q, &key->q) != WOLFSSL_SUCCESS) {
33149             WOLFSSL_MSG("dh param q error");
33150             return WOLFSSL_FATAL_ERROR;
33151         }
33152     }
33153     if (elm & ELEMENT_G) {
33154         if (SetIndividualExternal(&dh->g, &key->g) != WOLFSSL_SUCCESS) {
33155             WOLFSSL_MSG("dh param g error");
33156             return WOLFSSL_FATAL_ERROR;
33157         }
33158     }
33159 #ifdef WOLFSSL_DH_EXTRA
33160     if (elm & ELEMENT_PRV) {
33161         if (SetIndividualExternal(&dh->priv_key, &key->priv) !=
33162                                                       WOLFSSL_SUCCESS) {
33163             WOLFSSL_MSG("No DH Private Key");
33164             return WOLFSSL_FATAL_ERROR;
33165         }
33166     }
33167     if (elm & ELEMENT_PUB) {
33168         if (SetIndividualExternal(&dh->pub_key, &key->pub) != WOLFSSL_SUCCESS) {
33169             WOLFSSL_MSG("No DH Public Key");
33170             return WOLFSSL_FATAL_ERROR;
33171         }
33172     }
33173 #endif /* WOLFSSL_DH_EXTRA */
33174 
33175     dh->exSet = 1;
33176 
33177     return WOLFSSL_SUCCESS;
33178 }
33179 /* Set the members of DhKey into WOLFSSL_DH
33180  * DhKey was populated from wc_DhKeyDecode
33181  * p, g, pub_key and pri_key are set.
33182  */
SetDhExternal(WOLFSSL_DH * dh)33183 int SetDhExternal(WOLFSSL_DH *dh)
33184 {
33185     int elements = ELEMENT_P | ELEMENT_G | ELEMENT_PUB | ELEMENT_PRV;
33186     WOLFSSL_MSG("Entering SetDhExternal");
33187     return SetDhExternal_ex(dh, elements);
33188 }
33189 #endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
33190 
33191 /* return code compliant with OpenSSL :
33192  *   DH prime size in bytes if success, 0 if error
33193  */
wolfSSL_DH_size(WOLFSSL_DH * dh)33194 int wolfSSL_DH_size(WOLFSSL_DH* dh)
33195 {
33196     WOLFSSL_MSG("wolfSSL_DH_size");
33197 
33198     if (dh == NULL)
33199         return WOLFSSL_FATAL_ERROR;
33200 
33201     return wolfSSL_BN_num_bytes(dh->p);
33202 }
33203 
33204 /* This sets a big number with the 768-bit prime from RFC 2409.
33205  *
33206  * bn  if not NULL then the big number structure is used. If NULL then a new
33207  *     big number structure is created.
33208  *
33209  * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
33210  */
wolfSSL_DH_768_prime(WOLFSSL_BIGNUM * bn)33211 WOLFSSL_BIGNUM* wolfSSL_DH_768_prime(WOLFSSL_BIGNUM* bn)
33212 {
33213     const char prm[] = {
33214         "FFFFFFFFFFFFFFFFC90FDAA22168C234"
33215         "C4C6628B80DC1CD129024E088A67CC74"
33216         "020BBEA63B139B22514A08798E3404DD"
33217         "EF9519B3CD3A431B302B0A6DF25F1437"
33218         "4FE1356D6D51C245E485B576625E7EC6"
33219         "F44C42E9A63A3620FFFFFFFFFFFFFFFF"
33220     };
33221 
33222     WOLFSSL_ENTER("wolfSSL_DH_768_prime");
33223 
33224     if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) {
33225         WOLFSSL_MSG("Error converting DH 768 prime to big number");
33226         return NULL;
33227     }
33228 
33229     return bn;
33230 }
33231 
33232 /* This sets a big number with the 1024-bit prime from RFC 2409.
33233  *
33234  * bn  if not NULL then the big number structure is used. If NULL then a new
33235  *     big number structure is created.
33236  *
33237  * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
33238  */
wolfSSL_DH_1024_prime(WOLFSSL_BIGNUM * bn)33239 WOLFSSL_BIGNUM* wolfSSL_DH_1024_prime(WOLFSSL_BIGNUM* bn)
33240 {
33241     const char prm[] = {
33242         "FFFFFFFFFFFFFFFFC90FDAA22168C234"
33243         "C4C6628B80DC1CD129024E088A67CC74"
33244         "020BBEA63B139B22514A08798E3404DD"
33245         "EF9519B3CD3A431B302B0A6DF25F1437"
33246         "4FE1356D6D51C245E485B576625E7EC6"
33247         "F44C42E9A637ED6B0BFF5CB6F406B7ED"
33248         "EE386BFB5A899FA5AE9F24117C4B1FE6"
33249         "49286651ECE65381FFFFFFFFFFFFFFFF"
33250     };
33251 
33252     WOLFSSL_ENTER("wolfSSL_DH_1024_prime");
33253 
33254     if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) {
33255         WOLFSSL_MSG("Error converting DH 1024 prime to big number");
33256         return NULL;
33257     }
33258 
33259     return bn;
33260 }
33261 
33262 /* This sets a big number with the 1536-bit prime from RFC 3526.
33263  *
33264  * bn  if not NULL then the big number structure is used. If NULL then a new
33265  *     big number structure is created.
33266  *
33267  * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
33268  */
wolfSSL_DH_1536_prime(WOLFSSL_BIGNUM * bn)33269 WOLFSSL_BIGNUM* wolfSSL_DH_1536_prime(WOLFSSL_BIGNUM* bn)
33270 {
33271     const char prm[] = {
33272         "FFFFFFFFFFFFFFFFC90FDAA22168C234"
33273         "C4C6628B80DC1CD129024E088A67CC74"
33274         "020BBEA63B139B22514A08798E3404DD"
33275         "EF9519B3CD3A431B302B0A6DF25F1437"
33276         "4FE1356D6D51C245E485B576625E7EC6"
33277         "F44C42E9A637ED6B0BFF5CB6F406B7ED"
33278         "EE386BFB5A899FA5AE9F24117C4B1FE6"
33279         "49286651ECE45B3DC2007CB8A163BF05"
33280         "98DA48361C55D39A69163FA8FD24CF5F"
33281         "83655D23DCA3AD961C62F356208552BB"
33282         "9ED529077096966D670C354E4ABC9804"
33283         "F1746C08CA237327FFFFFFFFFFFFFFFF"
33284     };
33285 
33286     WOLFSSL_ENTER("wolfSSL_DH_1536_prime");
33287 
33288     if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) {
33289         WOLFSSL_MSG("Error converting DH 1536 prime to big number");
33290         return NULL;
33291     }
33292 
33293     return bn;
33294 }
33295 
33296 /* This sets a big number with the 2048-bit prime from RFC 3526.
33297  *
33298  * bn  if not NULL then the big number structure is used. If NULL then a new
33299  *     big number structure is created.
33300  *
33301  * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
33302  */
wolfSSL_DH_2048_prime(WOLFSSL_BIGNUM * bn)33303 WOLFSSL_BIGNUM* wolfSSL_DH_2048_prime(WOLFSSL_BIGNUM* bn)
33304 {
33305     const char prm[] = {
33306         "FFFFFFFFFFFFFFFFC90FDAA22168C234"
33307         "C4C6628B80DC1CD129024E088A67CC74"
33308         "020BBEA63B139B22514A08798E3404DD"
33309         "EF9519B3CD3A431B302B0A6DF25F1437"
33310         "4FE1356D6D51C245E485B576625E7EC6"
33311         "F44C42E9A637ED6B0BFF5CB6F406B7ED"
33312         "EE386BFB5A899FA5AE9F24117C4B1FE6"
33313         "49286651ECE45B3DC2007CB8A163BF05"
33314         "98DA48361C55D39A69163FA8FD24CF5F"
33315         "83655D23DCA3AD961C62F356208552BB"
33316         "9ED529077096966D670C354E4ABC9804"
33317         "F1746C08CA18217C32905E462E36CE3B"
33318         "E39E772C180E86039B2783A2EC07A28F"
33319         "B5C55DF06F4C52C9DE2BCBF695581718"
33320         "3995497CEA956AE515D2261898FA0510"
33321         "15728E5A8AACAA68FFFFFFFFFFFFFFFF"
33322     };
33323 
33324     WOLFSSL_ENTER("wolfSSL_DH_2048_prime");
33325 
33326     if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) {
33327         WOLFSSL_MSG("Error converting DH 2048 prime to big number");
33328         return NULL;
33329     }
33330 
33331     return bn;
33332 }
33333 
33334 /* This sets a big number with the 3072-bit prime from RFC 3526.
33335  *
33336  * bn  if not NULL then the big number structure is used. If NULL then a new
33337  *     big number structure is created.
33338  *
33339  * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
33340  */
wolfSSL_DH_3072_prime(WOLFSSL_BIGNUM * bn)33341 WOLFSSL_BIGNUM* wolfSSL_DH_3072_prime(WOLFSSL_BIGNUM* bn)
33342 {
33343     const char prm[] = {
33344         "FFFFFFFFFFFFFFFFC90FDAA22168C234"
33345         "C4C6628B80DC1CD129024E088A67CC74"
33346         "020BBEA63B139B22514A08798E3404DD"
33347         "EF9519B3CD3A431B302B0A6DF25F1437"
33348         "4FE1356D6D51C245E485B576625E7EC6"
33349         "F44C42E9A637ED6B0BFF5CB6F406B7ED"
33350         "EE386BFB5A899FA5AE9F24117C4B1FE6"
33351         "49286651ECE45B3DC2007CB8A163BF05"
33352         "98DA48361C55D39A69163FA8FD24CF5F"
33353         "83655D23DCA3AD961C62F356208552BB"
33354         "9ED529077096966D670C354E4ABC9804"
33355         "F1746C08CA18217C32905E462E36CE3B"
33356         "E39E772C180E86039B2783A2EC07A28F"
33357         "B5C55DF06F4C52C9DE2BCBF695581718"
33358         "3995497CEA956AE515D2261898FA0510"
33359         "15728E5A8AAAC42DAD33170D04507A33"
33360         "A85521ABDF1CBA64ECFB850458DBEF0A"
33361         "8AEA71575D060C7DB3970F85A6E1E4C7"
33362         "ABF5AE8CDB0933D71E8C94E04A25619D"
33363         "CEE3D2261AD2EE6BF12FFA06D98A0864"
33364         "D87602733EC86A64521F2B18177B200C"
33365         "BBE117577A615D6C770988C0BAD946E2"
33366         "08E24FA074E5AB3143DB5BFCE0FD108E"
33367         "4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
33368     };
33369 
33370     WOLFSSL_ENTER("wolfSSL_DH_3072_prime");
33371 
33372     if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) {
33373         WOLFSSL_MSG("Error converting DH 3072 prime to big number");
33374         return NULL;
33375     }
33376 
33377     return bn;
33378 }
33379 
33380 /* This sets a big number with the 4096-bit prime from RFC 3526.
33381  *
33382  * bn  if not NULL then the big number structure is used. If NULL then a new
33383  *     big number structure is created.
33384  *
33385  * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
33386  */
wolfSSL_DH_4096_prime(WOLFSSL_BIGNUM * bn)33387 WOLFSSL_BIGNUM* wolfSSL_DH_4096_prime(WOLFSSL_BIGNUM* bn)
33388 {
33389     const char prm[] = {
33390         "FFFFFFFFFFFFFFFFC90FDAA22168C234"
33391         "C4C6628B80DC1CD129024E088A67CC74"
33392         "020BBEA63B139B22514A08798E3404DD"
33393         "EF9519B3CD3A431B302B0A6DF25F1437"
33394         "4FE1356D6D51C245E485B576625E7EC6"
33395         "F44C42E9A637ED6B0BFF5CB6F406B7ED"
33396         "EE386BFB5A899FA5AE9F24117C4B1FE6"
33397         "49286651ECE45B3DC2007CB8A163BF05"
33398         "98DA48361C55D39A69163FA8FD24CF5F"
33399         "83655D23DCA3AD961C62F356208552BB"
33400         "9ED529077096966D670C354E4ABC9804"
33401         "F1746C08CA18217C32905E462E36CE3B"
33402         "E39E772C180E86039B2783A2EC07A28F"
33403         "B5C55DF06F4C52C9DE2BCBF695581718"
33404         "3995497CEA956AE515D2261898FA0510"
33405         "15728E5A8AAAC42DAD33170D04507A33"
33406         "A85521ABDF1CBA64ECFB850458DBEF0A"
33407         "8AEA71575D060C7DB3970F85A6E1E4C7"
33408         "ABF5AE8CDB0933D71E8C94E04A25619D"
33409         "CEE3D2261AD2EE6BF12FFA06D98A0864"
33410         "D87602733EC86A64521F2B18177B200C"
33411         "BBE117577A615D6C770988C0BAD946E2"
33412         "08E24FA074E5AB3143DB5BFCE0FD108E"
33413         "4B82D120A92108011A723C12A787E6D7"
33414         "88719A10BDBA5B2699C327186AF4E23C"
33415         "1A946834B6150BDA2583E9CA2AD44CE8"
33416         "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
33417         "287C59474E6BC05D99B2964FA090C3A2"
33418         "233BA186515BE7ED1F612970CEE2D7AF"
33419         "B81BDD762170481CD0069127D5B05AA9"
33420         "93B4EA988D8FDDC186FFB7DC90A6C08F"
33421         "4DF435C934063199FFFFFFFFFFFFFFFF"
33422     };
33423 
33424     WOLFSSL_ENTER("wolfSSL_DH_4096_prime");
33425 
33426     if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) {
33427         WOLFSSL_MSG("Error converting DH 4096 prime to big number");
33428         return NULL;
33429     }
33430 
33431     return bn;
33432 }
33433 
33434 /* This sets a big number with the 6144-bit prime from RFC 3526.
33435  *
33436  * bn  if not NULL then the big number structure is used. If NULL then a new
33437  *     big number structure is created.
33438  *
33439  * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
33440  */
wolfSSL_DH_6144_prime(WOLFSSL_BIGNUM * bn)33441 WOLFSSL_BIGNUM* wolfSSL_DH_6144_prime(WOLFSSL_BIGNUM* bn)
33442 {
33443     const char prm[] = {
33444         "FFFFFFFFFFFFFFFFC90FDAA22168C234"
33445         "C4C6628B80DC1CD129024E088A67CC74"
33446         "020BBEA63B139B22514A08798E3404DD"
33447         "EF9519B3CD3A431B302B0A6DF25F1437"
33448         "4FE1356D6D51C245E485B576625E7EC6"
33449         "F44C42E9A637ED6B0BFF5CB6F406B7ED"
33450         "EE386BFB5A899FA5AE9F24117C4B1FE6"
33451         "49286651ECE45B3DC2007CB8A163BF05"
33452         "98DA48361C55D39A69163FA8FD24CF5F"
33453         "83655D23DCA3AD961C62F356208552BB"
33454         "9ED529077096966D670C354E4ABC9804"
33455         "F1746C08CA18217C32905E462E36CE3B"
33456         "E39E772C180E86039B2783A2EC07A28F"
33457         "B5C55DF06F4C52C9DE2BCBF695581718"
33458         "3995497CEA956AE515D2261898FA0510"
33459         "15728E5A8AAAC42DAD33170D04507A33"
33460         "A85521ABDF1CBA64ECFB850458DBEF0A"
33461         "8AEA71575D060C7DB3970F85A6E1E4C7"
33462         "ABF5AE8CDB0933D71E8C94E04A25619D"
33463         "CEE3D2261AD2EE6BF12FFA06D98A0864"
33464         "D87602733EC86A64521F2B18177B200C"
33465         "BBE117577A615D6C770988C0BAD946E2"
33466         "08E24FA074E5AB3143DB5BFCE0FD108E"
33467         "4B82D120A92108011A723C12A787E6D7"
33468         "88719A10BDBA5B2699C327186AF4E23C"
33469         "1A946834B6150BDA2583E9CA2AD44CE8"
33470         "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
33471         "287C59474E6BC05D99B2964FA090C3A2"
33472         "233BA186515BE7ED1F612970CEE2D7AF"
33473         "B81BDD762170481CD0069127D5B05AA9"
33474         "93B4EA988D8FDDC186FFB7DC90A6C08F"
33475         "4DF435C93402849236C3FAB4D27C7026"
33476         "C1D4DCB2602646DEC9751E763DBA37BD"
33477         "F8FF9406AD9E530EE5DB382F413001AE"
33478         "B06A53ED9027D831179727B0865A8918"
33479         "DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
33480         "DB7F1447E6CC254B332051512BD7AF42"
33481         "6FB8F401378CD2BF5983CA01C64B92EC"
33482         "F032EA15D1721D03F482D7CE6E74FEF6"
33483         "D55E702F46980C82B5A84031900B1C9E"
33484         "59E7C97FBEC7E8F323A97A7E36CC88BE"
33485         "0F1D45B7FF585AC54BD407B22B4154AA"
33486         "CC8F6D7EBF48E1D814CC5ED20F8037E0"
33487         "A79715EEF29BE32806A1D58BB7C5DA76"
33488         "F550AA3D8A1FBFF0EB19CCB1A313D55C"
33489         "DA56C9EC2EF29632387FE8D76E3C0468"
33490         "043E8F663F4860EE12BF2D5B0B7474D6"
33491         "E694F91E6DCC4024FFFFFFFFFFFFFFFF"
33492     };
33493 
33494     WOLFSSL_ENTER("wolfSSL_DH_6144_prime");
33495 
33496     if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) {
33497         WOLFSSL_MSG("Error converting DH 6144 prime to big number");
33498         return NULL;
33499     }
33500 
33501     return bn;
33502 }
33503 
33504 
33505 /* This sets a big number with the 8192-bit prime from RFC 3526.
33506  *
33507  * bn  if not NULL then the big number structure is used. If NULL then a new
33508  *     big number structure is created.
33509  *
33510  * Returns a WOLFSSL_BIGNUM structure on success and NULL with failure.
33511  */
wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM * bn)33512 WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn)
33513 {
33514     const char prm[] = {
33515         "FFFFFFFFFFFFFFFFC90FDAA22168C234"
33516         "C4C6628B80DC1CD129024E088A67CC74"
33517         "020BBEA63B139B22514A08798E3404DD"
33518         "EF9519B3CD3A431B302B0A6DF25F1437"
33519         "4FE1356D6D51C245E485B576625E7EC6"
33520         "F44C42E9A637ED6B0BFF5CB6F406B7ED"
33521         "EE386BFB5A899FA5AE9F24117C4B1FE6"
33522         "49286651ECE45B3DC2007CB8A163BF05"
33523         "98DA48361C55D39A69163FA8FD24CF5F"
33524         "83655D23DCA3AD961C62F356208552BB"
33525         "9ED529077096966D670C354E4ABC9804"
33526         "F1746C08CA18217C32905E462E36CE3B"
33527         "E39E772C180E86039B2783A2EC07A28F"
33528         "B5C55DF06F4C52C9DE2BCBF695581718"
33529         "3995497CEA956AE515D2261898FA0510"
33530         "15728E5A8AAAC42DAD33170D04507A33"
33531         "A85521ABDF1CBA64ECFB850458DBEF0A"
33532         "8AEA71575D060C7DB3970F85A6E1E4C7"
33533         "ABF5AE8CDB0933D71E8C94E04A25619D"
33534         "CEE3D2261AD2EE6BF12FFA06D98A0864"
33535         "D87602733EC86A64521F2B18177B200C"
33536         "BBE117577A615D6C770988C0BAD946E2"
33537         "08E24FA074E5AB3143DB5BFCE0FD108E"
33538         "4B82D120A92108011A723C12A787E6D7"
33539         "88719A10BDBA5B2699C327186AF4E23C"
33540         "1A946834B6150BDA2583E9CA2AD44CE8"
33541         "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
33542         "287C59474E6BC05D99B2964FA090C3A2"
33543         "233BA186515BE7ED1F612970CEE2D7AF"
33544         "B81BDD762170481CD0069127D5B05AA9"
33545         "93B4EA988D8FDDC186FFB7DC90A6C08F"
33546         "4DF435C93402849236C3FAB4D27C7026"
33547         "C1D4DCB2602646DEC9751E763DBA37BD"
33548         "F8FF9406AD9E530EE5DB382F413001AE"
33549         "B06A53ED9027D831179727B0865A8918"
33550         "DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
33551         "DB7F1447E6CC254B332051512BD7AF42"
33552         "6FB8F401378CD2BF5983CA01C64B92EC"
33553         "F032EA15D1721D03F482D7CE6E74FEF6"
33554         "D55E702F46980C82B5A84031900B1C9E"
33555         "59E7C97FBEC7E8F323A97A7E36CC88BE"
33556         "0F1D45B7FF585AC54BD407B22B4154AA"
33557         "CC8F6D7EBF48E1D814CC5ED20F8037E0"
33558         "A79715EEF29BE32806A1D58BB7C5DA76"
33559         "F550AA3D8A1FBFF0EB19CCB1A313D55C"
33560         "DA56C9EC2EF29632387FE8D76E3C0468"
33561         "043E8F663F4860EE12BF2D5B0B7474D6"
33562         "E694F91E6DBE115974A3926F12FEE5E4"
33563         "38777CB6A932DF8CD8BEC4D073B931BA"
33564         "3BC832B68D9DD300741FA7BF8AFC47ED"
33565         "2576F6936BA424663AAB639C5AE4F568"
33566         "3423B4742BF1C978238F16CBE39D652D"
33567         "E3FDB8BEFC848AD922222E04A4037C07"
33568         "13EB57A81A23F0C73473FC646CEA306B"
33569         "4BCBC8862F8385DDFA9D4B7FA2C087E8"
33570         "79683303ED5BDD3A062B3CF5B3A278A6"
33571         "6D2A13F83F44F82DDF310EE074AB6A36"
33572         "4597E899A0255DC164F31CC50846851D"
33573         "F9AB48195DED7EA1B1D510BD7EE74D73"
33574         "FAF36BC31ECFA268359046F4EB879F92"
33575         "4009438B481C6CD7889A002ED5EE382B"
33576         "C9190DA6FC026E479558E4475677E9AA"
33577         "9E3050E2765694DFC81F56E880B96E71"
33578         "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"
33579     };
33580 
33581     WOLFSSL_ENTER("wolfSSL_DH_8192_prime");
33582 
33583     if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) {
33584         WOLFSSL_MSG("Error converting DH 8192 prime to big number");
33585         return NULL;
33586     }
33587 
33588     return bn;
33589 }
33590 
33591 /* The functions inside the macro guard below are fine to use with FIPS provided
33592  * WOLFSSL_DH_EXTRA isn't defined. That define will cause SetDhInternal to have
33593  * a call to wc_DhImportKeyPair, which isn't defined in the FIPS v2 module. */
33594 #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && !defined(WOLFSSL_DH_EXTRA)) \
33595  || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
33596 /* return code compliant with OpenSSL :
33597  *   1 if success, 0 if error
33598  */
wolfSSL_DH_generate_key(WOLFSSL_DH * dh)33599 int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
33600 {
33601     int            ret    = WOLFSSL_FAILURE;
33602     word32         pubSz  = 0;
33603     word32         privSz = 0;
33604     int            initTmpRng = 0;
33605     WC_RNG*        rng    = NULL;
33606 #ifdef WOLFSSL_SMALL_STACK
33607     WC_RNG*        tmpRNG;
33608 #else
33609     WC_RNG         tmpRNG[1];
33610 #endif
33611     unsigned char* pub    = NULL;
33612     unsigned char* priv   = NULL;
33613 
33614     WOLFSSL_MSG("wolfSSL_DH_generate_key");
33615 
33616 #ifdef WOLFSSL_SMALL_STACK
33617     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
33618     if (tmpRNG == NULL) {
33619         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
33620         return ret;
33621     }
33622 #endif
33623 
33624     if (dh == NULL || dh->p == NULL || dh->g == NULL)
33625         WOLFSSL_MSG("Bad function arguments");
33626     else if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS)
33627             WOLFSSL_MSG("Bad DH set internal");
33628     else if (wc_InitRng(tmpRNG) == 0) {
33629         rng = tmpRNG;
33630         initTmpRng = 1;
33631     }
33632     else {
33633         WOLFSSL_MSG("Bad RNG Init, trying global");
33634         if (initGlobalRNG == 0)
33635             WOLFSSL_MSG("Global RNG no Init");
33636         else
33637             rng = &globalRNG;
33638     }
33639 
33640     if (rng) {
33641         pubSz = wolfSSL_BN_num_bytes(dh->p);
33642         if (dh->length) {
33643             privSz = dh->length/8; /* to bytes */
33644         } else {
33645             privSz = pubSz;
33646         }
33647         if (pubSz > 0) {
33648             pub = (unsigned char*)XMALLOC(pubSz,
33649                     NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33650         }
33651         if (privSz > 0) {
33652             priv = (unsigned char*)XMALLOC(privSz,
33653                     NULL, DYNAMIC_TYPE_PRIVATE_KEY);
33654         }
33655         PRIVATE_KEY_UNLOCK();
33656         if (pub == NULL || priv == NULL) {
33657             WOLFSSL_MSG("Unable to malloc memory");
33658         }
33659         else if (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv, &privSz,
33660                                                                pub, &pubSz) < 0)
33661             WOLFSSL_MSG("Bad wc_DhGenerateKeyPair");
33662         else {
33663             if (dh->pub_key)
33664                 wolfSSL_BN_free(dh->pub_key);
33665 
33666             dh->pub_key = wolfSSL_BN_new();
33667             if (dh->pub_key == NULL) {
33668                 WOLFSSL_MSG("Bad DH new pub");
33669             }
33670             if (dh->priv_key)
33671                 wolfSSL_BN_free(dh->priv_key);
33672 
33673             dh->priv_key = wolfSSL_BN_new();
33674 
33675             if (dh->priv_key == NULL) {
33676                 WOLFSSL_MSG("Bad DH new priv");
33677             }
33678 
33679             if (dh->pub_key && dh->priv_key) {
33680                if (wolfSSL_BN_bin2bn(pub, pubSz, dh->pub_key) == NULL)
33681                    WOLFSSL_MSG("Bad DH bn2bin error pub");
33682                else if (wolfSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL)
33683                    WOLFSSL_MSG("Bad DH bn2bin error priv");
33684                else
33685                    ret = WOLFSSL_SUCCESS;
33686             }
33687         }
33688         PRIVATE_KEY_LOCK();
33689     }
33690 
33691     if (initTmpRng)
33692         wc_FreeRng(tmpRNG);
33693 
33694 #ifdef WOLFSSL_SMALL_STACK
33695     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
33696 #endif
33697     XFREE(pub,    NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33698     XFREE(priv,   NULL, DYNAMIC_TYPE_PRIVATE_KEY);
33699 
33700     return ret;
33701 }
33702 
33703 
33704 /* return code compliant with OpenSSL :
33705  *   size of shared secret if success, -1 if error
33706  */
wolfSSL_DH_compute_key(unsigned char * key,const WOLFSSL_BIGNUM * otherPub,WOLFSSL_DH * dh)33707 int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub,
33708                           WOLFSSL_DH* dh)
33709 {
33710     int            ret    = WOLFSSL_FATAL_ERROR;
33711     word32         keySz  = 0;
33712     int            pubSz  = 1024;
33713     int            privSz = 1024;
33714 #ifdef WOLFSSL_SMALL_STACK
33715     unsigned char* pub;
33716     unsigned char* priv   = NULL;
33717 #else
33718     unsigned char  pub [1024];
33719     unsigned char  priv[1024];
33720 #endif
33721 
33722     WOLFSSL_MSG("wolfSSL_DH_compute_key");
33723 
33724 #ifdef WOLFSSL_SMALL_STACK
33725     pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33726     if (pub == NULL)
33727         return ret;
33728 
33729     priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
33730     if (priv == NULL) {
33731         XFREE(pub, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33732         return ret;
33733     }
33734 #endif
33735 
33736     if (dh == NULL || dh->priv_key == NULL || otherPub == NULL)
33737         WOLFSSL_MSG("Bad function arguments");
33738     else if ((keySz = (word32)DH_size(dh)) == 0)
33739         WOLFSSL_MSG("Bad DH_size");
33740     else if (wolfSSL_BN_bn2bin(dh->priv_key, NULL) > (int)privSz)
33741         WOLFSSL_MSG("Bad priv internal size");
33742     else if (wolfSSL_BN_bn2bin(otherPub, NULL) > (int)pubSz)
33743         WOLFSSL_MSG("Bad otherPub size");
33744     else {
33745         privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
33746         pubSz  = wolfSSL_BN_bn2bin(otherPub, pub);
33747         if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS){
33748             WOLFSSL_MSG("Bad DH set internal");
33749         }
33750         PRIVATE_KEY_UNLOCK();
33751         if (privSz <= 0 || pubSz <= 0)
33752             WOLFSSL_MSG("Bad BN2bin set");
33753         else if (wc_DhAgree((DhKey*)dh->internal, key, &keySz,
33754                             priv, privSz, pub, pubSz) < 0)
33755             WOLFSSL_MSG("wc_DhAgree failed");
33756         else
33757             ret = (int)keySz;
33758         PRIVATE_KEY_LOCK();
33759     }
33760 
33761 #ifdef WOLFSSL_SMALL_STACK
33762     XFREE(pub,  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
33763     XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
33764 #endif
33765 
33766     WOLFSSL_LEAVE("wolfSSL_DH_compute_key", ret);
33767 
33768     return ret;
33769 }
33770 
33771 
33772 #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
wolfSSL_DH_set_length(WOLFSSL_DH * dh,long len)33773 int wolfSSL_DH_set_length(WOLFSSL_DH *dh, long len)
33774 {
33775     WOLFSSL_ENTER("wolfSSL_DH_set_length");
33776 
33777     /* len is checked at generation */
33778     if (dh == NULL) {
33779         WOLFSSL_MSG("Bad function arguments");
33780         return WOLFSSL_FAILURE;
33781     }
33782 
33783     dh->length = (int)len;
33784     return WOLFSSL_SUCCESS;
33785 }
33786 
33787 /* ownership of p,q,and g get taken over by "dh" on success and should be free'd
33788  * with a call to wolfSSL_DH_free -- not individually.
33789  *
33790  * returns WOLFSSL_SUCCESS on success
33791  */
wolfSSL_DH_set0_pqg(WOLFSSL_DH * dh,WOLFSSL_BIGNUM * p,WOLFSSL_BIGNUM * q,WOLFSSL_BIGNUM * g)33792 int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p,
33793     WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g)
33794 {
33795     int ret;
33796     WOLFSSL_ENTER("wolfSSL_DH_set0_pqg");
33797 
33798     /* q can be NULL */
33799     if (dh == NULL || p == NULL || g == NULL) {
33800         WOLFSSL_MSG("Bad function arguments");
33801         return WOLFSSL_FAILURE;
33802     }
33803 
33804     /* free existing internal DH structure and recreate with new p / g */
33805     if (dh->inSet) {
33806         ret = wc_FreeDhKey((DhKey*)dh->internal);
33807         if (ret != 0) {
33808             WOLFSSL_MSG("Unable to free internal DH key");
33809             return WOLFSSL_FAILURE;
33810         }
33811     }
33812 
33813     wolfSSL_BN_free(dh->p);
33814     wolfSSL_BN_free(dh->q);
33815     wolfSSL_BN_free(dh->g);
33816 
33817     dh->p = p;
33818     dh->q = q;
33819     dh->g = g;
33820 
33821     ret = SetDhInternal(dh);
33822     if (ret != WOLFSSL_SUCCESS) {
33823         WOLFSSL_MSG("Unable to set internal DH key");
33824         dh->p = NULL;
33825         dh->q = NULL;
33826         dh->g = NULL;
33827         dh->inSet = 0;
33828         return WOLFSSL_FAILURE;
33829     }
33830 
33831     return WOLFSSL_SUCCESS;
33832 }
33833 #endif /* v1.1.0 or later */
33834 #endif /* !HAVE_FIPS || (HAVE_FIPS && !WOLFSSL_DH_EXTRA) ||
33835         * HAVE_FIPS_VERSION > 2 */
33836 
wolfSSL_DH_get0_key(const WOLFSSL_DH * dh,const WOLFSSL_BIGNUM ** pub_key,const WOLFSSL_BIGNUM ** priv_key)33837 void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh,
33838         const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key)
33839 {
33840     WOLFSSL_ENTER("wolfSSL_DH_get0_key");
33841 
33842     if (dh != NULL) {
33843         if (pub_key != NULL && dh->pub_key != NULL &&
33844                 wolfSSL_BN_is_zero(dh->pub_key) != WOLFSSL_SUCCESS)
33845             *pub_key = dh->pub_key;
33846         if (priv_key != NULL && dh->priv_key != NULL &&
33847                 wolfSSL_BN_is_zero(dh->priv_key) != WOLFSSL_SUCCESS)
33848             *priv_key = dh->priv_key;
33849     }
33850 }
33851 
wolfSSL_DH_set0_key(WOLFSSL_DH * dh,WOLFSSL_BIGNUM * pub_key,WOLFSSL_BIGNUM * priv_key)33852 int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key,
33853         WOLFSSL_BIGNUM *priv_key)
33854 {
33855     WOLFSSL_ENTER("wolfSSL_DH_set0_key");
33856 
33857     if (dh == NULL)
33858         return WOLFSSL_FAILURE;
33859 
33860     if (pub_key != NULL) {
33861         wolfSSL_BN_free(dh->pub_key);
33862         dh->pub_key = pub_key;
33863     }
33864 
33865     if (priv_key != NULL) {
33866         wolfSSL_BN_free(dh->priv_key);
33867         dh->priv_key = priv_key;
33868     }
33869 
33870     return SetDhInternal(dh);
33871 }
33872 
33873 #endif /* NO_DH */
33874 #endif /* OPENSSL_EXTRA */
33875 
33876 #if defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
33877     !defined(NO_STDIO_FILESYSTEM) && (!defined(NO_RSA) || !defined(NO_DSA))
33878 /* Print the number bn in hex with name field and indentation indent to file fp.
33879  * Used by wolfSSL_DSA_print_fp and wolfSSL_RSA_print_fp to print DSA and RSA
33880  * keys and parameters.
33881  */
PrintBNFieldFp(XFILE fp,int indent,const char * field,const WOLFSSL_BIGNUM * bn)33882 static int PrintBNFieldFp(XFILE fp, int indent, const char* field,
33883                           const WOLFSSL_BIGNUM* bn) {
33884     static const int HEX_INDENT = 4;
33885     static const int MAX_DIGITS_PER_LINE = 30;
33886 
33887     int ret = WOLFSSL_SUCCESS;
33888     int i = 0;
33889     char* buf = NULL;
33890 
33891     if (fp == XBADFILE || indent < 0 || field == NULL || bn == NULL) {
33892         ret = BAD_FUNC_ARG;
33893     }
33894 
33895     if (ret == WOLFSSL_SUCCESS) {
33896         buf = wolfSSL_BN_bn2hex(bn);
33897         if (buf == NULL) {
33898             ret = WOLFSSL_FAILURE;
33899         }
33900     }
33901     if (ret == WOLFSSL_SUCCESS) {
33902         XFPRINTF(fp, "%*s", indent, "");
33903         XFPRINTF(fp, "%s:\n", field);
33904         XFPRINTF(fp, "%*s", indent + HEX_INDENT, "");
33905         while (buf[i]) {
33906             if (i != 0) {
33907                 if (i % 2 == 0) {
33908                     XFPRINTF(fp, ":");
33909                 }
33910                 if (i % MAX_DIGITS_PER_LINE == 0) {
33911                     XFPRINTF(fp, "\n");
33912                     XFPRINTF(fp, "%*s", indent + HEX_INDENT, "");
33913                 }
33914             }
33915             XFPRINTF(fp, "%c", buf[i++]);
33916         }
33917         XFPRINTF(fp, "\n");
33918     }
33919 
33920     if (buf != NULL) {
33921         XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
33922     }
33923 
33924     return ret;
33925 }
33926 #endif /* OPENSSL_EXTRA && XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM
33927         * && (!NO_DSA || !NO_RSA)*/
33928 
33929 #ifndef NO_DSA
33930 #if defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
33931     !defined(NO_STDIO_FILESYSTEM)
33932 /* return code compliant with OpenSSL :
33933  *   1 if success, 0 if error
33934  */
wolfSSL_DSA_print_fp(XFILE fp,WOLFSSL_DSA * dsa,int indent)33935 int wolfSSL_DSA_print_fp(XFILE fp, WOLFSSL_DSA* dsa, int indent)
33936 {
33937     int ret = WOLFSSL_SUCCESS;
33938     int pBits;
33939 
33940     WOLFSSL_ENTER("wolfSSL_DSA_print_fp");
33941 
33942     if (fp == XBADFILE || dsa == NULL) {
33943         ret = WOLFSSL_FAILURE;
33944     }
33945 
33946     if (ret == WOLFSSL_SUCCESS && dsa->p != NULL) {
33947         pBits = wolfSSL_BN_num_bits(dsa->p);
33948         if (pBits == WOLFSSL_FAILURE) {
33949             ret = WOLFSSL_FAILURE;
33950         }
33951         else {
33952             XFPRINTF(fp, "%*s", indent, "");
33953             XFPRINTF(fp, "Private-Key: (%d bit)\n", pBits);
33954         }
33955     }
33956     if (ret == WOLFSSL_SUCCESS && dsa->priv_key != NULL) {
33957         ret = PrintBNFieldFp(fp, indent, "priv", dsa->priv_key);
33958     }
33959     if (ret == WOLFSSL_SUCCESS && dsa->pub_key != NULL) {
33960         ret = PrintBNFieldFp(fp, indent, "pub", dsa->pub_key);
33961     }
33962     if (ret == WOLFSSL_SUCCESS && dsa->p != NULL) {
33963         ret = PrintBNFieldFp(fp, indent, "P", dsa->p);
33964     }
33965     if (ret == WOLFSSL_SUCCESS && dsa->q != NULL) {
33966         ret = PrintBNFieldFp(fp, indent, "Q", dsa->q);
33967     }
33968     if (ret == WOLFSSL_SUCCESS && dsa->g != NULL) {
33969         ret = PrintBNFieldFp(fp, indent, "G", dsa->g);
33970     }
33971 
33972     WOLFSSL_LEAVE("wolfSSL_DSA_print_fp", ret);
33973 
33974     return ret;
33975 }
33976 #endif /* OPENSSL_EXTRA && XSNPRINTF && !NO_FILESYSTEM && NO_STDIO_FILESYSTEM */
33977 
33978 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
InitwolfSSL_DSA(WOLFSSL_DSA * dsa)33979 static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
33980 {
33981     if (dsa) {
33982         dsa->p        = NULL;
33983         dsa->q        = NULL;
33984         dsa->g        = NULL;
33985         dsa->pub_key  = NULL;
33986         dsa->priv_key = NULL;
33987         dsa->internal = NULL;
33988         dsa->inSet    = 0;
33989         dsa->exSet    = 0;
33990     }
33991 }
33992 
33993 
wolfSSL_DSA_new(void)33994 WOLFSSL_DSA* wolfSSL_DSA_new(void)
33995 {
33996     WOLFSSL_DSA* external;
33997     DsaKey*     key;
33998 
33999     WOLFSSL_MSG("wolfSSL_DSA_new");
34000 
34001     key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
34002     if (key == NULL) {
34003         WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
34004         return NULL;
34005     }
34006 
34007     external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
34008                                     DYNAMIC_TYPE_DSA);
34009     if (external == NULL) {
34010         WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
34011         XFREE(key, NULL, DYNAMIC_TYPE_DSA);
34012         return NULL;
34013     }
34014 
34015     InitwolfSSL_DSA(external);
34016     if (wc_InitDsaKey(key) != 0) {
34017         WOLFSSL_MSG("wolfSSL_DSA_new InitDsaKey failure");
34018         XFREE(key, NULL, DYNAMIC_TYPE_DSA);
34019         wolfSSL_DSA_free(external);
34020         return NULL;
34021     }
34022     external->internal = key;
34023 
34024     return external;
34025 }
34026 
34027 
wolfSSL_DSA_free(WOLFSSL_DSA * dsa)34028 void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
34029 {
34030     WOLFSSL_MSG("wolfSSL_DSA_free");
34031 
34032     if (dsa) {
34033         if (dsa->internal) {
34034             FreeDsaKey((DsaKey*)dsa->internal);
34035             XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
34036             dsa->internal = NULL;
34037         }
34038         wolfSSL_BN_free(dsa->priv_key);
34039         wolfSSL_BN_free(dsa->pub_key);
34040         wolfSSL_BN_free(dsa->g);
34041         wolfSSL_BN_free(dsa->q);
34042         wolfSSL_BN_free(dsa->p);
34043         InitwolfSSL_DSA(dsa);  /* set back to NULLs for safety */
34044 
34045         XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
34046 
34047         /* dsa = NULL, don't try to access or double free it */
34048     }
34049 }
34050 
34051 /* wolfSSL -> OpenSSL */
SetDsaExternal(WOLFSSL_DSA * dsa)34052 int SetDsaExternal(WOLFSSL_DSA* dsa)
34053 {
34054     DsaKey* key;
34055     WOLFSSL_MSG("Entering SetDsaExternal");
34056 
34057     if (dsa == NULL || dsa->internal == NULL) {
34058         WOLFSSL_MSG("dsa key NULL error");
34059         return WOLFSSL_FATAL_ERROR;
34060     }
34061 
34062     key = (DsaKey*)dsa->internal;
34063 
34064     if (SetIndividualExternal(&dsa->p, &key->p) != WOLFSSL_SUCCESS) {
34065         WOLFSSL_MSG("dsa p key error");
34066         return WOLFSSL_FATAL_ERROR;
34067     }
34068 
34069     if (SetIndividualExternal(&dsa->q, &key->q) != WOLFSSL_SUCCESS) {
34070         WOLFSSL_MSG("dsa q key error");
34071         return WOLFSSL_FATAL_ERROR;
34072     }
34073 
34074     if (SetIndividualExternal(&dsa->g, &key->g) != WOLFSSL_SUCCESS) {
34075         WOLFSSL_MSG("dsa g key error");
34076         return WOLFSSL_FATAL_ERROR;
34077     }
34078 
34079     if (SetIndividualExternal(&dsa->pub_key, &key->y) != WOLFSSL_SUCCESS) {
34080         WOLFSSL_MSG("dsa y key error");
34081         return WOLFSSL_FATAL_ERROR;
34082     }
34083 
34084     if (SetIndividualExternal(&dsa->priv_key, &key->x) != WOLFSSL_SUCCESS) {
34085         WOLFSSL_MSG("dsa x key error");
34086         return WOLFSSL_FATAL_ERROR;
34087     }
34088 
34089     dsa->exSet = 1;
34090 
34091     return WOLFSSL_SUCCESS;
34092 }
34093 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
34094 #endif /* !NO_DSA */
34095 
34096 #if !defined(NO_DSA) && defined(OPENSSL_EXTRA)
34097 /* Openssl -> WolfSSL */
SetDsaInternal(WOLFSSL_DSA * dsa)34098 int SetDsaInternal(WOLFSSL_DSA* dsa)
34099 {
34100     DsaKey* key;
34101     WOLFSSL_MSG("Entering SetDsaInternal");
34102 
34103     if (dsa == NULL || dsa->internal == NULL) {
34104         WOLFSSL_MSG("dsa key NULL error");
34105         return WOLFSSL_FATAL_ERROR;
34106     }
34107 
34108     key = (DsaKey*)dsa->internal;
34109 
34110     if (dsa->p != NULL &&
34111         SetIndividualInternal(dsa->p, &key->p) != WOLFSSL_SUCCESS) {
34112         WOLFSSL_MSG("rsa p key error");
34113         return WOLFSSL_FATAL_ERROR;
34114     }
34115 
34116     if (dsa->q != NULL &&
34117         SetIndividualInternal(dsa->q, &key->q) != WOLFSSL_SUCCESS) {
34118         WOLFSSL_MSG("rsa q key error");
34119         return WOLFSSL_FATAL_ERROR;
34120     }
34121 
34122     if (dsa->g != NULL &&
34123         SetIndividualInternal(dsa->g, &key->g) != WOLFSSL_SUCCESS) {
34124         WOLFSSL_MSG("rsa g key error");
34125         return WOLFSSL_FATAL_ERROR;
34126     }
34127 
34128     if (dsa->pub_key != NULL) {
34129         if (SetIndividualInternal(dsa->pub_key, &key->y) != WOLFSSL_SUCCESS) {
34130             WOLFSSL_MSG("rsa pub_key error");
34131             return WOLFSSL_FATAL_ERROR;
34132         }
34133 
34134         /* public key */
34135         key->type = DSA_PUBLIC;
34136     }
34137 
34138     if (dsa->priv_key != NULL) {
34139         if (SetIndividualInternal(dsa->priv_key, &key->x) != WOLFSSL_SUCCESS) {
34140             WOLFSSL_MSG("rsa priv_key error");
34141             return WOLFSSL_FATAL_ERROR;
34142         }
34143 
34144         /* private key */
34145         key->type = DSA_PRIVATE;
34146     }
34147 
34148     dsa->inSet = 1;
34149 
34150     return WOLFSSL_SUCCESS;
34151 }
34152 #endif /* !NO_DSA && OPENSSL_EXTRA */
34153 
34154 
34155 #ifdef OPENSSL_EXTRA
34156 #if !defined(NO_RSA)
34157 
34158 /* return wolfSSL native error codes. */
wolfSSL_RSA_generate_key_native(WOLFSSL_RSA * rsa,int bits,WOLFSSL_BIGNUM * bn,void * cb)34159 static int wolfSSL_RSA_generate_key_native(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn,
34160                                 void* cb)
34161 {
34162     int ret;
34163 
34164     (void)cb;
34165     (void)bn;
34166     (void)bits;
34167 
34168     WOLFSSL_ENTER("wolfSSL_RSA_generate_key_native");
34169 
34170     if (rsa == NULL || rsa->internal == NULL) {
34171         /* bit size checked during make key call */
34172         WOLFSSL_MSG("bad arguments");
34173         return BAD_FUNC_ARG;
34174     }
34175 
34176 #ifdef WOLFSSL_KEY_GEN
34177     {
34178     #ifdef WOLFSSL_SMALL_STACK
34179         WC_RNG* rng;
34180     #else
34181         WC_RNG  rng[1];
34182     #endif
34183 
34184     #ifdef WOLFSSL_SMALL_STACK
34185         rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
34186         if (rng == NULL)
34187             return MEMORY_E;
34188     #endif
34189 
34190         if ((ret = wc_InitRng(rng)) < 0)
34191             WOLFSSL_MSG("RNG init failed");
34192         else if ((ret = wc_MakeRsaKey((RsaKey*)rsa->internal, bits,
34193                     wolfSSL_BN_get_word(bn), rng)) != MP_OKAY)
34194             WOLFSSL_MSG("wc_MakeRsaKey failed");
34195         else if ((ret = SetRsaExternal(rsa)) != WOLFSSL_SUCCESS)
34196             WOLFSSL_MSG("SetRsaExternal failed");
34197         else {
34198             rsa->inSet = 1;
34199             ret = WOLFSSL_ERROR_NONE;
34200         }
34201 
34202         wc_FreeRng(rng);
34203     #ifdef WOLFSSL_SMALL_STACK
34204         XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
34205     #endif
34206     }
34207 #else
34208     WOLFSSL_MSG("No Key Gen built in");
34209     ret = NOT_COMPILED_IN;
34210 #endif
34211     return ret;
34212 }
34213 
34214 /* Generates a RSA key of length len
34215  *
34216  * len  length of RSA key i.e. 2048
34217  * e    e to use when generating RSA key
34218  * f    callback function for generation details
34219  * data user callback argument
34220  *
34221  * Note: Because of wc_MakeRsaKey an RSA key size generated can be slightly
34222  *       rounded down. For example generating a key of size 2999 with e =
34223  *       65537 will make a key of size 374 instead of 375.
34224  * Returns a new RSA key on success and NULL on failure
34225  */
wolfSSL_RSA_generate_key(int len,unsigned long e,void (* f)(int,int,void *),void * data)34226 WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long e,
34227                                       void(*f)(int, int, void*), void* data)
34228 {
34229     WOLFSSL_RSA*    rsa = NULL;
34230     WOLFSSL_BIGNUM* bn  = NULL;
34231 
34232     WOLFSSL_ENTER("wolfSSL_RSA_generate_key");
34233 
34234     (void)f;
34235     (void)data;
34236 
34237     if (len < 0) {
34238         WOLFSSL_MSG("Bad argument: length was less than 0");
34239         return NULL;
34240     }
34241 
34242     bn = wolfSSL_BN_new();
34243     if (bn == NULL) {
34244         WOLFSSL_MSG("Error creating big number");
34245         return NULL;
34246     }
34247 
34248     if (wolfSSL_BN_set_word(bn, e) != WOLFSSL_SUCCESS) {
34249         WOLFSSL_MSG("Error using e value");
34250         wolfSSL_BN_free(bn);
34251         return NULL;
34252     }
34253 
34254     rsa = wolfSSL_RSA_new();
34255     if (rsa == NULL) {
34256         WOLFSSL_MSG("memory error");
34257     }
34258     else {
34259 #ifdef HAVE_FIPS
34260         for (;;)
34261 #endif
34262         {
34263             int gen_ret = wolfSSL_RSA_generate_key_native(rsa, len, bn, NULL);
34264             if (gen_ret != WOLFSSL_ERROR_NONE) {
34265 #ifdef HAVE_FIPS
34266                 if (gen_ret == PRIME_GEN_E)
34267                     continue;
34268 #endif
34269                 wolfSSL_RSA_free(rsa);
34270                 rsa = NULL;
34271             }
34272 #ifdef HAVE_FIPS
34273             break;
34274 #endif
34275         }
34276     }
34277     wolfSSL_BN_free(bn);
34278 
34279     return rsa;
34280 }
34281 
34282 /* return compliant with OpenSSL
34283  *   1 if success, 0 if error
34284  */
wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA * rsa,int bits,WOLFSSL_BIGNUM * bn,void * cb)34285 int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn,
34286                                 void* cb)
34287 {
34288 #ifdef HAVE_FIPS
34289     for (;;)
34290 #endif
34291     {
34292         int gen_ret = wolfSSL_RSA_generate_key_native(rsa, bits, bn, cb);
34293         if (gen_ret == WOLFSSL_ERROR_NONE)
34294             return WOLFSSL_SUCCESS;
34295 #ifdef HAVE_FIPS
34296         else if (gen_ret == PRIME_GEN_E)
34297             continue;
34298 #endif
34299         else
34300             return WOLFSSL_FAILURE;
34301     }
34302 }
34303 #endif /* NO_RSA */
34304 
34305 #ifndef NO_DSA
34306 /* return code compliant with OpenSSL :
34307  *   1 if success, 0 if error
34308  */
wolfSSL_DSA_generate_key(WOLFSSL_DSA * dsa)34309 int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
34310 {
34311     int ret = WOLFSSL_FAILURE;
34312 
34313     WOLFSSL_ENTER("wolfSSL_DSA_generate_key");
34314 
34315     if (dsa == NULL || dsa->internal == NULL) {
34316         WOLFSSL_MSG("Bad arguments");
34317         return WOLFSSL_FAILURE;
34318     }
34319 
34320     if (dsa->inSet == 0) {
34321         WOLFSSL_MSG("No DSA internal set, do it");
34322 
34323         if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
34324             WOLFSSL_MSG("SetDsaInternal failed");
34325             return ret;
34326         }
34327     }
34328 
34329 #ifdef WOLFSSL_KEY_GEN
34330     {
34331         int initTmpRng = 0;
34332         WC_RNG *rng = NULL;
34333 #ifdef WOLFSSL_SMALL_STACK
34334         WC_RNG *tmpRNG;
34335 #else
34336         WC_RNG tmpRNG[1];
34337 #endif
34338 
34339 #ifdef WOLFSSL_SMALL_STACK
34340         tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
34341         if (tmpRNG == NULL)
34342             return WOLFSSL_FATAL_ERROR;
34343 #endif
34344         if (wc_InitRng(tmpRNG) == 0) {
34345             rng = tmpRNG;
34346             initTmpRng = 1;
34347         }
34348         else {
34349             WOLFSSL_MSG("Bad RNG Init, trying global");
34350             if (initGlobalRNG == 0)
34351                 WOLFSSL_MSG("Global RNG no Init");
34352             else
34353                 rng = &globalRNG;
34354         }
34355 
34356         if (rng) {
34357             if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY)
34358                 WOLFSSL_MSG("wc_MakeDsaKey failed");
34359             else if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS)
34360                 WOLFSSL_MSG("SetDsaExternal failed");
34361             else
34362                 ret = WOLFSSL_SUCCESS;
34363         }
34364 
34365         if (initTmpRng)
34366             wc_FreeRng(tmpRNG);
34367 
34368 #ifdef WOLFSSL_SMALL_STACK
34369         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
34370 #endif
34371     }
34372 #else /* WOLFSSL_KEY_GEN */
34373     WOLFSSL_MSG("No Key Gen built in");
34374 #endif
34375     return ret;
34376 }
34377 
34378 
34379 /* Returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
34380  */
wolfSSL_DSA_generate_parameters(int bits,unsigned char * seed,int seedLen,int * counterRet,unsigned long * hRet,WOLFSSL_BN_CB cb,void * CBArg)34381 WOLFSSL_DSA* wolfSSL_DSA_generate_parameters(int bits, unsigned char* seed,
34382         int seedLen, int* counterRet, unsigned long* hRet,
34383         WOLFSSL_BN_CB cb, void* CBArg)
34384 {
34385     WOLFSSL_DSA* dsa;
34386 
34387     WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters()");
34388 
34389     (void)cb;
34390     (void)CBArg;
34391     dsa = wolfSSL_DSA_new();
34392     if (dsa == NULL) {
34393         return NULL;
34394     }
34395 
34396     if (wolfSSL_DSA_generate_parameters_ex(dsa, bits, seed, seedLen,
34397                                   counterRet, hRet, NULL) != WOLFSSL_SUCCESS) {
34398         wolfSSL_DSA_free(dsa);
34399         return NULL;
34400     }
34401 
34402     return dsa;
34403 }
34404 
34405 
34406 /* return code compliant with OpenSSL :
34407  *   1 if success, 0 if error
34408  */
wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA * dsa,int bits,unsigned char * seed,int seedLen,int * counterRet,unsigned long * hRet,void * cb)34409 int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
34410                                        unsigned char* seed, int seedLen,
34411                                        int* counterRet,
34412                                        unsigned long* hRet, void* cb)
34413 {
34414     int ret = WOLFSSL_FAILURE;
34415 
34416     (void)bits;
34417     (void)seed;
34418     (void)seedLen;
34419     (void)counterRet;
34420     (void)hRet;
34421     (void)cb;
34422 
34423     WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters_ex");
34424 
34425     if (dsa == NULL || dsa->internal == NULL) {
34426         WOLFSSL_MSG("Bad arguments");
34427         return WOLFSSL_FAILURE;
34428     }
34429 
34430 #ifdef WOLFSSL_KEY_GEN
34431     {
34432         int initTmpRng = 0;
34433         WC_RNG *rng = NULL;
34434 #ifdef WOLFSSL_SMALL_STACK
34435         WC_RNG *tmpRNG;
34436 #else
34437         WC_RNG tmpRNG[1];
34438 #endif
34439 
34440 #ifdef WOLFSSL_SMALL_STACK
34441         tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
34442         if (tmpRNG == NULL)
34443             return WOLFSSL_FATAL_ERROR;
34444 #endif
34445         if (wc_InitRng(tmpRNG) == 0) {
34446             rng = tmpRNG;
34447             initTmpRng = 1;
34448         }
34449         else {
34450             WOLFSSL_MSG("Bad RNG Init, trying global");
34451             if (initGlobalRNG == 0)
34452                 WOLFSSL_MSG("Global RNG no Init");
34453             else
34454                 rng = &globalRNG;
34455         }
34456 
34457         if (rng) {
34458             if (wc_MakeDsaParameters(rng, bits,
34459                                      (DsaKey*)dsa->internal) != MP_OKAY)
34460                 WOLFSSL_MSG("wc_MakeDsaParameters failed");
34461             else if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS)
34462                 WOLFSSL_MSG("SetDsaExternal failed");
34463             else
34464                 ret = WOLFSSL_SUCCESS;
34465         }
34466 
34467         if (initTmpRng)
34468             wc_FreeRng(tmpRNG);
34469 
34470 #ifdef WOLFSSL_SMALL_STACK
34471         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
34472 #endif
34473     }
34474 #else /* WOLFSSL_KEY_GEN */
34475     WOLFSSL_MSG("No Key Gen built in");
34476 #endif
34477 
34478     return ret;
34479 }
34480 
wolfSSL_DSA_get0_pqg(const WOLFSSL_DSA * d,const WOLFSSL_BIGNUM ** p,const WOLFSSL_BIGNUM ** q,const WOLFSSL_BIGNUM ** g)34481 void wolfSSL_DSA_get0_pqg(const WOLFSSL_DSA *d, const WOLFSSL_BIGNUM **p,
34482         const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g)
34483 {
34484     WOLFSSL_ENTER("wolfSSL_DSA_get0_pqg");
34485     if (d != NULL) {
34486         if (p != NULL)
34487             *p = d->p;
34488         if (q != NULL)
34489             *q = d->q;
34490         if (g != NULL)
34491             *g = d->g;
34492     }
34493 }
34494 
wolfSSL_DSA_set0_pqg(WOLFSSL_DSA * d,WOLFSSL_BIGNUM * p,WOLFSSL_BIGNUM * q,WOLFSSL_BIGNUM * g)34495 int wolfSSL_DSA_set0_pqg(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *p,
34496         WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g)
34497 {
34498     WOLFSSL_ENTER("wolfSSL_DSA_set0_pqg");
34499     if (d == NULL || p == NULL || q == NULL || g == NULL) {
34500         WOLFSSL_MSG("Bad parameter");
34501         return WOLFSSL_FAILURE;
34502     }
34503     wolfSSL_BN_free(d->p);
34504     wolfSSL_BN_free(d->q);
34505     wolfSSL_BN_free(d->g);
34506     d->p = p;
34507     d->q = q;
34508     d->g = g;
34509     return WOLFSSL_SUCCESS;
34510 }
34511 
wolfSSL_DSA_get0_key(const WOLFSSL_DSA * d,const WOLFSSL_BIGNUM ** pub_key,const WOLFSSL_BIGNUM ** priv_key)34512 void wolfSSL_DSA_get0_key(const WOLFSSL_DSA *d,
34513         const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key)
34514 {
34515     WOLFSSL_ENTER("wolfSSL_DSA_get0_key");
34516     if (d != NULL) {
34517         if (pub_key != NULL)
34518             *pub_key = d->pub_key;
34519         if (priv_key != NULL)
34520             *priv_key = d->priv_key;
34521     }
34522 }
34523 
wolfSSL_DSA_set0_key(WOLFSSL_DSA * d,WOLFSSL_BIGNUM * pub_key,WOLFSSL_BIGNUM * priv_key)34524 int wolfSSL_DSA_set0_key(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *pub_key,
34525         WOLFSSL_BIGNUM *priv_key)
34526 {
34527     WOLFSSL_ENTER("wolfSSL_DSA_set0_key");
34528 
34529     /* The private key may be NULL */
34530     if (pub_key == NULL) {
34531         WOLFSSL_MSG("Bad parameter");
34532         return WOLFSSL_FAILURE;
34533     }
34534 
34535     wolfSSL_BN_free(d->pub_key);
34536     wolfSSL_BN_free(d->priv_key);
34537     d->pub_key = pub_key;
34538     d->priv_key = priv_key;
34539 
34540     return WOLFSSL_SUCCESS;
34541 }
34542 
wolfSSL_DSA_SIG_new(void)34543 WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void)
34544 {
34545     WOLFSSL_DSA_SIG* sig;
34546     WOLFSSL_ENTER("wolfSSL_DSA_SIG_new");
34547     sig = (WOLFSSL_DSA_SIG*)XMALLOC(sizeof(WOLFSSL_DSA_SIG), NULL, DYNAMIC_TYPE_OPENSSL);
34548     if (sig)
34549         XMEMSET(sig, 0, sizeof(WOLFSSL_DSA_SIG));
34550     return sig;
34551 }
34552 
wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG * sig)34553 void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig)
34554 {
34555     WOLFSSL_ENTER("wolfSSL_DSA_SIG_free");
34556     if (sig) {
34557         if (sig->r) {
34558             wolfSSL_BN_free(sig->r);
34559         }
34560         if (sig->s) {
34561             wolfSSL_BN_free(sig->s);
34562         }
34563         XFREE(sig, NULL, DYNAMIC_TYPE_OPENSSL);
34564     }
34565 }
34566 
wolfSSL_DSA_SIG_get0(const WOLFSSL_DSA_SIG * sig,const WOLFSSL_BIGNUM ** r,const WOLFSSL_BIGNUM ** s)34567 void wolfSSL_DSA_SIG_get0(const WOLFSSL_DSA_SIG *sig,
34568         const WOLFSSL_BIGNUM **r, const WOLFSSL_BIGNUM **s)
34569 {
34570     WOLFSSL_ENTER("wolfSSL_DSA_SIG_get0");
34571     if (sig != NULL) {
34572         *r = sig->r;
34573         *s = sig->s;
34574     }
34575 }
34576 
wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG * sig,WOLFSSL_BIGNUM * r,WOLFSSL_BIGNUM * s)34577 int wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG *sig, WOLFSSL_BIGNUM *r,
34578         WOLFSSL_BIGNUM *s)
34579 {
34580     WOLFSSL_ENTER("wolfSSL_DSA_SIG_set0");
34581     if (r == NULL || s == NULL) {
34582         WOLFSSL_MSG("Bad parameter");
34583         return WOLFSSL_FAILURE;
34584     }
34585 
34586     wolfSSL_BN_clear_free(sig->r);
34587     wolfSSL_BN_clear_free(sig->s);
34588     sig->r = r;
34589     sig->s = s;
34590 
34591     return WOLFSSL_SUCCESS;
34592 }
34593 
34594 #ifndef HAVE_SELFTEST
34595 /**
34596  *
34597  * @param sig The input signature to encode
34598  * @param out The output buffer. If *out is NULL then a new buffer is
34599  *            allocated. Otherwise the output is written to the buffer.
34600  * @return length on success and -1 on error
34601  */
wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG * sig,byte ** out)34602 int wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG *sig, byte **out)
34603 {
34604     /* Space for sequence + two asn ints */
34605     byte buf[MAX_SEQ_SZ + 2*(ASN_TAG_SZ + MAX_LENGTH_SZ + DSA_MAX_HALF_SIZE)];
34606     word32 bufLen = sizeof(buf);
34607 
34608     WOLFSSL_ENTER("wolfSSL_i2d_DSA_SIG");
34609 
34610     if (sig == NULL || sig->r == NULL || sig->s == NULL ||
34611             out == NULL) {
34612         WOLFSSL_MSG("Bad function arguments");
34613         return WOLFSSL_FATAL_ERROR;
34614     }
34615 
34616     if (StoreECC_DSA_Sig(buf, &bufLen,
34617             (mp_int*)sig->r->internal, (mp_int*)sig->s->internal) != 0) {
34618         WOLFSSL_MSG("StoreECC_DSA_Sig error");
34619         return WOLFSSL_FATAL_ERROR;
34620     }
34621 
34622     if (*out == NULL) {
34623         byte* tmp = (byte*)XMALLOC(bufLen, NULL, DYNAMIC_TYPE_ASN1);
34624         if (tmp == NULL) {
34625             WOLFSSL_MSG("malloc error");
34626             return WOLFSSL_FATAL_ERROR;
34627         }
34628         *out = tmp;
34629     }
34630 
34631     XMEMCPY(*out, buf, bufLen);
34632 
34633     return (int)bufLen;
34634 }
34635 
34636 /**
34637  * Same as wolfSSL_DSA_SIG_new but also initializes the internal bignums as well.
34638  * @return New WOLFSSL_DSA_SIG with r and s created as well
34639  */
wolfSSL_DSA_SIG_new_bn(void)34640 static WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new_bn(void)
34641 {
34642     WOLFSSL_DSA_SIG* ret;
34643 
34644     if ((ret = wolfSSL_DSA_SIG_new()) == NULL) {
34645         WOLFSSL_MSG("wolfSSL_DSA_SIG_new error");
34646         return NULL;
34647     }
34648 
34649     if ((ret->r = wolfSSL_BN_new()) == NULL) {
34650         WOLFSSL_MSG("wolfSSL_BN_new error");
34651         wolfSSL_DSA_SIG_free(ret);
34652         return NULL;
34653     }
34654 
34655     if ((ret->s = wolfSSL_BN_new()) == NULL) {
34656         WOLFSSL_MSG("wolfSSL_BN_new error");
34657         wolfSSL_DSA_SIG_free(ret);
34658         return NULL;
34659     }
34660 
34661     return ret;
34662 }
34663 
34664 /**
34665  * This parses a DER encoded ASN.1 structure. The ASN.1 encoding is:
34666  * ASN1_SEQUENCE
34667  *   ASN1_INTEGER (DSA r)
34668  *   ASN1_INTEGER (DSA s)
34669  * Alternatively, if the input is DSA_160_SIG_SIZE or DSA_256_SIG_SIZE in
34670  * length then this API interprets this as two unsigned binary numbers.
34671  * @param sig    If non-null then free'd first and then newly created
34672  *               WOLFSSL_DSA_SIG is assigned
34673  * @param pp     Input buffer that is moved forward on success
34674  * @param length Length of input buffer
34675  * @return Newly created WOLFSSL_DSA_SIG on success or NULL on failure
34676  */
wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG ** sig,const unsigned char ** pp,long length)34677 WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig,
34678         const unsigned char **pp, long length)
34679 {
34680     WOLFSSL_DSA_SIG* ret;
34681     mp_int* r;
34682     mp_int* s;
34683 
34684     WOLFSSL_ENTER("wolfSSL_d2i_DSA_SIG");
34685 
34686     if (pp == NULL || *pp == NULL || length < 0) {
34687         WOLFSSL_MSG("Bad function arguments");
34688         return NULL;
34689     }
34690 
34691     if ((ret = wolfSSL_DSA_SIG_new_bn()) == NULL) {
34692         WOLFSSL_MSG("wolfSSL_DSA_SIG_new_bn error");
34693         return NULL;
34694     }
34695 
34696     r = (mp_int*)ret->r->internal;
34697     s = (mp_int*)ret->s->internal;
34698 
34699     if (DecodeECC_DSA_Sig(*pp, (word32)length, r, s) != 0) {
34700         if (length == DSA_160_SIG_SIZE || length == DSA_256_SIG_SIZE) {
34701             /* Two raw numbers of length/2 size each */
34702             if (mp_read_unsigned_bin(r, *pp, (int)length/2) != 0) {
34703                 WOLFSSL_MSG("r mp_read_unsigned_bin error");
34704                 wolfSSL_DSA_SIG_free(ret);
34705                 return NULL;
34706             }
34707 
34708             if (mp_read_unsigned_bin(s, *pp + (length/2), (int)length/2) != 0) {
34709                 WOLFSSL_MSG("s mp_read_unsigned_bin error");
34710                 wolfSSL_DSA_SIG_free(ret);
34711                 return NULL;
34712             }
34713 
34714             *pp += length;
34715         }
34716         else {
34717             WOLFSSL_MSG("DecodeECC_DSA_Sig error");
34718             wolfSSL_DSA_SIG_free(ret);
34719             return NULL;
34720         }
34721     }
34722     else {
34723         /* DecodeECC_DSA_Sig success move pointer forward */
34724 #ifndef NO_STRICT_ECDSA_LEN
34725         *pp += length;
34726 #else
34727         {
34728             /* We need to figure out how much to move by ourselves */
34729             word32 idx = 0;
34730             int len = 0;
34731             if (GetSequence(*pp, &idx, &len, (word32)length) < 0) {
34732                 WOLFSSL_MSG("GetSequence error");
34733                 wolfSSL_DSA_SIG_free(ret);
34734                 return NULL;
34735             }
34736             *pp += len;
34737         }
34738 #endif
34739     }
34740 
34741     if (sig != NULL) {
34742         if (*sig != NULL)
34743             wolfSSL_DSA_SIG_free(*sig);
34744         *sig = ret;
34745     }
34746 
34747     return ret;
34748 }
34749 #endif
34750 
34751 /* return WOLFSSL_SUCCESS on success, < 0 otherwise */
wolfSSL_DSA_do_sign(const unsigned char * d,unsigned char * sigRet,WOLFSSL_DSA * dsa)34752 int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
34753                        WOLFSSL_DSA* dsa)
34754 {
34755     int     ret = WOLFSSL_FATAL_ERROR;
34756     int     initTmpRng = 0;
34757     WC_RNG* rng = NULL;
34758 #ifdef WOLFSSL_SMALL_STACK
34759     WC_RNG* tmpRNG = NULL;
34760 #else
34761     WC_RNG  tmpRNG[1];
34762 #endif
34763 
34764     WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
34765 
34766     if (d == NULL || sigRet == NULL || dsa == NULL) {
34767         WOLFSSL_MSG("Bad function arguments");
34768         return ret;
34769     }
34770 
34771     if (dsa->inSet == 0) {
34772         WOLFSSL_MSG("No DSA internal set, do it");
34773         if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
34774             WOLFSSL_MSG("SetDsaInternal failed");
34775             return ret;
34776         }
34777     }
34778 
34779 #ifdef WOLFSSL_SMALL_STACK
34780     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
34781     if (tmpRNG == NULL)
34782         return WOLFSSL_FATAL_ERROR;
34783 #endif
34784 
34785     if (wc_InitRng(tmpRNG) == 0) {
34786         rng = tmpRNG;
34787         initTmpRng = 1;
34788     }
34789     else {
34790         WOLFSSL_MSG("Bad RNG Init, trying global");
34791         if (initGlobalRNG == 0)
34792             WOLFSSL_MSG("Global RNG no Init");
34793         else
34794             rng = &globalRNG;
34795     }
34796 
34797     if (rng) {
34798         if (wc_DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0)
34799             WOLFSSL_MSG("DsaSign failed");
34800         else
34801             ret = WOLFSSL_SUCCESS;
34802     }
34803 
34804     if (initTmpRng)
34805         wc_FreeRng(tmpRNG);
34806 #ifdef WOLFSSL_SMALL_STACK
34807     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
34808 #endif
34809 
34810     return ret;
34811 }
34812 
34813 #ifndef HAVE_SELFTEST
wolfSSL_DSA_do_sign_ex(const unsigned char * digest,int inLen,WOLFSSL_DSA * dsa)34814 WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
34815                                         int inLen, WOLFSSL_DSA* dsa)
34816 {
34817     byte sigBin[DSA_MAX_SIG_SIZE];
34818     const byte *tmp = sigBin;
34819     int sigLen;
34820 
34821     WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex");
34822 
34823     if (!digest || !dsa || inLen != WC_SHA_DIGEST_SIZE) {
34824         WOLFSSL_MSG("Bad function arguments");
34825         return NULL;
34826     }
34827 
34828     if (wolfSSL_DSA_do_sign(digest, sigBin, dsa) != WOLFSSL_SUCCESS) {
34829         WOLFSSL_MSG("wolfSSL_DSA_do_sign error");
34830         return NULL;
34831     }
34832 
34833     if (dsa->internal == NULL) {
34834         WOLFSSL_MSG("dsa->internal is null");
34835         return NULL;
34836     }
34837 
34838     sigLen = mp_unsigned_bin_size(&((DsaKey*)dsa->internal)->q);
34839     if (sigLen <= 0) {
34840         WOLFSSL_MSG("mp_unsigned_bin_size error");
34841         return NULL;
34842     }
34843 
34844     /* 2 * sigLen for the two points r and s */
34845     return wolfSSL_d2i_DSA_SIG(NULL, &tmp, 2 * sigLen);
34846 }
34847 #endif /* !HAVE_SELFTEST */
34848 
wolfSSL_DSA_do_verify(const unsigned char * d,unsigned char * sig,WOLFSSL_DSA * dsa,int * dsacheck)34849 int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
34850                         WOLFSSL_DSA* dsa, int *dsacheck)
34851 {
34852     int    ret = WOLFSSL_FATAL_ERROR;
34853 
34854     WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
34855 
34856     if (d == NULL || sig == NULL || dsa == NULL) {
34857         WOLFSSL_MSG("Bad function arguments");
34858         return WOLFSSL_FATAL_ERROR;
34859     }
34860     if (dsa->inSet == 0)
34861     {
34862         WOLFSSL_MSG("No DSA internal set, do it");
34863 
34864         if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
34865             WOLFSSL_MSG("SetDsaInternal failed");
34866             return WOLFSSL_FATAL_ERROR;
34867         }
34868     }
34869 
34870     ret = DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck);
34871     if (ret != 0 || *dsacheck != 1) {
34872         WOLFSSL_MSG("DsaVerify failed");
34873         return ret;
34874     }
34875 
34876     return WOLFSSL_SUCCESS;
34877 }
34878 
34879 
wolfSSL_DSA_bits(const WOLFSSL_DSA * d)34880 int wolfSSL_DSA_bits(const WOLFSSL_DSA *d)
34881 {
34882     if (!d)
34883         return WOLFSSL_FAILURE;
34884     if (!d->exSet && SetDsaExternal((WOLFSSL_DSA*)d) != WOLFSSL_SUCCESS)
34885         return WOLFSSL_FAILURE;
34886     return wolfSSL_BN_num_bits(d->p);
34887 }
34888 
34889 #ifndef HAVE_SELFTEST
wolfSSL_DSA_do_verify_ex(const unsigned char * digest,int digest_len,WOLFSSL_DSA_SIG * sig,WOLFSSL_DSA * dsa)34890 int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len,
34891                              WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa)
34892 {
34893     int dsacheck, sz;
34894     byte sigBin[DSA_MAX_SIG_SIZE];
34895     byte* sigBinPtr = sigBin;
34896     DsaKey* key;
34897     int qSz;
34898 
34899     WOLFSSL_ENTER("wolfSSL_DSA_do_verify_ex");
34900 
34901     if (!digest || !sig || !dsa || digest_len != WC_SHA_DIGEST_SIZE) {
34902         WOLFSSL_MSG("Bad function arguments");
34903         return WOLFSSL_FAILURE;
34904     }
34905 
34906     if (!sig->r || !sig->s) {
34907         WOLFSSL_MSG("No signature found in DSA_SIG");
34908         return WOLFSSL_FAILURE;
34909     }
34910 
34911     if (dsa->inSet == 0) {
34912         WOLFSSL_MSG("No DSA internal set, do it");
34913         if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
34914             WOLFSSL_MSG("SetDsaInternal failed");
34915             return WOLFSSL_FAILURE;
34916         }
34917     }
34918 
34919     key = (DsaKey*)dsa->internal;
34920 
34921     if (key == NULL) {
34922         WOLFSSL_MSG("dsa->internal is null");
34923         return WOLFSSL_FAILURE;
34924     }
34925 
34926     qSz = mp_unsigned_bin_size(&key->q);
34927     if (qSz < 0 || qSz > DSA_MAX_HALF_SIZE) {
34928         WOLFSSL_MSG("mp_unsigned_bin_size error");
34929         return WOLFSSL_FAILURE;
34930     }
34931 
34932     /* read r */
34933     /* front pad with zeros */
34934     if ((sz = wolfSSL_BN_num_bytes(sig->r)) < 0 || sz > DSA_MAX_HALF_SIZE)
34935         return WOLFSSL_FAILURE;
34936     while (sz++ < qSz)
34937         *sigBinPtr++ = 0;
34938     if (wolfSSL_BN_bn2bin(sig->r, sigBinPtr) == WOLFSSL_FATAL_ERROR)
34939         return WOLFSSL_FAILURE;
34940 
34941     /* Move to s */
34942     sigBinPtr = sigBin + qSz;
34943 
34944     /* read s */
34945     /* front pad with zeros */
34946     if ((sz = wolfSSL_BN_num_bytes(sig->s)) < 0 || sz > DSA_MAX_HALF_SIZE)
34947         return WOLFSSL_FAILURE;
34948     while (sz++ < qSz)
34949         *sigBinPtr++ = 0;
34950     if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == WOLFSSL_FATAL_ERROR)
34951         return WOLFSSL_FAILURE;
34952 
34953     if (wolfSSL_DSA_do_verify(digest, sigBin, dsa, &dsacheck) != WOLFSSL_SUCCESS ||
34954             dsacheck != 1)
34955         return WOLFSSL_FAILURE;
34956 
34957     return WOLFSSL_SUCCESS;
34958 }
34959 #endif /* !HAVE_SELFTEST */
34960 
wolfSSL_i2d_DSAparams(const WOLFSSL_DSA * dsa,unsigned char ** out)34961 WOLFSSL_API int wolfSSL_i2d_DSAparams(const WOLFSSL_DSA* dsa,
34962     unsigned char** out)
34963 {
34964     int ret = 0;
34965     word32 derLen = 0;
34966     int preAllocated = 1;
34967     DsaKey* key = NULL;
34968 
34969     WOLFSSL_ENTER("wolfSSL_i2d_DSAparams");
34970 
34971     if (dsa == NULL || dsa->internal == NULL || out == NULL) {
34972         ret = BAD_FUNC_ARG;
34973     }
34974 
34975     if (ret == 0) {
34976         key = (DsaKey*)dsa->internal;
34977         ret = wc_DsaKeyToParamsDer_ex(key, NULL, &derLen);
34978         if (ret == LENGTH_ONLY_E) {
34979             ret = 0;
34980         }
34981     }
34982     if (ret == 0 && *out == NULL) {
34983         /* If we're allocating out for the caller, we don't increment out just
34984            past the end of the DER buffer. If out is already allocated, we do.
34985            (OpenSSL convention) */
34986         preAllocated = 0;
34987         *out = (unsigned char*)XMALLOC(derLen, key->heap, DYNAMIC_TYPE_OPENSSL);
34988         if (*out == NULL) {
34989             ret = MEMORY_E;
34990         }
34991     }
34992     if (ret == 0) {
34993         ret = wc_DsaKeyToParamsDer_ex(key, *out, &derLen);
34994     }
34995     if (ret >= 0 && preAllocated == 1) {
34996         *out += derLen;
34997     }
34998 
34999     if (ret < 0 && preAllocated == 0) {
35000         XFREE(*out, key->heap, DYNAMIC_TYPE_OPENSSL);
35001     }
35002 
35003     WOLFSSL_LEAVE("wolfSSL_i2d_DSAparams", ret);
35004 
35005     return ret;
35006 }
35007 
wolfSSL_d2i_DSAparams(WOLFSSL_DSA ** dsa,const unsigned char ** der,long derLen)35008 WOLFSSL_API WOLFSSL_DSA* wolfSSL_d2i_DSAparams(WOLFSSL_DSA** dsa,
35009     const unsigned char** der, long derLen)
35010 {
35011     WOLFSSL_DSA* ret = NULL;
35012     int err = 0;
35013     word32 idx = 0;
35014     int asnLen;
35015     DsaKey* internalKey = NULL;
35016 
35017     WOLFSSL_ENTER("wolfSSL_d2i_DSAparams");
35018 
35019     if (der == NULL || *der == NULL || derLen <= 0) {
35020         err = 1;
35021     }
35022     if (err == 0) {
35023         ret = wolfSSL_DSA_new();
35024         err = ret == NULL;
35025     }
35026     if (err == 0) {
35027         err = GetSequence(*der, &idx, &asnLen, (word32)derLen) <= 0;
35028     }
35029     if (err == 0) {
35030         internalKey = (DsaKey*)ret->internal;
35031         err = GetInt(&internalKey->p, *der, &idx, (word32)derLen) != 0;
35032     }
35033     if (err == 0) {
35034         err = GetInt(&internalKey->q, *der, &idx, (word32)derLen) != 0;
35035     }
35036     if (err == 0) {
35037         err = GetInt(&internalKey->g, *der, &idx, (word32)derLen) != 0;
35038     }
35039     if (err == 0) {
35040         err = SetIndividualExternal(&ret->p, &internalKey->p)
35041                 != WOLFSSL_SUCCESS;
35042     }
35043     if (err == 0) {
35044         err = SetIndividualExternal(&ret->q, &internalKey->q)
35045                 != WOLFSSL_SUCCESS;
35046     }
35047     if (err == 0) {
35048         err = SetIndividualExternal(&ret->g, &internalKey->g)
35049                 != WOLFSSL_SUCCESS;
35050     }
35051     if (err == 0 && dsa != NULL) {
35052         *dsa = ret;
35053     }
35054 
35055     if (err != 0 && ret != NULL) {
35056         wolfSSL_DSA_free(ret);
35057         ret = NULL;
35058     }
35059 
35060     return ret;
35061 }
35062 #endif /* NO_DSA */
35063 
35064 #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
35065 
35066 #ifdef DEBUG_SIGN
DEBUG_SIGN_msg(const char * title,const unsigned char * out,unsigned int outlen)35067 static void DEBUG_SIGN_msg(const char *title, const unsigned char *out, unsigned int outlen)
35068 {
35069     const unsigned char *pt;
35070     printf("%s[%d] = \n", title, (int)outlen);
35071     outlen = outlen>100?100:outlen;
35072     for (pt = out; pt < out + outlen;
35073             printf("%c", ((*pt)&0x6f)>='A'?((*pt)&0x6f):'.'), pt++);
35074     printf("\n");
35075 }
35076 #else
35077 #define DEBUG_SIGN_msg(a,b,c)
35078 #endif
35079 
nid2HashSum(int type)35080 static int nid2HashSum(int type) {
35081     switch (type) {
35082     #ifdef WOLFSSL_MD2
35083         case NID_md2:       type = MD2h;    break;
35084     #endif
35085     #ifndef NO_MD5
35086         case NID_md5:       type = MD5h;    break;
35087     #endif
35088     #ifndef NO_SHA
35089         case NID_sha1:      type = SHAh;    break;
35090     #endif
35091     #ifndef NO_SHA256
35092         case NID_sha256:    type = SHA256h; break;
35093     #endif
35094     #ifdef WOLFSSL_SHA384
35095         case NID_sha384:    type = SHA384h; break;
35096     #endif
35097     #ifdef WOLFSSL_SHA512
35098         case NID_sha512:    type = SHA512h; break;
35099     #endif
35100     #ifndef WOLFSSL_NOSHA3_224
35101         case NID_sha3_224:  type = SHA3_224h; break;
35102     #endif
35103     #ifndef WOLFSSL_NOSHA3_256
35104         case NID_sha3_256:  type = SHA3_256h; break;
35105     #endif
35106     #ifndef WOLFSSL_NOSHA3_384
35107         case NID_sha3_384:  type = SHA3_384h; break;
35108     #endif
35109     #ifndef WOLFSSL_NOSHA3_512
35110         case NID_sha3_512:  type = SHA3_512h; break;
35111     #endif
35112         default:
35113             WOLFSSL_MSG("This NID (md type) not configured or not implemented");
35114             return 0;
35115     }
35116     return type;
35117 }
35118 
35119 /* return WOLFSSL_SUCCESS on ok, 0 otherwise */
wolfSSL_RSA_sign(int type,const unsigned char * m,unsigned int mLen,unsigned char * sigRet,unsigned int * sigLen,WOLFSSL_RSA * rsa)35120 int wolfSSL_RSA_sign(int type, const unsigned char* m,
35121                            unsigned int mLen, unsigned char* sigRet,
35122                            unsigned int* sigLen, WOLFSSL_RSA* rsa)
35123 {
35124     return wolfSSL_RSA_sign_ex(type, m, mLen, sigRet, sigLen, rsa, 1);
35125 }
35126 
wolfSSL_RSA_sign_ex(int type,const unsigned char * m,unsigned int mLen,unsigned char * sigRet,unsigned int * sigLen,WOLFSSL_RSA * rsa,int flag)35127 int wolfSSL_RSA_sign_ex(int type, const unsigned char* m,
35128                            unsigned int mLen, unsigned char* sigRet,
35129                            unsigned int* sigLen, WOLFSSL_RSA* rsa, int flag)
35130 {
35131     return wolfSSL_RSA_sign_generic_padding(type, m, mLen, sigRet, sigLen,
35132             rsa, flag, RSA_PKCS1_PADDING);
35133 }
35134 
35135 /**
35136  * Sign a message with the chosen message digest, padding, and RSA key.
35137  * @param type      Hash NID
35138  * @param m         Message to sign. Most likely this will be the digest of
35139  *                  the message to sign
35140  * @param mLen      Length of message to sign
35141  * @param sigRet    Output buffer
35142  * @param sigLen    On Input: length of sigRet buffer
35143  *                  On Output: length of data written to sigRet
35144  * @param rsa       RSA key used to sign the input
35145  * @param flag      1: Output the signature
35146  *                  0: Output the value that the unpadded signature should be
35147  *                     compared to. Note: for RSA_PKCS1_PSS_PADDING the
35148  *                     wc_RsaPSS_CheckPadding_ex function should be used to check
35149  *                     the output of a *Verify* function.
35150  * @param padding   Padding to use. Only RSA_PKCS1_PSS_PADDING and
35151  *                  RSA_PKCS1_PADDING are currently supported for signing.
35152  * @return          WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
35153  */
wolfSSL_RSA_sign_generic_padding(int type,const unsigned char * m,unsigned int mLen,unsigned char * sigRet,unsigned int * sigLen,WOLFSSL_RSA * rsa,int flag,int padding)35154 int wolfSSL_RSA_sign_generic_padding(int type, const unsigned char* m,
35155                            unsigned int mLen, unsigned char* sigRet,
35156                            unsigned int* sigLen, WOLFSSL_RSA* rsa, int flag,
35157                            int padding)
35158 {
35159     word32  outLen;
35160     word32  signSz;
35161     int     initTmpRng = 0;
35162     WC_RNG* rng        = NULL;
35163     int     ret        = 0;
35164 #ifdef WOLFSSL_SMALL_STACK
35165     WC_RNG* tmpRNG     = NULL;
35166     byte*   encodedSig = NULL;
35167 #else
35168     WC_RNG  tmpRNG[1];
35169     byte    encodedSig[MAX_ENCODED_SIG_SZ];
35170 #endif
35171 
35172     WOLFSSL_ENTER("wolfSSL_RSA_sign_generic_padding");
35173 
35174     if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL) {
35175         WOLFSSL_MSG("Bad function arguments");
35176         return WOLFSSL_FAILURE;
35177     }
35178     DEBUG_SIGN_msg("Message to Sign", m, mLen);
35179 
35180     if (rsa->inSet == 0) {
35181         WOLFSSL_MSG("No RSA internal set, do it");
35182 
35183         if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
35184             WOLFSSL_MSG("SetRsaInternal failed");
35185             return WOLFSSL_FAILURE;
35186         }
35187     }
35188 
35189     type = nid2HashSum(type);
35190 
35191     outLen = (word32)wolfSSL_BN_num_bytes(rsa->n);
35192 
35193 #ifdef WOLFSSL_SMALL_STACK
35194     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
35195     if (tmpRNG == NULL)
35196         return WOLFSSL_FAILURE;
35197 
35198     encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
35199                                                    DYNAMIC_TYPE_SIGNATURE);
35200     if (encodedSig == NULL) {
35201         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
35202         return WOLFSSL_FAILURE;
35203     }
35204 #endif
35205 
35206     if (outLen == 0) {
35207         WOLFSSL_MSG("Bad RSA size");
35208     }
35209     else if (wc_InitRng(tmpRNG) == 0) {
35210         rng = tmpRNG;
35211         initTmpRng = 1;
35212     }
35213     else {
35214         WOLFSSL_MSG("Bad RNG Init, trying global");
35215 
35216         if (initGlobalRNG == 0)
35217             WOLFSSL_MSG("Global RNG no Init");
35218         else
35219             rng = &globalRNG;
35220     }
35221 
35222     if (rng) {
35223         if (flag != 0) {
35224             switch (padding) {
35225 #ifdef WC_RSA_NO_PADDING
35226             case RSA_NO_PADDING:
35227                 WOLFSSL_MSG("RSA_NO_PADDING not supported for signing");
35228                 ret = BAD_FUNC_ARG;
35229                 break;
35230 #endif
35231 #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && defined(WC_RSA_PSS)
35232             case RSA_PKCS1_PSS_PADDING:
35233             {
35234                 enum wc_HashType hType = wc_OidGetHash(type);
35235 #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
35236                 WOLFSSL_MSG("Using RSA-PSS with hash length salt. "
35237                             "OpenSSL uses max length by default.");
35238 #endif
35239                 ret = wc_RsaPSS_Sign_ex(m, mLen, sigRet, outLen,
35240                         hType, wc_hash2mgf(hType),
35241 #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
35242                         RSA_PSS_SALT_LEN_DEFAULT,
35243 #else
35244                         RSA_PSS_SALT_LEN_DISCOVER,
35245 #endif
35246                         (RsaKey*)rsa->internal, rng);
35247                 break;
35248             }
35249 #endif
35250 #ifndef WC_NO_RSA_OAEP
35251             case RSA_PKCS1_OAEP_PADDING:
35252             {
35253                 WOLFSSL_MSG("RSA_PKCS1_OAEP_PADDING not supported for signing");
35254                 ret = BAD_FUNC_ARG;
35255                 break;
35256             }
35257 #endif
35258             case RSA_PKCS1_PADDING:
35259                 signSz = wc_EncodeSignature(encodedSig, m, mLen, type);
35260                 if (signSz == 0) {
35261                     WOLFSSL_MSG("Bad Encode Signature");
35262                 }
35263                 DEBUG_SIGN_msg("Encoded Message", encodedSig, signSz);
35264                 ret = wc_RsaSSL_Sign(encodedSig, signSz, sigRet, outLen,
35265                                 (RsaKey*)rsa->internal, rng);
35266                 break;
35267             default:
35268                 WOLFSSL_MSG("Unsupported padding");
35269                 ret = BAD_FUNC_ARG;
35270                 break;
35271             }
35272             if (ret <= 0) {
35273                 WOLFSSL_MSG("Bad Rsa Sign");
35274                 ret = 0;
35275             }
35276             else {
35277                 *sigLen = (unsigned int)ret;
35278                 ret = WOLFSSL_SUCCESS;
35279                 DEBUG_SIGN_msg("Signature", sigRet, *sigLen);
35280             }
35281         } else {
35282             switch (padding) {
35283             case RSA_NO_PADDING:
35284             case RSA_PKCS1_PSS_PADDING:
35285             case RSA_PKCS1_OAEP_PADDING:
35286                 ret = WOLFSSL_SUCCESS;
35287                 XMEMCPY(sigRet, m, mLen);
35288                 *sigLen = mLen;
35289                 break;
35290             case RSA_PKCS1_PADDING:
35291             default:
35292                 signSz = wc_EncodeSignature(encodedSig, m, mLen, type);
35293                 if (signSz == 0) {
35294                     WOLFSSL_MSG("Bad Encode Signature");
35295                 }
35296                 ret = WOLFSSL_SUCCESS;
35297                 XMEMCPY(sigRet, encodedSig, signSz);
35298                 *sigLen = signSz;
35299                 break;
35300             }
35301         }
35302     }
35303 
35304     if (initTmpRng)
35305         wc_FreeRng(tmpRNG);
35306 
35307 #ifdef WOLFSSL_SMALL_STACK
35308     XFREE(tmpRNG,     NULL, DYNAMIC_TYPE_RNG);
35309     XFREE(encodedSig, NULL, DYNAMIC_TYPE_SIGNATURE);
35310 #endif
35311 
35312     if (ret == WOLFSSL_SUCCESS) {
35313         WOLFSSL_MSG("wolfSSL_RSA_sign_generic_padding success");
35314     }
35315     else {
35316         WOLFSSL_LEAVE("wolfSSL_RSA_sign_generic_padding", ret);
35317         WOLFSSL_MSG("wolfSSL_RSA_sign_generic_padding failed. "
35318                     "Returning WOLFSSL_FAILURE.");
35319         ret = WOLFSSL_FAILURE;
35320     }
35321     return ret;
35322 }
35323 
35324 /* returns WOLFSSL_SUCCESS on successful verify and WOLFSSL_FAILURE on fail */
wolfSSL_RSA_verify(int type,const unsigned char * m,unsigned int mLen,const unsigned char * sig,unsigned int sigLen,WOLFSSL_RSA * rsa)35325 int wolfSSL_RSA_verify(int type, const unsigned char* m,
35326                                unsigned int mLen, const unsigned char* sig,
35327                                unsigned int sigLen, WOLFSSL_RSA* rsa)
35328 {
35329     return wolfSSL_RSA_verify_ex(type, m, mLen, sig, sigLen, rsa, RSA_PKCS1_PADDING);
35330 }
35331 
35332 /* returns WOLFSSL_SUCCESS on successful verify and WOLFSSL_FAILURE on fail */
wolfSSL_RSA_verify_ex(int type,const unsigned char * m,unsigned int mLen,const unsigned char * sig,unsigned int sigLen,WOLFSSL_RSA * rsa,int padding)35333 int wolfSSL_RSA_verify_ex(int type, const unsigned char* m,
35334                                unsigned int mLen, const unsigned char* sig,
35335                                unsigned int sigLen, WOLFSSL_RSA* rsa,
35336                                int padding) {
35337     int     ret = WOLFSSL_FAILURE;
35338     unsigned char *sigRet = NULL;
35339     unsigned char *sigDec = NULL;
35340     unsigned int   len = 0;
35341     int verLen;
35342 #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
35343     int hSum = nid2HashSum(type);
35344     enum wc_HashType hType;
35345 #endif
35346 
35347     WOLFSSL_ENTER("wolfSSL_RSA_verify");
35348     if ((m == NULL) || (sig == NULL)) {
35349         WOLFSSL_MSG("Bad function arguments");
35350         return WOLFSSL_FAILURE;
35351     }
35352     sigDec = (unsigned char *)XMALLOC(sigLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
35353     if (sigDec == NULL) {
35354         WOLFSSL_MSG("Memory failure");
35355         goto cleanup;
35356     }
35357     if (padding != RSA_PKCS1_PSS_PADDING) {
35358         sigRet = (unsigned char *)XMALLOC(sigLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
35359         if (sigRet == NULL) {
35360             WOLFSSL_MSG("Memory failure");
35361             goto cleanup;
35362         }
35363         /* get non-encrypted signature to be compared with decrypted signature */
35364         if (wolfSSL_RSA_sign_generic_padding(type, m, mLen, sigRet, &len, rsa,
35365                 0, padding) <= 0) {
35366             WOLFSSL_MSG("Message Digest Error");
35367             goto cleanup;
35368         }
35369         DEBUG_SIGN_msg("Encoded Message", sigRet, len);
35370     }
35371     else {
35372         DEBUG_SIGN_msg("Encoded Message", m, mLen);
35373     }
35374     /* decrypt signature */
35375 #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
35376     hType = wc_OidGetHash(hSum);
35377     if ((verLen = wc_RsaSSL_Verify_ex2(sig, sigLen, (unsigned char *)sigDec,
35378             sigLen, (RsaKey*)rsa->internal, padding, hType)) <= 0) {
35379         WOLFSSL_MSG("RSA Decrypt error");
35380         goto cleanup;
35381     }
35382 #else
35383     verLen = wc_RsaSSL_Verify(sig, sigLen, (unsigned char *)sigDec, sigLen,
35384         (RsaKey*)rsa->internal);
35385 #endif
35386     DEBUG_SIGN_msg("Decrypted Signature", sigDec, ret);
35387 #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && defined(WC_RSA_PSS)
35388     if (padding == RSA_PKCS1_PSS_PADDING) {
35389         if (wc_RsaPSS_CheckPadding_ex(m, mLen, sigDec, verLen,
35390                 hType,
35391 #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
35392                 RSA_PSS_SALT_LEN_DEFAULT,
35393 #else
35394                 RSA_PSS_SALT_LEN_DISCOVER,
35395 #endif
35396                 mp_count_bits(&((RsaKey*)rsa->internal)->n)) != 0) {
35397             WOLFSSL_MSG("wc_RsaPSS_CheckPadding_ex error");
35398             goto cleanup;
35399         }
35400     }
35401     else
35402 #endif /* !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) */
35403     if ((int)len != verLen || XMEMCMP(sigRet, sigDec, verLen) != 0) {
35404         WOLFSSL_MSG("wolfSSL_RSA_verify_ex failed");
35405         goto cleanup;
35406     }
35407 
35408     WOLFSSL_MSG("wolfSSL_RSA_verify_ex success");
35409     ret = WOLFSSL_SUCCESS;
35410 cleanup:
35411     if (sigRet)
35412         XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER);
35413     if (sigDec)
35414         XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
35415     return ret;
35416 }
35417 
wolfSSL_RSA_get0_crt_params(const WOLFSSL_RSA * r,const WOLFSSL_BIGNUM ** dmp1,const WOLFSSL_BIGNUM ** dmq1,const WOLFSSL_BIGNUM ** iqmp)35418 void wolfSSL_RSA_get0_crt_params(const WOLFSSL_RSA *r,
35419         const WOLFSSL_BIGNUM **dmp1, const WOLFSSL_BIGNUM **dmq1,
35420         const WOLFSSL_BIGNUM **iqmp)
35421 {
35422     WOLFSSL_ENTER("wolfSSL_RSA_get0_crt_params");
35423 
35424     if (r != NULL) {
35425         if (dmp1 != NULL)
35426             *dmp1 = r->dmp1;
35427         if (dmq1 != NULL)
35428             *dmq1 = r->dmq1;
35429         if (iqmp != NULL)
35430             *iqmp = r->iqmp;
35431     } else {
35432         if (dmp1 != NULL)
35433             *dmp1 = NULL;
35434         if (dmq1 != NULL)
35435             *dmq1 = NULL;
35436         if (iqmp != NULL)
35437             *iqmp = NULL;
35438     }
35439 }
35440 
wolfSSL_RSA_set0_crt_params(WOLFSSL_RSA * r,WOLFSSL_BIGNUM * dmp1,WOLFSSL_BIGNUM * dmq1,WOLFSSL_BIGNUM * iqmp)35441 int wolfSSL_RSA_set0_crt_params(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *dmp1,
35442                                 WOLFSSL_BIGNUM *dmq1, WOLFSSL_BIGNUM *iqmp)
35443 {
35444     WOLFSSL_ENTER("wolfSSL_RSA_set0_crt_params");
35445 
35446     /* If a param is null in r then it must be non-null in the
35447      * corresponding user input. */
35448     if (r == NULL || (r->dmp1 == NULL && dmp1 == NULL) ||
35449             (r->dmq1 == NULL && dmq1 == NULL) ||
35450             (r->iqmp == NULL && iqmp == NULL)) {
35451         WOLFSSL_MSG("Bad parameters");
35452         return WOLFSSL_FAILURE;
35453     }
35454 
35455     if (dmp1 != NULL) {
35456         wolfSSL_BN_clear_free(r->dmp1);
35457         r->dmp1 = dmp1;
35458     }
35459     if (dmq1 != NULL) {
35460         wolfSSL_BN_clear_free(r->dmq1);
35461         r->dmq1 = dmq1;
35462     }
35463     if (iqmp != NULL) {
35464         wolfSSL_BN_clear_free(r->iqmp);
35465         r->iqmp = iqmp;
35466     }
35467 
35468     return SetRsaInternal(r) == WOLFSSL_SUCCESS ?
35469             WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
35470 }
35471 
wolfSSL_RSA_get0_factors(const WOLFSSL_RSA * r,const WOLFSSL_BIGNUM ** p,const WOLFSSL_BIGNUM ** q)35472 void wolfSSL_RSA_get0_factors(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **p,
35473                               const WOLFSSL_BIGNUM **q)
35474 {
35475     WOLFSSL_ENTER("wolfSSL_RSA_get0_factors");
35476 
35477     if (r != NULL) {
35478         if (p != NULL)
35479             *p = r->p;
35480         if (q != NULL)
35481             *q = r->q;
35482     } else {
35483         if (p != NULL)
35484             *p = NULL;
35485         if (q != NULL)
35486             *q = NULL;
35487     }
35488 }
35489 
wolfSSL_RSA_set0_factors(WOLFSSL_RSA * r,WOLFSSL_BIGNUM * p,WOLFSSL_BIGNUM * q)35490 int wolfSSL_RSA_set0_factors(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *p, WOLFSSL_BIGNUM *q)
35491 {
35492     WOLFSSL_ENTER("wolfSSL_RSA_set0_factors");
35493 
35494     /* If a param is null in r then it must be non-null in the
35495      * corresponding user input. */
35496     if (r == NULL || (r->p == NULL && p == NULL) ||
35497             (r->q == NULL && q == NULL)) {
35498         WOLFSSL_MSG("Bad parameters");
35499         return WOLFSSL_FAILURE;
35500     }
35501 
35502     if (p != NULL) {
35503         wolfSSL_BN_clear_free(r->p);
35504         r->p = p;
35505     }
35506     if (q != NULL) {
35507         wolfSSL_BN_clear_free(r->q);
35508         r->q = q;
35509     }
35510 
35511     return SetRsaInternal(r) == WOLFSSL_SUCCESS ?
35512             WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
35513 }
35514 
wolfSSL_RSA_get0_key(const WOLFSSL_RSA * r,const WOLFSSL_BIGNUM ** n,const WOLFSSL_BIGNUM ** e,const WOLFSSL_BIGNUM ** d)35515 void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **n,
35516     const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d)
35517 {
35518     WOLFSSL_ENTER("wolfSSL_RSA_get0_key");
35519 
35520     if (r != NULL) {
35521         if (n != NULL)
35522             *n = r->n;
35523         if (e != NULL)
35524             *e = r->e;
35525         if (d != NULL)
35526             *d = r->d;
35527     } else {
35528         if (n != NULL)
35529             *n = NULL;
35530         if (e != NULL)
35531             *e = NULL;
35532         if (d != NULL)
35533             *d = NULL;
35534     }
35535 }
35536 
35537 /* generate p-1 and q-1, WOLFSSL_SUCCESS on ok */
wolfSSL_RSA_GenAdd(WOLFSSL_RSA * rsa)35538 int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
35539 {
35540     int    err;
35541     mp_int tmp;
35542 
35543     WOLFSSL_MSG("wolfSSL_RsaGenAdd");
35544 
35545     if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL ||
35546                        rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
35547         WOLFSSL_MSG("rsa no init error");
35548         return WOLFSSL_FATAL_ERROR;
35549     }
35550 
35551     if (mp_init(&tmp) != MP_OKAY) {
35552         WOLFSSL_MSG("mp_init error");
35553         return WOLFSSL_FATAL_ERROR;
35554     }
35555 
35556     err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp);
35557     if (err != MP_OKAY) {
35558         WOLFSSL_MSG("mp_sub_d error");
35559     }
35560     else
35561         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
35562                      (mp_int*)rsa->dmp1->internal);
35563 
35564     if (err != MP_OKAY) {
35565         WOLFSSL_MSG("mp_mod error");
35566     }
35567     else
35568         err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp);
35569     if (err != MP_OKAY) {
35570         WOLFSSL_MSG("mp_sub_d error");
35571     }
35572     else
35573         err = mp_mod((mp_int*)rsa->d->internal, &tmp,
35574                      (mp_int*)rsa->dmq1->internal);
35575 
35576     mp_clear(&tmp);
35577 
35578     if (err == MP_OKAY)
35579         return WOLFSSL_SUCCESS;
35580     else
35581         return WOLFSSL_FATAL_ERROR;
35582 }
35583 #endif /* !NO_RSA && !HAVE_USER_RSA */
35584 
wolfSSL_HMAC_CTX_new(void)35585 WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void)
35586 {
35587     WOLFSSL_HMAC_CTX* hmac_ctx = (WOLFSSL_HMAC_CTX*)XMALLOC(
35588         sizeof(WOLFSSL_HMAC_CTX), NULL, DYNAMIC_TYPE_OPENSSL);
35589     if (hmac_ctx != NULL) {
35590         XMEMSET(hmac_ctx, 0, sizeof(WOLFSSL_HMAC_CTX));
35591     }
35592     return hmac_ctx;
35593 }
35594 
wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX * ctx)35595 int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx)
35596 {
35597     WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init");
35598 
35599     if (ctx != NULL) {
35600         /* wc_HmacSetKey sets up ctx->hmac */
35601         XMEMSET(ctx, 0, sizeof(WOLFSSL_HMAC_CTX));
35602     }
35603 
35604     return WOLFSSL_SUCCESS;
35605 }
35606 
35607 
wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX * ctx,const void * key,int keylen,const EVP_MD * type,WOLFSSL_ENGINE * e)35608 int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key,
35609                              int keylen, const EVP_MD* type, WOLFSSL_ENGINE* e)
35610 {
35611     WOLFSSL_ENTER("wolfSSL_HMAC_Init_ex");
35612 
35613     /* WOLFSSL_ENGINE not used, call wolfSSL_HMAC_Init */
35614     (void)e;
35615     return wolfSSL_HMAC_Init(ctx, key, keylen, type);
35616 }
35617 
35618 
35619 /* helper function for Deep copy of internal wolfSSL hmac structure
35620  * returns WOLFSSL_SUCCESS on success */
wolfSSL_HmacCopy(Hmac * des,Hmac * src)35621 int wolfSSL_HmacCopy(Hmac* des, Hmac* src)
35622 {
35623     void* heap;
35624     int ret;
35625 
35626 #ifndef HAVE_FIPS
35627     heap = src->heap;
35628 #else
35629     heap = NULL;
35630 #endif
35631     if (wc_HmacInit(des, heap, 0) != 0) {
35632         return WOLFSSL_FAILURE;
35633     }
35634 
35635     /* requires that hash structures have no dynamic parts to them */
35636     switch (src->macType) {
35637     #ifndef NO_MD5
35638         case WC_MD5:
35639             ret = wc_Md5Copy(&src->hash.md5, &des->hash.md5);
35640             break;
35641     #endif /* !NO_MD5 */
35642 
35643     #ifndef NO_SHA
35644         case WC_SHA:
35645             ret = wc_ShaCopy(&src->hash.sha, &des->hash.sha);
35646             break;
35647     #endif /* !NO_SHA */
35648 
35649     #ifdef WOLFSSL_SHA224
35650         case WC_SHA224:
35651             ret = wc_Sha224Copy(&src->hash.sha224, &des->hash.sha224);
35652             break;
35653     #endif /* WOLFSSL_SHA224 */
35654 
35655     #ifndef NO_SHA256
35656         case WC_SHA256:
35657             ret = wc_Sha256Copy(&src->hash.sha256, &des->hash.sha256);
35658             break;
35659     #endif /* !NO_SHA256 */
35660 
35661     #ifdef WOLFSSL_SHA384
35662         case WC_SHA384:
35663             ret = wc_Sha384Copy(&src->hash.sha384, &des->hash.sha384);
35664             break;
35665     #endif /* WOLFSSL_SHA384 */
35666     #ifdef WOLFSSL_SHA512
35667         case WC_SHA512:
35668             ret = wc_Sha512Copy(&src->hash.sha512, &des->hash.sha512);
35669             break;
35670     #endif /* WOLFSSL_SHA512 */
35671 #ifdef WOLFSSL_SHA3
35672     #ifndef WOLFSSL_NOSHA3_224
35673         case WC_SHA3_224:
35674             ret = wc_Sha3_224_Copy(&src->hash.sha3, &des->hash.sha3);
35675             break;
35676     #endif /* WOLFSSL_NO_SHA3_224 */
35677     #ifndef WOLFSSL_NOSHA3_256
35678         case WC_SHA3_256:
35679             ret = wc_Sha3_256_Copy(&src->hash.sha3, &des->hash.sha3);
35680             break;
35681     #endif /* WOLFSSL_NO_SHA3_256 */
35682     #ifndef WOLFSSL_NOSHA3_384
35683         case WC_SHA3_384:
35684             ret = wc_Sha3_384_Copy(&src->hash.sha3, &des->hash.sha3);
35685             break;
35686     #endif /* WOLFSSL_NO_SHA3_384 */
35687     #ifndef WOLFSSL_NOSHA3_512
35688         case WC_SHA3_512:
35689             ret = wc_Sha3_512_Copy(&src->hash.sha3, &des->hash.sha3);
35690             break;
35691     #endif /* WOLFSSL_NO_SHA3_512 */
35692 #endif /* WOLFSSL_SHA3 */
35693 
35694         default:
35695             return WOLFSSL_FAILURE;
35696     }
35697 
35698     if (ret != 0)
35699         return WOLFSSL_FAILURE;
35700 
35701     XMEMCPY((byte*)des->ipad, (byte*)src->ipad, WC_HMAC_BLOCK_SIZE);
35702     XMEMCPY((byte*)des->opad, (byte*)src->opad, WC_HMAC_BLOCK_SIZE);
35703     XMEMCPY((byte*)des->innerHash, (byte*)src->innerHash, WC_MAX_DIGEST_SIZE);
35704 #ifndef HAVE_FIPS
35705     des->heap    = heap;
35706 #endif
35707     des->macType = src->macType;
35708     des->innerHashKeyed = src->innerHashKeyed;
35709 
35710 #ifdef WOLFSSL_ASYNC_CRYPT
35711     XMEMCPY(&des->asyncDev, &src->asyncDev, sizeof(WC_ASYNC_DEV));
35712     des->keyLen = src->keyLen;
35713     #ifdef HAVE_CAVIUM
35714         des->data = (byte*)XMALLOC(src->dataLen, des->heap,
35715                 DYNAMIC_TYPE_HMAC);
35716         if (des->data == NULL) {
35717             return BUFFER_E;
35718         }
35719         XMEMCPY(des->data, src->data, src->dataLen);
35720         des->dataLen = src->dataLen;
35721     #endif /* HAVE_CAVIUM */
35722 #endif /* WOLFSSL_ASYNC_CRYPT */
35723         return WOLFSSL_SUCCESS;
35724 }
35725 
35726 
35727 /* Deep copy of information from src to des structure
35728  *
35729  * des destination to copy information to
35730  * src structure to get information from
35731  *
35732  * Returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
35733  */
wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX * des,WOLFSSL_HMAC_CTX * src)35734 int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* des, WOLFSSL_HMAC_CTX* src)
35735 {
35736     WOLFSSL_ENTER("wolfSSL_HMAC_CTX_copy");
35737 
35738     if (des == NULL || src == NULL) {
35739         return WOLFSSL_FAILURE;
35740     }
35741 
35742     des->type = src->type;
35743     XMEMCPY((byte *)&des->save_ipad, (byte *)&src->hmac.ipad,
35744                                         WC_HMAC_BLOCK_SIZE);
35745     XMEMCPY((byte *)&des->save_opad, (byte *)&src->hmac.opad,
35746                                         WC_HMAC_BLOCK_SIZE);
35747 
35748     return wolfSSL_HmacCopy(&des->hmac, &src->hmac);
35749 }
35750 
35751 
35752 #if defined(HAVE_FIPS) && \
35753     (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
35754 
_HMAC_Init(Hmac * hmac,int type,void * heap)35755 static int _HMAC_Init(Hmac* hmac, int type, void* heap)
35756 {
35757     int ret = 0;
35758 
35759     switch (type) {
35760     #ifndef NO_MD5
35761         case WC_MD5:
35762             ret = wc_InitMd5(&hmac->hash.md5);
35763             break;
35764     #endif /* !NO_MD5 */
35765 
35766     #ifndef NO_SHA
35767         case WC_SHA:
35768             ret = wc_InitSha(&hmac->hash.sha);
35769             break;
35770     #endif /* !NO_SHA */
35771 
35772     #ifdef WOLFSSL_SHA224
35773         case WC_SHA224:
35774             ret = wc_InitSha224(&hmac->hash.sha224);
35775             break;
35776     #endif /* WOLFSSL_SHA224 */
35777 
35778     #ifndef NO_SHA256
35779         case WC_SHA256:
35780             ret = wc_InitSha256(&hmac->hash.sha256);
35781             break;
35782     #endif /* !NO_SHA256 */
35783 
35784     #ifdef WOLFSSL_SHA384
35785         case WC_SHA384:
35786             ret = wc_InitSha384(&hmac->hash.sha384);
35787             break;
35788     #endif /* WOLFSSL_SHA384 */
35789     #ifdef WOLFSSL_SHA512
35790         case WC_SHA512:
35791             ret = wc_InitSha512(&hmac->hash.sha512);
35792             break;
35793     #endif /* WOLFSSL_SHA512 */
35794 
35795     #ifdef WOLFSSL_SHA3
35796         case WC_SHA3_224:
35797             ret = wc_InitSha3_224(&hmac->hash.sha3, heap, INVALID_DEVID);
35798             break;
35799         case WC_SHA3_256:
35800             ret = wc_InitSha3_256(&hmac->hash.sha3, heap, INVALID_DEVID);
35801             break;
35802         case WC_SHA3_384:
35803             ret = wc_InitSha3_384(&hmac->hash.sha3, heap, INVALID_DEVID);
35804             break;
35805         case WC_SHA3_512:
35806             ret = wc_InitSha3_512(&hmac->hash.sha3, heap, INVALID_DEVID);
35807             break;
35808     #endif
35809 
35810         default:
35811             ret = BAD_FUNC_ARG;
35812             break;
35813     }
35814 
35815     (void)heap;
35816 
35817     return ret;
35818 }
35819 
35820 #else
35821     #define _HMAC_Init _InitHmac
35822 #endif
35823 
35824 
wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX * ctx,const void * key,int keylen,const EVP_MD * type)35825 int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
35826                   const EVP_MD* type)
35827 {
35828     int hmac_error = 0;
35829     void* heap = NULL;
35830     int inited;
35831 
35832     WOLFSSL_MSG("wolfSSL_HMAC_Init");
35833 
35834     if (ctx == NULL) {
35835         WOLFSSL_MSG("no ctx on init");
35836         return WOLFSSL_FAILURE;
35837     }
35838 
35839 #ifndef HAVE_FIPS
35840     heap = ctx->hmac.heap;
35841 #endif
35842 
35843     if (type) {
35844         WOLFSSL_MSG("init has type");
35845 
35846 #ifndef NO_MD5
35847         if (XSTRNCMP(type, "MD5", 3) == 0) {
35848             WOLFSSL_MSG("md5 hmac");
35849             ctx->type = WC_MD5;
35850         }
35851         else
35852 #endif
35853 #ifdef WOLFSSL_SHA224
35854         if (XSTRNCMP(type, "SHA224", 6) == 0) {
35855             WOLFSSL_MSG("sha224 hmac");
35856             ctx->type = WC_SHA224;
35857         }
35858         else
35859 #endif
35860 #ifndef NO_SHA256
35861         if (XSTRNCMP(type, "SHA256", 6) == 0) {
35862             WOLFSSL_MSG("sha256 hmac");
35863             ctx->type = WC_SHA256;
35864         }
35865         else
35866 #endif
35867 #ifdef WOLFSSL_SHA384
35868         if (XSTRNCMP(type, "SHA384", 6) == 0) {
35869             WOLFSSL_MSG("sha384 hmac");
35870             ctx->type = WC_SHA384;
35871         }
35872         else
35873 #endif
35874 #ifdef WOLFSSL_SHA512
35875         if (XSTRNCMP(type, "SHA512", 6) == 0) {
35876             WOLFSSL_MSG("sha512 hmac");
35877             ctx->type = WC_SHA512;
35878         }
35879         else
35880 #endif
35881 #ifdef WOLFSSL_SHA3
35882     #ifndef WOLFSSL_NOSHA3_224
35883         if (XSTRNCMP(type, "SHA3_224", 8) == 0) {
35884             WOLFSSL_MSG("sha3_224 hmac");
35885             ctx->type = WC_SHA3_224;
35886         }
35887         else
35888     #endif
35889     #ifndef WOLFSSL_NOSHA3_256
35890         if (XSTRNCMP(type, "SHA3_256", 8) == 0) {
35891             WOLFSSL_MSG("sha3_256 hmac");
35892             ctx->type = WC_SHA3_256;
35893         }
35894         else
35895     #endif
35896         if (XSTRNCMP(type, "SHA3_384", 8) == 0) {
35897             WOLFSSL_MSG("sha3_384 hmac");
35898             ctx->type = WC_SHA3_384;
35899         }
35900         else
35901     #ifndef WOLFSSL_NOSHA3_512
35902         if (XSTRNCMP(type, "SHA3_512", 8) == 0) {
35903             WOLFSSL_MSG("sha3_512 hmac");
35904             ctx->type = WC_SHA3_512;
35905         }
35906         else
35907     #endif
35908 #endif
35909 
35910 #ifndef NO_SHA
35911         /* has to be last since would pick or 256, 384, or 512 too */
35912         if (XSTRNCMP(type, "SHA", 3) == 0) {
35913             WOLFSSL_MSG("sha hmac");
35914             ctx->type = WC_SHA;
35915         }
35916         else
35917 #endif
35918         {
35919             WOLFSSL_MSG("bad init type");
35920             return WOLFSSL_FAILURE;
35921         }
35922     }
35923 
35924     /* Check if init has been called before */
35925     inited = (ctx->hmac.macType != WC_HASH_TYPE_NONE);
35926     /* Free if needed */
35927     if (inited) {
35928         wc_HmacFree(&ctx->hmac);
35929     }
35930     if (key != NULL) {
35931         WOLFSSL_MSG("keying hmac");
35932 
35933         if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
35934             hmac_error = wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key,
35935                                        (word32)keylen);
35936             if (hmac_error < 0){
35937                 wc_HmacFree(&ctx->hmac);
35938                 return WOLFSSL_FAILURE;
35939             }
35940             XMEMCPY((byte *)&ctx->save_ipad, (byte *)&ctx->hmac.ipad,
35941                                         WC_HMAC_BLOCK_SIZE);
35942             XMEMCPY((byte *)&ctx->save_opad, (byte *)&ctx->hmac.opad,
35943                                         WC_HMAC_BLOCK_SIZE);
35944         }
35945         /* OpenSSL compat, no error */
35946     }
35947     else if (!inited) {
35948         return WOLFSSL_FAILURE;
35949     }
35950     else if (ctx->type >= 0) { /* MD5 == 0 */
35951         WOLFSSL_MSG("recover hmac");
35952         if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
35953             ctx->hmac.macType = (byte)ctx->type;
35954             ctx->hmac.innerHashKeyed = 0;
35955             XMEMCPY((byte *)&ctx->hmac.ipad, (byte *)&ctx->save_ipad,
35956                                        WC_HMAC_BLOCK_SIZE);
35957             XMEMCPY((byte *)&ctx->hmac.opad, (byte *)&ctx->save_opad,
35958                                        WC_HMAC_BLOCK_SIZE);
35959             if ((hmac_error = _HMAC_Init(&ctx->hmac, ctx->hmac.macType, heap))
35960                     !=0) {
35961                return hmac_error;
35962             }
35963         }
35964     }
35965 
35966     (void)hmac_error;
35967 
35968     return WOLFSSL_SUCCESS;
35969 }
35970 
35971 
wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX * ctx,const unsigned char * data,int len)35972 int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
35973                     int len)
35974 {
35975     int hmac_error = 0;
35976 
35977     WOLFSSL_MSG("wolfSSL_HMAC_Update");
35978 
35979     if (ctx == NULL) {
35980         WOLFSSL_MSG("no ctx");
35981         return WOLFSSL_FAILURE;
35982     }
35983 
35984     if (data) {
35985         WOLFSSL_MSG("updating hmac");
35986         hmac_error = wc_HmacUpdate(&ctx->hmac, data, (word32)len);
35987         if (hmac_error < 0){
35988             WOLFSSL_MSG("hmac update error");
35989             return WOLFSSL_FAILURE;
35990         }
35991     }
35992 
35993     return WOLFSSL_SUCCESS;
35994 }
35995 
35996 
wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX * ctx,unsigned char * hash,unsigned int * len)35997 int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
35998                    unsigned int* len)
35999 {
36000     int hmac_error;
36001 
36002     WOLFSSL_MSG("wolfSSL_HMAC_Final");
36003 
36004     /* "len" parameter is optional. */
36005     if (ctx == NULL || hash == NULL) {
36006         WOLFSSL_MSG("invalid parameter");
36007         return WOLFSSL_FAILURE;
36008     }
36009 
36010     WOLFSSL_MSG("final hmac");
36011     hmac_error = wc_HmacFinal(&ctx->hmac, hash);
36012     if (hmac_error < 0){
36013         WOLFSSL_MSG("final hmac error");
36014         return WOLFSSL_FAILURE;
36015     }
36016 
36017     if (len) {
36018         WOLFSSL_MSG("setting output len");
36019         switch (ctx->type) {
36020             #ifndef NO_MD5
36021             case WC_MD5:
36022                 *len = WC_MD5_DIGEST_SIZE;
36023                 break;
36024             #endif
36025 
36026             #ifndef NO_SHA
36027             case WC_SHA:
36028                 *len = WC_SHA_DIGEST_SIZE;
36029                 break;
36030             #endif
36031 
36032             #ifdef WOLFSSL_SHA224
36033             case WC_SHA224:
36034                 *len = WC_SHA224_DIGEST_SIZE;
36035                 break;
36036             #endif
36037 
36038             #ifndef NO_SHA256
36039             case WC_SHA256:
36040                 *len = WC_SHA256_DIGEST_SIZE;
36041                 break;
36042             #endif
36043 
36044             #ifdef WOLFSSL_SHA384
36045             case WC_SHA384:
36046                 *len = WC_SHA384_DIGEST_SIZE;
36047                 break;
36048             #endif
36049 
36050             #ifdef WOLFSSL_SHA512
36051             case WC_SHA512:
36052                 *len = WC_SHA512_DIGEST_SIZE;
36053                 break;
36054             #endif
36055 
36056         #ifdef WOLFSSL_SHA3
36057             #ifndef WOLFSSL_NOSHA3_224
36058             case WC_SHA3_224:
36059                 *len = WC_SHA3_224_DIGEST_SIZE;
36060                 break;
36061             #endif
36062             #ifndef WOLFSSL_NOSHA3_256
36063             case WC_SHA3_256:
36064                 *len = WC_SHA3_256_DIGEST_SIZE;
36065                 break;
36066             #endif
36067             #ifndef WOLFSSL_NOSHA3_384
36068             case WC_SHA3_384:
36069                 *len = WC_SHA3_384_DIGEST_SIZE;
36070                 break;
36071             #endif
36072             #ifndef WOLFSSL_NOSHA3_512
36073             case WC_SHA3_512:
36074                 *len = WC_SHA3_512_DIGEST_SIZE;
36075                 break;
36076             #endif
36077         #endif
36078 
36079             default:
36080                 WOLFSSL_MSG("bad hmac type");
36081                 return WOLFSSL_FAILURE;
36082         }
36083     }
36084 
36085     return WOLFSSL_SUCCESS;
36086 }
36087 
36088 
wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX * ctx)36089 int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
36090 {
36091     WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
36092 
36093     if (ctx) {
36094         wc_HmacFree(&ctx->hmac);
36095     }
36096 
36097     return WOLFSSL_SUCCESS;
36098 }
36099 
wolfSSL_HMAC_CTX_cleanup(WOLFSSL_HMAC_CTX * ctx)36100 void wolfSSL_HMAC_CTX_cleanup(WOLFSSL_HMAC_CTX* ctx)
36101 {
36102     if (ctx) {
36103         wolfSSL_HMAC_cleanup(ctx);
36104     }
36105 }
36106 
wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX * ctx)36107 void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx)
36108 {
36109     if (ctx) {
36110         wolfSSL_HMAC_CTX_cleanup(ctx);
36111         XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
36112     }
36113 }
36114 
wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX * ctx)36115 size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx)
36116 {
36117     if (!ctx) {
36118         return 0;
36119     }
36120 
36121     return (size_t)wc_HashGetDigestSize((enum wc_HashType)ctx->hmac.macType);
36122 }
36123 
wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX * ctx)36124 const WOLFSSL_EVP_MD *wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX *ctx)
36125 {
36126     if (!ctx) {
36127         return NULL;
36128     }
36129 
36130     return wolfSSL_macType2EVP_md((enum wc_HashType)ctx->type);
36131 }
36132 
36133 #if defined(WOLFSSL_CMAC) && defined(OPENSSL_EXTRA) && \
36134     defined(WOLFSSL_AES_DIRECT)
wolfSSL_CMAC_CTX_new(void)36135 WOLFSSL_CMAC_CTX* wolfSSL_CMAC_CTX_new(void)
36136 {
36137     WOLFSSL_CMAC_CTX* ctx = NULL;
36138 
36139     ctx = (WOLFSSL_CMAC_CTX*)XMALLOC(sizeof(WOLFSSL_CMAC_CTX), NULL,
36140                                      DYNAMIC_TYPE_OPENSSL);
36141     if (ctx != NULL) {
36142         ctx->internal = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC);
36143         if (ctx->internal == NULL) {
36144             XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
36145             ctx = NULL;
36146         }
36147     }
36148     if (ctx != NULL) {
36149         ctx->cctx = wolfSSL_EVP_CIPHER_CTX_new();
36150         if (ctx->cctx == NULL) {
36151             XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC);
36152             XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
36153             ctx = NULL;
36154         }
36155     }
36156 
36157     return ctx;
36158 }
36159 
wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX * ctx)36160 void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx)
36161 {
36162     if (ctx != NULL) {
36163         if (ctx->internal != NULL) {
36164             XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC);
36165         }
36166         if (ctx->cctx != NULL) {
36167             wolfSSL_EVP_CIPHER_CTX_free(ctx->cctx);
36168         }
36169         XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
36170     }
36171 }
36172 
wolfSSL_CMAC_CTX_get0_cipher_ctx(WOLFSSL_CMAC_CTX * ctx)36173 WOLFSSL_EVP_CIPHER_CTX* wolfSSL_CMAC_CTX_get0_cipher_ctx(WOLFSSL_CMAC_CTX* ctx)
36174 {
36175     WOLFSSL_EVP_CIPHER_CTX* cctx = NULL;
36176 
36177     if (ctx != NULL) {
36178         cctx = ctx->cctx;
36179     }
36180 
36181     return cctx;
36182 }
36183 
wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX * ctx,const void * key,size_t keyLen,const WOLFSSL_EVP_CIPHER * cipher,WOLFSSL_ENGINE * engine)36184 int wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX* ctx, const void *key, size_t keyLen,
36185                       const WOLFSSL_EVP_CIPHER* cipher, WOLFSSL_ENGINE* engine)
36186 {
36187     int ret = WOLFSSL_SUCCESS;
36188 
36189     (void)engine;
36190 
36191     WOLFSSL_ENTER("wolfSSL_CMAC_Init");
36192 
36193     if (ctx == NULL || cipher == NULL || (
36194             cipher != EVP_AES_128_CBC &&
36195             cipher != EVP_AES_192_CBC &&
36196             cipher != EVP_AES_256_CBC)) {
36197         ret = WOLFSSL_FAILURE;
36198     }
36199 
36200     if (ret == WOLFSSL_SUCCESS) {
36201         ret = wc_InitCmac((Cmac*)ctx->internal, (const byte*)key,
36202                           (word32)keyLen, WC_CMAC_AES, NULL);
36203         if (ret != 0) {
36204             ret = WOLFSSL_FAILURE;
36205         }
36206         else {
36207             ret = WOLFSSL_SUCCESS;
36208         }
36209     }
36210     if (ret == WOLFSSL_SUCCESS) {
36211         ret = wolfSSL_EVP_CipherInit(ctx->cctx, cipher, (const byte*)key, NULL,
36212                                      1);
36213     }
36214 
36215     WOLFSSL_LEAVE("wolfSSL_CMAC_Init", ret);
36216 
36217     return ret;
36218 }
36219 
wolfSSL_CMAC_Update(WOLFSSL_CMAC_CTX * ctx,const void * data,size_t len)36220 int wolfSSL_CMAC_Update(WOLFSSL_CMAC_CTX* ctx, const void* data, size_t len)
36221 {
36222     int ret = WOLFSSL_SUCCESS;
36223 
36224     WOLFSSL_ENTER("wolfSSL_CMAC_Update");
36225 
36226     if (ctx == NULL || ctx->internal == NULL) {
36227         ret = WOLFSSL_FAILURE;
36228     }
36229 
36230     if (ret == WOLFSSL_SUCCESS) {
36231         if (data) {
36232             ret = wc_CmacUpdate((Cmac*)ctx->internal, (const byte*)data,
36233                                 (word32)len);
36234             if (ret != 0){
36235                 ret = WOLFSSL_FAILURE;
36236             }
36237             else {
36238                 ret = WOLFSSL_SUCCESS;
36239             }
36240         }
36241     }
36242 
36243     WOLFSSL_LEAVE("wolfSSL_CMAC_Update", ret);
36244 
36245     return ret;
36246 }
36247 
wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX * ctx,unsigned char * out,size_t * len)36248 int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out,
36249                        size_t* len)
36250 {
36251     int ret = WOLFSSL_SUCCESS;
36252     int blockSize;
36253 
36254     WOLFSSL_ENTER("wolfSSL_CMAC_Final");
36255 
36256     if (ctx == NULL || ctx->cctx == NULL || ctx->internal == NULL ||
36257                                                                   len == NULL) {
36258         ret = WOLFSSL_FAILURE;
36259     }
36260 
36261     if (ret == WOLFSSL_SUCCESS) {
36262         blockSize = EVP_CIPHER_CTX_block_size(ctx->cctx);
36263         if (blockSize <= 0) {
36264             ret = WOLFSSL_FAILURE;
36265         }
36266         else {
36267             *len = blockSize;
36268         }
36269     }
36270     if (ret == WOLFSSL_SUCCESS) {
36271         word32 len32 = (word32)*len;
36272 
36273         ret = wc_CmacFinal((Cmac*)ctx->internal, out, &len32);
36274         *len = (size_t)len32;
36275         if (ret != 0) {
36276             ret = WOLFSSL_FAILURE;
36277         }
36278         else {
36279             ret = WOLFSSL_SUCCESS;
36280         }
36281     }
36282 
36283     WOLFSSL_LEAVE("wolfSSL_CMAC_Final", ret);
36284 
36285     return ret;
36286 }
36287 #endif /* WOLFSSL_CMAC && OPENSSL_EXTRA && WOLFSSL_AES_DIRECT */
36288 
36289 /* Free the dynamically allocated data.
36290  *
36291  * p  Pointer to dynamically allocated memory.
36292  */
wolfSSL_OPENSSL_free(void * p)36293 void wolfSSL_OPENSSL_free(void* p)
36294 {
36295     WOLFSSL_MSG("wolfSSL_OPENSSL_free");
36296 
36297     XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
36298 }
36299 
wolfSSL_OPENSSL_malloc(size_t a)36300 void *wolfSSL_OPENSSL_malloc(size_t a)
36301 {
36302     return (void *)XMALLOC(a, NULL, DYNAMIC_TYPE_OPENSSL);
36303 }
36304 
wolfSSL_OPENSSL_hexchar2int(unsigned char c)36305 int wolfSSL_OPENSSL_hexchar2int(unsigned char c)
36306 {
36307     /* 'char' is unsigned on some platforms. */
36308     return (int)(signed char)HexCharToByte((char)c);
36309 }
36310 
wolfSSL_OPENSSL_hexstr2buf(const char * str,long * len)36311 unsigned char *wolfSSL_OPENSSL_hexstr2buf(const char *str, long *len)
36312 {
36313     unsigned char* targetBuf;
36314     int srcDigitHigh = 0;
36315     int srcDigitLow = 0;
36316     size_t srcLen;
36317     size_t srcIdx = 0;
36318     long targetIdx = 0;
36319 
36320     srcLen = XSTRLEN(str);
36321     targetBuf = (unsigned char*)XMALLOC(srcLen / 2, NULL, DYNAMIC_TYPE_OPENSSL);
36322     if (targetBuf == NULL) {
36323         return NULL;
36324     }
36325 
36326     while (srcIdx < srcLen) {
36327         if (str[srcIdx] == ':') {
36328             srcIdx++;
36329             continue;
36330         }
36331 
36332         srcDigitHigh = wolfSSL_OPENSSL_hexchar2int(str[srcIdx++]);
36333         srcDigitLow = wolfSSL_OPENSSL_hexchar2int(str[srcIdx++]);
36334         if (srcDigitHigh < 0 || srcDigitLow < 0) {
36335             WOLFSSL_MSG("Invalid hex character.");
36336             XFREE(targetBuf, NULL, DYNAMIC_TYPE_OPENSSL);
36337             return NULL;
36338         }
36339 
36340         targetBuf[targetIdx++] = (unsigned char)((srcDigitHigh << 4) | srcDigitLow);
36341     }
36342 
36343     if (len != NULL)
36344         *len = targetIdx;
36345 
36346     return targetBuf;
36347 }
36348 
wolfSSL_OPENSSL_init_ssl(word64 opts,const OPENSSL_INIT_SETTINGS * settings)36349 int wolfSSL_OPENSSL_init_ssl(word64 opts, const OPENSSL_INIT_SETTINGS *settings)
36350 {
36351     (void)opts;
36352     (void)settings;
36353     return wolfSSL_library_init();
36354 }
36355 
wolfSSL_OPENSSL_init_crypto(word64 opts,const OPENSSL_INIT_SETTINGS * settings)36356 int wolfSSL_OPENSSL_init_crypto(word64 opts, const OPENSSL_INIT_SETTINGS* settings)
36357 {
36358     (void)opts;
36359     (void)settings;
36360     return wolfSSL_library_init();
36361 }
36362 
36363 #if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_PEM_TO_DER)
36364 
EncryptDerKey(byte * der,int * derSz,const EVP_CIPHER * cipher,unsigned char * passwd,int passwdSz,byte ** cipherInfo,int maxDerSz)36365 static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
36366                          unsigned char* passwd, int passwdSz, byte **cipherInfo,
36367                          int maxDerSz)
36368 {
36369     int ret, paddingSz;
36370     word32 idx, cipherInfoSz;
36371 #ifdef WOLFSSL_SMALL_STACK
36372     EncryptedInfo* info = NULL;
36373 #else
36374     EncryptedInfo  info[1];
36375 #endif
36376 
36377     WOLFSSL_ENTER("EncryptDerKey");
36378 
36379     if (der == NULL || derSz == NULL || cipher == NULL ||
36380         passwd == NULL || cipherInfo == NULL)
36381         return BAD_FUNC_ARG;
36382 
36383 #ifdef WOLFSSL_SMALL_STACK
36384     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
36385                                    DYNAMIC_TYPE_ENCRYPTEDINFO);
36386     if (info == NULL) {
36387         WOLFSSL_MSG("malloc failed");
36388         return WOLFSSL_FAILURE;
36389     }
36390 #endif
36391 
36392     XMEMSET(info, 0, sizeof(EncryptedInfo));
36393 
36394     /* set the cipher name on info */
36395     XSTRNCPY(info->name, cipher, NAME_SZ-1);
36396     info->name[NAME_SZ-1] = '\0'; /* null term */
36397 
36398     ret = wc_EncryptedInfoGet(info, info->name);
36399     if (ret != 0) {
36400         WOLFSSL_MSG("unsupported cipher");
36401     #ifdef WOLFSSL_SMALL_STACK
36402         XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
36403     #endif
36404         return WOLFSSL_FAILURE;
36405     }
36406 
36407     /* Generate a random salt */
36408     if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != WOLFSSL_SUCCESS) {
36409         WOLFSSL_MSG("generate iv failed");
36410 #ifdef WOLFSSL_SMALL_STACK
36411         XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
36412 #endif
36413         return WOLFSSL_FAILURE;
36414     }
36415 
36416     /* add the padding before encryption */
36417     paddingSz = ((*derSz)/info->ivSz + 1) * info->ivSz - (*derSz);
36418     if (paddingSz == 0)
36419         paddingSz = info->ivSz;
36420     if (maxDerSz < *derSz + paddingSz) {
36421         WOLFSSL_MSG("not enough DER buffer allocated");
36422 #ifdef WOLFSSL_SMALL_STACK
36423         XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
36424 #endif
36425         return WOLFSSL_FAILURE;
36426     }
36427     XMEMSET(der+(*derSz), (byte)paddingSz, paddingSz);
36428     (*derSz) += paddingSz;
36429 
36430     /* encrypt buffer */
36431     if (wc_BufferKeyEncrypt(info, der, *derSz, passwd, passwdSz, WC_MD5) != 0) {
36432         WOLFSSL_MSG("encrypt key failed");
36433 #ifdef WOLFSSL_SMALL_STACK
36434         XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
36435 #endif
36436         return WOLFSSL_FAILURE;
36437     }
36438 
36439     /* create cipher info : 'cipher_name,Salt(hex)' */
36440     cipherInfoSz = (word32)(2*info->ivSz + XSTRLEN(info->name) + 2);
36441     *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL,
36442                                 DYNAMIC_TYPE_STRING);
36443     if (*cipherInfo == NULL) {
36444         WOLFSSL_MSG("malloc failed");
36445 #ifdef WOLFSSL_SMALL_STACK
36446         XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
36447 #endif
36448         return WOLFSSL_FAILURE;
36449     }
36450     XSTRNCPY((char*)*cipherInfo, info->name, cipherInfoSz);
36451     XSTRNCAT((char*)*cipherInfo, ",", 2);
36452 
36453     idx = (word32)XSTRLEN((char*)*cipherInfo);
36454     cipherInfoSz -= idx;
36455     ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo+idx, &cipherInfoSz);
36456 
36457 #ifdef WOLFSSL_SMALL_STACK
36458     XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
36459 #endif
36460     if (ret != 0) {
36461         WOLFSSL_MSG("Base16_Encode failed");
36462         XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_STRING);
36463         return WOLFSSL_FAILURE;
36464     }
36465 
36466     return WOLFSSL_SUCCESS;
36467 }
36468 #endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */
36469 
36470 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
wolfSSL_RSA_To_Der(WOLFSSL_RSA * rsa,byte ** outBuf,int publicKey,void * heap)36471 static int wolfSSL_RSA_To_Der(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey, void* heap)
36472 {
36473     int derSz  = 0;
36474     int ret;
36475     byte* derBuf;
36476 
36477     WOLFSSL_ENTER("wolfSSL_RSA_To_Der");
36478 
36479     if (!rsa || (publicKey != 0 && publicKey != 1)) {
36480         WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", BAD_FUNC_ARG);
36481         return BAD_FUNC_ARG;
36482     }
36483 
36484     if (rsa->inSet == 0) {
36485         if ((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) {
36486             WOLFSSL_MSG("SetRsaInternal() Failed");
36487             WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", ret);
36488             return ret;
36489         }
36490     }
36491 
36492     if (publicKey) {
36493         if ((derSz = wc_RsaPublicKeyDerSize((RsaKey *)rsa->internal, 1)) < 0) {
36494             WOLFSSL_MSG("wc_RsaPublicKeyDerSize failed");
36495             WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz);
36496             return derSz;
36497         }
36498     }
36499     else {
36500         if ((derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, NULL, 0)) < 0) {
36501             WOLFSSL_MSG("wc_RsaKeyToDer failed");
36502             WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz);
36503             return derSz;
36504         }
36505     }
36506 
36507     if (outBuf) {
36508         if (!(derBuf = (byte*)XMALLOC(derSz, heap, DYNAMIC_TYPE_TMP_BUFFER))) {
36509             WOLFSSL_MSG("malloc failed");
36510             WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", MEMORY_ERROR);
36511             return MEMORY_ERROR;
36512         }
36513 
36514         /* Key to DER */
36515         if (publicKey) {
36516             derSz = wc_RsaKeyToPublicDer((RsaKey*)rsa->internal, derBuf, derSz);
36517         }
36518         else {
36519             derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf, derSz);
36520         }
36521 
36522         if (derSz < 0) {
36523             WOLFSSL_MSG("wc_RsaKeyToPublicDer failed");
36524             XFREE(derBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
36525         }
36526         else {
36527             if (*outBuf) {
36528                 XMEMCPY(*outBuf, derBuf, derSz);
36529                 XFREE(derBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
36530             }
36531             else {
36532                 *outBuf = derBuf;
36533             }
36534         }
36535     }
36536 
36537     (void)heap; /* unused if memory is disabled */
36538     WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz);
36539     return derSz;
36540 }
36541 #endif
36542 
36543 #ifndef NO_BIO
36544 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && !defined(NO_RSA)
36545 /* Takes a WOLFSSL_RSA key and writes it out to a WOLFSSL_BIO
36546  *
36547  * bio    the WOLFSSL_BIO to write to
36548  * key    the WOLFSSL_RSA key to write out
36549  * cipher cipher used
36550  * passwd password string if used
36551  * len    length of password string
36552  * cb     password callback to use
36553  * arg    null terminated string for passphrase
36554  */
wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO * bio,WOLFSSL_RSA * key,const WOLFSSL_EVP_CIPHER * cipher,unsigned char * passwd,int len,wc_pem_password_cb * cb,void * arg)36555 int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key,
36556                                         const WOLFSSL_EVP_CIPHER* cipher,
36557                                         unsigned char* passwd, int len,
36558                                         wc_pem_password_cb* cb, void* arg)
36559 {
36560     int ret;
36561     WOLFSSL_EVP_PKEY* pkey;
36562 
36563     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_RSAPrivateKey");
36564 
36565     if (bio == NULL || key == NULL) {
36566         WOLFSSL_MSG("Bad Function Arguments");
36567         return WOLFSSL_FAILURE;
36568     }
36569 
36570     pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
36571     if (pkey == NULL) {
36572         WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
36573         return WOLFSSL_FAILURE;
36574     }
36575 
36576     pkey->type   = EVP_PKEY_RSA;
36577     pkey->rsa    = key;
36578     pkey->ownRsa = 0;
36579 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
36580     /* similar to how wolfSSL_PEM_write_mem_RSAPrivateKey finds DER of key */
36581     {
36582         int derSz;
36583         byte* derBuf = NULL;
36584 
36585         if ((derSz = wolfSSL_RSA_To_Der(key, &derBuf, 0, bio->heap)) < 0) {
36586             WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
36587             return WOLFSSL_FAILURE;
36588         }
36589 
36590         if (derBuf == NULL) {
36591             WOLFSSL_MSG("wolfSSL_RSA_To_Der failed to get buffer");
36592             return WOLFSSL_FAILURE;
36593         }
36594 
36595         pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap,
36596                 DYNAMIC_TYPE_TMP_BUFFER);
36597         if (pkey->pkey.ptr == NULL) {
36598             WOLFSSL_MSG("key malloc failed");
36599             XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
36600             wolfSSL_EVP_PKEY_free(pkey);
36601             return WOLFSSL_FAILURE;
36602         }
36603         pkey->pkey_sz = derSz;
36604         XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
36605         XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
36606     }
36607 #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
36608 
36609     ret = wolfSSL_PEM_write_bio_PrivateKey(bio, pkey, cipher, passwd, len,
36610                                         cb, arg);
36611 
36612     wolfSSL_EVP_PKEY_free(pkey);
36613 
36614     return ret;
36615 }
36616 
36617 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
36618 /* forward declaration for wolfSSL_PEM_write_bio_RSA_PUBKEY */
36619 static int WriteBioPUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key);
36620 
36621 /* Takes an RSA public key and writes it out to a WOLFSSL_BIO
36622  * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
36623  */
wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO * bio,WOLFSSL_RSA * rsa)36624 int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa)
36625 {
36626     int ret = 0;
36627     WOLFSSL_EVP_PKEY* pkey = NULL;
36628 
36629     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_RSA_PUBKEY");
36630 
36631     if (bio == NULL || rsa == NULL) {
36632         WOLFSSL_MSG("Bad Function Arguments");
36633         return WOLFSSL_FAILURE;
36634     }
36635 
36636     /* Initialize pkey structure */
36637     pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
36638     if (pkey == NULL) {
36639         WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
36640         return WOLFSSL_FAILURE;
36641     }
36642 
36643     pkey->type   = EVP_PKEY_RSA;
36644     pkey->rsa    = rsa;
36645     pkey->ownRsa = 0;
36646 
36647     ret = WriteBioPUBKEY(bio, pkey);
36648     wolfSSL_EVP_PKEY_free(pkey);
36649 
36650     return ret;
36651 }
36652 #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
36653 
36654 
36655 /* Reads an RSA public key from a WOLFSSL_BIO into a WOLFSSL_RSA
36656  * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
36657  */
wolfSSL_PEM_read_bio_RSA_PUBKEY(WOLFSSL_BIO * bio,WOLFSSL_RSA ** rsa,wc_pem_password_cb * cb,void * pass)36658 WOLFSSL_RSA *wolfSSL_PEM_read_bio_RSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_RSA** rsa,
36659                                              wc_pem_password_cb* cb,
36660                                              void *pass)
36661 {
36662     WOLFSSL_EVP_PKEY* pkey;
36663     WOLFSSL_RSA* local;
36664 
36665     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_RSA_PUBKEY");
36666 
36667     pkey = wolfSSL_PEM_read_bio_PUBKEY(bio, NULL, cb, pass);
36668     if (pkey == NULL) {
36669         return NULL;
36670     }
36671 
36672     /* Since the WOLFSSL_RSA structure is being taken from WOLFSSL_EVP_PKEY the
36673      * flag indicating that the WOLFSSL_RSA structure is owned should be FALSE
36674      * to avoid having it free'd */
36675     pkey->ownRsa = 0;
36676     local = pkey->rsa;
36677     if (rsa != NULL){
36678         *rsa = local;
36679     }
36680 
36681     wolfSSL_EVP_PKEY_free(pkey);
36682     return local;
36683 }
36684 
36685 #endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) && !defined(NO_RSA) */
36686 
WriteBioPUBKEY(WOLFSSL_BIO * bio,WOLFSSL_EVP_PKEY * key)36687 static int WriteBioPUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
36688 {
36689     int ret;
36690     int pemSz;
36691     byte* pemBuf;
36692     int derSz = 0;
36693     byte* derBuf = NULL;
36694 
36695     if (bio == NULL || key == NULL) {
36696         WOLFSSL_MSG("Bad parameters");
36697         return WOLFSSL_FAILURE;
36698     }
36699 
36700     switch (key->type) {
36701 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
36702         case EVP_PKEY_RSA:
36703             if ((derSz = wolfSSL_RSA_To_Der(key->rsa, &derBuf, 1, bio->heap))
36704                     < 0) {
36705                 WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
36706                 break;
36707             }
36708             break;
36709 #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
36710 #if !defined(NO_DSA) && !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
36711         defined(WOLFSSL_CERT_GEN))
36712         case EVP_PKEY_DSA:
36713             if (key->dsa == NULL) {
36714                 WOLFSSL_MSG("key->dsa is null");
36715                 break;
36716             }
36717             derSz = MAX_DSA_PUBKEY_SZ;
36718             derBuf = (byte*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
36719             if (derBuf == NULL) {
36720                 WOLFSSL_MSG("malloc failed");
36721                 break;
36722             }
36723             /* Key to DER */
36724             derSz = wc_DsaKeyToPublicDer((DsaKey*)key->dsa->internal, derBuf,
36725                     derSz);
36726             if (derSz < 0) {
36727                 WOLFSSL_MSG("wc_DsaKeyToDer failed");
36728                 break;
36729             }
36730             break;
36731 #endif /* !NO_DSA && !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
36732 #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
36733         case EVP_PKEY_EC:
36734         {
36735             if (key->ecc == NULL) {
36736                 WOLFSSL_MSG("key->ecc is null");
36737                 break;
36738             }
36739             derSz = wc_EccPublicKeyDerSize((ecc_key*)key->ecc->internal, 1);
36740             if (derSz <= 0) {
36741                 WOLFSSL_MSG("wc_EccPublicKeyDerSize failed");
36742                 break;
36743             }
36744             derBuf = (byte*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
36745             if (derBuf == NULL) {
36746                 WOLFSSL_MSG("malloc failed");
36747                 break;
36748             }
36749             derSz = wc_EccPublicKeyToDer((ecc_key*)key->ecc->internal, derBuf,
36750                     derSz, 1);
36751             if (derSz < 0) {
36752                 WOLFSSL_MSG("wc_EccPublicKeyToDer failed");
36753                 break;
36754             }
36755             break;
36756         }
36757 #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
36758 #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
36759         case EVP_PKEY_DH:
36760             WOLFSSL_MSG("Writing DH PUBKEY not supported!");
36761             break;
36762 #endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
36763         default:
36764             WOLFSSL_MSG("Unknown Key type!");
36765             break;
36766     }
36767 
36768     if (derBuf == NULL || derSz <= 0) {
36769         if (derBuf != NULL)
36770             XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
36771         return WOLFSSL_FAILURE;
36772     }
36773 
36774     pemSz = wc_DerToPem(derBuf, derSz, NULL, 0, PUBLICKEY_TYPE);
36775     if (pemSz < 0) {
36776         WOLFSSL_LEAVE("WriteBioPUBKEY", pemSz);
36777         XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
36778         return WOLFSSL_FAILURE;
36779     }
36780 
36781     pemBuf = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
36782     if (pemBuf == NULL) {
36783         WOLFSSL_LEAVE("WriteBioPUBKEY", pemSz);
36784         XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
36785         return WOLFSSL_FAILURE;
36786     }
36787 
36788     ret = wc_DerToPem(derBuf, derSz, pemBuf, pemSz, PUBLICKEY_TYPE);
36789     XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
36790     if (ret < 0) {
36791         WOLFSSL_LEAVE("WriteBioPUBKEY", ret);
36792         XFREE(pemBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
36793         return WOLFSSL_FAILURE;
36794     }
36795 
36796     ret = wolfSSL_BIO_write(bio, pemBuf, pemSz);
36797     XFREE(pemBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
36798     if (ret != pemSz) {
36799         WOLFSSL_MSG("Unable to write full PEM to BIO");
36800         return WOLFSSL_FAILURE;
36801     }
36802 
36803     return WOLFSSL_SUCCESS;
36804 }
36805 
36806 /* Takes a public key and writes it out to a WOLFSSL_BIO
36807  * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
36808  */
wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO * bio,WOLFSSL_EVP_PKEY * key)36809 int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
36810 {
36811     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY");
36812 
36813     return WriteBioPUBKEY(bio, key);
36814 }
36815 
36816 /* Takes a private key and writes it out to a WOLFSSL_BIO
36817  * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
36818  */
wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO * bio,WOLFSSL_EVP_PKEY * key,const WOLFSSL_EVP_CIPHER * cipher,unsigned char * passwd,int len,wc_pem_password_cb * cb,void * arg)36819 int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
36820                                      const WOLFSSL_EVP_CIPHER* cipher,
36821                                      unsigned char* passwd, int len,
36822                                      wc_pem_password_cb* cb, void* arg)
36823 {
36824     byte* keyDer;
36825     int pemSz;
36826     int type;
36827     int ret;
36828     byte* tmp;
36829 
36830     (void)cipher;
36831     (void)passwd;
36832     (void)len;
36833     (void)cb;
36834     (void)arg;
36835 
36836     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
36837 
36838     if (bio == NULL || key == NULL) {
36839         WOLFSSL_MSG("Bad Function Arguments");
36840         return WOLFSSL_FAILURE;
36841     }
36842 
36843     keyDer = (byte*)key->pkey.ptr;
36844 
36845     switch (key->type) {
36846 #ifndef NO_RSA
36847         case EVP_PKEY_RSA:
36848             type = PRIVATEKEY_TYPE;
36849             break;
36850 #endif
36851 
36852 #ifndef NO_DSA
36853         case EVP_PKEY_DSA:
36854             type = DSA_PRIVATEKEY_TYPE;
36855             break;
36856 #endif
36857 
36858 #ifdef HAVE_ECC
36859         case EVP_PKEY_EC:
36860             type = ECC_PRIVATEKEY_TYPE;
36861             break;
36862 #endif
36863 
36864 #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
36865         case EVP_PKEY_DH:
36866             type = DH_PRIVATEKEY_TYPE;
36867             break;
36868 #endif
36869 
36870         default:
36871             WOLFSSL_MSG("Unknown Key type!");
36872             type = PRIVATEKEY_TYPE;
36873     }
36874 
36875     pemSz = wc_DerToPem(keyDer, key->pkey_sz, NULL, 0, type);
36876     if (pemSz < 0) {
36877         WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", pemSz);
36878         return WOLFSSL_FAILURE;
36879     }
36880     tmp = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
36881     if (tmp == NULL) {
36882         return MEMORY_E;
36883     }
36884 
36885     ret = wc_DerToPem(keyDer, key->pkey_sz, tmp, pemSz, type);
36886     if (ret < 0) {
36887         WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", ret);
36888         XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
36889         return WOLFSSL_FAILURE;
36890     }
36891 
36892     ret = wolfSSL_BIO_write(bio, tmp, pemSz);
36893     XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
36894     if (ret != pemSz) {
36895         WOLFSSL_MSG("Unable to write full PEM to BIO");
36896         return WOLFSSL_FAILURE;
36897     }
36898 
36899     return WOLFSSL_SUCCESS;
36900 }
36901 #endif /* !NO_BIO */
36902 
36903 #if (defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)) && \
36904     (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
36905 
36906 /* return code compliant with OpenSSL :
36907  *   1 if success, 0 if error
36908  */
wolfSSL_PEM_write_mem_RSAPrivateKey(RSA * rsa,const EVP_CIPHER * cipher,unsigned char * passwd,int passwdSz,unsigned char ** pem,int * plen)36909 int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher,
36910                                         unsigned char* passwd, int passwdSz,
36911                                         unsigned char **pem, int *plen)
36912 {
36913     byte *derBuf = NULL, *tmp, *cipherInfo = NULL;
36914     int  derSz = 0;
36915     const int type = PRIVATEKEY_TYPE;
36916     const char* header = NULL;
36917     const char* footer = NULL;
36918 
36919     WOLFSSL_ENTER("wolfSSL_PEM_write_mem_RSAPrivateKey");
36920 
36921     if (pem == NULL || plen == NULL || rsa == NULL || rsa->internal == NULL) {
36922         WOLFSSL_MSG("Bad function arguments");
36923         return WOLFSSL_FAILURE;
36924     }
36925 
36926     if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
36927         return WOLFSSL_FAILURE;
36928 
36929     if (rsa->inSet == 0) {
36930         WOLFSSL_MSG("No RSA internal set, do it");
36931 
36932         if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
36933             WOLFSSL_MSG("SetRsaInternal failed");
36934             return WOLFSSL_FAILURE;
36935         }
36936     }
36937 
36938     if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 0, rsa->heap)) < 0) {
36939         WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
36940         return WOLFSSL_FAILURE;
36941     }
36942 
36943     /* encrypt DER buffer if required */
36944     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
36945         int ret;
36946         int blockSz = wolfSSL_EVP_CIPHER_block_size(cipher);
36947         byte *tmpBuf;
36948 
36949         /* Add space for padding */
36950         if (!(tmpBuf = (byte*)XREALLOC(derBuf, derSz + blockSz, rsa->heap,
36951                 DYNAMIC_TYPE_TMP_BUFFER))) {
36952             WOLFSSL_MSG("Extending DER buffer failed");
36953             XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
36954             return WOLFSSL_FAILURE;
36955         }
36956         derBuf = tmpBuf;
36957 
36958         ret = EncryptDerKey(derBuf, &derSz, cipher,
36959                             passwd, passwdSz, &cipherInfo, derSz + blockSz);
36960         if (ret != WOLFSSL_SUCCESS) {
36961             WOLFSSL_MSG("EncryptDerKey failed");
36962             XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_DER);
36963             return ret;
36964         }
36965 
36966         /* tmp buffer with a max size */
36967         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
36968             (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
36969     }
36970     else {
36971         /* tmp buffer with a max size */
36972         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
36973             (int)XSTRLEN(footer) + 1;
36974     }
36975 
36976     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_PEM);
36977     if (tmp == NULL) {
36978         WOLFSSL_MSG("malloc failed");
36979         XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_DER);
36980         if (cipherInfo != NULL)
36981             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
36982         return WOLFSSL_FAILURE;
36983     }
36984 
36985     /* DER to PEM */
36986     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type);
36987     if (*plen <= 0) {
36988         WOLFSSL_MSG("wc_DerToPemEx failed");
36989         XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_DER);
36990         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
36991         if (cipherInfo != NULL)
36992             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
36993         return WOLFSSL_FAILURE;
36994     }
36995     XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_DER);
36996     if (cipherInfo != NULL)
36997         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
36998 
36999     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
37000     if (*pem == NULL) {
37001         WOLFSSL_MSG("malloc failed");
37002         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
37003         return WOLFSSL_FAILURE;
37004     }
37005     XMEMSET(*pem, 0, (*plen)+1);
37006 
37007     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
37008         WOLFSSL_MSG("XMEMCPY failed");
37009         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
37010         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
37011         return WOLFSSL_FAILURE;
37012     }
37013     XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
37014 
37015     return WOLFSSL_SUCCESS;
37016 }
37017 
37018 
37019 #ifndef NO_FILESYSTEM
37020 /* return code compliant with OpenSSL :
37021  *   1 if success, 0 if error
37022  */
wolfSSL_PEM_write_RSAPrivateKey(XFILE fp,WOLFSSL_RSA * rsa,const EVP_CIPHER * enc,unsigned char * kstr,int klen,wc_pem_password_cb * cb,void * u)37023 int wolfSSL_PEM_write_RSAPrivateKey(XFILE fp, WOLFSSL_RSA *rsa,
37024                                     const EVP_CIPHER *enc,
37025                                     unsigned char *kstr, int klen,
37026                                     wc_pem_password_cb *cb, void *u)
37027 {
37028     byte *pem;
37029     int  plen, ret;
37030 
37031     (void)cb;
37032     (void)u;
37033 
37034     WOLFSSL_MSG("wolfSSL_PEM_write_RSAPrivateKey");
37035 
37036     if (fp == XBADFILE || rsa == NULL || rsa->internal == NULL)
37037     {
37038         WOLFSSL_MSG("Bad function arguments");
37039         return WOLFSSL_FAILURE;
37040     }
37041 
37042     ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, enc, kstr, klen, &pem, &plen);
37043     if (ret != WOLFSSL_SUCCESS) {
37044         WOLFSSL_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed");
37045         return WOLFSSL_FAILURE;
37046     }
37047 
37048     ret = (int)XFWRITE(pem, plen, 1, fp);
37049     if (ret != 1) {
37050         WOLFSSL_MSG("RSA private key file write failed");
37051         return WOLFSSL_FAILURE;
37052     }
37053 
37054     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
37055     return WOLFSSL_SUCCESS;
37056 }
37057 #endif /* NO_FILESYSTEM */
37058 #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA && WOLFSSL_PEM_TO_DER */
37059 
37060 /* Colon separated list of <public key>+<digest> algorithms.
37061  * Replaces list in context.
37062  */
wolfSSL_CTX_set1_sigalgs_list(WOLFSSL_CTX * ctx,const char * list)37063 int wolfSSL_CTX_set1_sigalgs_list(WOLFSSL_CTX* ctx, const char* list)
37064 {
37065     WOLFSSL_MSG("wolfSSL_CTX_set1_sigalg_list");
37066 
37067     if (ctx == NULL || list == NULL) {
37068         WOLFSSL_MSG("Bad function arguments");
37069         return WOLFSSL_FAILURE;
37070     }
37071 
37072     /* alloc/init on demand only */
37073     if (ctx->suites == NULL) {
37074         ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
37075                                        DYNAMIC_TYPE_SUITES);
37076         if (ctx->suites == NULL) {
37077             WOLFSSL_MSG("Memory alloc for Suites failed");
37078             return WOLFSSL_FAILURE;
37079         }
37080         XMEMSET(ctx->suites, 0, sizeof(Suites));
37081     }
37082 
37083     return SetSuitesHashSigAlgo(ctx->suites, list);
37084 }
37085 
37086 /* Colon separated list of <public key>+<digest> algorithms.
37087  * Replaces list in SSL.
37088  */
wolfSSL_set1_sigalgs_list(WOLFSSL * ssl,const char * list)37089 int wolfSSL_set1_sigalgs_list(WOLFSSL* ssl, const char* list)
37090 {
37091     WOLFSSL_MSG("wolfSSL_set1_sigalg_list");
37092 
37093     if (ssl == NULL) {
37094         WOLFSSL_MSG("Bad function arguments");
37095         return WOLFSSL_FAILURE;
37096     }
37097 
37098 #ifdef SINGLE_THREADED
37099     if (ssl->ctx->suites == ssl->suites) {
37100         ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
37101                                        DYNAMIC_TYPE_SUITES);
37102         if (ssl->suites == NULL) {
37103             WOLFSSL_MSG("Suites Memory error");
37104             return MEMORY_E;
37105         }
37106         *ssl->suites = *ssl->ctx->suites;
37107         ssl->options.ownSuites = 1;
37108     }
37109 #endif
37110     if (ssl == NULL || list == NULL) {
37111         WOLFSSL_MSG("Bad function arguments");
37112         return WOLFSSL_FAILURE;
37113     }
37114 
37115     return SetSuitesHashSigAlgo(ssl->suites, list);
37116 }
37117 
37118 struct WOLFSSL_HashSigInfo {
37119     int hashAlgo;
37120     int sigAlgo;
37121     int nid;
37122 }  wolfssl_hash_sig_info[] =
37123 {
37124 #ifndef NO_RSA
37125     #ifndef NO_SHA256
37126         { sha256_mac, rsa_sa_algo, CTC_SHA256wRSA },
37127     #endif
37128     #ifdef WOLFSSL_SHA384
37129         { sha384_mac, rsa_sa_algo, CTC_SHA384wRSA },
37130     #endif
37131     #ifdef WOLFSSL_SHA512
37132         { sha512_mac, rsa_sa_algo, CTC_SHA512wRSA },
37133     #endif
37134     #ifdef WOLFSSL_SHA224
37135         { sha224_mac, rsa_sa_algo, CTC_SHA224wRSA },
37136     #endif
37137     #ifndef NO_SHA
37138         { sha_mac,    rsa_sa_algo, CTC_SHAwRSA },
37139     #endif
37140     #ifdef WC_RSA_PSS
37141         #ifndef NO_SHA256
37142             { sha256_mac, rsa_pss_sa_algo, CTC_SHA256wRSA },
37143         #endif
37144         #ifdef WOLFSSL_SHA384
37145             { sha384_mac, rsa_pss_sa_algo, CTC_SHA384wRSA },
37146         #endif
37147         #ifdef WOLFSSL_SHA512
37148             { sha512_mac, rsa_pss_sa_algo, CTC_SHA512wRSA },
37149         #endif
37150         #ifdef WOLFSSL_SHA224
37151             { sha224_mac, rsa_pss_sa_algo, CTC_SHA224wRSA },
37152         #endif
37153     #endif
37154 #endif
37155 #ifdef HAVE_ECC
37156     #ifndef NO_SHA256
37157         { sha256_mac, ecc_dsa_sa_algo, CTC_SHA256wECDSA },
37158     #endif
37159     #ifdef WOLFSSL_SHA384
37160         { sha384_mac, ecc_dsa_sa_algo, CTC_SHA384wECDSA },
37161     #endif
37162     #ifdef WOLFSSL_SHA512
37163         { sha512_mac, ecc_dsa_sa_algo, CTC_SHA512wECDSA },
37164     #endif
37165     #ifdef WOLFSSL_SHA224
37166         { sha224_mac, ecc_dsa_sa_algo, CTC_SHA224wECDSA },
37167     #endif
37168     #ifndef NO_SHA
37169         { sha_mac,    ecc_dsa_sa_algo, CTC_SHAwECDSA },
37170     #endif
37171 #endif
37172 #ifdef HAVE_ED25519
37173     { no_mac, ed25519_sa_algo, CTC_ED25519 },
37174 #endif
37175 #ifdef HAVE_ED448
37176     { no_mac, ed448_sa_algo, CTC_ED448 },
37177 #endif
37178 #ifdef HAVE_PQC
37179     { no_mac, falcon_level1_sa_algo, CTC_FALCON_LEVEL1 },
37180     { no_mac, falcon_level5_sa_algo, CTC_FALCON_LEVEL5 },
37181 #endif
37182 #ifndef NO_DSA
37183     #ifndef NO_SHA
37184         { sha_mac,    dsa_sa_algo, CTC_SHAwDSA },
37185     #endif
37186 #endif
37187 };
37188 #define WOLFSSL_HASH_SIG_INFO_SZ \
37189     (int)(sizeof(wolfssl_hash_sig_info)/sizeof(*wolfssl_hash_sig_info))
37190 
wolfSSL_get_signature_nid(WOLFSSL * ssl,int * nid)37191 int wolfSSL_get_signature_nid(WOLFSSL *ssl, int* nid)
37192 {
37193     int i;
37194     int ret = WOLFSSL_FAILURE;
37195 
37196     WOLFSSL_MSG("wolfSSL_get_signature_nid");
37197 
37198     if (ssl == NULL) {
37199         WOLFSSL_MSG("Bad function arguments");
37200         return WOLFSSL_FAILURE;
37201     }
37202 
37203     for (i = 0; i < WOLFSSL_HASH_SIG_INFO_SZ; i++) {
37204         if (ssl->suites->hashAlgo == wolfssl_hash_sig_info[i].hashAlgo &&
37205                      ssl->suites->sigAlgo == wolfssl_hash_sig_info[i].sigAlgo) {
37206             *nid = wolfssl_hash_sig_info[i].nid;
37207             ret = WOLFSSL_SUCCESS;
37208             break;
37209         }
37210     }
37211 
37212     return ret;
37213 }
37214 
37215 #ifdef HAVE_ECC
37216 
37217 #ifdef ALT_ECC_SIZE
SetIndividualInternalEcc(WOLFSSL_BIGNUM * bn,mp_int * mpi)37218 static int SetIndividualInternalEcc(WOLFSSL_BIGNUM* bn, mp_int* mpi)
37219 {
37220     WOLFSSL_MSG("Entering SetIndividualInternal");
37221 
37222     if (bn == NULL || bn->internal == NULL) {
37223         WOLFSSL_MSG("bn NULL error");
37224         return WOLFSSL_FATAL_ERROR;
37225     }
37226 
37227     if (mpi == NULL) {
37228         WOLFSSL_MSG("mpi NULL error");
37229         return WOLFSSL_FATAL_ERROR;
37230     }
37231 
37232     if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
37233         WOLFSSL_MSG("mp_copy error");
37234         return WOLFSSL_FATAL_ERROR;
37235     }
37236 
37237     return WOLFSSL_SUCCESS;
37238 }
37239 #endif /* ALT_ECC_SIZE */
37240 
37241 /* EC_POINT Openssl -> WolfSSL */
SetECPointInternal(WOLFSSL_EC_POINT * p)37242 static int SetECPointInternal(WOLFSSL_EC_POINT *p)
37243 {
37244     ecc_point* point;
37245     WOLFSSL_ENTER("SetECPointInternal");
37246 
37247     if (p == NULL || p->internal == NULL) {
37248         WOLFSSL_MSG("ECPoint NULL error");
37249         return WOLFSSL_FATAL_ERROR;
37250     }
37251 
37252     point = (ecc_point*)p->internal;
37253 
37254 #ifndef ALT_ECC_SIZE
37255     if (p->X != NULL && SetIndividualInternal(p->X, point->x) != WOLFSSL_SUCCESS) {
37256         WOLFSSL_MSG("ecc point X error");
37257         return WOLFSSL_FATAL_ERROR;
37258     }
37259 
37260     if (p->Y != NULL && SetIndividualInternal(p->Y, point->y) != WOLFSSL_SUCCESS) {
37261         WOLFSSL_MSG("ecc point Y error");
37262         return WOLFSSL_FATAL_ERROR;
37263     }
37264 
37265     if (p->Z != NULL && SetIndividualInternal(p->Z, point->z) != WOLFSSL_SUCCESS) {
37266         WOLFSSL_MSG("ecc point Z error");
37267         return WOLFSSL_FATAL_ERROR;
37268     }
37269 #else
37270     if (p->X != NULL && SetIndividualInternalEcc(p->X, point->x) != WOLFSSL_SUCCESS) {
37271         WOLFSSL_MSG("ecc point X error");
37272         return WOLFSSL_FATAL_ERROR;
37273     }
37274 
37275     if (p->Y != NULL && SetIndividualInternalEcc(p->Y, point->y) != WOLFSSL_SUCCESS) {
37276         WOLFSSL_MSG("ecc point Y error");
37277         return WOLFSSL_FATAL_ERROR;
37278     }
37279 
37280     if (p->Z != NULL && SetIndividualInternalEcc(p->Z, point->z) != WOLFSSL_SUCCESS) {
37281         WOLFSSL_MSG("ecc point Z error");
37282         return WOLFSSL_FATAL_ERROR;
37283     }
37284 #endif
37285 
37286     p->inSet = 1;
37287 
37288     return WOLFSSL_SUCCESS;
37289 }
37290 
37291 /* EC_POINT WolfSSL -> OpenSSL */
SetECPointExternal(WOLFSSL_EC_POINT * p)37292 static int SetECPointExternal(WOLFSSL_EC_POINT *p)
37293 {
37294     ecc_point* point;
37295 
37296     WOLFSSL_ENTER("SetECPointExternal");
37297 
37298     if (p == NULL || p->internal == NULL) {
37299         WOLFSSL_MSG("ECPoint NULL error");
37300         return WOLFSSL_FATAL_ERROR;
37301     }
37302 
37303     point = (ecc_point*)p->internal;
37304 
37305     if (SetIndividualExternal(&p->X, point->x) != WOLFSSL_SUCCESS) {
37306         WOLFSSL_MSG("ecc point X error");
37307         return WOLFSSL_FATAL_ERROR;
37308     }
37309 
37310     if (SetIndividualExternal(&p->Y, point->y) != WOLFSSL_SUCCESS) {
37311         WOLFSSL_MSG("ecc point Y error");
37312         return WOLFSSL_FATAL_ERROR;
37313     }
37314 
37315     if (SetIndividualExternal(&p->Z, point->z) != WOLFSSL_SUCCESS) {
37316         WOLFSSL_MSG("ecc point Z error");
37317         return WOLFSSL_FATAL_ERROR;
37318     }
37319 
37320     p->exSet = 1;
37321 
37322     return WOLFSSL_SUCCESS;
37323 }
37324 
37325 
37326 /* EC_KEY wolfSSL -> OpenSSL */
SetECKeyExternal(WOLFSSL_EC_KEY * eckey)37327 int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
37328 {
37329     ecc_key* key;
37330 
37331     WOLFSSL_ENTER("SetECKeyExternal");
37332 
37333     if (eckey == NULL || eckey->internal == NULL) {
37334         WOLFSSL_MSG("ec key NULL error");
37335         return WOLFSSL_FATAL_ERROR;
37336     }
37337 
37338     key = (ecc_key*)eckey->internal;
37339 
37340     /* set group (OID, nid and idx) */
37341     eckey->group->curve_oid = ecc_sets[key->idx].oidSum;
37342     eckey->group->curve_nid = EccEnumToNID(ecc_sets[key->idx].id);
37343     eckey->group->curve_idx = key->idx;
37344 
37345     if (eckey->pub_key->internal != NULL) {
37346         /* set the internal public key */
37347         if (wc_ecc_copy_point(&key->pubkey,
37348                              (ecc_point*)eckey->pub_key->internal) != MP_OKAY) {
37349             WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed");
37350             return WOLFSSL_FATAL_ERROR;
37351         }
37352 
37353         /* set the external pubkey (point) */
37354         if (SetECPointExternal(eckey->pub_key) != WOLFSSL_SUCCESS) {
37355             WOLFSSL_MSG("SetECKeyExternal SetECPointExternal failed");
37356             return WOLFSSL_FATAL_ERROR;
37357         }
37358     }
37359 
37360     /* set the external privkey */
37361     if (key->type == ECC_PRIVATEKEY) {
37362         if (SetIndividualExternal(&eckey->priv_key, &key->k) != WOLFSSL_SUCCESS) {
37363             WOLFSSL_MSG("ec priv key error");
37364             return WOLFSSL_FATAL_ERROR;
37365         }
37366     }
37367 
37368     eckey->exSet = 1;
37369 
37370     return WOLFSSL_SUCCESS;
37371 }
37372 
37373 /* EC_KEY Openssl -> WolfSSL */
SetECKeyInternal(WOLFSSL_EC_KEY * eckey)37374 int SetECKeyInternal(WOLFSSL_EC_KEY* eckey)
37375 {
37376     ecc_key* key;
37377 
37378     WOLFSSL_ENTER("SetECKeyInternal");
37379 
37380     if (eckey == NULL || eckey->internal == NULL || eckey->group == NULL) {
37381         WOLFSSL_MSG("ec key NULL error");
37382         return WOLFSSL_FATAL_ERROR;
37383     }
37384 
37385     key = (ecc_key*)eckey->internal;
37386 
37387     /* validate group */
37388     if ((eckey->group->curve_idx < 0) ||
37389         (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) {
37390         WOLFSSL_MSG("invalid curve idx");
37391         return WOLFSSL_FATAL_ERROR;
37392     }
37393 
37394     /* set group (idx of curve and corresponding domain parameters) */
37395     key->idx = eckey->group->curve_idx;
37396     key->dp = &ecc_sets[key->idx];
37397 
37398     /* set pubkey (point) */
37399     if (eckey->pub_key != NULL) {
37400         if (SetECPointInternal(eckey->pub_key) != WOLFSSL_SUCCESS) {
37401             WOLFSSL_MSG("ec key pub error");
37402             return WOLFSSL_FATAL_ERROR;
37403         }
37404 
37405         /* copy over the public point to key */
37406         if (wc_ecc_copy_point((ecc_point*)eckey->pub_key->internal, &key->pubkey) != MP_OKAY) {
37407             WOLFSSL_MSG("wc_ecc_copy_point error");
37408             return WOLFSSL_FATAL_ERROR;
37409         }
37410 
37411         /* public key */
37412         key->type = ECC_PUBLICKEY;
37413     }
37414 
37415     /* set privkey */
37416     if (eckey->priv_key != NULL) {
37417         if (SetIndividualInternal(eckey->priv_key, &key->k) != WOLFSSL_SUCCESS) {
37418             WOLFSSL_MSG("ec key priv error");
37419             return WOLFSSL_FATAL_ERROR;
37420         }
37421 
37422         /* private key */
37423         if (!mp_iszero(&key->k))
37424             key->type = ECC_PRIVATEKEY;
37425     }
37426 
37427     eckey->inSet = 1;
37428 
37429     return WOLFSSL_SUCCESS;
37430 }
37431 
wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY * key)37432 WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key)
37433 {
37434     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_public_key");
37435 
37436     if (key == NULL) {
37437         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_public_key Bad arguments");
37438         return NULL;
37439     }
37440 
37441     return key->pub_key;
37442 }
37443 
wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY * key)37444 const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key)
37445 {
37446     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_group");
37447 
37448     if (key == NULL) {
37449         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_group Bad arguments");
37450         return NULL;
37451     }
37452 
37453     return key->group;
37454 }
37455 
37456 
37457 /* return code compliant with OpenSSL :
37458  *   1 if success, 0 if error
37459  */
wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY * key,const WOLFSSL_BIGNUM * priv_key)37460 int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key,
37461                                    const WOLFSSL_BIGNUM *priv_key)
37462 {
37463     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_private_key");
37464 
37465     if (key == NULL || priv_key == NULL) {
37466         WOLFSSL_MSG("Bad arguments");
37467         return WOLFSSL_FAILURE;
37468     }
37469 
37470     /* free key if previously set */
37471     if (key->priv_key != NULL)
37472         wolfSSL_BN_free(key->priv_key);
37473 
37474     key->priv_key = wolfSSL_BN_dup(priv_key);
37475     if (key->priv_key == NULL) {
37476         WOLFSSL_MSG("key ecc priv key NULL");
37477         return WOLFSSL_FAILURE;
37478     }
37479 
37480     if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
37481         WOLFSSL_MSG("SetECKeyInternal failed");
37482         wolfSSL_BN_free(key->priv_key);
37483         return WOLFSSL_FAILURE;
37484     }
37485 
37486     return WOLFSSL_SUCCESS;
37487 }
37488 
37489 
wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY * key)37490 WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key)
37491 {
37492     WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_private_key");
37493 
37494     if (key == NULL) {
37495         WOLFSSL_MSG("wolfSSL_EC_KEY_get0_private_key Bad arguments");
37496         return NULL;
37497     }
37498 
37499     if (wolfSSL_BN_is_zero(key->priv_key)) {
37500         /* return NULL if not set */
37501         return NULL;
37502     }
37503 
37504     return key->priv_key;
37505 }
37506 
wolfSSL_EC_KEY_new_by_curve_name(int nid)37507 WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid)
37508 {
37509     WOLFSSL_EC_KEY *key;
37510     int x;
37511     int eccEnum = NIDToEccEnum(nid);
37512 
37513     WOLFSSL_ENTER("wolfSSL_EC_KEY_new_by_curve_name");
37514 
37515     key = wolfSSL_EC_KEY_new();
37516     if (key == NULL) {
37517         WOLFSSL_MSG("wolfSSL_EC_KEY_new failure");
37518         return NULL;
37519     }
37520 
37521     /* set the nid of the curve */
37522     key->group->curve_nid = nid;
37523 
37524     if (eccEnum != -1) {
37525         /* search and set the corresponding internal curve idx */
37526         for (x = 0; ecc_sets[x].size != 0; x++)
37527             if (ecc_sets[x].id == eccEnum) {
37528                 key->group->curve_idx = x;
37529                 key->group->curve_oid = ecc_sets[x].oidSum;
37530                 break;
37531             }
37532     }
37533 
37534     return key;
37535 }
37536 
wolfSSL_EC_curve_nid2nist(int nid)37537 const char* wolfSSL_EC_curve_nid2nist(int nid)
37538 {
37539     const WOLF_EC_NIST_NAME* nist_name;
37540     for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
37541         if (nist_name->nid == nid) {
37542             return nist_name->name;
37543         }
37544     }
37545     return NULL;
37546 }
37547 
37548 /**
37549  * return nist curve id
37550  * @param name nist curve name
37551  * @return nist curve id when found, 0 when not found
37552  */
wolfSSL_EC_curve_nist2nid(const char * name)37553 int wolfSSL_EC_curve_nist2nid(const char* name)
37554 {
37555     const WOLF_EC_NIST_NAME* nist_name;
37556     for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
37557         if (XSTRCMP(nist_name->name, name) == 0) {
37558             return nist_name->nid;
37559         }
37560     }
37561     return 0;
37562 }
37563 
37564 #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
populate_groups(int * groups,int max_count,char * list)37565 static int populate_groups(int* groups, int max_count, char *list)
37566 {
37567     char *end;
37568     int len;
37569     int count = 0;
37570     const WOLF_EC_NIST_NAME* nist_name;
37571 
37572     if (!groups || !list) {
37573         return -1;
37574     }
37575 
37576     for (end = list; ; list = ++end) {
37577         if (count > max_count) {
37578             WOLFSSL_MSG("Too many curves in list");
37579             return -1;
37580         }
37581         while (*end != ':' && *end != '\0') end++;
37582         len = (int)(end - list); /* end points to char after end
37583                                   * of curve name so no need for -1 */
37584         if ((len < kNistCurves_MIN_NAME_LEN) ||
37585                 (len > kNistCurves_MAX_NAME_LEN)) {
37586             WOLFSSL_MSG("Unrecognized curve name in list");
37587             return -1;
37588         }
37589         for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
37590             if (len == nist_name->name_len &&
37591                     XSTRNCMP(list, nist_name->name, nist_name->name_len) == 0) {
37592                 break;
37593             }
37594         }
37595         if (!nist_name->name) {
37596             WOLFSSL_MSG("Unrecognized curve name in list");
37597             return -1;
37598         }
37599         groups[count++] = nist_name->nid;
37600         if (*end == '\0') break;
37601     }
37602 
37603     return count;
37604 }
37605 
wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX * ctx,char * list)37606 int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list)
37607 {
37608     int groups[WOLFSSL_MAX_GROUP_COUNT];
37609     int count;
37610 
37611     if (!ctx || !list) {
37612         return WOLFSSL_FAILURE;
37613     }
37614 
37615     if ((count = populate_groups(groups,
37616             WOLFSSL_MAX_GROUP_COUNT, list)) == -1) {
37617         return WOLFSSL_FAILURE;
37618     }
37619 
37620     return wolfSSL_CTX_set1_groups(ctx, groups, count);
37621 }
37622 
wolfSSL_set1_groups_list(WOLFSSL * ssl,char * list)37623 int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list)
37624 {
37625     int groups[WOLFSSL_MAX_GROUP_COUNT];
37626     int count;
37627 
37628     if (!ssl || !list) {
37629         return WOLFSSL_FAILURE;
37630     }
37631 
37632     if ((count = populate_groups(groups,
37633             WOLFSSL_MAX_GROUP_COUNT, list)) == -1) {
37634         return WOLFSSL_FAILURE;
37635     }
37636 
37637     return wolfSSL_set1_groups(ssl, groups, count);
37638 }
37639 #endif /* WOLFSSL_TLS13 */
37640 
InitwolfSSL_ECKey(WOLFSSL_EC_KEY * key)37641 static void InitwolfSSL_ECKey(WOLFSSL_EC_KEY* key)
37642 {
37643     if (key) {
37644         key->group    = NULL;
37645         key->pub_key  = NULL;
37646         key->priv_key = NULL;
37647         key->internal = NULL;
37648         key->inSet    = 0;
37649         key->exSet    = 0;
37650     }
37651 }
37652 
wolfSSL_EC_KEY_new_ex(void * heap,int devId)37653 WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_ex(void* heap, int devId)
37654 {
37655     WOLFSSL_EC_KEY *external;
37656     WOLFSSL_ENTER("wolfSSL_EC_KEY_new");
37657 
37658     external = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), heap,
37659                                         DYNAMIC_TYPE_ECC);
37660     if (external == NULL) {
37661         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_KEY failure");
37662         return NULL;
37663     }
37664     XMEMSET(external, 0, sizeof(WOLFSSL_EC_KEY));
37665     external->heap = heap;
37666 
37667     InitwolfSSL_ECKey(external);
37668 
37669     external->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), heap,
37670                                            DYNAMIC_TYPE_ECC);
37671     if (external->internal == NULL) {
37672         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc ecc key failure");
37673         goto error;
37674     }
37675     XMEMSET(external->internal, 0, sizeof(ecc_key));
37676 
37677     if (wc_ecc_init_ex((ecc_key*)external->internal, heap, devId) != 0) {
37678         WOLFSSL_MSG("wolfSSL_EC_KEY_new init ecc key failure");
37679         goto error;
37680     }
37681 
37682     /* Group unknown at creation */
37683     external->group = wolfSSL_EC_GROUP_new_by_curve_name(NID_undef);
37684     if (external->group == NULL) {
37685         WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_GROUP failure");
37686         goto error;
37687     }
37688 
37689     /* public key */
37690     external->pub_key = wolfSSL_EC_POINT_new(external->group);
37691     if (external->pub_key == NULL) {
37692         WOLFSSL_MSG("wolfSSL_EC_POINT_new failure");
37693         goto error;
37694     }
37695 
37696     /* private key */
37697     external->priv_key = wolfSSL_BN_new();
37698     if (external->priv_key == NULL) {
37699         WOLFSSL_MSG("wolfSSL_BN_new failure");
37700         goto error;
37701     }
37702 
37703     return external;
37704 error:
37705     wolfSSL_EC_KEY_free(external);
37706     return NULL;
37707 }
37708 
wolfSSL_EC_KEY_new(void)37709 WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void)
37710 {
37711     return wolfSSL_EC_KEY_new_ex(NULL, INVALID_DEVID);
37712 }
37713 
wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY * key)37714 void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key)
37715 {
37716     WOLFSSL_ENTER("wolfSSL_EC_KEY_free");
37717 
37718     if (key != NULL) {
37719         void* heap = key->heap;
37720         if (key->internal != NULL) {
37721             wc_ecc_free((ecc_key*)key->internal);
37722             XFREE(key->internal, heap, DYNAMIC_TYPE_ECC);
37723         }
37724         wolfSSL_BN_free(key->priv_key);
37725         wolfSSL_EC_POINT_free(key->pub_key);
37726         wolfSSL_EC_GROUP_free(key->group);
37727         InitwolfSSL_ECKey(key); /* set back to NULLs for safety */
37728 
37729         XFREE(key, heap, DYNAMIC_TYPE_ECC);
37730         (void)heap;
37731         /* key = NULL, don't try to access or double free it */
37732     }
37733 }
37734 
37735 /* set the group in WOLFSSL_EC_KEY and return WOLFSSL_SUCCESS on success */
wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY * key,WOLFSSL_EC_GROUP * group)37736 int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group)
37737 {
37738     if (key == NULL || group == NULL)
37739         return WOLFSSL_FAILURE;
37740 
37741     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_group");
37742 
37743     if (key->group != NULL) {
37744         /* free the current group */
37745         wolfSSL_EC_GROUP_free(key->group);
37746     }
37747 
37748     key->group = wolfSSL_EC_GROUP_dup(group);
37749     if (key->group == NULL) {
37750         return WOLFSSL_FAILURE;
37751     }
37752 
37753     return WOLFSSL_SUCCESS;
37754 }
37755 
37756 
wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY * key)37757 int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key)
37758 {
37759     int     initTmpRng = 0;
37760     int     eccEnum;
37761     WC_RNG* rng = NULL;
37762 #ifdef WOLFSSL_SMALL_STACK
37763     WC_RNG* tmpRNG = NULL;
37764 #else
37765     WC_RNG  tmpRNG[1];
37766 #endif
37767 
37768     WOLFSSL_ENTER("wolfSSL_EC_KEY_generate_key");
37769 
37770     if (key == NULL || key->internal == NULL ||
37771         key->group == NULL) {
37772         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key Bad arguments");
37773         return 0;
37774     }
37775     if (key->group->curve_idx < 0) {
37776         /* generate key using the default curve */
37777         /* group should be set, but to retain compat use index 0 */
37778         key->group->curve_idx = ECC_CURVE_DEF;
37779     }
37780 
37781 #ifdef WOLFSSL_SMALL_STACK
37782     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
37783     if (tmpRNG == NULL)
37784         return 0;
37785 #endif
37786 
37787     if (wc_InitRng(tmpRNG) == 0) {
37788         rng = tmpRNG;
37789         initTmpRng = 1;
37790     }
37791     else {
37792         WOLFSSL_MSG("Bad RNG Init, trying global");
37793         if (initGlobalRNG == 0)
37794             WOLFSSL_MSG("Global RNG no Init");
37795         else
37796             rng = &globalRNG;
37797     }
37798 
37799     if (rng == NULL) {
37800         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to set RNG");
37801 #ifdef WOLFSSL_SMALL_STACK
37802         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
37803 #endif
37804         return 0;
37805     }
37806 
37807     /* NIDToEccEnum returns -1 for invalid NID so if key->group->curve_nid
37808      * is 0 then pass ECC_CURVE_DEF as arg */
37809     eccEnum = key->group->curve_nid ?
37810             NIDToEccEnum(key->group->curve_nid) : ECC_CURVE_DEF;
37811     if (wc_ecc_make_key_ex(rng, 0, (ecc_key*)key->internal, eccEnum) != MP_OKAY) {
37812         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed");
37813 #ifdef WOLFSSL_SMALL_STACK
37814         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
37815 #endif
37816         return 0;
37817     }
37818 
37819     if (initTmpRng)
37820         wc_FreeRng(tmpRNG);
37821 #ifdef WOLFSSL_SMALL_STACK
37822     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
37823 #endif
37824 
37825     if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) {
37826         WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key SetECKeyExternal failed");
37827         return 0;
37828     }
37829 
37830     return 1;
37831 }
37832 
37833 #ifndef NO_WOLFSSL_STUB
wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY * key,int asn1_flag)37834 void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag)
37835 {
37836     (void)key;
37837     (void)asn1_flag;
37838 
37839     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_asn1_flag");
37840     WOLFSSL_STUB("EC_KEY_set_asn1_flag");
37841 }
37842 #endif
37843 
setupPoint(const WOLFSSL_EC_POINT * p)37844 static int setupPoint(const WOLFSSL_EC_POINT *p) {
37845     if (!p) {
37846         return WOLFSSL_FAILURE;
37847     }
37848     if (p->inSet == 0) {
37849         WOLFSSL_MSG("No ECPoint internal set, do it");
37850 
37851         if (SetECPointInternal((WOLFSSL_EC_POINT *)p) != WOLFSSL_SUCCESS) {
37852             WOLFSSL_MSG("SetECPointInternal SetECPointInternal failed");
37853             return WOLFSSL_FAILURE;
37854         }
37855     }
37856     return WOLFSSL_SUCCESS;
37857 }
37858 
37859 /* return code compliant with OpenSSL :
37860  *   1 if success, 0 if error
37861  */
wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY * key,const WOLFSSL_EC_POINT * pub)37862 int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
37863                                   const WOLFSSL_EC_POINT *pub)
37864 {
37865     ecc_point *pub_p, *key_p;
37866 
37867     WOLFSSL_ENTER("wolfSSL_EC_KEY_set_public_key");
37868 
37869     if (key == NULL || key->internal == NULL ||
37870         pub == NULL || pub->internal == NULL) {
37871         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad arguments");
37872         return WOLFSSL_FAILURE;
37873     }
37874 
37875     if (key->inSet == 0) {
37876         if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
37877             WOLFSSL_MSG("SetECKeyInternal failed");
37878             return WOLFSSL_FAILURE;
37879         }
37880     }
37881 
37882     if (setupPoint(pub) != WOLFSSL_SUCCESS) {
37883         return WOLFSSL_FAILURE;
37884     }
37885 
37886     pub_p = (ecc_point*)pub->internal;
37887     key_p = (ecc_point*)key->pub_key->internal;
37888 
37889     /* create new point if required */
37890     if (key_p == NULL)
37891         key_p = wc_ecc_new_point();
37892 
37893     if (key_p == NULL) {
37894         WOLFSSL_MSG("key ecc point NULL");
37895         return WOLFSSL_FAILURE;
37896     }
37897 
37898     if (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY) {
37899         WOLFSSL_MSG("ecc_copy_point failure");
37900         return WOLFSSL_FAILURE;
37901     }
37902 
37903     if (SetECPointExternal(key->pub_key) != WOLFSSL_SUCCESS) {
37904         WOLFSSL_MSG("SetECKeyInternal failed");
37905         return WOLFSSL_FAILURE;
37906     }
37907 
37908     if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
37909         WOLFSSL_MSG("SetECKeyInternal failed");
37910         return WOLFSSL_FAILURE;
37911     }
37912 
37913     wolfSSL_EC_POINT_dump("pub", pub);
37914     wolfSSL_EC_POINT_dump("key->pub_key", key->pub_key);
37915 
37916     return WOLFSSL_SUCCESS;
37917 }
37918 
wolfSSL_EC_KEY_check_key(const WOLFSSL_EC_KEY * key)37919 int wolfSSL_EC_KEY_check_key(const WOLFSSL_EC_KEY *key)
37920 {
37921     WOLFSSL_ENTER("wolfSSL_EC_KEY_check_key");
37922 
37923     if (key == NULL || key->internal == NULL) {
37924         WOLFSSL_MSG("Bad parameter");
37925         return WOLFSSL_FAILURE;
37926     }
37927 
37928     if (key->inSet == 0) {
37929         if (SetECKeyInternal((WOLFSSL_EC_KEY*)key) != WOLFSSL_SUCCESS) {
37930             WOLFSSL_MSG("SetECKeyInternal failed");
37931             return WOLFSSL_FAILURE;
37932         }
37933     }
37934 
37935     return wc_ecc_check_key((ecc_key*)key->internal) == 0 ?
37936             WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
37937 }
37938 /* End EC_KEY */
37939 
37940 /* Calculate and return maximum size of the ECDSA signature for the curve */
wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY * key)37941 int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key)
37942 {
37943     const EC_GROUP *group;
37944     int bits, bytes;
37945     word32 headerSz = SIG_HEADER_SZ; /* 2*ASN_TAG + 2*LEN(ENUM) */
37946 
37947     if (key == NULL) {
37948         return WOLFSSL_FAILURE;
37949     }
37950 
37951     if ((group = wolfSSL_EC_KEY_get0_group(key)) == NULL) {
37952         return WOLFSSL_FAILURE;
37953     }
37954     if ((bits = wolfSSL_EC_GROUP_order_bits(group)) == 0) {
37955         /* group is not set */
37956         return WOLFSSL_FAILURE;
37957     }
37958 
37959     bytes = (bits + 7) / 8;  /* bytes needed to hold bits */
37960     return headerSz +
37961             ECC_MAX_PAD_SZ + /* possible leading zeroes in r and s */
37962             bytes + bytes;   /* r and s */
37963 }
37964 
wolfSSL_ECDSA_sign(int type,const unsigned char * digest,int digestSz,unsigned char * sig,unsigned int * sigSz,WOLFSSL_EC_KEY * key)37965 int wolfSSL_ECDSA_sign(int type,
37966     const unsigned char *digest, int digestSz,
37967     unsigned char *sig, unsigned int *sigSz, WOLFSSL_EC_KEY *key)
37968 {
37969     int ret = WOLFSSL_SUCCESS;
37970     WC_RNG* rng = NULL;
37971 #ifdef WOLFSSL_SMALL_STACK
37972     WC_RNG* tmpRNG = NULL;
37973 #else
37974     WC_RNG  tmpRNG[1];
37975 #endif
37976     int initTmpRng = 0;
37977 
37978     WOLFSSL_ENTER("wolfSSL_ECDSA_sign");
37979 
37980     if (!key) {
37981         return WOLFSSL_FAILURE;
37982     }
37983 
37984 #ifdef WOLFSSL_SMALL_STACK
37985     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
37986     if (tmpRNG == NULL)
37987         return WOLFSSL_FAILURE;
37988 #endif
37989 
37990     if (wc_InitRng(tmpRNG) == 0) {
37991         rng = tmpRNG;
37992         initTmpRng = 1;
37993     }
37994     else {
37995         WOLFSSL_MSG("Bad RNG Init, trying global");
37996         if (initGlobalRNG == 0) {
37997             WOLFSSL_MSG("Global RNG no Init");
37998         }
37999         else {
38000             rng = &globalRNG;
38001         }
38002     }
38003     if (rng) {
38004         if (wc_ecc_sign_hash(digest, digestSz, sig, sigSz, rng,
38005                 (ecc_key*)key->internal) != 0) {
38006             ret = WOLFSSL_FAILURE;
38007         }
38008         if (initTmpRng) {
38009             wc_FreeRng(tmpRNG);
38010         }
38011     } else {
38012         ret = WOLFSSL_FAILURE;
38013     }
38014 
38015 #ifdef WOLFSSL_SMALL_STACK
38016     if (tmpRNG)
38017         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
38018 #endif
38019 
38020     (void)type;
38021     return ret;
38022 }
38023 
wolfSSL_ECDSA_verify(int type,const unsigned char * digest,int digestSz,const unsigned char * sig,int sigSz,WOLFSSL_EC_KEY * key)38024 int wolfSSL_ECDSA_verify(int type,
38025     const unsigned char *digest, int digestSz,
38026     const unsigned char *sig, int sigSz, WOLFSSL_EC_KEY *key)
38027 {
38028     int ret = WOLFSSL_SUCCESS;
38029     int verify = 0;
38030 
38031     WOLFSSL_ENTER("wolfSSL_ECDSA_verify");
38032 
38033     if (key == NULL) {
38034         return WOLFSSL_FAILURE;
38035     }
38036 
38037     if (wc_ecc_verify_hash(sig, sigSz, digest, digestSz,
38038             &verify, (ecc_key*)key->internal) != 0) {
38039         ret = WOLFSSL_FAILURE;
38040     }
38041     if (ret == WOLFSSL_SUCCESS && verify != 1) {
38042         WOLFSSL_MSG("wolfSSL_ECDSA_verify failed");
38043         ret = WOLFSSL_FAILURE;
38044     }
38045 
38046     (void)type;
38047     return ret;
38048 }
38049 
38050 #ifndef HAVE_SELFTEST
38051 /* ECC point compression types were not included in selftest ecc.h */
38052 
wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP * group,const WOLFSSL_EC_POINT * point,int form,WOLFSSL_BN_CTX * ctx)38053 char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group,
38054                                  const WOLFSSL_EC_POINT* point, int form,
38055                                  WOLFSSL_BN_CTX* ctx)
38056 {
38057     static const char* hexDigit = "0123456789ABCDEF";
38058     char* hex = NULL;
38059     int id;
38060     int i, sz, len;
38061 
38062     (void)ctx;
38063 
38064     if (group == NULL || point == NULL)
38065         return NULL;
38066 
38067     id = wc_ecc_get_curve_id(group->curve_idx);
38068 
38069     if ((sz = wc_ecc_get_curve_size_from_id(id)) < 0)
38070         return NULL;
38071 
38072     len = sz + 1;
38073     if (form == POINT_CONVERSION_UNCOMPRESSED)
38074         len += sz;
38075 
38076     hex = (char*)XMALLOC(2 * len + 1, NULL, DYNAMIC_TYPE_ECC);
38077     if (hex == NULL)
38078         return NULL;
38079     XMEMSET(hex, 0, 2 * len + 1);
38080 
38081     /* Put in x-ordinate after format byte. */
38082     i = sz - mp_unsigned_bin_size((mp_int*)point->X->internal) + 1;
38083     if (mp_to_unsigned_bin((mp_int*)point->X->internal, (byte*)(hex + i)) < 0) {
38084         XFREE(hex,  NULL, DYNAMIC_TYPE_ECC);
38085         return NULL;
38086     }
38087 
38088     if (form == POINT_CONVERSION_COMPRESSED) {
38089         hex[0] = mp_isodd((mp_int*)point->Y->internal) ? ECC_POINT_COMP_ODD :
38090                                                          ECC_POINT_COMP_EVEN;
38091     }
38092     else {
38093         hex[0] = ECC_POINT_UNCOMP;
38094         /* Put in y-ordinate after x-ordinate */
38095         i = 1 + 2 * sz - mp_unsigned_bin_size((mp_int*)point->Y->internal);
38096         if (mp_to_unsigned_bin((mp_int*)point->Y->internal,
38097                                                         (byte*)(hex + i)) < 0) {
38098             XFREE(hex,  NULL, DYNAMIC_TYPE_ECC);
38099             return NULL;
38100         }
38101     }
38102 
38103     for (i = len-1; i >= 0; i--) {
38104         byte b = hex[i];
38105         hex[i * 2 + 1] = hexDigit[b  & 0xf];
38106         hex[i * 2    ] = hexDigit[b >>   4];
38107     }
38108 
38109     return hex;
38110 }
38111 
38112 #endif /* HAVE_SELFTEST */
38113 
wolfSSL_EC_POINT_dump(const char * msg,const WOLFSSL_EC_POINT * p)38114 void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p)
38115 {
38116 #if defined(DEBUG_WOLFSSL)
38117     char *num;
38118 
38119     WOLFSSL_ENTER("wolfSSL_EC_POINT_dump");
38120 
38121     if (!WOLFSSL_IS_DEBUG_ON() || wolfSSL_GetLoggingCb()) {
38122         return;
38123     }
38124 
38125     if (p == NULL) {
38126         printf("%s = NULL", msg);
38127         return;
38128     }
38129 
38130     printf("%s:\n\tinSet=%d, exSet=%d\n", msg, p->inSet, p->exSet);
38131     num = wolfSSL_BN_bn2hex(p->X);
38132     printf("\tX = %s\n", num);
38133     XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
38134     num = wolfSSL_BN_bn2hex(p->Y);
38135     printf("\tY = %s\n", num);
38136     XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
38137     num = wolfSSL_BN_bn2hex(p->Z);
38138     printf("\tZ = %s\n", num);
38139     XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
38140 #else
38141     (void)msg;
38142     (void)p;
38143 #endif
38144 }
38145 
38146 /* Start EC_GROUP */
38147 
38148 /* return code compliant with OpenSSL :
38149  *   0 if equal, 1 if not and -1 in case of error
38150  */
wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP * a,const WOLFSSL_EC_GROUP * b,WOLFSSL_BN_CTX * ctx)38151 int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
38152                          WOLFSSL_BN_CTX *ctx)
38153 {
38154     (void)ctx;
38155 
38156     WOLFSSL_ENTER("wolfSSL_EC_GROUP_cmp");
38157 
38158     if (a == NULL || b == NULL) {
38159         WOLFSSL_MSG("wolfSSL_EC_GROUP_cmp Bad arguments");
38160         return WOLFSSL_FATAL_ERROR;
38161     }
38162 
38163     /* ok */
38164     if ((a->curve_idx == b->curve_idx) && (a->curve_nid == b->curve_nid))
38165         return 0;
38166 
38167     /* ko */
38168     return 1;
38169 }
38170 
wolfSSL_EC_GROUP_dup(const WOLFSSL_EC_GROUP * src)38171 WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_dup(const WOLFSSL_EC_GROUP *src)
38172 {
38173     if (!src)
38174         return NULL;
38175     return wolfSSL_EC_GROUP_new_by_curve_name(src->curve_nid);
38176 }
38177 
38178 #endif /* HAVE_ECC */
38179 #endif /* OPENSSL_EXTRA */
38180 
38181 #if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
wolfSSL_EC_GROUP_method_of(const WOLFSSL_EC_GROUP * group)38182 const WOLFSSL_EC_METHOD* wolfSSL_EC_GROUP_method_of(
38183                                                 const WOLFSSL_EC_GROUP *group)
38184 {
38185     return group;
38186 }
38187 
wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD * meth)38188 int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth)
38189 {
38190     if (meth) {
38191         return NID_X9_62_prime_field;
38192     }
38193     return WOLFSSL_FAILURE;
38194 }
38195 
wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP * group)38196 void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group)
38197 {
38198     WOLFSSL_ENTER("wolfSSL_EC_GROUP_free");
38199 
38200     XFREE(group, NULL, DYNAMIC_TYPE_ECC);
38201     /* group = NULL, don't try to access or double free it */
38202 }
38203 #endif
38204 
38205 #ifdef OPENSSL_EXTRA
38206 #ifdef HAVE_ECC
38207 #ifndef NO_WOLFSSL_STUB
wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP * group,int flag)38208 void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag)
38209 {
38210     (void)group;
38211     (void)flag;
38212 
38213     WOLFSSL_ENTER("wolfSSL_EC_GROUP_set_asn1_flag");
38214     WOLFSSL_STUB("EC_GROUP_set_asn1_flag");
38215 }
38216 #endif
38217 
wolfSSL_EC_GROUP_new_by_curve_name(int nid)38218 WOLFSSL_EC_GROUP *wolfSSL_EC_GROUP_new_by_curve_name(int nid)
38219 {
38220     WOLFSSL_EC_GROUP *g;
38221     int x, eccEnum;
38222 
38223     WOLFSSL_ENTER("wolfSSL_EC_GROUP_new_by_curve_name");
38224 
38225     /* curve group */
38226     g = (WOLFSSL_EC_GROUP*)XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
38227                                     DYNAMIC_TYPE_ECC);
38228     if (g == NULL) {
38229         WOLFSSL_MSG("wolfSSL_EC_GROUP_new_by_curve_name malloc failure");
38230         return NULL;
38231     }
38232     XMEMSET(g, 0, sizeof(WOLFSSL_EC_GROUP));
38233 
38234     /* set the nid of the curve */
38235     g->curve_nid = nid;
38236     g->curve_idx = -1;
38237 
38238     /* If NID passed in is OpenSSL type, convert it to ecc_curve_id enum */
38239     eccEnum = NIDToEccEnum(nid);
38240     if (eccEnum != -1) {
38241         /* search and set the corresponding internal curve idx */
38242         for (x = 0; ecc_sets[x].size != 0; x++) {
38243             if (ecc_sets[x].id == eccEnum) {
38244                 g->curve_idx = x;
38245                 g->curve_oid = ecc_sets[x].oidSum;
38246                 break;
38247             }
38248         }
38249     }
38250 
38251     return g;
38252 }
38253 
38254 /* return code compliant with OpenSSL :
38255  *   the curve nid if success, 0 if error
38256  */
wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP * group)38257 int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group)
38258 {
38259     int nid;
38260     WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_curve_name");
38261 
38262     if (group == NULL) {
38263         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_curve_name Bad arguments");
38264         return WOLFSSL_FAILURE;
38265     }
38266 
38267     /* If curve_nid is ECC Enum type, return corresponding OpenSSL nid */
38268     if ((nid = EccEnumToNID(group->curve_nid)) != -1)
38269         return nid;
38270 
38271     return group->curve_nid;
38272 }
38273 
38274 /* return code compliant with OpenSSL :
38275  *   the degree of the curve if success, 0 if error
38276  */
wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP * group)38277 int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group)
38278 {
38279     int nid;
38280     int tmp;
38281 
38282     WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_degree");
38283 
38284     if (group == NULL || group->curve_idx < 0) {
38285         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_degree Bad arguments");
38286         return WOLFSSL_FAILURE;
38287     }
38288 
38289     /* If curve_nid passed in is an ecc_curve_id enum, convert it to the
38290         corresponding OpenSSL NID */
38291     tmp = EccEnumToNID(group->curve_nid);
38292     if (tmp != -1){
38293         nid = tmp;
38294     }
38295     else{
38296         nid = group->curve_nid;
38297     }
38298 
38299     switch(nid) {
38300         case NID_secp112r1:
38301         case NID_secp112r2:
38302             return 112;
38303         case NID_secp128r1:
38304         case NID_secp128r2:
38305             return 128;
38306         case NID_secp160k1:
38307         case NID_secp160r1:
38308         case NID_secp160r2:
38309         case NID_brainpoolP160r1:
38310             return 160;
38311         case NID_secp192k1:
38312         case NID_brainpoolP192r1:
38313         case NID_X9_62_prime192v1:
38314             return 192;
38315         case NID_secp224k1:
38316         case NID_secp224r1:
38317         case NID_brainpoolP224r1:
38318             return 224;
38319         case NID_secp256k1:
38320         case NID_brainpoolP256r1:
38321         case NID_X9_62_prime256v1:
38322             return 256;
38323         case NID_brainpoolP320r1:
38324             return 320;
38325         case NID_secp384r1:
38326         case NID_brainpoolP384r1:
38327             return 384;
38328         case NID_secp521r1:
38329             return 521;
38330         case NID_brainpoolP512r1:
38331             return 512;
38332         default:
38333             return WOLFSSL_FAILURE;
38334     }
38335 }
38336 
38337 /* Converts OpenSSL NID value of ECC curves to the associated enum values in
38338    ecc_curve_id, used by ecc_sets[].*/
NIDToEccEnum(int n)38339 int NIDToEccEnum(int n)
38340 {
38341     WOLFSSL_ENTER("NIDToEccEnum()");
38342 
38343     switch(n) {
38344         case NID_X9_62_prime192v1:
38345             return ECC_SECP192R1;
38346         case NID_X9_62_prime192v2:
38347             return ECC_PRIME192V2;
38348         case NID_X9_62_prime192v3:
38349             return ECC_PRIME192V3;
38350         case NID_X9_62_prime239v1:
38351             return ECC_PRIME239V1;
38352         case NID_X9_62_prime239v2:
38353             return ECC_PRIME239V2;
38354         case NID_X9_62_prime239v3:
38355             return ECC_PRIME239V3;
38356         case NID_X9_62_prime256v1:
38357             return ECC_SECP256R1;
38358         case NID_secp112r1:
38359             return ECC_SECP112R1;
38360         case NID_secp112r2:
38361             return ECC_SECP112R2;
38362         case NID_secp128r1:
38363             return ECC_SECP128R1;
38364         case NID_secp128r2:
38365             return ECC_SECP128R2;
38366         case NID_secp160r1:
38367             return ECC_SECP160R1;
38368         case NID_secp160r2:
38369             return ECC_SECP160R2;
38370         case NID_secp224r1:
38371             return ECC_SECP224R1;
38372         case NID_secp384r1:
38373             return ECC_SECP384R1;
38374         case NID_secp521r1:
38375             return ECC_SECP521R1;
38376         case NID_secp160k1:
38377             return ECC_SECP160K1;
38378         case NID_secp192k1:
38379             return ECC_SECP192K1;
38380         case NID_secp224k1:
38381             return ECC_SECP224K1;
38382         case NID_secp256k1:
38383             return ECC_SECP256K1;
38384         case NID_brainpoolP160r1:
38385             return ECC_BRAINPOOLP160R1;
38386         case NID_brainpoolP192r1:
38387             return ECC_BRAINPOOLP192R1;
38388         case NID_brainpoolP224r1:
38389             return ECC_BRAINPOOLP224R1;
38390         case NID_brainpoolP256r1:
38391             return ECC_BRAINPOOLP256R1;
38392         case NID_brainpoolP320r1:
38393             return ECC_BRAINPOOLP320R1;
38394         case NID_brainpoolP384r1:
38395             return ECC_BRAINPOOLP384R1;
38396         case NID_brainpoolP512r1:
38397             return ECC_BRAINPOOLP512R1;
38398         default:
38399             WOLFSSL_MSG("NID not found");
38400             return -1;
38401     }
38402 }
38403 
38404 /* return code compliant with OpenSSL :
38405  *   1 if success, 0 if error
38406  */
wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP * group,WOLFSSL_BIGNUM * order,WOLFSSL_BN_CTX * ctx)38407 int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
38408                                WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx)
38409 {
38410     (void)ctx;
38411 
38412     if (group == NULL || order == NULL || order->internal == NULL) {
38413         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order NULL error");
38414         return WOLFSSL_FAILURE;
38415     }
38416 
38417     if (mp_init((mp_int*)order->internal) != MP_OKAY) {
38418         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_init failure");
38419         return WOLFSSL_FAILURE;
38420     }
38421 
38422     if (mp_read_radix((mp_int*)order->internal,
38423                   ecc_sets[group->curve_idx].order, MP_RADIX_HEX) != MP_OKAY) {
38424         WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_read order failure");
38425         mp_clear((mp_int*)order->internal);
38426         return WOLFSSL_FAILURE;
38427     }
38428 
38429     return WOLFSSL_SUCCESS;
38430 }
38431 
wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP * group)38432 int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group)
38433 {
38434     int ret;
38435     mp_int order;
38436 
38437     if (group == NULL || group->curve_idx < 0) {
38438         WOLFSSL_MSG("wolfSSL_EC_GROUP_order_bits NULL error");
38439         return 0;
38440     }
38441 
38442     ret = mp_init(&order);
38443     if (ret == 0) {
38444         ret = mp_read_radix(&order, ecc_sets[group->curve_idx].order,
38445             MP_RADIX_HEX);
38446         if (ret == 0)
38447             ret = mp_count_bits(&order);
38448         mp_clear(&order);
38449     }
38450 
38451     return ret;
38452 }
38453 
38454 /* End EC_GROUP */
38455 
38456 /* Start EC_POINT */
38457 
38458 /* return code compliant with OpenSSL :
38459  *   1 if success, 0 if error
38460  */
wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP * group,const WOLFSSL_EC_POINT * p,unsigned char * out,unsigned int * len)38461 int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group,
38462                         const WOLFSSL_EC_POINT *p,
38463                         unsigned char *out, unsigned int *len)
38464 {
38465     int err;
38466 
38467     WOLFSSL_ENTER("wolfSSL_ECPoint_i2d");
38468 
38469     if (group == NULL || p == NULL || len == NULL) {
38470         WOLFSSL_MSG("wolfSSL_ECPoint_i2d NULL error");
38471         return WOLFSSL_FAILURE;
38472     }
38473 
38474     if (setupPoint(p) != WOLFSSL_SUCCESS) {
38475         return WOLFSSL_FAILURE;
38476     }
38477 
38478     if (out != NULL) {
38479         wolfSSL_EC_POINT_dump("i2d p", p);
38480     }
38481 
38482     err = wc_ecc_export_point_der(group->curve_idx, (ecc_point*)p->internal,
38483                                   out, len);
38484     if (err != MP_OKAY && !(out == NULL && err == LENGTH_ONLY_E)) {
38485         WOLFSSL_MSG("wolfSSL_ECPoint_i2d wc_ecc_export_point_der failed");
38486         return WOLFSSL_FAILURE;
38487     }
38488 
38489     return WOLFSSL_SUCCESS;
38490 }
38491 
38492 /* return code compliant with OpenSSL :
38493  *   1 if success, 0 if error
38494  */
wolfSSL_ECPoint_d2i(unsigned char * in,unsigned int len,const WOLFSSL_EC_GROUP * group,WOLFSSL_EC_POINT * p)38495 int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len,
38496                         const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p)
38497 {
38498     WOLFSSL_ENTER("wolfSSL_ECPoint_d2i");
38499 
38500     if (group == NULL || p == NULL || p->internal == NULL || in == NULL) {
38501         WOLFSSL_MSG("wolfSSL_ECPoint_d2i NULL error");
38502         return WOLFSSL_FAILURE;
38503     }
38504 
38505 #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
38506     (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)))
38507     if (wc_ecc_import_point_der_ex(in, len, group->curve_idx,
38508                                    (ecc_point*)p->internal, 0) != MP_OKAY) {
38509         WOLFSSL_MSG("wc_ecc_import_point_der_ex failed");
38510         return WOLFSSL_FAILURE;
38511     }
38512 #else
38513     /* ECC_POINT_UNCOMP is not defined CAVP self test so use magic number */
38514     if (in[0] == 0x04) {
38515         if (wc_ecc_import_point_der(in, len, group->curve_idx,
38516                                     (ecc_point*)p->internal) != MP_OKAY) {
38517             WOLFSSL_MSG("wc_ecc_import_point_der failed");
38518             return WOLFSSL_FAILURE;
38519         }
38520     }
38521     else {
38522         WOLFSSL_MSG("Only uncompressed points supported with HAVE_SELFTEST");
38523         return WOLFSSL_FAILURE;
38524     }
38525 #endif
38526 
38527     /* Set new external point */
38528     if (SetECPointExternal(p) != WOLFSSL_SUCCESS) {
38529         WOLFSSL_MSG("SetECPointExternal failed");
38530         return WOLFSSL_FAILURE;
38531     }
38532 
38533     wolfSSL_EC_POINT_dump("d2i p", p);
38534 
38535     return WOLFSSL_SUCCESS;
38536 }
38537 
wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP * group,const WOLFSSL_EC_POINT * p,char form,byte * buf,size_t len,WOLFSSL_BN_CTX * ctx)38538 size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group,
38539                                   const WOLFSSL_EC_POINT *p,
38540                                   char form,
38541                                   byte *buf, size_t len, WOLFSSL_BN_CTX *ctx)
38542 {
38543     word32 min_len = (word32)len;
38544 #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
38545     (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
38546     int compressed = form == POINT_CONVERSION_COMPRESSED ? 1 : 0;
38547 #endif /* !HAVE_SELFTEST */
38548 
38549     WOLFSSL_ENTER("EC_POINT_point2oct");
38550 
38551     if (!group || !p) {
38552         return WOLFSSL_FAILURE;
38553     }
38554 
38555     if (setupPoint(p) != WOLFSSL_SUCCESS) {
38556         return WOLFSSL_FAILURE;
38557     }
38558 
38559     if (wolfSSL_EC_POINT_is_at_infinity(group, p)) {
38560         /* encodes to a single 0 octet */
38561         if (buf != NULL) {
38562             if (len < 1) {
38563                 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
38564                 return WOLFSSL_FAILURE;
38565             }
38566             buf[0] = 0;
38567         }
38568         return 1;
38569     }
38570 
38571     if (form != POINT_CONVERSION_UNCOMPRESSED
38572 #ifndef HAVE_SELFTEST
38573             && form != POINT_CONVERSION_COMPRESSED
38574 #endif /* !HAVE_SELFTEST */
38575             ) {
38576         WOLFSSL_MSG("Unsupported curve form");
38577         return WOLFSSL_FAILURE;
38578     }
38579 
38580 #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
38581     (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
38582     if (wc_ecc_export_point_der_ex(group->curve_idx, (ecc_point*)p->internal,
38583                buf, &min_len, compressed) != (buf ? MP_OKAY : LENGTH_ONLY_E)) {
38584         return WOLFSSL_FAILURE;
38585     }
38586 #else
38587     if (wc_ecc_export_point_der(group->curve_idx, (ecc_point*)p->internal,
38588                                 buf, &min_len) != (buf ? MP_OKAY : LENGTH_ONLY_E)) {
38589         return WOLFSSL_FAILURE;
38590     }
38591 #endif /* !HAVE_SELFTEST */
38592 
38593     (void)ctx;
38594 
38595     return (size_t)min_len;
38596 }
38597 
38598 
wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP * group,WOLFSSL_EC_POINT * p,const unsigned char * buf,size_t len,WOLFSSL_BN_CTX * ctx)38599 int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group,
38600                                WOLFSSL_EC_POINT *p, const unsigned char *buf,
38601                                size_t len, WOLFSSL_BN_CTX *ctx)
38602 {
38603     WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point");
38604 
38605     if (!group || !p) {
38606         return WOLFSSL_FAILURE;
38607     }
38608 
38609     (void)ctx;
38610 
38611     return wolfSSL_ECPoint_d2i((unsigned char*)buf, (unsigned int)len, group, p);
38612 }
38613 
38614 
wolfSSL_o2i_ECPublicKey(WOLFSSL_EC_KEY ** a,const unsigned char ** in,long len)38615 WOLFSSL_EC_KEY *wolfSSL_o2i_ECPublicKey(WOLFSSL_EC_KEY **a, const unsigned char **in,
38616                                         long len)
38617 {
38618     WOLFSSL_EC_KEY* ret;
38619 
38620     WOLFSSL_ENTER("wolfSSL_o2i_ECPublicKey");
38621 
38622     if (!a || !*a || !(*a)->group || !in || !*in || len <= 0) {
38623         WOLFSSL_MSG("wolfSSL_o2i_ECPublicKey Bad arguments");
38624         return NULL;
38625     }
38626 
38627     ret = *a;
38628 
38629     if (wolfSSL_EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)
38630             != WOLFSSL_SUCCESS) {
38631         WOLFSSL_MSG("wolfSSL_EC_POINT_oct2point error");
38632         return NULL;
38633     }
38634 
38635     *in += len;
38636     return ret;
38637 }
38638 
wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY * in,unsigned char ** out)38639 int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out)
38640 {
38641     size_t len;
38642     unsigned char *tmp = NULL;
38643     char form;
38644     WOLFSSL_ENTER("wolfSSL_i2o_ECPublicKey");
38645 
38646     if (!in) {
38647         WOLFSSL_MSG("wolfSSL_i2o_ECPublicKey Bad arguments");
38648         return WOLFSSL_FAILURE;
38649     }
38650 
38651 #ifdef HAVE_COMP_KEY
38652     /* Default to compressed form if not set */
38653     form = in->form == POINT_CONVERSION_UNCOMPRESSED ?
38654             POINT_CONVERSION_UNCOMPRESSED:
38655             POINT_CONVERSION_COMPRESSED;
38656 #else
38657     form = POINT_CONVERSION_UNCOMPRESSED;
38658 #endif
38659 
38660     len = wolfSSL_EC_POINT_point2oct(in->group, in->pub_key, form,
38661                                      NULL, 0, NULL);
38662 
38663     if (len != WOLFSSL_FAILURE && out) {
38664         if (!*out) {
38665             if (!(tmp = (unsigned char*)XMALLOC(len, NULL,
38666                                                 DYNAMIC_TYPE_OPENSSL))) {
38667                 WOLFSSL_MSG("malloc failed");
38668                 return WOLFSSL_FAILURE;
38669             }
38670             *out = tmp;
38671         }
38672 
38673         if (wolfSSL_EC_POINT_point2oct(in->group, in->pub_key, form, *out,
38674                                        len, NULL) == WOLFSSL_FAILURE) {
38675             if (tmp) {
38676                 XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
38677                 *out = NULL;
38678             }
38679             return WOLFSSL_FAILURE;
38680         }
38681 
38682         if (!tmp) {
38683             /* Move buffer forward if it was not alloced in this function */
38684             *out += len;
38685         }
38686     }
38687 
38688     return (int)len;
38689 }
38690 
38691 #ifdef HAVE_ECC_KEY_IMPORT
wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY ** key,const unsigned char ** in,long len)38692 WOLFSSL_EC_KEY *wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY **key, const unsigned char **in,
38693                                          long len)
38694 {
38695     WOLFSSL_EC_KEY *eckey = NULL;
38696     WOLFSSL_ENTER("wolfSSL_d2i_ECPrivateKey");
38697 
38698     if (!in || !*in || len <= 0) {
38699         WOLFSSL_MSG("wolfSSL_d2i_ECPrivateKey Bad arguments");
38700         return NULL;
38701     }
38702 
38703     if (!(eckey = wolfSSL_EC_KEY_new())) {
38704         WOLFSSL_MSG("wolfSSL_EC_KEY_new error");
38705         return NULL;
38706     }
38707 
38708     if (wc_ecc_import_private_key(*in, (word32)len, NULL, 0,
38709             (ecc_key*)eckey->internal) != MP_OKAY) {
38710         WOLFSSL_MSG("wc_ecc_import_private_key error");
38711         goto error;
38712     }
38713 
38714     eckey->inSet = 1;
38715 
38716     if (SetECKeyExternal(eckey) != WOLFSSL_SUCCESS) {
38717         WOLFSSL_MSG("SetECKeyExternal error");
38718         goto error;
38719     }
38720 
38721     if (key) {
38722         *key = eckey;
38723     }
38724 
38725     return eckey;
38726 
38727 error:
38728     wolfSSL_EC_KEY_free(eckey);
38729     return NULL;
38730 }
38731 #endif /* HAVE_ECC_KEY_IMPORT */
38732 
wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY * in,unsigned char ** out)38733 int wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY *in, unsigned char **out)
38734 {
38735     int len;
38736     byte* buf = NULL;
38737     WOLFSSL_ENTER("wolfSSL_i2d_ECPrivateKey");
38738 
38739     if (!in) {
38740         WOLFSSL_MSG("wolfSSL_i2d_ECPrivateKey Bad arguments");
38741         return WOLFSSL_FAILURE;
38742     }
38743 
38744     if (!in->inSet && SetECKeyInternal((WOLFSSL_EC_KEY*)in) != WOLFSSL_SUCCESS) {
38745         WOLFSSL_MSG("SetECKeyInternal error");
38746         return WOLFSSL_FAILURE;
38747     }
38748 
38749     if ((len = wc_ecc_size((ecc_key*)in->internal)) <= 0) {
38750         WOLFSSL_MSG("wc_ecc_size error");
38751         return WOLFSSL_FAILURE;
38752     }
38753 
38754     if (out) {
38755         if (!(buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER))) {
38756             WOLFSSL_MSG("tmp buffer malloc error");
38757             return WOLFSSL_FAILURE;
38758         }
38759 
38760         if (wc_ecc_export_private_only((ecc_key*)in->internal, buf,
38761                 (word32*)&len) != MP_OKAY) {
38762             WOLFSSL_MSG("wc_ecc_export_private_only error");
38763             XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38764             return WOLFSSL_FAILURE;
38765         }
38766 
38767         if (*out) {
38768             XMEMCPY(*out, buf, len);
38769             XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38770         }
38771         else {
38772             *out = buf;
38773         }
38774     }
38775 
38776     return len;
38777 }
38778 
wolfSSL_EC_KEY_set_conv_form(WOLFSSL_EC_KEY * eckey,char form)38779 void wolfSSL_EC_KEY_set_conv_form(WOLFSSL_EC_KEY *eckey, char form)
38780 {
38781     if (eckey && (form == POINT_CONVERSION_UNCOMPRESSED
38782 #ifdef HAVE_COMP_KEY
38783                   || form == POINT_CONVERSION_COMPRESSED
38784 #endif
38785                   )) {
38786         eckey->form = form;
38787     } else {
38788         WOLFSSL_MSG("Incorrect form or HAVE_COMP_KEY not compiled in");
38789     }
38790 }
38791 
38792 
38793 /* wolfSSL_EC_POINT_point2bn should return "in" if not null */
wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP * group,const WOLFSSL_EC_POINT * p,char form,WOLFSSL_BIGNUM * in,WOLFSSL_BN_CTX * ctx)38794 WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group,
38795                                           const WOLFSSL_EC_POINT *p,
38796                                           char form,
38797                                           WOLFSSL_BIGNUM *in, WOLFSSL_BN_CTX *ctx)
38798 {
38799     size_t len;
38800     byte *buf;
38801     WOLFSSL_BIGNUM *ret = NULL;
38802 
38803     WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point");
38804 
38805     if (!group || !p) {
38806         return NULL;
38807     }
38808 
38809     if ((len = wolfSSL_EC_POINT_point2oct(group, p, form,
38810                                           NULL, 0, ctx)) == WOLFSSL_FAILURE) {
38811         return NULL;
38812     }
38813 
38814     if (!(buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER))) {
38815         WOLFSSL_MSG("malloc failed");
38816         return NULL;
38817     }
38818 
38819     if (wolfSSL_EC_POINT_point2oct(group, p, form,
38820                                    buf, len, ctx) == len) {
38821         ret = wolfSSL_BN_bin2bn(buf, (int)len, in);
38822     }
38823 
38824     XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38825 
38826     return ret;
38827 }
38828 
38829 #if defined(USE_ECC_B_PARAM) && (!defined(HAVE_FIPS) || \
38830     (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP * group,const WOLFSSL_EC_POINT * point,WOLFSSL_BN_CTX * ctx)38831 int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group,
38832                                  const WOLFSSL_EC_POINT *point,
38833                                  WOLFSSL_BN_CTX *ctx)
38834 {
38835     (void)ctx;
38836     WOLFSSL_ENTER("wolfSSL_EC_POINT_is_on_curve");
38837 
38838     if (!group || !point) {
38839         WOLFSSL_MSG("Invalid arguments");
38840         return WOLFSSL_FAILURE;
38841     }
38842 
38843     if (!point->inSet && SetECPointInternal((WOLFSSL_EC_POINT*)point)) {
38844         WOLFSSL_MSG("SetECPointInternal error");
38845         return WOLFSSL_FAILURE;
38846     }
38847 
38848     return wc_ecc_point_is_on_curve((ecc_point*)point->internal, group->curve_idx)
38849             == MP_OKAY ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
38850 }
38851 #endif /* USE_ECC_B_PARAM && (!HAVE_FIPS || HAVE_FIPS_VERSION > 2) */
38852 
wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP * group)38853 WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group)
38854 {
38855     WOLFSSL_EC_POINT *p;
38856 
38857     WOLFSSL_ENTER("wolfSSL_EC_POINT_new");
38858 
38859     if (group == NULL) {
38860         WOLFSSL_MSG("wolfSSL_EC_POINT_new NULL error");
38861         return NULL;
38862     }
38863 
38864     p = (WOLFSSL_EC_POINT *)XMALLOC(sizeof(WOLFSSL_EC_POINT), NULL,
38865                                     DYNAMIC_TYPE_ECC);
38866     if (p == NULL) {
38867         WOLFSSL_MSG("wolfSSL_EC_POINT_new malloc ecc point failure");
38868         return NULL;
38869     }
38870     XMEMSET(p, 0, sizeof(WOLFSSL_EC_POINT));
38871 
38872     p->internal = wc_ecc_new_point();
38873     if (p->internal == NULL) {
38874         WOLFSSL_MSG("ecc_new_point failure");
38875         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
38876         return NULL;
38877     }
38878 
38879     return p;
38880 }
38881 
38882 /* return code compliant with OpenSSL :
38883  *   1 if success, 0 if error
38884  */
wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP * group,const WOLFSSL_EC_POINT * point,WOLFSSL_BIGNUM * x,WOLFSSL_BIGNUM * y,WOLFSSL_BN_CTX * ctx)38885 int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group,
38886                                                 const WOLFSSL_EC_POINT *point,
38887                                                 WOLFSSL_BIGNUM *x,
38888                                                 WOLFSSL_BIGNUM *y,
38889                                                 WOLFSSL_BN_CTX *ctx)
38890 {
38891     mp_digit mp;
38892     mp_int modulus;
38893     (void)ctx;
38894 
38895     WOLFSSL_ENTER("wolfSSL_EC_POINT_get_affine_coordinates_GFp");
38896 
38897     if (group == NULL || point == NULL || point->internal == NULL ||
38898         x == NULL || y == NULL || wolfSSL_EC_POINT_is_at_infinity(group, point)) {
38899         WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error");
38900         return WOLFSSL_FAILURE;
38901     }
38902 
38903     if (setupPoint(point) != WOLFSSL_SUCCESS) {
38904         return WOLFSSL_FAILURE;
38905     }
38906 
38907     if (!wolfSSL_BN_is_one(point->Z)) {
38908         if (mp_init(&modulus) != MP_OKAY) {
38909             WOLFSSL_MSG("mp_init failed");
38910             return WOLFSSL_FAILURE;
38911         }
38912         /* Map the Jacobian point back to affine space */
38913         if (mp_read_radix(&modulus, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX) != MP_OKAY) {
38914             WOLFSSL_MSG("mp_read_radix failed");
38915             mp_clear(&modulus);
38916             return WOLFSSL_FAILURE;
38917         }
38918         if (mp_montgomery_setup(&modulus, &mp) != MP_OKAY) {
38919             WOLFSSL_MSG("mp_montgomery_setup failed");
38920             mp_clear(&modulus);
38921             return WOLFSSL_FAILURE;
38922         }
38923         if (ecc_map((ecc_point*)point->internal, &modulus, mp) != MP_OKAY) {
38924             WOLFSSL_MSG("ecc_map failed");
38925             mp_clear(&modulus);
38926             return WOLFSSL_FAILURE;
38927         }
38928         if (SetECPointExternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) {
38929             WOLFSSL_MSG("SetECPointExternal failed");
38930             mp_clear(&modulus);
38931             return WOLFSSL_FAILURE;
38932         }
38933 
38934         mp_clear(&modulus);
38935     }
38936 
38937     BN_copy(x, point->X);
38938     BN_copy(y, point->Y);
38939 
38940     return WOLFSSL_SUCCESS;
38941 }
38942 
wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP * group,WOLFSSL_EC_POINT * point,const WOLFSSL_BIGNUM * x,const WOLFSSL_BIGNUM * y,WOLFSSL_BN_CTX * ctx)38943 int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group,
38944                                                 WOLFSSL_EC_POINT *point,
38945                                                 const WOLFSSL_BIGNUM *x,
38946                                                 const WOLFSSL_BIGNUM *y,
38947                                                 WOLFSSL_BN_CTX *ctx)
38948 {
38949     (void)ctx;
38950     WOLFSSL_ENTER("wolfSSL_EC_POINT_set_affine_coordinates_GFp");
38951 
38952     if (group == NULL || point == NULL || point->internal == NULL ||
38953         x == NULL || y == NULL) {
38954         WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp NULL error");
38955         return WOLFSSL_FAILURE;
38956     }
38957 
38958     if (!point->X) {
38959         point->X = wolfSSL_BN_new();
38960     }
38961     if (!point->Y) {
38962         point->Y = wolfSSL_BN_new();
38963     }
38964     if (!point->Z) {
38965         point->Z = wolfSSL_BN_new();
38966     }
38967     if (!point->X || !point->Y || !point->Z) {
38968         WOLFSSL_MSG("wolfSSL_BN_new failed");
38969         return WOLFSSL_FAILURE;
38970     }
38971 
38972     BN_copy(point->X, x);
38973     BN_copy(point->Y, y);
38974     BN_copy(point->Z, wolfSSL_BN_value_one());
38975 
38976     if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) {
38977         WOLFSSL_MSG("SetECPointInternal failed");
38978         return WOLFSSL_FAILURE;
38979     }
38980 
38981     return WOLFSSL_SUCCESS;
38982 }
38983 
38984 #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
38985     !defined(HAVE_SELFTEST)
wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP * group,WOLFSSL_EC_POINT * r,const WOLFSSL_EC_POINT * p1,const WOLFSSL_EC_POINT * p2,WOLFSSL_BN_CTX * ctx)38986 int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
38987                          const WOLFSSL_EC_POINT *p1,
38988                          const WOLFSSL_EC_POINT *p2, WOLFSSL_BN_CTX *ctx)
38989 {
38990     mp_int a, prime, mu;
38991     mp_digit mp = 0;
38992     ecc_point* montP1 = NULL;
38993     ecc_point* montP2 = NULL;
38994     ecc_point* eccP1;
38995     ecc_point* eccP2;
38996     int ret = WOLFSSL_FAILURE;
38997 
38998     (void)ctx;
38999 
39000     if (!group || !r || !p1 || !p2) {
39001         WOLFSSL_MSG("wolfSSL_EC_POINT_add error");
39002         return WOLFSSL_FAILURE;
39003     }
39004 
39005     if (setupPoint(r) != WOLFSSL_SUCCESS ||
39006         setupPoint(p1) != WOLFSSL_SUCCESS ||
39007         setupPoint(p2) != WOLFSSL_SUCCESS) {
39008         WOLFSSL_MSG("setupPoint error");
39009         return WOLFSSL_FAILURE;
39010     }
39011 
39012     /* read the curve prime and a */
39013     if (mp_init_multi(&prime, &a, &mu, NULL, NULL, NULL) != MP_OKAY) {
39014         WOLFSSL_MSG("mp_init_multi error");
39015         goto cleanup;
39016     }
39017 
39018     if (mp_read_radix(&a, ecc_sets[group->curve_idx].Af, MP_RADIX_HEX)
39019             != MP_OKAY) {
39020         WOLFSSL_MSG("mp_read_radix a error");
39021         goto cleanup;
39022     }
39023 
39024     if (mp_read_radix(&prime, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX)
39025             != MP_OKAY) {
39026         WOLFSSL_MSG("mp_read_radix prime error");
39027         goto cleanup;
39028     }
39029 
39030     if (mp_montgomery_setup(&prime, &mp) != MP_OKAY) {
39031         WOLFSSL_MSG("mp_montgomery_setup nqm error");
39032         goto cleanup;
39033     }
39034 
39035     eccP1 = (ecc_point*)p1->internal;
39036     eccP2 = (ecc_point*)p2->internal;
39037 
39038     if (!(montP1 = wc_ecc_new_point_h(NULL)) ||
39039             !(montP2 = wc_ecc_new_point_h(NULL))) {
39040         WOLFSSL_MSG("wc_ecc_new_point_h nqm error");
39041         goto cleanup;
39042     }
39043 
39044     if ((mp_montgomery_calc_normalization(&mu, &prime)) != MP_OKAY) {
39045         WOLFSSL_MSG("mp_montgomery_calc_normalization error");
39046         goto cleanup;
39047     }
39048 
39049     /* Convert to Montgomery form */
39050     if (mp_cmp_d(&mu, 1) == MP_EQ) {
39051         if (wc_ecc_copy_point(eccP1, montP1) != MP_OKAY ||
39052                 wc_ecc_copy_point(eccP2, montP2) != MP_OKAY) {
39053             WOLFSSL_MSG("wc_ecc_copy_point error");
39054             goto cleanup;
39055         }
39056     } else {
39057         if (mp_mulmod(eccP1->x, &mu, &prime, montP1->x) != MP_OKAY ||
39058                 mp_mulmod(eccP1->y, &mu, &prime, montP1->y) != MP_OKAY ||
39059                 mp_mulmod(eccP1->z, &mu, &prime, montP1->z) != MP_OKAY) {
39060             WOLFSSL_MSG("mp_mulmod error");
39061             goto cleanup;
39062         }
39063         if (mp_mulmod(eccP2->x, &mu, &prime, montP2->x) != MP_OKAY ||
39064                 mp_mulmod(eccP2->y, &mu, &prime, montP2->y) != MP_OKAY ||
39065                 mp_mulmod(eccP2->z, &mu, &prime, montP2->z) != MP_OKAY) {
39066             WOLFSSL_MSG("mp_mulmod error");
39067             goto cleanup;
39068         }
39069     }
39070 
39071     if (ecc_projective_add_point(montP1, montP2, (ecc_point*)r->internal,
39072             &a, &prime, mp) != MP_OKAY) {
39073         WOLFSSL_MSG("ecc_projective_add_point error");
39074         goto cleanup;
39075     }
39076 
39077     if (ecc_map((ecc_point*)r->internal, &prime, mp) != MP_OKAY) {
39078         WOLFSSL_MSG("ecc_map error");
39079         goto cleanup;
39080     }
39081 
39082     ret = WOLFSSL_SUCCESS;
39083 cleanup:
39084     mp_clear(&a);
39085     mp_clear(&prime);
39086     mp_clear(&mu);
39087     wc_ecc_del_point_h(montP1, NULL);
39088     wc_ecc_del_point_h(montP2, NULL);
39089     return ret;
39090 }
39091 
39092 /* Calculate the value: generator * n + q * m
39093  * return code compliant with OpenSSL :
39094  *   1 if success, 0 if error
39095  */
wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP * group,WOLFSSL_EC_POINT * r,const WOLFSSL_BIGNUM * n,const WOLFSSL_EC_POINT * q,const WOLFSSL_BIGNUM * m,WOLFSSL_BN_CTX * ctx)39096 int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
39097                          const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q,
39098                          const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
39099 {
39100     mp_int a, prime;
39101     int ret = WOLFSSL_FAILURE;
39102     ecc_point* result = NULL;
39103     ecc_point* tmp = NULL;
39104 
39105     (void)ctx;
39106 
39107     WOLFSSL_ENTER("wolfSSL_EC_POINT_mul");
39108 
39109     if (!group || !r) {
39110         WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error");
39111         return WOLFSSL_FAILURE;
39112     }
39113 
39114     if (!(result = wc_ecc_new_point())) {
39115         WOLFSSL_MSG("wolfSSL_EC_POINT_new error");
39116         return WOLFSSL_FAILURE;
39117     }
39118 
39119     /* read the curve prime and a */
39120     if (mp_init_multi(&prime, &a, NULL, NULL, NULL, NULL) != MP_OKAY) {
39121         WOLFSSL_MSG("mp_init_multi error");
39122         goto cleanup;
39123     }
39124 
39125     if (q && setupPoint(q) != WOLFSSL_SUCCESS) {
39126         WOLFSSL_MSG("setupPoint error");
39127         goto cleanup;
39128     }
39129 
39130     if (mp_read_radix(&prime, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX)
39131             != MP_OKAY) {
39132         WOLFSSL_MSG("mp_read_radix prime error");
39133         goto cleanup;
39134     }
39135 
39136     if (mp_read_radix(&a, ecc_sets[group->curve_idx].Af, MP_RADIX_HEX)
39137             != MP_OKAY) {
39138         WOLFSSL_MSG("mp_read_radix a error");
39139         goto cleanup;
39140     }
39141 
39142     if (n) {
39143         /* load generator */
39144     #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
39145         if (wc_ecc_get_generator(result, group->curve_idx)
39146                 != MP_OKAY) {
39147             WOLFSSL_MSG("wc_ecc_get_generator error");
39148             goto cleanup;
39149         }
39150     #else
39151         /* wc_ecc_get_generator is not defined in the FIPS v2 module. */
39152         if (mp_read_radix(result->x, ecc_sets[group->curve_idx].Gx, MP_RADIX_HEX)
39153                 != MP_OKAY) {
39154             WOLFSSL_MSG("mp_read_radix Gx error");
39155             goto cleanup;
39156         }
39157         if (mp_read_radix(result->y, ecc_sets[group->curve_idx].Gy, MP_RADIX_HEX)
39158                 != MP_OKAY) {
39159             WOLFSSL_MSG("mp_read_radix Gy error");
39160             goto cleanup;
39161         }
39162         if (mp_set(result->z, 1) != MP_OKAY) {
39163             WOLFSSL_MSG("mp_set Gz error");
39164             goto cleanup;
39165         }
39166     #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
39167     }
39168 
39169     if (n && q && m) {
39170         /* r = generator * n + q * m */
39171 #ifdef ECC_SHAMIR
39172         if (ecc_mul2add(result, (mp_int*)n->internal,
39173                         (ecc_point*)q->internal, (mp_int*)m->internal,
39174                         result, &a, &prime, NULL)
39175                 != MP_OKAY) {
39176             WOLFSSL_MSG("ecc_mul2add error");
39177             goto cleanup;
39178         }
39179 #else
39180         mp_digit mp = 0;
39181         if (mp_montgomery_setup(&prime, &mp) != MP_OKAY) {
39182             WOLFSSL_MSG("mp_montgomery_setup nqm error");
39183             goto cleanup;
39184         }
39185         if (!(tmp = wc_ecc_new_point())) {
39186             WOLFSSL_MSG("wolfSSL_EC_POINT_new nqm error");
39187             goto cleanup;
39188         }
39189         /* r = generator * n */
39190         if (wc_ecc_mulmod((mp_int*)n->internal, result, result, &a, &prime, 0)
39191                 != MP_OKAY) {
39192             WOLFSSL_MSG("wc_ecc_mulmod nqm error");
39193             goto cleanup;
39194         }
39195         /* tmp = q * m */
39196         if (wc_ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal,
39197                 tmp, &a, &prime, 0) != MP_OKAY) {
39198             WOLFSSL_MSG("wc_ecc_mulmod nqm error");
39199             goto cleanup;
39200         }
39201         /* result = result + tmp */
39202         if (ecc_projective_add_point(tmp, result, result, &a, &prime, mp)
39203                 != MP_OKAY) {
39204             WOLFSSL_MSG("wc_ecc_mulmod nqm error");
39205             goto cleanup;
39206         }
39207         if (ecc_map(result, &prime, mp) != MP_OKAY) {
39208             WOLFSSL_MSG("ecc_map nqm error");
39209             goto cleanup;
39210         }
39211 #endif
39212     }
39213     else if (n) {
39214         /* r = generator * n */
39215         if (wc_ecc_mulmod((mp_int*)n->internal, result, result, &a, &prime, 1)
39216                 != MP_OKAY) {
39217             WOLFSSL_MSG("wc_ecc_mulmod gn error");
39218             goto cleanup;
39219         }
39220     }
39221     else if (q && m) {
39222         /* r = q * m */
39223         if (wc_ecc_mulmod((mp_int*)m->internal, (ecc_point*)q->internal,
39224                            result, &a, &prime, 1) != MP_OKAY) {
39225             WOLFSSL_MSG("wc_ecc_mulmod qm error");
39226             goto cleanup;
39227         }
39228     }
39229 
39230     /* copy to destination */
39231     if (wc_ecc_copy_point(result, (ecc_point*)r->internal)) {
39232         WOLFSSL_MSG("wc_ecc_copy_point error");
39233         goto cleanup;
39234     }
39235     r->inSet = 1;
39236     if (SetECPointExternal(r) != WOLFSSL_SUCCESS) {
39237         WOLFSSL_MSG("SetECPointExternal error");
39238         goto cleanup;
39239     }
39240 
39241     ret = WOLFSSL_SUCCESS;
39242 cleanup:
39243     mp_clear(&a);
39244     mp_clear(&prime);
39245     wc_ecc_del_point(result);
39246     wc_ecc_del_point(tmp);
39247     return ret;
39248 }
39249 #endif /* !defined(WOLFSSL_ATECC508A) && defined(ECC_SHAMIR) &&
39250         * !defined(HAVE_SELFTEST) */
39251 
39252 /* (x, y) -> (x, -y) */
wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP * group,WOLFSSL_EC_POINT * a,WOLFSSL_BN_CTX * ctx)39253 int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *a,
39254                             WOLFSSL_BN_CTX *ctx)
39255 {
39256     ecc_point* p;
39257     mp_int prime;
39258 
39259     (void)ctx;
39260 
39261     WOLFSSL_ENTER("wolfSSL_EC_POINT_invert");
39262 
39263     if (!group || !a || !a->internal || setupPoint(a) != WOLFSSL_SUCCESS) {
39264         return WOLFSSL_FAILURE;
39265     }
39266 
39267     p = (ecc_point*)a->internal;
39268 
39269     /* read the curve prime and a */
39270     if (mp_init_multi(&prime, NULL, NULL, NULL, NULL, NULL) != MP_OKAY) {
39271         WOLFSSL_MSG("mp_init_multi error");
39272         return WOLFSSL_FAILURE;
39273     }
39274 
39275     if (mp_sub(&prime, p->y, p->y) != MP_OKAY) {
39276         WOLFSSL_MSG("mp_sub error");
39277         return WOLFSSL_FAILURE;
39278     }
39279 
39280     if (SetECPointExternal(a) != WOLFSSL_SUCCESS) {
39281         WOLFSSL_MSG("SetECPointExternal error");
39282         return WOLFSSL_FAILURE;
39283     }
39284 
39285     return WOLFSSL_SUCCESS;
39286 }
39287 
wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT * p)39288 void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *p)
39289 {
39290     WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free");
39291 
39292     wolfSSL_EC_POINT_free(p);
39293 }
39294 
39295 /* return code compliant with OpenSSL :
39296  *   0 if equal, 1 if not and -1 in case of error
39297  */
wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP * group,const WOLFSSL_EC_POINT * a,const WOLFSSL_EC_POINT * b,WOLFSSL_BN_CTX * ctx)39298 int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group,
39299                          const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b,
39300                          WOLFSSL_BN_CTX *ctx)
39301 {
39302     int ret;
39303 
39304     (void)ctx;
39305 
39306     WOLFSSL_ENTER("wolfSSL_EC_POINT_cmp");
39307 
39308     if (group == NULL || a == NULL || a->internal == NULL || b == NULL ||
39309         b->internal == NULL) {
39310         WOLFSSL_MSG("wolfSSL_EC_POINT_cmp Bad arguments");
39311         return WOLFSSL_FATAL_ERROR;
39312     }
39313 
39314     ret = wc_ecc_cmp_point((ecc_point*)a->internal, (ecc_point*)b->internal);
39315     if (ret == MP_EQ)
39316         return 0;
39317     else if (ret == MP_LT || ret == MP_GT)
39318         return 1;
39319 
39320     return WOLFSSL_FATAL_ERROR;
39321 }
39322 
wolfSSL_EC_POINT_copy(WOLFSSL_EC_POINT * dest,const WOLFSSL_EC_POINT * src)39323 int wolfSSL_EC_POINT_copy(WOLFSSL_EC_POINT *dest, const WOLFSSL_EC_POINT *src)
39324 {
39325     WOLFSSL_ENTER("wolfSSL_EC_POINT_copy");
39326 
39327     if (!dest || !src) {
39328         return WOLFSSL_FAILURE;
39329     }
39330 
39331     if (setupPoint(src) != WOLFSSL_SUCCESS) {
39332         return WOLFSSL_FAILURE;
39333     }
39334 
39335     if (wc_ecc_copy_point((ecc_point*) dest->internal,
39336                           (ecc_point*) src->internal) != MP_OKAY) {
39337         return WOLFSSL_FAILURE;
39338     }
39339 
39340     dest->inSet = 1;
39341 
39342     if (SetECPointExternal(dest) != WOLFSSL_SUCCESS) {
39343         return WOLFSSL_FAILURE;
39344     }
39345 
39346     return WOLFSSL_SUCCESS;
39347 }
39348 #endif /* HAVE_ECC */
39349 #endif /* OPENSSL_EXTRA */
39350 
39351 #if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT * p)39352 void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *p)
39353 {
39354     WOLFSSL_ENTER("wolfSSL_EC_POINT_free");
39355 
39356     if (p != NULL) {
39357         if (p->internal != NULL) {
39358             wc_ecc_del_point((ecc_point*)p->internal);
39359             p->internal = NULL;
39360         }
39361 
39362         wolfSSL_BN_free(p->X);
39363         wolfSSL_BN_free(p->Y);
39364         wolfSSL_BN_free(p->Z);
39365         p->X = NULL;
39366         p->Y = NULL;
39367         p->Z = NULL;
39368         p->inSet = p->exSet = 0;
39369 
39370         XFREE(p, NULL, DYNAMIC_TYPE_ECC);
39371         /* p = NULL, don't try to access or double free it */
39372     }
39373 }
39374 #endif
39375 
39376 #ifdef OPENSSL_EXTRA
39377 #ifdef HAVE_ECC
39378 /* return code compliant with OpenSSL :
39379  *   1 if point at infinity, 0 else
39380  */
wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP * group,const WOLFSSL_EC_POINT * point)39381 int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
39382                                     const WOLFSSL_EC_POINT *point)
39383 {
39384     int ret;
39385 
39386     WOLFSSL_ENTER("wolfSSL_EC_POINT_is_at_infinity");
39387 
39388     if (group == NULL || point == NULL || point->internal == NULL) {
39389         WOLFSSL_MSG("wolfSSL_EC_POINT_is_at_infinity NULL error");
39390         return WOLFSSL_FAILURE;
39391     }
39392 
39393     if (setupPoint(point) != WOLFSSL_SUCCESS) {
39394         return WOLFSSL_FAILURE;
39395     }
39396 
39397     ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal);
39398     if (ret < 0) {
39399         WOLFSSL_MSG("ecc_point_is_at_infinity failure");
39400         return WOLFSSL_FAILURE;
39401     }
39402 
39403     return ret;
39404 }
39405 
39406 /* End EC_POINT */
39407 
39408 #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_BUILTIN_CURVE * r,size_t nitems)39409 size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_BUILTIN_CURVE *r, size_t nitems)
39410 {
39411     size_t i, min_nitems;
39412 #ifdef HAVE_SELFTEST
39413     size_t ecc_sets_count;
39414     for (i = 0; ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; i++);
39415     ecc_sets_count = i;
39416 #endif
39417 
39418     if (r == NULL || nitems == 0)
39419         return ecc_sets_count;
39420 
39421     min_nitems = nitems < ecc_sets_count ? nitems : ecc_sets_count;
39422 
39423     for (i = 0; i < min_nitems; i++) {
39424         r[i].nid = EccEnumToNID(ecc_sets[i].id);
39425         r[i].comment = wolfSSL_OBJ_nid2sn(r[i].nid);
39426     }
39427 
39428     return min_nitems;
39429 }
39430 #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
39431 
39432 /* Start ECDSA_SIG */
wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG * sig)39433 void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig)
39434 {
39435     WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_free");
39436 
39437     if (sig) {
39438         wolfSSL_BN_free(sig->r);
39439         wolfSSL_BN_free(sig->s);
39440 
39441         XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
39442     }
39443 }
39444 
wolfSSL_ECDSA_SIG_new(void)39445 WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void)
39446 {
39447     WOLFSSL_ECDSA_SIG *sig;
39448 
39449     WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_new");
39450 
39451     sig = (WOLFSSL_ECDSA_SIG*) XMALLOC(sizeof(WOLFSSL_ECDSA_SIG), NULL,
39452                                        DYNAMIC_TYPE_ECC);
39453     if (sig == NULL) {
39454         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA signature failure");
39455         return NULL;
39456     }
39457 
39458     sig->s = NULL;
39459     sig->r = wolfSSL_BN_new();
39460     if (sig->r == NULL) {
39461         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA r failure");
39462         wolfSSL_ECDSA_SIG_free(sig);
39463         return NULL;
39464     }
39465 
39466     sig->s = wolfSSL_BN_new();
39467     if (sig->s == NULL) {
39468         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA s failure");
39469         wolfSSL_ECDSA_SIG_free(sig);
39470         return NULL;
39471     }
39472 
39473     return sig;
39474 }
39475 
wolfSSL_ECDSA_SIG_get0(const WOLFSSL_ECDSA_SIG * sig,const WOLFSSL_BIGNUM ** r,const WOLFSSL_BIGNUM ** s)39476 void wolfSSL_ECDSA_SIG_get0(const WOLFSSL_ECDSA_SIG* sig,
39477     const WOLFSSL_BIGNUM** r, const WOLFSSL_BIGNUM** s)
39478 {
39479     if (sig == NULL) {
39480         return;
39481     }
39482 
39483     if (r != NULL) {
39484         *r = sig->r;
39485     }
39486     if (s != NULL) {
39487         *s = sig->s;
39488     }
39489 }
39490 
wolfSSL_ECDSA_SIG_set0(WOLFSSL_ECDSA_SIG * sig,WOLFSSL_BIGNUM * r,WOLFSSL_BIGNUM * s)39491 int wolfSSL_ECDSA_SIG_set0(WOLFSSL_ECDSA_SIG* sig, WOLFSSL_BIGNUM* r,
39492     WOLFSSL_BIGNUM* s)
39493 {
39494     if (sig == NULL || r == NULL || s == NULL) {
39495         return WOLFSSL_FAILURE;
39496     }
39497 
39498     wolfSSL_BN_free(sig->r);
39499     wolfSSL_BN_free(sig->s);
39500 
39501     sig->r = r;
39502     sig->s = s;
39503 
39504     return WOLFSSL_SUCCESS;
39505 }
39506 
39507 /* return signature structure on success, NULL otherwise */
wolfSSL_ECDSA_do_sign(const unsigned char * d,int dlen,WOLFSSL_EC_KEY * key)39508 WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen,
39509                                          WOLFSSL_EC_KEY *key)
39510 {
39511     WOLFSSL_ECDSA_SIG *sig = NULL;
39512     int     initTmpRng = 0;
39513     WC_RNG* rng = NULL;
39514 #ifdef WOLFSSL_SMALL_STACK
39515     WC_RNG* tmpRNG = NULL;
39516 #else
39517     WC_RNG  tmpRNG[1];
39518 #endif
39519 
39520     WOLFSSL_ENTER("wolfSSL_ECDSA_do_sign");
39521 
39522     if (d == NULL || key == NULL || key->internal == NULL) {
39523         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad arguments");
39524         return NULL;
39525     }
39526 
39527     /* set internal key if not done */
39528     if (key->inSet == 0)
39529     {
39530         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign No EC key internal set, do it");
39531 
39532         if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
39533             WOLFSSL_MSG("wolfSSL_ECDSA_do_sign SetECKeyInternal failed");
39534             return NULL;
39535         }
39536     }
39537 
39538 #ifdef WOLFSSL_SMALL_STACK
39539     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
39540     if (tmpRNG == NULL)
39541         return NULL;
39542 #endif
39543 
39544     if (wc_InitRng(tmpRNG) == 0) {
39545         rng = tmpRNG;
39546         initTmpRng = 1;
39547     }
39548     else {
39549         WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad RNG Init, trying global");
39550         if (initGlobalRNG == 0)
39551             WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Global RNG no Init");
39552         else
39553             rng = &globalRNG;
39554     }
39555 
39556     if (rng) {
39557         byte   out[ECC_BUFSIZE];
39558         word32 outlen = ECC_BUFSIZE;
39559         /* use wc_ecc_sign_hash because it supports crypto callbacks */
39560         if (wc_ecc_sign_hash(d, dlen, out, &outlen, rng,
39561                                                 (ecc_key*)key->internal) == 0) {
39562             mp_int sig_r, sig_s;
39563             if (mp_init_multi(&sig_r, &sig_s, NULL, NULL, NULL, NULL) == MP_OKAY) {
39564                 /* put signature blob in ECDSA structure */
39565                 if (DecodeECC_DSA_Sig(out, outlen, &sig_r, &sig_s) == 0) {
39566                     sig = wolfSSL_ECDSA_SIG_new();
39567                     if (sig == NULL)
39568                         WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new failed");
39569                     else if (SetIndividualExternal(&sig->r, &sig_r) != WOLFSSL_SUCCESS) {
39570                         WOLFSSL_MSG("ecdsa r key error");
39571                         wolfSSL_ECDSA_SIG_free(sig);
39572                         sig = NULL;
39573                     }
39574                     else if (SetIndividualExternal(&sig->s, &sig_s)!=WOLFSSL_SUCCESS){
39575                         WOLFSSL_MSG("ecdsa s key error");
39576                         wolfSSL_ECDSA_SIG_free(sig);
39577                         sig = NULL;
39578                     }
39579                 }
39580                 mp_free(&sig_r);
39581                 mp_free(&sig_s);
39582             }
39583         }
39584         else {
39585             WOLFSSL_MSG("wc_ecc_sign_hash_ex failed");
39586         }
39587     }
39588 
39589     if (initTmpRng)
39590         wc_FreeRng(tmpRNG);
39591 #ifdef WOLFSSL_SMALL_STACK
39592     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
39593 #endif
39594 
39595     return sig;
39596 }
39597 
39598 /* return code compliant with OpenSSL :
39599  *   1 for a valid signature, 0 for an invalid signature and -1 on error
39600  */
wolfSSL_ECDSA_do_verify(const unsigned char * d,int dlen,const WOLFSSL_ECDSA_SIG * sig,WOLFSSL_EC_KEY * key)39601 int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen,
39602                             const WOLFSSL_ECDSA_SIG *sig, WOLFSSL_EC_KEY *key)
39603 {
39604     int check_sign = 0;
39605 
39606     WOLFSSL_ENTER("wolfSSL_ECDSA_do_verify");
39607 
39608     if (d == NULL || sig == NULL || key == NULL || key->internal == NULL) {
39609         WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad arguments");
39610         return WOLFSSL_FATAL_ERROR;
39611     }
39612 
39613     /* set internal key if not done */
39614     if (key->inSet == 0)
39615     {
39616         WOLFSSL_MSG("No EC key internal set, do it");
39617 
39618         if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) {
39619             WOLFSSL_MSG("SetECKeyInternal failed");
39620             return WOLFSSL_FATAL_ERROR;
39621         }
39622     }
39623 
39624     if (wc_ecc_verify_hash_ex((mp_int*)sig->r->internal,
39625                               (mp_int*)sig->s->internal, d, dlen, &check_sign,
39626                               (ecc_key *)key->internal) != MP_OKAY) {
39627         WOLFSSL_MSG("wc_ecc_verify_hash failed");
39628         return WOLFSSL_FATAL_ERROR;
39629     }
39630     else if (check_sign == 0) {
39631         WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
39632         return WOLFSSL_FAILURE;
39633     }
39634 
39635     return WOLFSSL_SUCCESS;
39636 }
39637 
wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG ** sig,const unsigned char ** pp,long len)39638 WOLFSSL_ECDSA_SIG *wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG **sig,
39639                                          const unsigned char **pp, long len)
39640 {
39641     WOLFSSL_ECDSA_SIG *s = NULL;
39642 
39643     if (pp == NULL)
39644         return NULL;
39645 
39646     if (sig != NULL)
39647         s = *sig;
39648     if (s == NULL) {
39649         s = wolfSSL_ECDSA_SIG_new();
39650         if (s == NULL)
39651             return NULL;
39652     }
39653 
39654     /* DecodeECC_DSA_Sig calls mp_init, so free these */
39655     mp_free((mp_int*)s->r->internal);
39656     mp_free((mp_int*)s->s->internal);
39657 
39658     if (DecodeECC_DSA_Sig(*pp, (word32)len, (mp_int*)s->r->internal,
39659                                           (mp_int*)s->s->internal) != MP_OKAY) {
39660         if (sig == NULL || *sig == NULL)
39661             wolfSSL_ECDSA_SIG_free(s);
39662         return NULL;
39663     }
39664 
39665     *pp += len;
39666     if (sig != NULL)
39667         *sig = s;
39668     return s;
39669 }
39670 
wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG * sig,unsigned char ** pp)39671 int wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG *sig, unsigned char **pp)
39672 {
39673     word32 len;
39674 
39675     if (sig == NULL)
39676         return 0;
39677 
39678     /* ASN.1: SEQ + INT + INT
39679      *   ASN.1 Integer must be a positive value - prepend zero if number has
39680      *   top bit set.
39681      */
39682     len = 2 + mp_leading_bit((mp_int*)sig->r->internal) +
39683               mp_unsigned_bin_size((mp_int*)sig->r->internal) +
39684           2 + mp_leading_bit((mp_int*)sig->s->internal) +
39685               mp_unsigned_bin_size((mp_int*)sig->s->internal);
39686     /* Two bytes required for length if ASN.1 SEQ data greater than 127 bytes
39687      * and less than 256 bytes.
39688      */
39689     len = 1 + ((len > 127) ? 2 : 1) + len;
39690     if (pp != NULL && *pp != NULL) {
39691         if (StoreECC_DSA_Sig(*pp, &len, (mp_int*)sig->r->internal,
39692                                         (mp_int*)sig->s->internal) != MP_OKAY) {
39693             len = 0;
39694         }
39695         else
39696             *pp += len;
39697     }
39698 
39699     return (int)len;
39700 }
39701 /* End ECDSA_SIG */
39702 
39703 
39704 /* Remove this prototype when code is reorganized. */
39705 static int wolfSSL_RAND_Init(void);
39706 
39707 /* Start ECDH */
39708 /* return code compliant with OpenSSL :
39709  *   length of computed key if success, -1 if error
39710  */
wolfSSL_ECDH_compute_key(void * out,size_t outlen,const WOLFSSL_EC_POINT * pub_key,WOLFSSL_EC_KEY * ecdh,void * (* KDF)(const void * in,size_t inlen,void * out,size_t * outlen))39711 int wolfSSL_ECDH_compute_key(void *out, size_t outlen,
39712                              const WOLFSSL_EC_POINT *pub_key,
39713                              WOLFSSL_EC_KEY *ecdh,
39714                              void *(*KDF) (const void *in, size_t inlen,
39715                                            void *out, size_t *outlen))
39716 {
39717     word32 len;
39718     ecc_key* key;
39719     int ret;
39720 #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) \
39721     && !defined(HAVE_FIPS)
39722     int setGlobalRNG = 0;
39723 #endif
39724     (void)KDF;
39725 
39726     WOLFSSL_ENTER("wolfSSL_ECDH_compute_key");
39727 
39728     if (out == NULL || pub_key == NULL || pub_key->internal == NULL ||
39729         ecdh == NULL || ecdh->internal == NULL) {
39730         WOLFSSL_MSG("Bad function arguments");
39731         return WOLFSSL_FATAL_ERROR;
39732     }
39733 
39734     /* set internal key if not done */
39735     if (ecdh->inSet == 0)
39736     {
39737         WOLFSSL_MSG("No EC key internal set, do it");
39738 
39739         if (SetECKeyInternal(ecdh) != WOLFSSL_SUCCESS) {
39740             WOLFSSL_MSG("SetECKeyInternal failed");
39741             return WOLFSSL_FATAL_ERROR;
39742         }
39743     }
39744 
39745     len = (word32)outlen;
39746     key = (ecc_key*)ecdh->internal;
39747 
39748 #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) \
39749     && !defined(HAVE_FIPS)
39750     if (key->rng == NULL) {
39751         if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
39752             WOLFSSL_MSG("No RNG to use");
39753             return WOLFSSL_FATAL_ERROR;
39754         }
39755         key->rng = &globalRNG;
39756         setGlobalRNG = 1;
39757     }
39758 #endif
39759     PRIVATE_KEY_UNLOCK();
39760     ret = wc_ecc_shared_secret_ssh(key, (ecc_point*)pub_key->internal,
39761             (byte *)out, &len);
39762     PRIVATE_KEY_LOCK();
39763 #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) \
39764     && !defined(HAVE_FIPS)
39765     if (setGlobalRNG)
39766         key->rng = NULL;
39767 #endif
39768     if (ret != MP_OKAY) {
39769         WOLFSSL_MSG("wc_ecc_shared_secret failed");
39770         return WOLFSSL_FATAL_ERROR;
39771     }
39772 
39773     return len;
39774 }
39775 /* End ECDH */
39776 
39777 #if !defined(NO_FILESYSTEM)
39778 /* return code compliant with OpenSSL :
39779  *   1 if success, 0 if error
39780  */
39781 #ifndef NO_WOLFSSL_STUB
wolfSSL_PEM_write_EC_PUBKEY(XFILE fp,WOLFSSL_EC_KEY * x)39782 int wolfSSL_PEM_write_EC_PUBKEY(XFILE fp, WOLFSSL_EC_KEY *x)
39783 {
39784     (void)fp;
39785     (void)x;
39786     WOLFSSL_STUB("PEM_write_EC_PUBKEY");
39787     WOLFSSL_MSG("wolfSSL_PEM_write_EC_PUBKEY not implemented");
39788 
39789     return WOLFSSL_FAILURE;
39790 }
39791 #endif
39792 
39793 #ifndef NO_BIO
39794 
39795 /* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects
39796  * the results to be an EC key.
39797  *
39798  * bio  structure to read EC private key from
39799  * ec   if not null is then set to the result
39800  * cb   password callback for reading PEM
39801  * pass password string
39802  *
39803  * returns a pointer to a new WOLFSSL_EC_KEY struct on success and NULL on fail
39804  */
39805 
wolfSSL_PEM_read_bio_EC_PUBKEY(WOLFSSL_BIO * bio,WOLFSSL_EC_KEY ** ec,wc_pem_password_cb * cb,void * pass)39806 WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_EC_PUBKEY(WOLFSSL_BIO* bio,
39807                                                WOLFSSL_EC_KEY** ec,
39808                                                wc_pem_password_cb* cb,
39809                                                void *pass)
39810 {
39811     WOLFSSL_EVP_PKEY* pkey;
39812     WOLFSSL_EC_KEY* local;
39813 
39814     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_EC_PUBKEY");
39815 
39816     pkey = wolfSSL_PEM_read_bio_PUBKEY(bio, NULL, cb, pass);
39817     if (pkey == NULL) {
39818         return NULL;
39819     }
39820 
39821     /* Since the WOLFSSL_EC_KEY structure is being taken from WOLFSSL_EVP_PKEY the
39822      * flag indicating that the WOLFSSL_EC_KEY structure is owned should be FALSE
39823      * to avoid having it free'd */
39824     pkey->ownEcc = 0;
39825     local = pkey->ecc;
39826     if (ec != NULL) {
39827         *ec = local;
39828     }
39829 
39830     wolfSSL_EVP_PKEY_free(pkey);
39831     return local;
39832 }
39833 
39834 /* Reads a private EC key from a WOLFSSL_BIO into a WOLFSSL_EC_KEY.
39835  * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
39836  */
wolfSSL_PEM_read_bio_ECPrivateKey(WOLFSSL_BIO * bio,WOLFSSL_EC_KEY ** ec,wc_pem_password_cb * cb,void * pass)39837 WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_ECPrivateKey(WOLFSSL_BIO* bio,
39838                                                   WOLFSSL_EC_KEY** ec,
39839                                                   wc_pem_password_cb* cb,
39840                                                   void *pass)
39841 {
39842     WOLFSSL_EVP_PKEY* pkey;
39843     WOLFSSL_EC_KEY* local;
39844 
39845     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_ECPrivateKey");
39846 
39847     pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
39848     if (pkey == NULL) {
39849         return NULL;
39850     }
39851 
39852     /* Since the WOLFSSL_EC_KEY structure is being taken from WOLFSSL_EVP_PKEY the
39853      * flag indicating that the WOLFSSL_EC_KEY structure is owned should be FALSE
39854      * to avoid having it free'd */
39855     pkey->ownEcc = 0;
39856     local = pkey->ecc;
39857     if (ec != NULL) {
39858         *ec = local;
39859     }
39860 
39861     wolfSSL_EVP_PKEY_free(pkey);
39862     return local;
39863 }
39864 #endif /* !NO_BIO */
39865 #endif /* NO_FILESYSTEM */
39866 
39867 #if defined(WOLFSSL_KEY_GEN)
39868 #ifndef NO_BIO
39869 /* Takes a public WOLFSSL_EC_KEY and writes it out to WOLFSSL_BIO
39870  * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
39871  */
wolfSSL_PEM_write_bio_EC_PUBKEY(WOLFSSL_BIO * bio,WOLFSSL_EC_KEY * ec)39872 int wolfSSL_PEM_write_bio_EC_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec)
39873 {
39874     int ret = 0;
39875     WOLFSSL_EVP_PKEY* pkey;
39876 
39877     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_EC_PUBKEY");
39878 
39879     if (bio == NULL || ec == NULL) {
39880         WOLFSSL_MSG("Bad Function Arguments");
39881         return WOLFSSL_FAILURE;
39882     }
39883 
39884     /* Initialize pkey structure */
39885     pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
39886     if (pkey == NULL) {
39887         WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
39888         return WOLFSSL_FAILURE;
39889     }
39890 
39891     /* Set pkey info */
39892     pkey->ecc    = ec;
39893     pkey->ownEcc = 0; /* pkey does not own ECC */
39894     pkey->type = EVP_PKEY_EC;
39895 
39896     if((ret = WriteBioPUBKEY(bio, pkey)) != WOLFSSL_SUCCESS){
39897         WOLFSSL_MSG("wolfSSL_PEM_write_bio_PUBKEY failed");
39898     }
39899     wolfSSL_EVP_PKEY_free(pkey);
39900 
39901     return ret;
39902 }
39903 
39904 /* return code compliant with OpenSSL :
39905  *   1 if success, 0 if error
39906  */
wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO * bio,WOLFSSL_EC_KEY * ec,const EVP_CIPHER * cipher,unsigned char * passwd,int len,wc_pem_password_cb * cb,void * arg)39907 int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec,
39908                                        const EVP_CIPHER* cipher,
39909                                        unsigned char* passwd, int len,
39910                                        wc_pem_password_cb* cb, void* arg)
39911 {
39912     int ret = 0, der_max_len = 0, derSz = 0;
39913     byte *derBuf;
39914     WOLFSSL_EVP_PKEY* pkey;
39915     WOLFSSL_ENTER("WOLFSSL_PEM_write_bio_ECPrivateKey");
39916 
39917     if (bio == NULL || ec == NULL) {
39918         WOLFSSL_MSG("Bad Function Arguments");
39919         return WOLFSSL_FAILURE;
39920     }
39921 
39922     /* Initialize pkey structure */
39923     pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
39924     if (pkey == NULL) {
39925         WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
39926         return WOLFSSL_FAILURE;
39927     }
39928 
39929     /* Set pkey info */
39930     pkey->ecc    = ec;
39931     pkey->ownEcc = 0; /* pkey does not own ECC */
39932     pkey->type = EVP_PKEY_EC;
39933 
39934     /* 4 > size of pub, priv + ASN.1 additional informations
39935      */
39936     der_max_len = 4 * wc_ecc_size((ecc_key*)ec->internal) + AES_BLOCK_SIZE;
39937 
39938     derBuf = (byte*)XMALLOC(der_max_len, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
39939     if (derBuf == NULL) {
39940         WOLFSSL_MSG("Malloc failed");
39941         wolfSSL_EVP_PKEY_free(pkey);
39942         return WOLFSSL_FAILURE;
39943     }
39944 
39945     /* convert key to der format */
39946     derSz = wc_EccKeyToDer((ecc_key*)ec->internal, derBuf, der_max_len);
39947     if (derSz < 0) {
39948         WOLFSSL_MSG("wc_EccKeyToDer failed");
39949         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
39950         wolfSSL_EVP_PKEY_free(pkey);
39951         return WOLFSSL_FAILURE;
39952     }
39953 
39954     pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
39955     if (pkey->pkey.ptr == NULL) {
39956         WOLFSSL_MSG("key malloc failed");
39957         XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
39958         wolfSSL_EVP_PKEY_free(pkey);
39959         return WOLFSSL_FAILURE;
39960     }
39961 
39962     /* add der info to the evp key */
39963     pkey->pkey_sz = derSz;
39964     XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
39965     XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
39966 
39967     ret = wolfSSL_PEM_write_bio_PrivateKey(bio, pkey, cipher, passwd, len,
39968                                         cb, arg);
39969     wolfSSL_EVP_PKEY_free(pkey);
39970 
39971     return ret;
39972 }
39973 
39974 #endif /* !NO_BIO */
39975 
39976 /* return code compliant with OpenSSL :
39977  *   1 if success, 0 if error
39978  */
wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY * ecc,const EVP_CIPHER * cipher,unsigned char * passwd,int passwdSz,unsigned char ** pem,int * plen)39979 int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc,
39980                                        const EVP_CIPHER* cipher,
39981                                        unsigned char* passwd, int passwdSz,
39982                                        unsigned char **pem, int *plen)
39983 {
39984 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
39985     byte *derBuf, *tmp, *cipherInfo = NULL;
39986     int  der_max_len = 0, derSz = 0;
39987     const int type = ECC_PRIVATEKEY_TYPE;
39988     const char* header = NULL;
39989     const char* footer = NULL;
39990 
39991     WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey");
39992 
39993     if (pem == NULL || plen == NULL || ecc == NULL || ecc->internal == NULL) {
39994         WOLFSSL_MSG("Bad function arguments");
39995         return WOLFSSL_FAILURE;
39996     }
39997 
39998     if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
39999         return WOLFSSL_FAILURE;
40000 
40001     if (ecc->inSet == 0) {
40002         WOLFSSL_MSG("No ECC internal set, do it");
40003 
40004         if (SetECKeyInternal(ecc) != WOLFSSL_SUCCESS) {
40005             WOLFSSL_MSG("SetECKeyInternal failed");
40006             return WOLFSSL_FAILURE;
40007         }
40008     }
40009 
40010     /* 4 > size of pub, priv + ASN.1 additional information */
40011     der_max_len = 4 * wc_ecc_size((ecc_key*)ecc->internal) + AES_BLOCK_SIZE;
40012 
40013     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_DER);
40014     if (derBuf == NULL) {
40015         WOLFSSL_MSG("malloc failed");
40016         return WOLFSSL_FAILURE;
40017     }
40018 
40019     /* Key to DER */
40020     derSz = wc_EccKeyToDer((ecc_key*)ecc->internal, derBuf, der_max_len);
40021     if (derSz < 0) {
40022         WOLFSSL_MSG("wc_EccKeyToDer failed");
40023         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40024         return WOLFSSL_FAILURE;
40025     }
40026 
40027     /* encrypt DER buffer if required */
40028     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
40029         int ret;
40030 
40031         ret = EncryptDerKey(derBuf, &derSz, cipher,
40032                             passwd, passwdSz, &cipherInfo, der_max_len);
40033         if (ret != WOLFSSL_SUCCESS) {
40034             WOLFSSL_MSG("EncryptDerKey failed");
40035             XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40036             return ret;
40037         }
40038 
40039         /* tmp buffer with a max size */
40040         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
40041             (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
40042     }
40043     else { /* tmp buffer with a max size */
40044         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
40045             (int)XSTRLEN(footer) + 1;
40046     }
40047 
40048     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_PEM);
40049     if (tmp == NULL) {
40050         WOLFSSL_MSG("malloc failed");
40051         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40052         if (cipherInfo != NULL)
40053             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
40054         return WOLFSSL_FAILURE;
40055     }
40056 
40057     /* DER to PEM */
40058     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type);
40059     if (*plen <= 0) {
40060         WOLFSSL_MSG("wc_DerToPemEx failed");
40061         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40062         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
40063         if (cipherInfo != NULL)
40064             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
40065         return WOLFSSL_FAILURE;
40066     }
40067     XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40068     if (cipherInfo != NULL)
40069         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
40070 
40071     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
40072     if (*pem == NULL) {
40073         WOLFSSL_MSG("malloc failed");
40074         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
40075         return WOLFSSL_FAILURE;
40076     }
40077     XMEMSET(*pem, 0, (*plen)+1);
40078 
40079     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
40080         WOLFSSL_MSG("XMEMCPY failed");
40081         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
40082         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
40083         return WOLFSSL_FAILURE;
40084     }
40085     XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
40086 
40087     return WOLFSSL_SUCCESS;
40088 #else
40089     (void)ecc;
40090     (void)cipher;
40091     (void)passwd;
40092     (void)passwdSz;
40093     (void)pem;
40094     (void)plen;
40095     return WOLFSSL_FAILURE;
40096 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
40097 }
40098 
40099 #ifndef NO_FILESYSTEM
40100 /* return code compliant with OpenSSL :
40101  *   1 if success, 0 if error
40102  */
wolfSSL_PEM_write_ECPrivateKey(XFILE fp,WOLFSSL_EC_KEY * ecc,const EVP_CIPHER * enc,unsigned char * kstr,int klen,wc_pem_password_cb * cb,void * u)40103 int wolfSSL_PEM_write_ECPrivateKey(XFILE fp, WOLFSSL_EC_KEY *ecc,
40104                                    const EVP_CIPHER *enc,
40105                                    unsigned char *kstr, int klen,
40106                                    wc_pem_password_cb *cb, void *u)
40107 {
40108     byte *pem;
40109     int  plen, ret;
40110 
40111     (void)cb;
40112     (void)u;
40113 
40114     WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey");
40115 
40116     if (fp == XBADFILE || ecc == NULL || ecc->internal == NULL) {
40117         WOLFSSL_MSG("Bad function arguments");
40118         return WOLFSSL_FAILURE;
40119     }
40120 
40121     ret = wolfSSL_PEM_write_mem_ECPrivateKey(ecc, enc, kstr, klen, &pem, &plen);
40122     if (ret != WOLFSSL_SUCCESS) {
40123         WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed");
40124         return WOLFSSL_FAILURE;
40125     }
40126 
40127     ret = (int)XFWRITE(pem, plen, 1, fp);
40128     if (ret != 1) {
40129         WOLFSSL_MSG("ECC private key file write failed");
40130         return WOLFSSL_FAILURE;
40131     }
40132 
40133     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
40134     return WOLFSSL_SUCCESS;
40135 }
40136 
40137 #endif /* NO_FILESYSTEM */
40138 #endif /* defined(WOLFSSL_KEY_GEN) */
40139 
40140 #endif /* HAVE_ECC */
40141 
40142 
40143 #ifndef NO_DSA
40144 
40145 #if defined(WOLFSSL_KEY_GEN)
40146 #ifndef NO_BIO
40147 
40148 /* Takes a DSA Privatekey and writes it out to a WOLFSSL_BIO
40149  * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
40150  */
wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO * bio,WOLFSSL_DSA * dsa,const EVP_CIPHER * cipher,unsigned char * passwd,int len,wc_pem_password_cb * cb,void * arg)40151 int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa,
40152                                        const EVP_CIPHER* cipher,
40153                                        unsigned char* passwd, int len,
40154                                        wc_pem_password_cb* cb, void* arg)
40155 {
40156     int ret = 0, der_max_len = 0, derSz = 0;
40157     byte *derBuf;
40158     WOLFSSL_EVP_PKEY* pkey;
40159 
40160     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_DSAPrivateKey");
40161 
40162     if (bio == NULL || dsa == NULL) {
40163         WOLFSSL_MSG("Bad Function Arguments");
40164         return WOLFSSL_FAILURE;
40165     }
40166 
40167     pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
40168     if (pkey == NULL) {
40169         WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
40170         return WOLFSSL_FAILURE;
40171     }
40172 
40173     pkey->type   = EVP_PKEY_DSA;
40174     pkey->dsa    = dsa;
40175     pkey->ownDsa = 0;
40176 
40177     /* 4 > size of pub, priv, p, q, g + ASN.1 additional information */
40178     der_max_len = MAX_DSA_PRIVKEY_SZ;
40179 
40180     derBuf = (byte*)XMALLOC(der_max_len, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40181     if (derBuf == NULL) {
40182         WOLFSSL_MSG("Malloc failed");
40183         wolfSSL_EVP_PKEY_free(pkey);
40184         return WOLFSSL_FAILURE;
40185     }
40186 
40187     /* convert key to der format */
40188     derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, derBuf, der_max_len);
40189     if (derSz < 0) {
40190         WOLFSSL_MSG("wc_DsaKeyToDer failed");
40191         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40192         wolfSSL_EVP_PKEY_free(pkey);
40193         return WOLFSSL_FAILURE;
40194     }
40195 
40196     pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40197     if (pkey->pkey.ptr == NULL) {
40198         WOLFSSL_MSG("key malloc failed");
40199         XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40200         wolfSSL_EVP_PKEY_free(pkey);
40201         return WOLFSSL_FAILURE;
40202     }
40203 
40204     /* add der info to the evp key */
40205     pkey->pkey_sz = derSz;
40206     XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
40207     XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40208 
40209     ret = wolfSSL_PEM_write_bio_PrivateKey(bio, pkey, cipher, passwd, len,
40210                                         cb, arg);
40211     wolfSSL_EVP_PKEY_free(pkey);
40212 
40213     return ret;
40214 }
40215 
40216 #ifndef HAVE_SELFTEST
40217 /* Takes a DSA public key and writes it out to a WOLFSSL_BIO
40218  * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
40219  */
wolfSSL_PEM_write_bio_DSA_PUBKEY(WOLFSSL_BIO * bio,WOLFSSL_DSA * dsa)40220 int wolfSSL_PEM_write_bio_DSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa)
40221 {
40222     int ret = 0;
40223     WOLFSSL_EVP_PKEY* pkey;
40224 
40225     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_DSA_PUBKEY");
40226 
40227     if (bio == NULL || dsa == NULL) {
40228         WOLFSSL_MSG("Bad function arguements");
40229         return WOLFSSL_FAILURE;
40230     }
40231 
40232     pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap);
40233     if (pkey == NULL) {
40234         WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed");
40235         return WOLFSSL_FAILURE;
40236     }
40237 
40238     pkey->type   = EVP_PKEY_DSA;
40239     pkey->dsa    = dsa;
40240     pkey->ownDsa = 0;
40241 
40242     ret = WriteBioPUBKEY(bio, pkey);
40243     wolfSSL_EVP_PKEY_free(pkey);
40244     return ret;
40245 }
40246 #endif /* HAVE_SELFTEST */
40247 #endif /* !NO_BIO */
40248 
40249 /* return code compliant with OpenSSL :
40250  *   1 if success, 0 if error
40251  */
wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA * dsa,const EVP_CIPHER * cipher,unsigned char * passwd,int passwdSz,unsigned char ** pem,int * plen)40252 int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
40253                                         const EVP_CIPHER* cipher,
40254                                         unsigned char* passwd, int passwdSz,
40255                                         unsigned char **pem, int *plen)
40256 {
40257 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
40258     byte *derBuf, *tmp, *cipherInfo = NULL;
40259     int  der_max_len = 0, derSz = 0;
40260     const int type = DSA_PRIVATEKEY_TYPE;
40261     const char* header = NULL;
40262     const char* footer = NULL;
40263 
40264     WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey");
40265 
40266     if (pem == NULL || plen == NULL || dsa == NULL || dsa->internal == NULL) {
40267         WOLFSSL_MSG("Bad function arguments");
40268         return WOLFSSL_FAILURE;
40269     }
40270 
40271     if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
40272         return WOLFSSL_FAILURE;
40273 
40274     if (dsa->inSet == 0) {
40275         WOLFSSL_MSG("No DSA internal set, do it");
40276 
40277         if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) {
40278             WOLFSSL_MSG("SetDsaInternal failed");
40279             return WOLFSSL_FAILURE;
40280         }
40281     }
40282 
40283     der_max_len = MAX_DSA_PRIVKEY_SZ;
40284 
40285     derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_DER);
40286     if (derBuf == NULL) {
40287         WOLFSSL_MSG("malloc failed");
40288         return WOLFSSL_FAILURE;
40289     }
40290 
40291     /* Key to DER */
40292     derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, derBuf, der_max_len);
40293     if (derSz < 0) {
40294         WOLFSSL_MSG("wc_DsaKeyToDer failed");
40295         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40296         return WOLFSSL_FAILURE;
40297     }
40298 
40299     /* encrypt DER buffer if required */
40300     if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
40301         int ret;
40302 
40303         ret = EncryptDerKey(derBuf, &derSz, cipher,
40304                             passwd, passwdSz, &cipherInfo, der_max_len);
40305         if (ret != WOLFSSL_SUCCESS) {
40306             WOLFSSL_MSG("EncryptDerKey failed");
40307             XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40308             return ret;
40309         }
40310 
40311         /* tmp buffer with a max size */
40312         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
40313             (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
40314     }
40315     else { /* tmp buffer with a max size */
40316         *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
40317             (int)XSTRLEN(footer) + 1;
40318     }
40319 
40320     tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_PEM);
40321     if (tmp == NULL) {
40322         WOLFSSL_MSG("malloc failed");
40323         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40324         if (cipherInfo != NULL)
40325             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
40326         return WOLFSSL_FAILURE;
40327     }
40328 
40329     /* DER to PEM */
40330     *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type);
40331     if (*plen <= 0) {
40332         WOLFSSL_MSG("wc_DerToPemEx failed");
40333         XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40334         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
40335         if (cipherInfo != NULL)
40336             XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
40337         return WOLFSSL_FAILURE;
40338     }
40339     XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
40340     if (cipherInfo != NULL)
40341         XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
40342 
40343     *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY);
40344     if (*pem == NULL) {
40345         WOLFSSL_MSG("malloc failed");
40346         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
40347         return WOLFSSL_FAILURE;
40348     }
40349     XMEMSET(*pem, 0, (*plen)+1);
40350 
40351     if (XMEMCPY(*pem, tmp, *plen) == NULL) {
40352         WOLFSSL_MSG("XMEMCPY failed");
40353         XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
40354         XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
40355         return WOLFSSL_FAILURE;
40356     }
40357     XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
40358 
40359     return WOLFSSL_SUCCESS;
40360 #else
40361     (void)dsa;
40362     (void)cipher;
40363     (void)passwd;
40364     (void)passwdSz;
40365     (void)pem;
40366     (void)plen;
40367     return WOLFSSL_FAILURE;
40368 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
40369 }
40370 
40371 #ifndef NO_FILESYSTEM
40372 /* return code compliant with OpenSSL :
40373  *   1 if success, 0 if error
40374  */
wolfSSL_PEM_write_DSAPrivateKey(XFILE fp,WOLFSSL_DSA * dsa,const EVP_CIPHER * enc,unsigned char * kstr,int klen,wc_pem_password_cb * cb,void * u)40375 int wolfSSL_PEM_write_DSAPrivateKey(XFILE fp, WOLFSSL_DSA *dsa,
40376                                     const EVP_CIPHER *enc,
40377                                     unsigned char *kstr, int klen,
40378                                     wc_pem_password_cb *cb, void *u)
40379 {
40380     byte *pem;
40381     int  plen, ret;
40382 
40383     (void)cb;
40384     (void)u;
40385 
40386     WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey");
40387 
40388     if (fp == XBADFILE || dsa == NULL || dsa->internal == NULL) {
40389         WOLFSSL_MSG("Bad function arguments");
40390         return WOLFSSL_FAILURE;
40391     }
40392 
40393     ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem, &plen);
40394     if (ret != WOLFSSL_SUCCESS) {
40395         WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed");
40396         return WOLFSSL_FAILURE;
40397     }
40398 
40399     ret = (int)XFWRITE(pem, plen, 1, fp);
40400     if (ret != 1) {
40401         WOLFSSL_MSG("DSA private key file write failed");
40402         return WOLFSSL_FAILURE;
40403     }
40404 
40405     XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
40406     return WOLFSSL_SUCCESS;
40407 }
40408 
40409 #endif /* NO_FILESYSTEM */
40410 #endif /* defined(WOLFSSL_KEY_GEN) */
40411 
40412 #ifndef NO_FILESYSTEM
40413 /* return code compliant with OpenSSL :
40414  *   1 if success, 0 if error
40415  */
40416 #ifndef NO_WOLFSSL_STUB
wolfSSL_PEM_write_DSA_PUBKEY(XFILE fp,WOLFSSL_DSA * x)40417 int wolfSSL_PEM_write_DSA_PUBKEY(XFILE fp, WOLFSSL_DSA *x)
40418 {
40419     (void)fp;
40420     (void)x;
40421     WOLFSSL_STUB("PEM_write_DSA_PUBKEY");
40422     WOLFSSL_MSG("wolfSSL_PEM_write_DSA_PUBKEY not implemented");
40423 
40424     return WOLFSSL_FAILURE;
40425 }
40426 #endif
40427 #endif /* NO_FILESYSTEM */
40428 
40429 #endif /* #ifndef NO_DSA */
40430 
40431 #ifndef NO_BIO
40432 
pem_read_bio_key(WOLFSSL_BIO * bio,wc_pem_password_cb * cb,void * pass,int keyType,int * eccFlag,DerBuffer ** der)40433 static int pem_read_bio_key(WOLFSSL_BIO* bio, wc_pem_password_cb* cb,
40434                             void* pass, int keyType, int* eccFlag,
40435                             DerBuffer** der)
40436 {
40437 #ifdef WOLFSSL_SMALL_STACK
40438     EncryptedInfo* info = NULL;
40439 #else
40440     EncryptedInfo info[1];
40441 #endif /* WOLFSSL_SMALL_STACK */
40442     wc_pem_password_cb* localCb = NULL;
40443     char* mem = NULL;
40444     int memSz = 0;
40445     int ret;
40446 
40447     if(cb) {
40448         localCb = cb;
40449     } else {
40450         if(pass) {
40451             localCb = wolfSSL_PEM_def_callback;
40452         }
40453     }
40454 
40455     if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
40456         memSz = ret;
40457         mem = (char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
40458         if (mem == NULL) {
40459             WOLFSSL_MSG("Memory error");
40460             ret = MEMORY_E;
40461         }
40462         if (ret >= 0) {
40463             if ((ret = wolfSSL_BIO_read(bio, mem, memSz)) <= 0) {
40464                 XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
40465                 mem = NULL;
40466                 ret = MEMORY_E;
40467             }
40468         }
40469     }
40470     else if (bio->type == WOLFSSL_BIO_FILE) {
40471         int sz  = 100; /* read from file by 100 byte chunks */
40472         int idx = 0;
40473         char* tmp = (char*)XMALLOC(sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
40474         memSz = 0;
40475         if (tmp == NULL) {
40476             WOLFSSL_MSG("Memory error");
40477             ret = MEMORY_E;
40478         }
40479 
40480         while (ret >= 0 && (sz = wolfSSL_BIO_read(bio, tmp, sz)) > 0) {
40481             char* newMem;
40482             if (memSz + sz < 0) {
40483                 /* sanity check */
40484                 break;
40485             }
40486             newMem = (char*)XREALLOC(mem, memSz + sz, bio->heap,
40487                     DYNAMIC_TYPE_OPENSSL);
40488             if (newMem == NULL) {
40489                 WOLFSSL_MSG("Memory error");
40490                 XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
40491                 mem = NULL;
40492                 XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
40493                 tmp = NULL;
40494                 ret = MEMORY_E;
40495                 break;
40496             }
40497             mem = newMem;
40498             XMEMCPY(mem + idx, tmp, sz);
40499             memSz += sz;
40500             idx   += sz;
40501             sz = 100; /* read another 100 byte chunk from file */
40502         }
40503         XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
40504         tmp = NULL;
40505         if (memSz <= 0) {
40506             WOLFSSL_MSG("No data to read from bio");
40507             if (mem != NULL) {
40508                 XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
40509                 mem = NULL;
40510             }
40511             ret = BUFFER_E;
40512         }
40513     }
40514     else {
40515         WOLFSSL_MSG("No data to read from bio");
40516         ret = NOT_COMPILED_IN;
40517     }
40518 
40519 #ifdef WOLFSSL_SMALL_STACK
40520     if (ret >= 0) {
40521         info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
40522                                        DYNAMIC_TYPE_TMP_BUFFER);
40523         if (info == NULL) {
40524             WOLFSSL_MSG("Error getting memory for EncryptedInfo structure");
40525             XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
40526             mem = NULL;
40527             ret = MEMORY_E;
40528         }
40529     }
40530 #endif /* WOLFSSL_SMALL_STACK */
40531 
40532     if (ret >= 0) {
40533         XMEMSET(info, 0, sizeof(EncryptedInfo));
40534         info->passwd_cb       = localCb;
40535         info->passwd_userdata = pass;
40536 
40537         /* Do not strip PKCS8 header */
40538         ret = PemToDer((const unsigned char*)mem, memSz, keyType, der,
40539             NULL, info, eccFlag);
40540 
40541         if (ret < 0) {
40542             WOLFSSL_MSG("Bad PEM To DER");
40543         }
40544         else {
40545             /* write left over data back to bio */
40546             if ((memSz - (int)info->consumed) > 0 &&
40547                     bio->type != WOLFSSL_BIO_FILE) {
40548                 if (wolfSSL_BIO_write(bio, mem + (int)info->consumed,
40549                                        memSz - (int)info->consumed) <= 0) {
40550                     WOLFSSL_MSG("Unable to advance bio read pointer");
40551                 }
40552             }
40553         }
40554     }
40555 
40556 #ifdef WOLFSSL_SMALL_STACK
40557     XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40558 #endif
40559     XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
40560 
40561     return ret;
40562 }
40563 
wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO * bio,WOLFSSL_EVP_PKEY ** key,wc_pem_password_cb * cb,void * pass)40564 WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
40565                                                   WOLFSSL_EVP_PKEY** key,
40566                                                   wc_pem_password_cb* cb,
40567                                                   void* pass)
40568 {
40569     WOLFSSL_EVP_PKEY* pkey = NULL;
40570     DerBuffer*         der = NULL;
40571     int             keyFormat = 0;
40572     int                 type = -1;
40573 
40574     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey");
40575 
40576     if (bio == NULL)
40577         return pkey;
40578 
40579     if (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE, &keyFormat,
40580                                                                    &der) >= 0) {
40581         const unsigned char* ptr = der->buffer;
40582 
40583         if (keyFormat) {
40584             /* keyFormat is Key_Sum enum */
40585             if (keyFormat == RSAk)
40586                 type = EVP_PKEY_RSA;
40587             else if (keyFormat == ECDSAk)
40588                 type = EVP_PKEY_EC;
40589             else if (keyFormat == DSAk)
40590                 type = EVP_PKEY_DSA;
40591             else if (keyFormat == DHk)
40592                 type = EVP_PKEY_DH;
40593         }
40594         else {
40595             /* Default to RSA if format is not set */
40596             type = EVP_PKEY_RSA;
40597         }
40598 
40599         /* handle case where reuse is attempted */
40600         if (key != NULL && *key != NULL)
40601             pkey = *key;
40602 
40603         wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length);
40604         if (pkey == NULL) {
40605             WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
40606         }
40607     }
40608 
40609     FreeDer(&der);
40610 
40611     if (key != NULL && pkey != NULL)
40612         *key = pkey;
40613 
40614     WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", 0);
40615 
40616     return pkey;
40617 }
40618 
wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO * bio,WOLFSSL_EVP_PKEY ** key,wc_pem_password_cb * cb,void * pass)40619 WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
40620                                               WOLFSSL_EVP_PKEY **key,
40621                                               wc_pem_password_cb *cb,
40622                                               void *pass)
40623 {
40624     WOLFSSL_EVP_PKEY* pkey = NULL;
40625     DerBuffer*        der = NULL;
40626     int               keyFormat = 0;
40627 
40628     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY");
40629 
40630     if (bio == NULL)
40631         return pkey;
40632 
40633     if (pem_read_bio_key(bio, cb, pass, PUBLICKEY_TYPE, &keyFormat, &der) >= 0) {
40634         const unsigned char* ptr = der->buffer;
40635 
40636         /* handle case where reuse is attempted */
40637         if (key != NULL && *key != NULL)
40638             pkey = *key;
40639 
40640         wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length);
40641         if (pkey == NULL) {
40642             WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
40643         }
40644     }
40645 
40646     FreeDer(&der);
40647 
40648     if (key != NULL && pkey != NULL)
40649         *key = pkey;
40650 
40651     WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PUBKEY", 0);
40652 
40653     return pkey;
40654 }
40655 
40656 
40657 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && !defined(NO_RSA)
40658 /* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects
40659  * the results to be an RSA key.
40660  *
40661  * bio  structure to read RSA private key from
40662  * rsa  if not null is then set to the result
40663  * cb   password callback for reading PEM
40664  * pass password string
40665  *
40666  * returns a pointer to a new WOLFSSL_RSA structure on success and NULL on fail
40667  */
wolfSSL_PEM_read_bio_RSAPrivateKey(WOLFSSL_BIO * bio,WOLFSSL_RSA ** rsa,wc_pem_password_cb * cb,void * pass)40668 WOLFSSL_RSA* wolfSSL_PEM_read_bio_RSAPrivateKey(WOLFSSL_BIO* bio,
40669         WOLFSSL_RSA** rsa, wc_pem_password_cb* cb, void* pass)
40670 {
40671     WOLFSSL_EVP_PKEY* pkey;
40672     WOLFSSL_RSA* local;
40673 
40674     WOLFSSL_ENTER("PEM_read_bio_RSAPrivateKey");
40675 
40676     pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
40677     if (pkey == NULL) {
40678         return NULL;
40679     }
40680 
40681     /* Since the WOLFSSL_RSA structure is being taken from WOLFSSL_EVP_PEKY the
40682      * flag indicating that the WOLFSSL_RSA structure is owned should be FALSE
40683      * to avoid having it free'd */
40684     pkey->ownRsa = 0;
40685     local = pkey->rsa;
40686     if (rsa != NULL) {
40687         *rsa = local;
40688     }
40689 
40690     wolfSSL_EVP_PKEY_free(pkey);
40691     return local;
40692 }
40693 #endif /* OPENSSL_EXTRA || OPENSSL_ALL || !NO_RSA */
40694 
40695 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && (!defined(NO_CERTS) && \
40696        !defined(NO_FILESYSTEM) && !defined(NO_DSA) && defined(WOLFSSL_KEY_GEN))
40697 /* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects
40698  * the results to be an DSA key.
40699  *
40700  * bio  structure to read DSA private key from
40701  * dsa  if not null is then set to the result
40702  * cb   password callback for reading PEM
40703  * pass password string
40704  *
40705  * returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
40706  */
wolfSSL_PEM_read_bio_DSAPrivateKey(WOLFSSL_BIO * bio,WOLFSSL_DSA ** dsa,wc_pem_password_cb * cb,void * pass)40707 WOLFSSL_DSA* wolfSSL_PEM_read_bio_DSAPrivateKey(WOLFSSL_BIO* bio,
40708                                                 WOLFSSL_DSA** dsa,
40709                                                 wc_pem_password_cb* cb,
40710                                                 void* pass)
40711 {
40712     WOLFSSL_EVP_PKEY* pkey = NULL;
40713     WOLFSSL_DSA* local;
40714     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAPrivateKey");
40715 
40716 
40717     pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
40718     if (pkey == NULL) {
40719         WOLFSSL_MSG("Error in PEM_read_bio_PrivateKey");
40720          return NULL;
40721      }
40722      /* Since the WOLFSSL_DSA structure is being taken from WOLFSSL_EVP_PKEY the
40723      * flag indicating that the WOLFSSL_DSA structure is owned should be FALSE
40724      * to avoid having it free'd */
40725     pkey->ownDsa = 0;
40726     local = pkey->dsa;
40727     if (dsa != NULL) {
40728         *dsa = local;
40729     }
40730      wolfSSL_EVP_PKEY_free(pkey);
40731     return local;
40732 }
40733 
40734 /* Reads an DSA public key from a WOLFSSL_BIO into a WOLFSSL_DSA.
40735  * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
40736  */
wolfSSL_PEM_read_bio_DSA_PUBKEY(WOLFSSL_BIO * bio,WOLFSSL_DSA ** dsa,wc_pem_password_cb * cb,void * pass)40737 WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_DSA** dsa,
40738                                              wc_pem_password_cb* cb, void* pass)
40739 {
40740     WOLFSSL_EVP_PKEY* pkey;
40741     WOLFSSL_DSA* local;
40742     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSA_PUBKEY");
40743 
40744     pkey = wolfSSL_PEM_read_bio_PUBKEY(bio, NULL, cb, pass);
40745     if (pkey == NULL) {
40746         WOLFSSL_MSG("wolfSSL_PEM_read_bio_PUBKEY failed");
40747         return NULL;
40748     }
40749 
40750     /* Since the WOLFSSL_DSA structure is being taken from WOLFSSL_EVP_PKEY the
40751      * flag indicating that the WOLFSSL_DSA structure is owned should be FALSE
40752      * to avoid having it free'd */
40753     pkey->ownDsa = 0;
40754     local = pkey->dsa;
40755     if (dsa != NULL) {
40756         *dsa = local;
40757     }
40758 
40759     wolfSSL_EVP_PKEY_free(pkey);
40760     return local;
40761 }
40762 #endif /* (OPENSSL_EXTRA || OPENSSL_ALL) && (!NO_CERTS &&
40763           !NO_FILESYSTEM && !NO_DSA && WOLFSSL_KEY_GEN) */
40764 
40765 #ifdef HAVE_ECC
40766 /* returns a new WOLFSSL_EC_GROUP structure on success and NULL on fail */
wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO * bio,WOLFSSL_EC_GROUP ** group,wc_pem_password_cb * cb,void * pass)40767 WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio,
40768         WOLFSSL_EC_GROUP** group, wc_pem_password_cb* cb, void* pass)
40769 {
40770     WOLFSSL_EVP_PKEY* pkey;
40771     WOLFSSL_EC_GROUP* ret = NULL;
40772 
40773     /* check on if bio is null is done in wolfSSL_PEM_read_bio_PrivateKey */
40774     pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
40775     if (pkey != NULL) {
40776         if (pkey->type != EVP_PKEY_EC) {
40777             WOLFSSL_MSG("Unexpected key type");
40778         }
40779         else {
40780             ret = (WOLFSSL_EC_GROUP*)wolfSSL_EC_KEY_get0_group(pkey->ecc);
40781 
40782             /* set ecc group to null so it is not free'd when pkey is free'd */
40783             pkey->ecc->group = NULL;
40784         }
40785     }
40786 
40787     (void)group;
40788     wolfSSL_EVP_PKEY_free(pkey);
40789     return ret;
40790 }
40791 #endif /* HAVE_ECC */
40792 
40793 #endif /* !NO_BIO */
40794 
40795 #if !defined(NO_FILESYSTEM)
wolfSSL_PEM_read_PUBKEY(XFILE fp,EVP_PKEY ** x,wc_pem_password_cb * cb,void * u)40796 WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, EVP_PKEY **x,
40797                                           wc_pem_password_cb *cb, void *u)
40798 {
40799     (void)fp;
40800     (void)x;
40801     (void)cb;
40802     (void)u;
40803 
40804     WOLFSSL_MSG("wolfSSL_PEM_read_PUBKEY not implemented");
40805 
40806     return NULL;
40807 }
40808 #endif /* NO_FILESYSTEM */
40809 
40810 #ifndef NO_RSA
40811 
40812 #if defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
40813     !defined(NO_STDIO_FILESYSTEM)
wolfSSL_RSA_print_fp(XFILE fp,WOLFSSL_RSA * rsa,int indent)40814 int wolfSSL_RSA_print_fp(XFILE fp, WOLFSSL_RSA* rsa, int indent)
40815 {
40816     int ret = WOLFSSL_SUCCESS;
40817     int keySize;
40818 
40819     WOLFSSL_ENTER("wolfSSL_RSA_print_fp");
40820 
40821     if (fp == XBADFILE || rsa == NULL) {
40822         ret = WOLFSSL_FAILURE;
40823     }
40824 
40825     if (ret == WOLFSSL_SUCCESS && rsa->n != NULL) {
40826         keySize = wolfSSL_BN_num_bits(rsa->n);
40827         if (keySize == WOLFSSL_FAILURE) {
40828             ret = WOLFSSL_FAILURE;
40829         }
40830         else {
40831             XFPRINTF(fp, "%*s", indent, "");
40832             XFPRINTF(fp, "RSA Private-Key: (%d bit, 2 primes)\n", keySize);
40833         }
40834     }
40835     if (ret == WOLFSSL_SUCCESS && rsa->n != NULL) {
40836         ret = PrintBNFieldFp(fp, indent, "modulus", rsa->n);
40837     }
40838     if (ret == WOLFSSL_SUCCESS && rsa->d != NULL) {
40839         ret = PrintBNFieldFp(fp, indent, "privateExponent", rsa->d);
40840     }
40841     if (ret == WOLFSSL_SUCCESS && rsa->p != NULL) {
40842         ret = PrintBNFieldFp(fp, indent, "prime1", rsa->p);
40843     }
40844     if (ret == WOLFSSL_SUCCESS && rsa->q != NULL) {
40845         ret = PrintBNFieldFp(fp, indent, "prime2", rsa->q);
40846     }
40847     if (ret == WOLFSSL_SUCCESS && rsa->dmp1 != NULL) {
40848         ret = PrintBNFieldFp(fp, indent, "exponent1", rsa->dmp1);
40849     }
40850     if (ret == WOLFSSL_SUCCESS && rsa->dmq1 != NULL) {
40851         ret = PrintBNFieldFp(fp, indent, "exponent2", rsa->dmq1);
40852     }
40853     if (ret == WOLFSSL_SUCCESS && rsa->iqmp != NULL) {
40854         ret = PrintBNFieldFp(fp, indent, "coefficient", rsa->iqmp);
40855     }
40856 
40857     WOLFSSL_LEAVE("wolfSSL_RSA_print_fp", ret);
40858 
40859     return ret;
40860 }
40861 #endif /* XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
40862 #if defined(XSNPRINTF) && !defined(NO_BIO) && !defined(HAVE_FAST_RSA)
40863 /* snprintf() must be available */
40864 
40865 /******************************************************************************
40866 * wolfSSL_RSA_print - writes the human readable form of RSA to bio
40867 *
40868 * RETURNS:
40869 * returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
40870 */
wolfSSL_RSA_print(WOLFSSL_BIO * bio,WOLFSSL_RSA * rsa,int offset)40871 int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset)
40872 {
40873     char tmp[100] = {0};
40874     word32 idx = 0;
40875     int  sz = 0;
40876     byte lbit = 0;
40877     int  rawLen = 0;
40878     byte* rawKey = NULL;
40879     RsaKey* iRsa = NULL;
40880     int i = 0;
40881     mp_int *rsaElem = NULL;
40882     const char *rsaStr[] = {
40883                           "Modulus:",
40884                           "PublicExponent:",
40885                           "PrivateExponent:",
40886                           "Prime1:",
40887                           "Prime2:",
40888                           "Exponent1:",
40889                           "Exponent2:",
40890                           "Coefficient:"
40891                         };
40892 
40893     WOLFSSL_ENTER("wolfSSL_RSA_print");
40894     (void)offset;
40895 
40896     if (bio == NULL || rsa == NULL) {
40897         return WOLFSSL_FATAL_ERROR;
40898     }
40899 
40900     if ((sz = wolfSSL_RSA_size(rsa)) < 0) {
40901         WOLFSSL_MSG("Error getting RSA key size");
40902         return WOLFSSL_FAILURE;
40903     }
40904     iRsa = (RsaKey*)rsa->internal;
40905 
40906     XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s: (%d bit)",
40907             "RSA Private-Key", 8 * sz);
40908     tmp[sizeof(tmp) - 1] = '\0';
40909     if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
40910         return WOLFSSL_FAILURE;
40911     }
40912 
40913     for (i=0; i<RSA_INTS; i++) {
40914         switch(i) {
40915             case 0:
40916                 /* Print out modulus */
40917                 rsaElem = &iRsa->n;
40918                 break;
40919             case 1:
40920                 rsaElem = &iRsa->e;
40921                 break;
40922             case 2:
40923                 rsaElem = &iRsa->d;
40924                 break;
40925             case 3:
40926                 rsaElem = &iRsa->p;
40927                 break;
40928             case 4:
40929                 rsaElem = &iRsa->q;
40930                 break;
40931             case 5:
40932                 rsaElem = &iRsa->dP;
40933                 break;
40934             case 6:
40935                 rsaElem = &iRsa->dQ;
40936                 break;
40937             case 7:
40938                 rsaElem = &iRsa->u;
40939                 break;
40940             default:
40941                 WOLFSSL_MSG("Bad index value");
40942         }
40943 
40944         if (i == 1) {
40945             /* Print out exponent values */
40946             rawLen = mp_unsigned_bin_size(rsaElem);
40947             if (rawLen < 0) {
40948                 WOLFSSL_MSG("Error getting exponent size");
40949                 return WOLFSSL_FAILURE;
40950             }
40951 
40952             if ((word32)rawLen < sizeof(word32)) {
40953                 rawLen = sizeof(word32);
40954             }
40955             rawKey = (byte*)XMALLOC(rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40956             if (rawKey == NULL) {
40957                 WOLFSSL_MSG("Memory error");
40958                 return WOLFSSL_FAILURE;
40959             }
40960             XMEMSET(rawKey, 0, rawLen);
40961             if (mp_to_unsigned_bin(rsaElem, rawKey) < 0) {
40962                 XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40963                 return WOLFSSL_FAILURE;
40964             }
40965             if ((word32)rawLen <= sizeof(word32)) {
40966                 idx = *(word32*)rawKey;
40967                 #ifdef BIG_ENDIAN_ORDER
40968                     idx = ByteReverseWord32(idx);
40969                 #endif
40970             }
40971             XSNPRINTF(tmp, sizeof(tmp) - 1, "\nExponent: %d (0x%x)", idx, idx);
40972             if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
40973                 XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40974                 return WOLFSSL_FAILURE;
40975             }
40976             XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40977         }
40978         else {
40979             XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s\n    ", rsaStr[i]);
40980             tmp[sizeof(tmp) - 1] = '\0';
40981             if (mp_leading_bit(rsaElem)) {
40982                 lbit = 1;
40983                 XSTRNCAT(tmp, "00", 3);
40984             }
40985 
40986             rawLen = mp_unsigned_bin_size(rsaElem);
40987             rawKey = (byte*)XMALLOC(rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40988             if (rawKey == NULL) {
40989                 WOLFSSL_MSG("Memory error");
40990                 return WOLFSSL_FAILURE;
40991             }
40992             if (mp_to_unsigned_bin(rsaElem, rawKey) < 0) {
40993                 XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40994                 return WOLFSSL_FAILURE;
40995             }
40996             for (idx = 0; idx < (word32)rawLen; idx++) {
40997                 char val[5];
40998                 int  valSz = 5;
40999 
41000                 if ((idx == 0) && !lbit) {
41001                     XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]);
41002                 }
41003                 else if ((idx != 0) && (((idx + lbit) % 15) == 0)) {
41004                     tmp[sizeof(tmp) - 1] = '\0';
41005                     if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
41006                         XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
41007                         return WOLFSSL_FAILURE;
41008                     }
41009                     XSNPRINTF(tmp, sizeof(tmp) - 1,
41010                             ":\n    ");
41011                     XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]);
41012                 }
41013                 else {
41014                     XSNPRINTF(val, valSz - 1, ":%02x", rawKey[idx]);
41015                 }
41016                 XSTRNCAT(tmp, val, valSz);
41017             }
41018             XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
41019 
41020             /* print out remaining values */
41021             if ((idx > 0) && (((idx - 1 + lbit) % 15) != 0)) {
41022                 tmp[sizeof(tmp) - 1] = '\0';
41023                 if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
41024                     return WOLFSSL_FAILURE;
41025                 }
41026             }
41027             lbit = 0;
41028         }
41029 
41030     }
41031     /* done with print out */
41032     if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
41033         return WOLFSSL_FAILURE;
41034     }
41035 
41036     return WOLFSSL_SUCCESS;
41037 }
41038 #endif /* XSNPRINTF && !NO_BIO && !HAVE_FAST_RSA */
41039 
41040 #if !defined(NO_FILESYSTEM)
41041 #ifndef NO_WOLFSSL_STUB
wolfSSL_PEM_read_RSAPublicKey(XFILE fp,WOLFSSL_RSA ** x,wc_pem_password_cb * cb,void * u)41042 WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(XFILE fp, WOLFSSL_RSA **x,
41043                                            wc_pem_password_cb *cb, void *u)
41044 {
41045     (void)fp;
41046     (void)x;
41047     (void)cb;
41048     (void)u;
41049     WOLFSSL_STUB("PEM_read_RSAPublicKey");
41050     WOLFSSL_MSG("wolfSSL_PEM_read_RSAPublicKey not implemented");
41051 
41052     return NULL;
41053 }
41054 #endif
41055 /* return code compliant with OpenSSL :
41056  *   1 if success, 0 if error
41057  */
41058 #ifndef NO_WOLFSSL_STUB
wolfSSL_PEM_write_RSAPublicKey(XFILE fp,WOLFSSL_RSA * x)41059 int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA *x)
41060 {
41061     (void)fp;
41062     (void)x;
41063     WOLFSSL_STUB("PEM_write_RSAPublicKey");
41064     WOLFSSL_MSG("wolfSSL_PEM_write_RSAPublicKey not implemented");
41065 
41066     return WOLFSSL_FAILURE;
41067 }
41068 #endif
41069 
41070 /* return code compliant with OpenSSL :
41071  *   1 if success, 0 if error
41072  */
41073 #ifndef NO_WOLFSSL_STUB
wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp,WOLFSSL_RSA * x)41074 int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *x)
41075 {
41076     (void)fp;
41077     (void)x;
41078     WOLFSSL_STUB("PEM_write_RSA_PUBKEY");
41079     WOLFSSL_MSG("wolfSSL_PEM_write_RSA_PUBKEY not implemented");
41080 
41081     return WOLFSSL_FAILURE;
41082 }
41083 #endif
41084 
41085 #endif /* NO_FILESYSTEM */
41086 
wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA ** r,const unsigned char ** pp,long len)41087 WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **r, const unsigned char **pp,
41088     long len)
41089 {
41090     WOLFSSL_RSA *rsa = NULL;
41091 
41092     WOLFSSL_ENTER("d2i_RSAPublicKey");
41093 
41094     if (pp == NULL) {
41095         WOLFSSL_MSG("Bad argument");
41096         return NULL;
41097     }
41098     if ((rsa = wolfSSL_RSA_new()) == NULL) {
41099         WOLFSSL_MSG("RSA_new failed");
41100         return NULL;
41101     }
41102 
41103     if (wolfSSL_RSA_LoadDer_ex(rsa, *pp, (int)len, WOLFSSL_RSA_LOAD_PUBLIC)
41104                                                          != WOLFSSL_SUCCESS) {
41105         WOLFSSL_MSG("RSA_LoadDer failed");
41106         wolfSSL_RSA_free(rsa);
41107         rsa = NULL;
41108     }
41109     if (r != NULL)
41110         *r = rsa;
41111 
41112     return rsa;
41113 }
41114 
41115 /* Converts an RSA private key from DER format to an RSA structure.
41116 Returns pointer to the RSA structure on success and NULL if error. */
wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA ** r,const unsigned char ** derBuf,long derSz)41117 WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r,
41118                                        const unsigned char **derBuf, long derSz)
41119 {
41120     WOLFSSL_RSA *rsa = NULL;
41121 
41122     WOLFSSL_ENTER("wolfSSL_d2i_RSAPrivateKey");
41123 
41124     /* check for bad functions arguments */
41125     if (derBuf == NULL) {
41126         WOLFSSL_MSG("Bad argument");
41127         return NULL;
41128     }
41129     if ((rsa = wolfSSL_RSA_new()) == NULL) {
41130         WOLFSSL_MSG("RSA_new failed");
41131         return NULL;
41132     }
41133 
41134     if (wolfSSL_RSA_LoadDer_ex(rsa, *derBuf, (int)derSz,
41135                                  WOLFSSL_RSA_LOAD_PRIVATE) != WOLFSSL_SUCCESS) {
41136         WOLFSSL_MSG("RSA_LoadDer failed");
41137         wolfSSL_RSA_free(rsa);
41138         rsa = NULL;
41139     }
41140     if (r != NULL)
41141         *r = rsa;
41142 
41143     return rsa;
41144 }
41145 
41146 #if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
41147     !defined(HAVE_USER_RSA)
41148 /* Converts an internal RSA structure to DER format.
41149  * If "pp" is null then buffer size only is returned.
41150  * If "*pp" is null then a created buffer is set in *pp and the caller is
41151  *  responsible for free'ing it.
41152  * Returns size of DER on success and WOLFSSL_FAILURE if error
41153  */
wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA * rsa,unsigned char ** pp)41154 int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp)
41155 {
41156     int ret;
41157 
41158     WOLFSSL_ENTER("wolfSSL_i2d_RSAPrivateKey");
41159 
41160     /* check for bad functions arguments */
41161     if (rsa == NULL) {
41162         WOLFSSL_MSG("Bad Function Arguments");
41163         return BAD_FUNC_ARG;
41164     }
41165 
41166     /* No heap hint as this gets returned to the user */
41167     if ((ret = wolfSSL_RSA_To_Der(rsa, pp, 0, NULL)) < 0) {
41168         WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
41169         return WOLFSSL_FAILURE;
41170     }
41171 
41172     return ret; /* returns size of DER if successful */
41173 }
41174 
41175 
wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA * rsa,unsigned char ** pp)41176 int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, unsigned char **pp)
41177 {
41178     int ret;
41179 
41180     /* check for bad functions arguments */
41181     if (rsa == NULL) {
41182         WOLFSSL_MSG("Bad Function Arguments");
41183         return BAD_FUNC_ARG;
41184     }
41185 
41186     /* No heap hint as this gets returned to the user */
41187     if ((ret = wolfSSL_RSA_To_Der(rsa, (byte**)pp, 1, NULL)) < 0) {
41188         WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
41189         return WOLFSSL_FAILURE;
41190     }
41191 
41192     return ret;
41193 }
41194 #endif /* !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) &&
41195         * !defined(HAVE_USER_RSA) */
41196 
41197 #endif /* !NO_RSA */
41198 #endif /* OPENSSL_EXTRA */
41199 
41200 #if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
41201 /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
wolfSSL_RSA_LoadDer(WOLFSSL_RSA * rsa,const unsigned char * derBuf,int derSz)41202 int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* derBuf, int derSz)
41203 {
41204   return wolfSSL_RSA_LoadDer_ex(rsa, derBuf, derSz, WOLFSSL_RSA_LOAD_PRIVATE);
41205 }
41206 
41207 
wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA * rsa,const unsigned char * derBuf,int derSz,int opt)41208 int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf,
41209                                                      int derSz, int opt)
41210 {
41211     int ret;
41212     word32 idx = 0;
41213     word32 algId;
41214 
41215     WOLFSSL_ENTER("wolfSSL_RSA_LoadDer");
41216 
41217     if (rsa == NULL || rsa->internal == NULL || derBuf == NULL || derSz <= 0) {
41218         WOLFSSL_MSG("Bad function arguments");
41219         return WOLFSSL_FATAL_ERROR;
41220     }
41221 
41222     rsa->pkcs8HeaderSz = 0;
41223     /* Check if input buffer has PKCS8 header. In the case that it does not
41224      * have a PKCS8 header then do not error out. */
41225     if ((ret = ToTraditionalInline_ex((const byte*)derBuf, &idx, (word32)derSz,
41226                                                                  &algId)) > 0) {
41227         WOLFSSL_MSG("Found PKCS8 header");
41228         rsa->pkcs8HeaderSz = (word16)idx;
41229     }
41230     else {
41231         if (ret != ASN_PARSE_E) {
41232             WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header");
41233             return WOLFSSL_FATAL_ERROR;
41234         }
41235     }
41236 
41237     if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
41238         ret = wc_RsaPrivateKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, derSz);
41239     }
41240     else {
41241         ret = wc_RsaPublicKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, derSz);
41242     }
41243 
41244     if (ret < 0) {
41245         if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
41246              WOLFSSL_MSG("RsaPrivateKeyDecode failed");
41247         }
41248         else {
41249              WOLFSSL_MSG("RsaPublicKeyDecode failed");
41250         }
41251         return SSL_FATAL_ERROR;
41252     }
41253 
41254     if (SetRsaExternal(rsa) != WOLFSSL_SUCCESS) {
41255         WOLFSSL_MSG("SetRsaExternal failed");
41256         return WOLFSSL_FATAL_ERROR;
41257     }
41258 
41259     rsa->inSet = 1;
41260 
41261     return WOLFSSL_SUCCESS;
41262 }
41263 
41264 #if defined(WC_RSA_PSS) && (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || \
41265         defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX))
41266 #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
41267 /*
41268  *                                +-----------+
41269  *                                |     M     |
41270  *                                +-----------+
41271  *                                      |
41272  *                                      V
41273  *                                    Hash
41274  *                                      |
41275  *                                      V
41276  *                        +--------+----------+----------+
41277  *                   M' = |Padding1|  mHash   |   salt   |
41278  *                        +--------+----------+----------+
41279  *                                       |
41280  *             +--------+----------+     V
41281  *       DB =  |Padding2|maskedseed|   Hash
41282  *             +--------+----------+     |
41283  *                       |               |
41284  *                       V               |    +--+
41285  *                      xor <--- MGF <---|    |bc|
41286  *                       |               |    +--+
41287  *                       |               |      |
41288  *                       V               V      V
41289  *             +-------------------+----------+--+
41290  *       EM =  |    maskedDB       |maskedseed|bc|
41291  *             +-------------------+----------+--+
41292  * Diagram taken from https://tools.ietf.org/html/rfc3447#section-9.1
41293  */
wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA * rsa,unsigned char * EM,const unsigned char * mHash,const WOLFSSL_EVP_MD * hashAlg,int saltLen)41294 int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *EM,
41295                                       const unsigned char *mHash,
41296                                       const WOLFSSL_EVP_MD *hashAlg, int saltLen)
41297 {
41298     int hashLen, emLen, mgf;
41299     int ret = WOLFSSL_FAILURE;
41300     int initTmpRng = 0;
41301     WC_RNG *rng = NULL;
41302 #ifdef WOLFSSL_SMALL_STACK
41303     WC_RNG* tmpRNG = NULL;
41304 #else
41305     WC_RNG  _tmpRNG[1];
41306     WC_RNG* tmpRNG = _tmpRNG;
41307 #endif
41308     enum wc_HashType hashType;
41309 
41310     WOLFSSL_ENTER("wolfSSL_RSA_padding_add_PKCS1_PSS");
41311 
41312     if (!rsa || !EM || !mHash || !hashAlg) {
41313         return WOLFSSL_FAILURE;
41314     }
41315 
41316     if (!(rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRNG, &initTmpRng))) {
41317         WOLFSSL_MSG("WOLFSSL_RSA_GetRNG error");
41318         goto cleanup;
41319     }
41320 
41321     if (!rsa->exSet && SetRsaExternal(rsa) != WOLFSSL_SUCCESS) {
41322         WOLFSSL_MSG("SetRsaExternal error");
41323         goto cleanup;
41324     }
41325 
41326     hashType = wolfSSL_EVP_md2macType(hashAlg);
41327     if (hashType < WC_HASH_TYPE_NONE || hashType > WC_HASH_TYPE_MAX) {
41328         WOLFSSL_MSG("wolfSSL_EVP_md2macType error");
41329         goto cleanup;
41330     }
41331 
41332    if ((mgf = wc_hash2mgf(hashType)) == WC_MGF1NONE) {
41333        WOLFSSL_MSG("wc_hash2mgf error");
41334        goto cleanup;
41335    }
41336 
41337     if ((hashLen = wolfSSL_EVP_MD_size(hashAlg)) < 0) {
41338         WOLFSSL_MSG("wolfSSL_EVP_MD_size error");
41339         goto cleanup;
41340     }
41341 
41342     if ((emLen = wolfSSL_RSA_size(rsa)) <= 0) {
41343         WOLFSSL_MSG("wolfSSL_RSA_size error");
41344         goto cleanup;
41345     }
41346 
41347     switch (saltLen) {
41348     /* Negative saltLen values are treated differently */
41349         case RSA_PSS_SALTLEN_DIGEST:
41350             saltLen = hashLen;
41351             break;
41352         case RSA_PSS_SALTLEN_MAX_SIGN:
41353         case RSA_PSS_SALTLEN_MAX:
41354             saltLen = emLen - hashLen - 2;
41355             break;
41356         default:
41357             if (saltLen < 0) {
41358                 /* Not any currently implemented negative value */
41359                 WOLFSSL_MSG("invalid saltLen");
41360                 goto cleanup;
41361             }
41362     }
41363 
41364     if (wc_RsaPad_ex(mHash, hashLen, EM, emLen,
41365                      RSA_BLOCK_TYPE_1, rng, WC_RSA_PSS_PAD,
41366                      hashType, mgf, NULL, 0, saltLen,
41367                      wolfSSL_BN_num_bits(rsa->n), NULL) != MP_OKAY) {
41368         WOLFSSL_MSG("wc_RsaPad_ex error");
41369         goto cleanup;
41370     }
41371 
41372     ret = WOLFSSL_SUCCESS;
41373 cleanup:
41374     if (initTmpRng)
41375         wc_FreeRng(tmpRNG);
41376 #ifdef WOLFSSL_SMALL_STACK
41377     if (tmpRNG)
41378         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
41379 #endif
41380 
41381     return ret;
41382 }
41383 
41384 /*
41385  * Refer to wolfSSL_RSA_padding_add_PKCS1_PSS
41386  * for an explanation of the parameters.
41387  */
wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA * rsa,const unsigned char * mHash,const WOLFSSL_EVP_MD * hashAlg,const unsigned char * EM,int saltLen)41388 int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
41389                                  const WOLFSSL_EVP_MD *hashAlg,
41390                                  const unsigned char *EM, int saltLen)
41391 {
41392     int hashLen, mgf, emLen, mPrimeLen;
41393     enum wc_HashType hashType;
41394     byte *mPrime = NULL;
41395     byte *buf = NULL;
41396 
41397     WOLFSSL_ENTER("wolfSSL_RSA_verify_PKCS1_PSS");
41398 
41399     if (!rsa || !mHash || !hashAlg || !EM) {
41400         return WOLFSSL_FAILURE;
41401     }
41402 
41403     if ((hashLen = wolfSSL_EVP_MD_size(hashAlg)) < 0) {
41404         return WOLFSSL_FAILURE;
41405     }
41406 
41407     if ((emLen = wolfSSL_RSA_size(rsa)) <= 0) {
41408         WOLFSSL_MSG("wolfSSL_RSA_size error");
41409         return WOLFSSL_FAILURE;
41410     }
41411 
41412     switch (saltLen) {
41413     /* Negative saltLen values are treated differently */
41414         case RSA_PSS_SALTLEN_DIGEST:
41415             saltLen = hashLen;
41416             break;
41417         case RSA_PSS_SALTLEN_MAX_SIGN:
41418         case RSA_PSS_SALTLEN_MAX:
41419             saltLen = emLen - hashLen - 2;
41420             break;
41421         default:
41422             if (saltLen < 0) {
41423                 /* Not any currently implemented negative value */
41424                 WOLFSSL_MSG("invalid saltLen");
41425                 return WOLFSSL_FAILURE;
41426             }
41427     }
41428 
41429     if (!rsa->exSet && SetRsaExternal(rsa) != WOLFSSL_SUCCESS) {
41430         return WOLFSSL_FAILURE;
41431     }
41432 
41433     hashType = wolfSSL_EVP_md2macType(hashAlg);
41434     if (hashType < WC_HASH_TYPE_NONE || hashType > WC_HASH_TYPE_MAX) {
41435         WOLFSSL_MSG("wolfSSL_EVP_md2macType error");
41436         return WOLFSSL_FAILURE;
41437     }
41438 
41439     if ((mgf = wc_hash2mgf(hashType)) == WC_MGF1NONE) {
41440         WOLFSSL_MSG("wc_hash2mgf error");
41441         return WOLFSSL_FAILURE;
41442     }
41443 
41444     if ((hashLen = wolfSSL_EVP_MD_size(hashAlg)) < 0) {
41445         WOLFSSL_MSG("wolfSSL_EVP_MD_size error");
41446         return WOLFSSL_FAILURE;
41447     }
41448 
41449     if (!(buf = (byte*)XMALLOC(emLen, NULL, DYNAMIC_TYPE_TMP_BUFFER))) {
41450         WOLFSSL_MSG("malloc error");
41451         return WOLFSSL_FAILURE;
41452     }
41453     XMEMCPY(buf, EM, emLen);
41454 
41455     /* Remove and verify the PSS padding */
41456     if ((mPrimeLen = wc_RsaUnPad_ex(buf, emLen, &mPrime,
41457                                     RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD, hashType,
41458                                     mgf, NULL, 0, saltLen,
41459                                     wolfSSL_BN_num_bits(rsa->n), NULL)) < 0) {
41460         WOLFSSL_MSG("wc_RsaPad_ex error");
41461         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
41462         return WOLFSSL_FAILURE;
41463     }
41464 
41465     /* Verify the hash is correct */
41466     if (wc_RsaPSS_CheckPadding_ex(mHash, hashLen, mPrime, mPrimeLen, hashType,
41467                                   saltLen, wolfSSL_BN_num_bits(rsa->n))
41468                                   != MP_OKAY) {
41469         WOLFSSL_MSG("wc_RsaPSS_CheckPadding_ex error");
41470         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
41471         return WOLFSSL_FAILURE;
41472     }
41473     XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
41474     return WOLFSSL_SUCCESS;
41475 }
41476 #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
41477 #endif /* WC_RSA_PSS && (OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY
41478         *                || WOLFSSL_NGINX)
41479         */
41480 
41481 #if defined(OPENSSL_EXTRA)
wolfSSL_RSA_meth_new(const char * name,int flags)41482 WOLFSSL_RSA_METHOD *wolfSSL_RSA_meth_new(const char *name, int flags)
41483 {
41484     int name_len;
41485     WOLFSSL_RSA_METHOD* meth;
41486 
41487     if (name == NULL) {
41488         return NULL;
41489     }
41490 
41491     meth = (WOLFSSL_RSA_METHOD*)XMALLOC(sizeof(WOLFSSL_RSA_METHOD), NULL,
41492         DYNAMIC_TYPE_OPENSSL);
41493     name_len = (int)XSTRLEN(name);
41494     if (!meth) {
41495         return NULL;
41496     }
41497     meth->flags = flags;
41498     meth->name = (char*)XMALLOC(name_len+1, NULL, DYNAMIC_TYPE_OPENSSL);
41499     if (!meth->name) {
41500         XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL);
41501         return NULL;
41502     }
41503     XMEMCPY(meth->name, name, name_len+1);
41504 
41505     return meth;
41506 }
41507 
wolfSSL_RSA_meth_free(WOLFSSL_RSA_METHOD * meth)41508 void wolfSSL_RSA_meth_free(WOLFSSL_RSA_METHOD *meth)
41509 {
41510     if (meth) {
41511         XFREE(meth->name, NULL, DYNAMIC_TYPE_OPENSSL);
41512         XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL);
41513     }
41514 }
41515 
41516 #ifndef NO_WOLFSSL_STUB
wolfSSL_RSA_meth_set(WOLFSSL_RSA_METHOD * rsa,void * p)41517 int wolfSSL_RSA_meth_set(WOLFSSL_RSA_METHOD *rsa, void* p)
41518 {
41519     (void)rsa;
41520     (void)p;
41521     WOLFSSL_STUB("RSA_METHOD is not implemented.");
41522     return 1;
41523 }
41524 #endif
41525 
wolfSSL_RSA_set_method(WOLFSSL_RSA * rsa,WOLFSSL_RSA_METHOD * meth)41526 int wolfSSL_RSA_set_method(WOLFSSL_RSA *rsa, WOLFSSL_RSA_METHOD *meth)
41527 {
41528     if (rsa)
41529         rsa->meth = meth;
41530     return 1;
41531 }
41532 
wolfSSL_RSA_get_method(const WOLFSSL_RSA * rsa)41533 const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa)
41534 {
41535     if (!rsa) {
41536         return NULL;
41537     }
41538     return rsa->meth;
41539 }
41540 
wolfSSL_RSA_get_default_method(void)41541 const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_default_method(void)
41542 {
41543     return wolfSSL_RSA_meth_new("wolfSSL RSA", 0);
41544 }
41545 
wolfSSL_RSA_flags(const WOLFSSL_RSA * r)41546 int wolfSSL_RSA_flags(const WOLFSSL_RSA *r)
41547 {
41548     if (r && r->meth) {
41549         return r->meth->flags;
41550     } else {
41551         return 0;
41552     }
41553 }
41554 
wolfSSL_RSA_set_flags(WOLFSSL_RSA * r,int flags)41555 void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags)
41556 {
41557     if (r && r->meth) {
41558         r->meth->flags |= flags;
41559     }
41560 }
41561 
wolfSSL_RSA_clear_flags(WOLFSSL_RSA * r,int flags)41562 void wolfSSL_RSA_clear_flags(WOLFSSL_RSA *r, int flags)
41563 {
41564     if (r && r->meth) {
41565         r->meth->flags &= ~flags;
41566     }
41567 }
41568 
wolfSSL_RSA_test_flags(const WOLFSSL_RSA * r,int flags)41569 int wolfSSL_RSA_test_flags(const WOLFSSL_RSA *r, int flags)
41570 {
41571     return r && r->meth ? r->meth->flags & flags : 0;
41572 }
41573 
41574 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA * rsa)41575 WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa)
41576 {
41577     int derSz = 0;
41578     byte *derBuf = NULL;
41579     WOLFSSL_RSA* local;
41580 
41581     WOLFSSL_ENTER("wolfSSL_RSAPublicKey_dup");
41582 
41583     if (!rsa) {
41584         return NULL;
41585     }
41586 
41587     local = wolfSSL_RSA_new();
41588     if (local == NULL) {
41589         WOLFSSL_MSG("Error creating a new WOLFSSL_RSA structure");
41590         return NULL;
41591     }
41592 
41593     if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1, rsa->heap)) < 0) {
41594         WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
41595         return NULL;
41596     }
41597 
41598     if (wolfSSL_RSA_LoadDer_ex(local,
41599                 derBuf, derSz,
41600                 WOLFSSL_RSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
41601         wolfSSL_RSA_free(local);
41602         local = NULL;
41603     }
41604     XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_ASN1);
41605     return local;
41606 }
41607 #endif
41608 
wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA * rsa,int idx)41609 void* wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA *rsa, int idx)
41610 {
41611     WOLFSSL_ENTER("wolfSSL_RSA_get_ex_data");
41612 #ifdef HAVE_EX_DATA
41613     if (rsa) {
41614         return wolfSSL_CRYPTO_get_ex_data(&rsa->ex_data, idx);
41615     }
41616 #else
41617     (void)rsa;
41618     (void)idx;
41619 #endif
41620     return NULL;
41621 }
41622 
wolfSSL_RSA_set_ex_data(WOLFSSL_RSA * rsa,int idx,void * data)41623 int wolfSSL_RSA_set_ex_data(WOLFSSL_RSA *rsa, int idx, void *data)
41624 {
41625     WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data");
41626     #ifdef HAVE_EX_DATA
41627     if (rsa) {
41628         return wolfSSL_CRYPTO_set_ex_data(&rsa->ex_data, idx, data);
41629     }
41630     #else
41631     (void)rsa;
41632     (void)idx;
41633     (void)data;
41634     #endif
41635     return WOLFSSL_FAILURE;
41636 }
41637 
41638 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
wolfSSL_RSA_set_ex_data_with_cleanup(WOLFSSL_RSA * rsa,int idx,void * data,wolfSSL_ex_data_cleanup_routine_t cleanup_routine)41639 int wolfSSL_RSA_set_ex_data_with_cleanup(
41640     WOLFSSL_RSA *rsa,
41641     int idx,
41642     void *data,
41643     wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
41644 {
41645     WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data_with_cleanup");
41646     if (rsa) {
41647         return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&rsa->ex_data, idx, data,
41648                                                        cleanup_routine);
41649     }
41650     return WOLFSSL_FAILURE;
41651 }
41652 #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
41653 
wolfSSL_RSA_set0_key(WOLFSSL_RSA * r,WOLFSSL_BIGNUM * n,WOLFSSL_BIGNUM * e,WOLFSSL_BIGNUM * d)41654 int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e,
41655                          WOLFSSL_BIGNUM *d)
41656 {
41657     /* If the fields n and e in r are NULL, the corresponding input
41658      * parameters MUST be non-NULL for n and e.  d may be
41659      * left NULL (in case only the public key is used).
41660      */
41661     if ((!r->n && !n) || (!r->e && !e))
41662         return 0;
41663 
41664     if (n) {
41665         wolfSSL_BN_free(r->n);
41666         r->n = n;
41667     }
41668     if (e) {
41669         wolfSSL_BN_free(r->e);
41670         r->e = e;
41671     }
41672     if (d) {
41673         wolfSSL_BN_clear_free(r->d);
41674         r->d = d;
41675     }
41676 
41677     return SetRsaInternal(r) == WOLFSSL_SUCCESS ?
41678             WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
41679 }
41680 #endif /* OPENSSL_EXTRA */
41681 #endif /* NO_RSA */
41682 
41683 #if !defined(NO_DSA) && \
41684     (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
41685 /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
wolfSSL_DSA_LoadDer(WOLFSSL_DSA * dsa,const unsigned char * derBuf,int derSz)41686 int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz)
41687 {
41688     word32 idx = 0;
41689     int    ret;
41690 
41691     WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
41692 
41693     if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
41694         WOLFSSL_MSG("Bad function arguments");
41695         return WOLFSSL_FATAL_ERROR;
41696     }
41697 
41698     ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal, derSz);
41699     if (ret < 0) {
41700         WOLFSSL_MSG("DsaPrivateKeyDecode failed");
41701         return WOLFSSL_FATAL_ERROR;
41702     }
41703 
41704     if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS) {
41705         WOLFSSL_MSG("SetDsaExternal failed");
41706         return WOLFSSL_FATAL_ERROR;
41707     }
41708 
41709     dsa->inSet = 1;
41710 
41711     return WOLFSSL_SUCCESS;
41712 }
41713 
41714 /* Loads DSA key from DER buffer. opt = DSA_LOAD_PRIVATE or DSA_LOAD_PUBLIC.
41715     returns 1 on success, or 0 on failure.  */
wolfSSL_DSA_LoadDer_ex(WOLFSSL_DSA * dsa,const unsigned char * derBuf,int derSz,int opt)41716 int wolfSSL_DSA_LoadDer_ex(WOLFSSL_DSA* dsa, const unsigned char* derBuf,
41717                                                             int derSz, int opt)
41718 {
41719     word32 idx = 0;
41720     int    ret;
41721 
41722     WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
41723 
41724     if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
41725         WOLFSSL_MSG("Bad function arguments");
41726         return WOLFSSL_FATAL_ERROR;
41727     }
41728 
41729     if (opt == WOLFSSL_DSA_LOAD_PRIVATE) {
41730         ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal, derSz);
41731     }
41732     else {
41733         ret = DsaPublicKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal, derSz);
41734     }
41735 
41736     if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PRIVATE) {
41737         WOLFSSL_MSG("DsaPrivateKeyDecode failed");
41738         return WOLFSSL_FATAL_ERROR;
41739     }
41740     else if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PUBLIC) {
41741         WOLFSSL_MSG("DsaPublicKeyDecode failed");
41742         return WOLFSSL_FATAL_ERROR;
41743     }
41744 
41745     if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS) {
41746         WOLFSSL_MSG("SetDsaExternal failed");
41747         return WOLFSSL_FATAL_ERROR;
41748     }
41749 
41750     dsa->inSet = 1;
41751 
41752     return WOLFSSL_SUCCESS;
41753 }
41754 #endif /* !NO_DSA && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
41755 
41756 #ifdef OPENSSL_EXTRA
41757 #ifdef HAVE_ECC
41758 /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY * key,const unsigned char * derBuf,int derSz)41759 int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
41760                            int derSz)
41761 {
41762     return wolfSSL_EC_KEY_LoadDer_ex(key, derBuf, derSz,
41763                                      WOLFSSL_EC_KEY_LOAD_PRIVATE);
41764 }
41765 
wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY * key,const unsigned char * derBuf,int derSz,int opt)41766 int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
41767                               int derSz, int opt)
41768 {
41769     int ret;
41770     word32 idx = 0;
41771     word32 algId;
41772 
41773     WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer");
41774 
41775     if (key == NULL || key->internal == NULL || derBuf == NULL || derSz <= 0) {
41776         WOLFSSL_MSG("Bad function arguments");
41777         return WOLFSSL_FATAL_ERROR;
41778     }
41779 
41780     key->pkcs8HeaderSz = 0;
41781 
41782     /* Check if input buffer has PKCS8 header. In the case that it does not
41783      * have a PKCS8 header then do not error out. */
41784     if ((ret = ToTraditionalInline_ex((const byte*)derBuf, &idx, (word32)derSz,
41785                                                                  &algId)) > 0) {
41786         WOLFSSL_MSG("Found PKCS8 header");
41787         key->pkcs8HeaderSz = (word16)idx;
41788     }
41789     else {
41790         if (ret != ASN_PARSE_E) {
41791             WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header");
41792             return WOLFSSL_FATAL_ERROR;
41793         }
41794     }
41795 
41796     if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
41797         ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
41798                                      derSz);
41799     }
41800     else {
41801         ret = wc_EccPublicKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
41802                                     derSz);
41803     }
41804     if (ret < 0) {
41805         if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
41806             WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
41807         }
41808         else {
41809             WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
41810         }
41811         return WOLFSSL_FATAL_ERROR;
41812     }
41813 
41814     if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) {
41815         WOLFSSL_MSG("SetECKeyExternal failed");
41816         return WOLFSSL_FATAL_ERROR;
41817     }
41818 
41819     key->inSet = 1;
41820 
41821     return WOLFSSL_SUCCESS;
41822 }
41823 #endif /* HAVE_ECC */
41824 
41825 #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH))
41826 /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */
41827 #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
wolfSSL_DH_LoadDer(WOLFSSL_DH * dh,const unsigned char * derBuf,int derSz)41828 int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz)
41829 {
41830     word32 idx = 0;
41831     int    ret;
41832 
41833     if (dh == NULL || dh->internal == NULL || derBuf == NULL || derSz <= 0) {
41834         WOLFSSL_MSG("Bad function arguments");
41835         return WOLFSSL_FATAL_ERROR;
41836     }
41837 
41838     ret = wc_DhKeyDecode(derBuf, &idx, (DhKey*)dh->internal, (word32)derSz);
41839     if (ret < 0) {
41840         WOLFSSL_MSG("wc_DhKeyDecode failed");
41841         return WOLFSSL_FATAL_ERROR;
41842     }
41843     dh->inSet = 1;
41844 
41845     if (SetDhExternal(dh) != WOLFSSL_SUCCESS) {
41846         WOLFSSL_MSG("SetDhExternal failed");
41847         return WOLFSSL_FATAL_ERROR;
41848     }
41849 
41850     return WOLFSSL_SUCCESS;
41851 }
41852 #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
41853 #endif /* ! NO_DH && WOLFSSL_QT || OPENSSL_ALL */
41854 
41855 #endif /* OPENSSL_EXTRA */
41856 
41857 
41858 #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
41859 
41860 /* increments ref count of WOLFSSL_RSA. Return 1 on success, 0 on error */
wolfSSL_RSA_up_ref(WOLFSSL_RSA * rsa)41861 int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa)
41862 {
41863     if (rsa) {
41864 #ifndef SINGLE_THREADED
41865         if (wc_LockMutex(&rsa->refMutex) != 0) {
41866             WOLFSSL_MSG("Failed to lock x509 mutex");
41867         }
41868 #endif
41869         rsa->refCount++;
41870 #ifndef SINGLE_THREADED
41871         wc_UnLockMutex(&rsa->refMutex);
41872 #endif
41873 
41874         return WOLFSSL_SUCCESS;
41875     }
41876 
41877     return WOLFSSL_FAILURE;
41878 }
41879 
41880 /* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */
wolfSSL_X509_up_ref(WOLFSSL_X509 * x509)41881 int wolfSSL_X509_up_ref(WOLFSSL_X509* x509)
41882 {
41883     if (x509) {
41884 #ifndef SINGLE_THREADED
41885         if (wc_LockMutex(&x509->refMutex) != 0) {
41886             WOLFSSL_MSG("Failed to lock x509 mutex");
41887         }
41888 #endif
41889         x509->refCount++;
41890 #ifndef SINGLE_THREADED
41891         wc_UnLockMutex(&x509->refMutex);
41892 #endif
41893 
41894         return WOLFSSL_SUCCESS;
41895     }
41896 
41897     return WOLFSSL_FAILURE;
41898 }
41899 #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
41900 
41901 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLF_STACK_OF(WOLFSSL_X509)41902 WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
41903         WOLF_STACK_OF(WOLFSSL_X509)* chain)
41904 {
41905     /* wolfSSL_sk_dup takes care of doing a deep copy */
41906     return wolfSSL_sk_dup(chain);
41907 }
41908 #endif
41909 
41910 
41911 #ifdef WOLFSSL_ALT_CERT_CHAINS
wolfSSL_is_peer_alt_cert_chain(const WOLFSSL * ssl)41912 int wolfSSL_is_peer_alt_cert_chain(const WOLFSSL* ssl)
41913 {
41914     int isUsing = 0;
41915     if (ssl)
41916         isUsing = ssl->options.usingAltCertChain;
41917     return isUsing;
41918 }
41919 #endif /* WOLFSSL_ALT_CERT_CHAINS */
41920 
41921 
41922 #ifdef SESSION_CERTS
41923 
41924 #ifdef WOLFSSL_ALT_CERT_CHAINS
41925 /* Get peer's alternate certificate chain */
wolfSSL_get_peer_alt_chain(WOLFSSL * ssl)41926 WOLFSSL_X509_CHAIN* wolfSSL_get_peer_alt_chain(WOLFSSL* ssl)
41927 {
41928     WOLFSSL_ENTER("wolfSSL_get_peer_alt_chain");
41929     if (ssl)
41930         return &ssl->session.altChain;
41931 
41932     return 0;
41933 }
41934 #endif /* WOLFSSL_ALT_CERT_CHAINS */
41935 
41936 
41937 /* Get peer's certificate chain */
wolfSSL_get_peer_chain(WOLFSSL * ssl)41938 WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
41939 {
41940     WOLFSSL_ENTER("wolfSSL_get_peer_chain");
41941     if (ssl)
41942         return &ssl->session.chain;
41943 
41944     return 0;
41945 }
41946 
41947 
41948 /* Get peer's certificate chain total count */
wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN * chain)41949 int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
41950 {
41951     WOLFSSL_ENTER("wolfSSL_get_chain_count");
41952     if (chain)
41953         return chain->count;
41954 
41955     return 0;
41956 }
41957 
41958 
41959 /* Get peer's ASN.1 DER certificate at index (idx) length in bytes */
wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN * chain,int idx)41960 int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
41961 {
41962     WOLFSSL_ENTER("wolfSSL_get_chain_length");
41963     if (chain)
41964         return chain->certs[idx].length;
41965 
41966     return 0;
41967 }
41968 
41969 
41970 /* Get peer's ASN.1 DER certificate at index (idx) */
wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN * chain,int idx)41971 byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
41972 {
41973     WOLFSSL_ENTER("wolfSSL_get_chain_cert");
41974     if (chain)
41975         return chain->certs[idx].buffer;
41976 
41977     return 0;
41978 }
41979 
41980 
41981 /* Get peer's wolfSSL X509 certificate at index (idx) */
wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN * chain,int idx)41982 WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
41983 {
41984     int          ret;
41985     WOLFSSL_X509* x509 = NULL;
41986 #ifdef WOLFSSL_SMALL_STACK
41987     DecodedCert* cert = NULL;
41988 #else
41989     DecodedCert  cert[1];
41990 #endif
41991 
41992     WOLFSSL_ENTER("wolfSSL_get_chain_X509");
41993     if (chain != NULL) {
41994     #ifdef WOLFSSL_SMALL_STACK
41995         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
41996                                                        DYNAMIC_TYPE_DCERT);
41997         if (cert != NULL)
41998     #endif
41999         {
42000             InitDecodedCert(cert, chain->certs[idx].buffer,
42001                                   chain->certs[idx].length, NULL);
42002 
42003             if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0) {
42004                 WOLFSSL_MSG("Failed to parse cert");
42005             }
42006             else {
42007                 x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
42008                                                              DYNAMIC_TYPE_X509);
42009                 if (x509 == NULL) {
42010                     WOLFSSL_MSG("Failed alloc X509");
42011                 }
42012                 else {
42013                     InitX509(x509, 1, NULL);
42014 
42015                     if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
42016                         WOLFSSL_MSG("Failed to copy decoded");
42017                         wolfSSL_X509_free(x509);
42018                         x509 = NULL;
42019                     }
42020                 }
42021             }
42022 
42023             FreeDecodedCert(cert);
42024         #ifdef WOLFSSL_SMALL_STACK
42025             XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
42026         #endif
42027         }
42028     }
42029     (void)ret;
42030 
42031     return x509;
42032 }
42033 
42034 
42035 /* Get peer's PEM certificate at index (idx), output to buffer if inLen big
42036    enough else return error (-1). If buffer is NULL only calculate
42037    outLen. Output length is in *outLen WOLFSSL_SUCCESS on ok */
wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN * chain,int idx,unsigned char * buf,int inLen,int * outLen)42038 int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
42039                                unsigned char* buf, int inLen, int* outLen)
42040 {
42041 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
42042     const char* header = NULL;
42043     const char* footer = NULL;
42044     int headerLen;
42045     int footerLen;
42046     int i;
42047     int err;
42048     word32 szNeeded = 0;
42049 
42050     WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
42051     if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain))
42052         return BAD_FUNC_ARG;
42053 
42054     err = wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer);
42055     if (err != 0)
42056         return err;
42057 
42058     headerLen = (int)XSTRLEN(header);
42059     footerLen = (int)XSTRLEN(footer);
42060 
42061     /* Null output buffer return size needed in outLen */
42062     if(!buf) {
42063         if(Base64_Encode(chain->certs[idx].buffer, chain->certs[idx].length,
42064                     NULL, &szNeeded) != LENGTH_ONLY_E)
42065             return WOLFSSL_FAILURE;
42066         *outLen = szNeeded + headerLen + footerLen;
42067         return LENGTH_ONLY_E;
42068     }
42069 
42070     /* don't even try if inLen too short */
42071     if (inLen < headerLen + footerLen + chain->certs[idx].length)
42072         return BAD_FUNC_ARG;
42073 
42074     /* header */
42075     if (XMEMCPY(buf, header, headerLen) == NULL)
42076         return WOLFSSL_FATAL_ERROR;
42077 
42078     i = headerLen;
42079 
42080     /* body */
42081     *outLen = inLen;  /* input to Base64_Encode */
42082     if ( (err = Base64_Encode(chain->certs[idx].buffer,
42083                        chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
42084         return err;
42085     i += *outLen;
42086 
42087     /* footer */
42088     if ( (i + footerLen) > inLen)
42089         return BAD_FUNC_ARG;
42090     if (XMEMCPY(buf + i, footer, footerLen) == NULL)
42091         return WOLFSSL_FATAL_ERROR;
42092     *outLen += headerLen + footerLen;
42093 
42094     return WOLFSSL_SUCCESS;
42095 #else
42096     (void)chain;
42097     (void)idx;
42098     (void)buf;
42099     (void)inLen;
42100     (void)outLen;
42101     return WOLFSSL_FAILURE;
42102 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
42103 }
42104 
42105 
42106 /* get session ID */
42107 WOLFSSL_ABI
wolfSSL_get_sessionID(const WOLFSSL_SESSION * session)42108 const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
42109 {
42110     WOLFSSL_ENTER("wolfSSL_get_sessionID");
42111     if (session)
42112         return session->sessionID;
42113 
42114     return NULL;
42115 }
42116 
42117 
42118 #endif /* SESSION_CERTS */
42119 
42120 #ifdef HAVE_FUZZER
wolfSSL_SetFuzzerCb(WOLFSSL * ssl,CallbackFuzzer cbf,void * fCtx)42121 void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
42122 {
42123     if (ssl) {
42124         ssl->fuzzerCb  = cbf;
42125         ssl->fuzzerCtx = fCtx;
42126     }
42127 }
42128 #endif
42129 
42130 #ifndef NO_CERTS
42131 #ifdef  HAVE_PK_CALLBACKS
42132 
42133 #ifdef HAVE_ECC
wolfSSL_CTX_SetEccKeyGenCb(WOLFSSL_CTX * ctx,CallbackEccKeyGen cb)42134 void  wolfSSL_CTX_SetEccKeyGenCb(WOLFSSL_CTX* ctx, CallbackEccKeyGen cb)
42135 {
42136     if (ctx)
42137         ctx->EccKeyGenCb = cb;
42138 }
wolfSSL_SetEccKeyGenCtx(WOLFSSL * ssl,void * ctx)42139 void  wolfSSL_SetEccKeyGenCtx(WOLFSSL* ssl, void *ctx)
42140 {
42141     if (ssl)
42142         ssl->EccKeyGenCtx = ctx;
42143 }
wolfSSL_GetEccKeyGenCtx(WOLFSSL * ssl)42144 void* wolfSSL_GetEccKeyGenCtx(WOLFSSL* ssl)
42145 {
42146     if (ssl)
42147         return ssl->EccKeyGenCtx;
42148 
42149     return NULL;
42150 }
42151 
42152 WOLFSSL_ABI
wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX * ctx,CallbackEccSign cb)42153 void  wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
42154 {
42155     if (ctx)
42156         ctx->EccSignCb = cb;
42157 }
wolfSSL_SetEccSignCtx(WOLFSSL * ssl,void * ctx)42158 void  wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
42159 {
42160     if (ssl)
42161         ssl->EccSignCtx = ctx;
42162 }
wolfSSL_GetEccSignCtx(WOLFSSL * ssl)42163 void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
42164 {
42165     if (ssl)
42166         return ssl->EccSignCtx;
42167 
42168     return NULL;
42169 }
42170 
wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX * ctx,CallbackEccVerify cb)42171 void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
42172 {
42173     if (ctx)
42174         ctx->EccVerifyCb = cb;
42175 }
wolfSSL_SetEccVerifyCtx(WOLFSSL * ssl,void * ctx)42176 void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
42177 {
42178     if (ssl)
42179         ssl->EccVerifyCtx = ctx;
42180 }
wolfSSL_GetEccVerifyCtx(WOLFSSL * ssl)42181 void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
42182 {
42183     if (ssl)
42184         return ssl->EccVerifyCtx;
42185 
42186     return NULL;
42187 }
42188 
wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX * ctx,CallbackEccSharedSecret cb)42189 void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX* ctx, CallbackEccSharedSecret cb)
42190 {
42191     if (ctx)
42192         ctx->EccSharedSecretCb = cb;
42193 }
wolfSSL_SetEccSharedSecretCtx(WOLFSSL * ssl,void * ctx)42194 void  wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx)
42195 {
42196     if (ssl)
42197         ssl->EccSharedSecretCtx = ctx;
42198 }
wolfSSL_GetEccSharedSecretCtx(WOLFSSL * ssl)42199 void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl)
42200 {
42201     if (ssl)
42202         return ssl->EccSharedSecretCtx;
42203 
42204     return NULL;
42205 }
42206 #endif /* HAVE_ECC */
42207 
42208 #ifdef HAVE_ED25519
wolfSSL_CTX_SetEd25519SignCb(WOLFSSL_CTX * ctx,CallbackEd25519Sign cb)42209 void  wolfSSL_CTX_SetEd25519SignCb(WOLFSSL_CTX* ctx, CallbackEd25519Sign cb)
42210 {
42211     if (ctx)
42212         ctx->Ed25519SignCb = cb;
42213 }
wolfSSL_SetEd25519SignCtx(WOLFSSL * ssl,void * ctx)42214 void  wolfSSL_SetEd25519SignCtx(WOLFSSL* ssl, void *ctx)
42215 {
42216     if (ssl)
42217         ssl->Ed25519SignCtx = ctx;
42218 }
wolfSSL_GetEd25519SignCtx(WOLFSSL * ssl)42219 void* wolfSSL_GetEd25519SignCtx(WOLFSSL* ssl)
42220 {
42221     if (ssl)
42222         return ssl->Ed25519SignCtx;
42223 
42224     return NULL;
42225 }
42226 
wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX * ctx,CallbackEd25519Verify cb)42227 void  wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX* ctx, CallbackEd25519Verify cb)
42228 {
42229     if (ctx)
42230         ctx->Ed25519VerifyCb = cb;
42231 }
wolfSSL_SetEd25519VerifyCtx(WOLFSSL * ssl,void * ctx)42232 void  wolfSSL_SetEd25519VerifyCtx(WOLFSSL* ssl, void *ctx)
42233 {
42234     if (ssl)
42235         ssl->Ed25519VerifyCtx = ctx;
42236 }
wolfSSL_GetEd25519VerifyCtx(WOLFSSL * ssl)42237 void* wolfSSL_GetEd25519VerifyCtx(WOLFSSL* ssl)
42238 {
42239     if (ssl)
42240         return ssl->Ed25519VerifyCtx;
42241 
42242     return NULL;
42243 }
42244 #endif /* HAVE_ED25519 */
42245 
42246 #ifdef HAVE_CURVE25519
wolfSSL_CTX_SetX25519KeyGenCb(WOLFSSL_CTX * ctx,CallbackX25519KeyGen cb)42247 void wolfSSL_CTX_SetX25519KeyGenCb(WOLFSSL_CTX* ctx,
42248         CallbackX25519KeyGen cb)
42249 {
42250     if (ctx)
42251         ctx->X25519KeyGenCb = cb;
42252 }
wolfSSL_SetX25519KeyGenCtx(WOLFSSL * ssl,void * ctx)42253 void  wolfSSL_SetX25519KeyGenCtx(WOLFSSL* ssl, void *ctx)
42254 {
42255     if (ssl)
42256         ssl->X25519KeyGenCtx = ctx;
42257 }
wolfSSL_GetX25519KeyGenCtx(WOLFSSL * ssl)42258 void* wolfSSL_GetX25519KeyGenCtx(WOLFSSL* ssl)
42259 {
42260     if (ssl)
42261         return ssl->X25519KeyGenCtx;
42262 
42263     return NULL;
42264 }
42265 
wolfSSL_CTX_SetX25519SharedSecretCb(WOLFSSL_CTX * ctx,CallbackX25519SharedSecret cb)42266 void wolfSSL_CTX_SetX25519SharedSecretCb(WOLFSSL_CTX* ctx,
42267         CallbackX25519SharedSecret cb)
42268 {
42269     if (ctx)
42270         ctx->X25519SharedSecretCb = cb;
42271 }
wolfSSL_SetX25519SharedSecretCtx(WOLFSSL * ssl,void * ctx)42272 void  wolfSSL_SetX25519SharedSecretCtx(WOLFSSL* ssl, void *ctx)
42273 {
42274     if (ssl)
42275         ssl->X25519SharedSecretCtx = ctx;
42276 }
wolfSSL_GetX25519SharedSecretCtx(WOLFSSL * ssl)42277 void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl)
42278 {
42279     if (ssl)
42280         return ssl->X25519SharedSecretCtx;
42281 
42282     return NULL;
42283 }
42284 #endif /* HAVE_CURVE25519 */
42285 
42286 #ifdef HAVE_ED448
wolfSSL_CTX_SetEd448SignCb(WOLFSSL_CTX * ctx,CallbackEd448Sign cb)42287 void  wolfSSL_CTX_SetEd448SignCb(WOLFSSL_CTX* ctx, CallbackEd448Sign cb)
42288 {
42289     if (ctx)
42290         ctx->Ed448SignCb = cb;
42291 }
wolfSSL_SetEd448SignCtx(WOLFSSL * ssl,void * ctx)42292 void  wolfSSL_SetEd448SignCtx(WOLFSSL* ssl, void *ctx)
42293 {
42294     if (ssl)
42295         ssl->Ed448SignCtx = ctx;
42296 }
wolfSSL_GetEd448SignCtx(WOLFSSL * ssl)42297 void* wolfSSL_GetEd448SignCtx(WOLFSSL* ssl)
42298 {
42299     if (ssl)
42300         return ssl->Ed448SignCtx;
42301 
42302     return NULL;
42303 }
42304 
wolfSSL_CTX_SetEd448VerifyCb(WOLFSSL_CTX * ctx,CallbackEd448Verify cb)42305 void  wolfSSL_CTX_SetEd448VerifyCb(WOLFSSL_CTX* ctx, CallbackEd448Verify cb)
42306 {
42307     if (ctx)
42308         ctx->Ed448VerifyCb = cb;
42309 }
wolfSSL_SetEd448VerifyCtx(WOLFSSL * ssl,void * ctx)42310 void  wolfSSL_SetEd448VerifyCtx(WOLFSSL* ssl, void *ctx)
42311 {
42312     if (ssl)
42313         ssl->Ed448VerifyCtx = ctx;
42314 }
wolfSSL_GetEd448VerifyCtx(WOLFSSL * ssl)42315 void* wolfSSL_GetEd448VerifyCtx(WOLFSSL* ssl)
42316 {
42317     if (ssl)
42318         return ssl->Ed448VerifyCtx;
42319 
42320     return NULL;
42321 }
42322 #endif /* HAVE_ED448 */
42323 
42324 #ifdef HAVE_CURVE448
wolfSSL_CTX_SetX448KeyGenCb(WOLFSSL_CTX * ctx,CallbackX448KeyGen cb)42325 void wolfSSL_CTX_SetX448KeyGenCb(WOLFSSL_CTX* ctx,
42326         CallbackX448KeyGen cb)
42327 {
42328     if (ctx)
42329         ctx->X448KeyGenCb = cb;
42330 }
wolfSSL_SetX448KeyGenCtx(WOLFSSL * ssl,void * ctx)42331 void  wolfSSL_SetX448KeyGenCtx(WOLFSSL* ssl, void *ctx)
42332 {
42333     if (ssl)
42334         ssl->X448KeyGenCtx = ctx;
42335 }
wolfSSL_GetX448KeyGenCtx(WOLFSSL * ssl)42336 void* wolfSSL_GetX448KeyGenCtx(WOLFSSL* ssl)
42337 {
42338     if (ssl)
42339         return ssl->X448KeyGenCtx;
42340 
42341     return NULL;
42342 }
42343 
wolfSSL_CTX_SetX448SharedSecretCb(WOLFSSL_CTX * ctx,CallbackX448SharedSecret cb)42344 void wolfSSL_CTX_SetX448SharedSecretCb(WOLFSSL_CTX* ctx,
42345         CallbackX448SharedSecret cb)
42346 {
42347     if (ctx)
42348         ctx->X448SharedSecretCb = cb;
42349 }
wolfSSL_SetX448SharedSecretCtx(WOLFSSL * ssl,void * ctx)42350 void  wolfSSL_SetX448SharedSecretCtx(WOLFSSL* ssl, void *ctx)
42351 {
42352     if (ssl)
42353         ssl->X448SharedSecretCtx = ctx;
42354 }
wolfSSL_GetX448SharedSecretCtx(WOLFSSL * ssl)42355 void* wolfSSL_GetX448SharedSecretCtx(WOLFSSL* ssl)
42356 {
42357     if (ssl)
42358         return ssl->X448SharedSecretCtx;
42359 
42360     return NULL;
42361 }
42362 #endif /* HAVE_CURVE448 */
42363 
42364 #ifndef NO_RSA
wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX * ctx,CallbackRsaSign cb)42365 void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
42366 {
42367     if (ctx)
42368         ctx->RsaSignCb = cb;
42369 }
wolfSSL_CTX_SetRsaSignCheckCb(WOLFSSL_CTX * ctx,CallbackRsaVerify cb)42370 void  wolfSSL_CTX_SetRsaSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
42371 {
42372     if (ctx)
42373         ctx->RsaSignCheckCb = cb;
42374 }
wolfSSL_SetRsaSignCtx(WOLFSSL * ssl,void * ctx)42375 void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
42376 {
42377     if (ssl)
42378         ssl->RsaSignCtx = ctx;
42379 }
wolfSSL_GetRsaSignCtx(WOLFSSL * ssl)42380 void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
42381 {
42382     if (ssl)
42383         return ssl->RsaSignCtx;
42384 
42385     return NULL;
42386 }
42387 
42388 
wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX * ctx,CallbackRsaVerify cb)42389 void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
42390 {
42391     if (ctx)
42392         ctx->RsaVerifyCb = cb;
42393 }
wolfSSL_SetRsaVerifyCtx(WOLFSSL * ssl,void * ctx)42394 void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
42395 {
42396     if (ssl)
42397         ssl->RsaVerifyCtx = ctx;
42398 }
wolfSSL_GetRsaVerifyCtx(WOLFSSL * ssl)42399 void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
42400 {
42401     if (ssl)
42402         return ssl->RsaVerifyCtx;
42403 
42404     return NULL;
42405 }
42406 
42407 #ifdef WC_RSA_PSS
wolfSSL_CTX_SetRsaPssSignCb(WOLFSSL_CTX * ctx,CallbackRsaPssSign cb)42408 void  wolfSSL_CTX_SetRsaPssSignCb(WOLFSSL_CTX* ctx, CallbackRsaPssSign cb)
42409 {
42410     if (ctx)
42411         ctx->RsaPssSignCb = cb;
42412 }
wolfSSL_CTX_SetRsaPssSignCheckCb(WOLFSSL_CTX * ctx,CallbackRsaPssVerify cb)42413 void  wolfSSL_CTX_SetRsaPssSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
42414 {
42415     if (ctx)
42416         ctx->RsaPssSignCheckCb = cb;
42417 }
wolfSSL_SetRsaPssSignCtx(WOLFSSL * ssl,void * ctx)42418 void  wolfSSL_SetRsaPssSignCtx(WOLFSSL* ssl, void *ctx)
42419 {
42420     if (ssl)
42421         ssl->RsaPssSignCtx = ctx;
42422 }
wolfSSL_GetRsaPssSignCtx(WOLFSSL * ssl)42423 void* wolfSSL_GetRsaPssSignCtx(WOLFSSL* ssl)
42424 {
42425     if (ssl)
42426         return ssl->RsaPssSignCtx;
42427 
42428     return NULL;
42429 }
42430 
wolfSSL_CTX_SetRsaPssVerifyCb(WOLFSSL_CTX * ctx,CallbackRsaPssVerify cb)42431 void  wolfSSL_CTX_SetRsaPssVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
42432 {
42433     if (ctx)
42434         ctx->RsaPssVerifyCb = cb;
42435 }
wolfSSL_SetRsaPssVerifyCtx(WOLFSSL * ssl,void * ctx)42436 void  wolfSSL_SetRsaPssVerifyCtx(WOLFSSL* ssl, void *ctx)
42437 {
42438     if (ssl)
42439         ssl->RsaPssVerifyCtx = ctx;
42440 }
wolfSSL_GetRsaPssVerifyCtx(WOLFSSL * ssl)42441 void* wolfSSL_GetRsaPssVerifyCtx(WOLFSSL* ssl)
42442 {
42443     if (ssl)
42444         return ssl->RsaPssVerifyCtx;
42445 
42446     return NULL;
42447 }
42448 #endif /* WC_RSA_PSS */
42449 
wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX * ctx,CallbackRsaEnc cb)42450 void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
42451 {
42452     if (ctx)
42453         ctx->RsaEncCb = cb;
42454 }
wolfSSL_SetRsaEncCtx(WOLFSSL * ssl,void * ctx)42455 void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
42456 {
42457     if (ssl)
42458         ssl->RsaEncCtx = ctx;
42459 }
wolfSSL_GetRsaEncCtx(WOLFSSL * ssl)42460 void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
42461 {
42462     if (ssl)
42463         return ssl->RsaEncCtx;
42464 
42465     return NULL;
42466 }
42467 
wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX * ctx,CallbackRsaDec cb)42468 void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
42469 {
42470     if (ctx)
42471         ctx->RsaDecCb = cb;
42472 }
wolfSSL_SetRsaDecCtx(WOLFSSL * ssl,void * ctx)42473 void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
42474 {
42475     if (ssl)
42476         ssl->RsaDecCtx = ctx;
42477 }
wolfSSL_GetRsaDecCtx(WOLFSSL * ssl)42478 void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
42479 {
42480     if (ssl)
42481         return ssl->RsaDecCtx;
42482 
42483     return NULL;
42484 }
42485 #endif /* NO_RSA */
42486 
42487 /* callback for premaster secret generation */
wolfSSL_CTX_SetGenPreMasterCb(WOLFSSL_CTX * ctx,CallbackGenPreMaster cb)42488 void  wolfSSL_CTX_SetGenPreMasterCb(WOLFSSL_CTX* ctx, CallbackGenPreMaster cb)
42489 {
42490     if (ctx)
42491         ctx->GenPreMasterCb = cb;
42492 }
42493 /* Set premaster secret generation callback context */
wolfSSL_SetGenPreMasterCtx(WOLFSSL * ssl,void * ctx)42494 void  wolfSSL_SetGenPreMasterCtx(WOLFSSL* ssl, void *ctx)
42495 {
42496     if (ssl)
42497         ssl->GenPreMasterCtx = ctx;
42498 }
42499 /* Get premaster secret generation callback context */
wolfSSL_GetGenPreMasterCtx(WOLFSSL * ssl)42500 void* wolfSSL_GetGenPreMasterCtx(WOLFSSL* ssl)
42501 {
42502     if (ssl)
42503         return ssl->GenPreMasterCtx;
42504 
42505     return NULL;
42506 }
42507 
42508 /* callback for master secret generation */
wolfSSL_CTX_SetGenMasterSecretCb(WOLFSSL_CTX * ctx,CallbackGenMasterSecret cb)42509 void  wolfSSL_CTX_SetGenMasterSecretCb(WOLFSSL_CTX* ctx, CallbackGenMasterSecret cb)
42510 {
42511     if (ctx)
42512         ctx->GenMasterCb = cb;
42513 }
42514 /* Set master secret generation callback context */
wolfSSL_SetGenMasterSecretCtx(WOLFSSL * ssl,void * ctx)42515 void  wolfSSL_SetGenMasterSecretCtx(WOLFSSL* ssl, void *ctx)
42516 {
42517     if (ssl)
42518         ssl->GenMasterCtx = ctx;
42519 }
42520 /* Get master secret generation callback context */
wolfSSL_GetGenMasterSecretCtx(WOLFSSL * ssl)42521 void* wolfSSL_GetGenMasterSecretCtx(WOLFSSL* ssl)
42522 {
42523     if (ssl)
42524         return ssl->GenMasterCtx;
42525 
42526     return NULL;
42527 }
42528 
42529 /* callback for session key generation */
wolfSSL_CTX_SetGenSessionKeyCb(WOLFSSL_CTX * ctx,CallbackGenSessionKey cb)42530 void  wolfSSL_CTX_SetGenSessionKeyCb(WOLFSSL_CTX* ctx, CallbackGenSessionKey cb)
42531 {
42532     if (ctx)
42533         ctx->GenSessionKeyCb = cb;
42534 }
42535 /* Set sesssion key generation callback context */
wolfSSL_SetGenSessionKeyCtx(WOLFSSL * ssl,void * ctx)42536 void  wolfSSL_SetGenSessionKeyCtx(WOLFSSL* ssl, void *ctx)
42537 {
42538     if (ssl)
42539         ssl->GenSessionKeyCtx = ctx;
42540 }
42541 /* Get sesssion key generation callback context */
wolfSSL_GetGenSessionKeyCtx(WOLFSSL * ssl)42542 void* wolfSSL_GetGenSessionKeyCtx(WOLFSSL* ssl)
42543 {
42544     if (ssl)
42545         return ssl->GenSessionKeyCtx;
42546 
42547     return NULL;
42548 }
42549 
42550 /* callback for setting encryption keys */
wolfSSL_CTX_SetEncryptKeysCb(WOLFSSL_CTX * ctx,CallbackEncryptKeys cb)42551 void  wolfSSL_CTX_SetEncryptKeysCb(WOLFSSL_CTX* ctx, CallbackEncryptKeys cb)
42552 {
42553     if (ctx)
42554         ctx->EncryptKeysCb = cb;
42555 }
42556 /* Set encryption keys callback context */
wolfSSL_SetEncryptKeysCtx(WOLFSSL * ssl,void * ctx)42557 void  wolfSSL_SetEncryptKeysCtx(WOLFSSL* ssl, void *ctx)
42558 {
42559     if (ssl)
42560         ssl->EncryptKeysCtx = ctx;
42561 }
42562 /* Get encryption keys callback context */
wolfSSL_GetEncryptKeysCtx(WOLFSSL * ssl)42563 void* wolfSSL_GetEncryptKeysCtx(WOLFSSL* ssl)
42564 {
42565     if (ssl)
42566         return ssl->EncryptKeysCtx;
42567 
42568     return NULL;
42569 }
42570 
42571 /* callback for Tls finished */
42572 /* the callback can be used to build TLS Finished message if enabled */
wolfSSL_CTX_SetTlsFinishedCb(WOLFSSL_CTX * ctx,CallbackTlsFinished cb)42573 void  wolfSSL_CTX_SetTlsFinishedCb(WOLFSSL_CTX* ctx, CallbackTlsFinished cb)
42574 {
42575     if (ctx)
42576         ctx->TlsFinishedCb = cb;
42577 }
42578 /* Set Tls finished callback context */
wolfSSL_SetTlsFinishedCtx(WOLFSSL * ssl,void * ctx)42579 void  wolfSSL_SetTlsFinishedCtx(WOLFSSL* ssl, void *ctx)
42580 {
42581     if (ssl)
42582         ssl->TlsFinishedCtx = ctx;
42583 }
42584 /* Get Tls finished callback context */
wolfSSL_GetTlsFinishedCtx(WOLFSSL * ssl)42585 void* wolfSSL_GetTlsFinishedCtx(WOLFSSL* ssl)
42586 {
42587     if (ssl)
42588         return ssl->TlsFinishedCtx;
42589 
42590     return NULL;
42591 }
42592 #if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
42593 /* callback for verify data */
wolfSSL_CTX_SetVerifyMacCb(WOLFSSL_CTX * ctx,CallbackVerifyMac cb)42594 void  wolfSSL_CTX_SetVerifyMacCb(WOLFSSL_CTX* ctx, CallbackVerifyMac cb)
42595 {
42596     if (ctx)
42597         ctx->VerifyMacCb = cb;
42598 }
42599 
42600 /* Set set keys callback context */
wolfSSL_SetVerifyMacCtx(WOLFSSL * ssl,void * ctx)42601 void  wolfSSL_SetVerifyMacCtx(WOLFSSL* ssl, void *ctx)
42602 {
42603     if (ssl)
42604         ssl->VerifyMacCtx = ctx;
42605 }
42606 /* Get set  keys callback context */
wolfSSL_GetVerifyMacCtx(WOLFSSL * ssl)42607 void* wolfSSL_GetVerifyMacCtx(WOLFSSL* ssl)
42608 {
42609     if (ssl)
42610         return ssl->VerifyMacCtx;
42611 
42612     return NULL;
42613 }
42614 #endif /* !WOLFSSL_NO_TLS12 && !WOLFSSL_AEAD_ONLY */
42615 
42616 #endif /* HAVE_PK_CALLBACKS */
42617 #endif /* NO_CERTS */
42618 
42619 #if defined(HAVE_PK_CALLBACKS) && !defined(NO_DH)
wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX * ctx,CallbackDhAgree cb)42620 void wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX* ctx, CallbackDhAgree cb)
42621 {
42622     if (ctx)
42623         ctx->DhAgreeCb = cb;
42624 }
wolfSSL_SetDhAgreeCtx(WOLFSSL * ssl,void * ctx)42625 void wolfSSL_SetDhAgreeCtx(WOLFSSL* ssl, void *ctx)
42626 {
42627     if (ssl)
42628         ssl->DhAgreeCtx = ctx;
42629 }
wolfSSL_GetDhAgreeCtx(WOLFSSL * ssl)42630 void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
42631 {
42632     if (ssl)
42633         return ssl->DhAgreeCtx;
42634 
42635     return NULL;
42636 }
42637 #endif /* HAVE_PK_CALLBACKS && !NO_DH */
42638 
42639 #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_HKDF)
42640 
wolfSSL_CTX_SetHKDFExtractCb(WOLFSSL_CTX * ctx,CallbackHKDFExtract cb)42641 void wolfSSL_CTX_SetHKDFExtractCb(WOLFSSL_CTX* ctx, CallbackHKDFExtract cb)
42642 {
42643     if (ctx)
42644         ctx->HkdfExtractCb = cb;
42645 }
42646 
wolfSSL_SetHKDFExtractCtx(WOLFSSL * ssl,void * ctx)42647 void wolfSSL_SetHKDFExtractCtx(WOLFSSL* ssl, void *ctx)
42648 {
42649     if (ssl)
42650         ssl->HkdfExtractCtx = ctx;
42651 }
42652 
wolfSSL_GetHKDFExtractCtx(WOLFSSL * ssl)42653 void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl)
42654 {
42655     if (ssl)
42656         return ssl->HkdfExtractCtx;
42657 
42658     return NULL;
42659 }
42660 #endif /* HAVE_PK_CALLBACKS && HAVE_HKDF */
42661 
42662 #ifdef WOLFSSL_HAVE_WOLFSCEP
42663     /* Used by autoconf to see if wolfSCEP is available */
wolfSSL_wolfSCEP(void)42664     void wolfSSL_wolfSCEP(void) {}
42665 #endif
42666 
42667 
42668 #ifdef WOLFSSL_HAVE_CERT_SERVICE
42669     /* Used by autoconf to see if cert service is available */
wolfSSL_cert_service(void)42670     void wolfSSL_cert_service(void) {}
42671 #endif
42672 
42673 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
42674     !defined(WOLFCRYPT_ONLY)
42675 #ifndef NO_CERTS
wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME * name)42676     void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name)
42677     {
42678         WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
42679         FreeX509Name(name);
42680         XFREE(name, NULL, DYNAMIC_TYPE_X509);
42681     }
42682 
42683 
42684     /* Malloc's a new WOLFSSL_X509_NAME structure
42685      *
42686      * returns NULL on failure, otherwise returns a new structure.
42687      */
wolfSSL_X509_NAME_new(void)42688     WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void)
42689     {
42690         WOLFSSL_X509_NAME* name;
42691 
42692         WOLFSSL_ENTER("wolfSSL_X509_NAME_new");
42693 
42694         name = (WOLFSSL_X509_NAME*)XMALLOC(sizeof(WOLFSSL_X509_NAME), NULL,
42695                 DYNAMIC_TYPE_X509);
42696         if (name != NULL) {
42697             InitX509Name(name, 1, NULL);
42698         }
42699         return name;
42700     }
42701 
42702     /* Creates a duplicate of a WOLFSSL_X509_NAME structure.
42703        Returns a new WOLFSSL_X509_NAME structure or NULL on failure */
wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME * name)42704     WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME *name)
42705     {
42706         WOLFSSL_X509_NAME* copy = NULL;
42707 
42708         WOLFSSL_ENTER("wolfSSL_X509_NAME_dup");
42709 
42710         if (name == NULL) {
42711             WOLFSSL_MSG("NULL parameter");
42712             return NULL;
42713         }
42714 
42715         if (!(copy = wolfSSL_X509_NAME_new())) {
42716             return NULL;
42717         }
42718 
42719         /* copy contents */
42720         InitX509Name(copy, 1, name->heap);
42721         if (wolfSSL_X509_NAME_copy(name, copy) != WOLFSSL_SUCCESS) {
42722             wolfSSL_X509_NAME_free(copy);
42723             return NULL;
42724         }
42725 
42726         return copy;
42727     }
42728 
42729 #ifdef WOLFSSL_CERT_GEN
42730 
42731 #if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
42732     /* Helper function to copy cert name from a WOLFSSL_X509_NAME structure to
42733     * a Cert structure.
42734     *
42735     * returns length of DER on success and a negative error value on failure
42736     */
CopyX509NameToCert(WOLFSSL_X509_NAME * n,byte * out)42737     static int CopyX509NameToCert(WOLFSSL_X509_NAME* n, byte* out)
42738     {
42739         unsigned char* der = NULL;
42740         int length = BAD_FUNC_ARG, ret;
42741         word32 idx = 0;
42742 
42743         ret = wolfSSL_i2d_X509_NAME(n, &der);
42744         if (ret > (int)sizeof(CertName) || ret < 0) {
42745             WOLFSSL_MSG("Name conversion error");
42746             ret = MEMORY_E;
42747         }
42748 
42749         if (ret > 0) {
42750             /* strip off sequence, this gets added on certificate creation */
42751             ret = GetSequence(der, &idx, &length, ret);
42752         }
42753 
42754         if (ret > 0) {
42755             XMEMCPY(out, der + idx, length);
42756         }
42757 
42758         if (der != NULL)
42759             XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
42760 
42761         return length;
42762     }
42763 #endif
42764 
42765 #ifdef WOLFSSL_CERT_REQ
ReqCertFromX509(Cert * cert,WOLFSSL_X509 * req)42766     static int ReqCertFromX509(Cert* cert, WOLFSSL_X509* req)
42767     {
42768         int ret;
42769 
42770         if (wc_InitCert(cert) != 0)
42771             return WOLFSSL_FAILURE;
42772 
42773 
42774         ret = CopyX509NameToCert(&req->subject, cert->sbjRaw);
42775         if (ret < 0) {
42776             WOLFSSL_MSG("REQ subject conversion error");
42777             ret = MEMORY_E;
42778         }
42779         else {
42780             ret = WOLFSSL_SUCCESS;
42781         }
42782 
42783         if (ret == WOLFSSL_SUCCESS) {
42784             cert->version = req->version;
42785             cert->isCA = req->isCa;
42786     #ifdef WOLFSSL_CERT_EXT
42787             if (req->subjKeyIdSz != 0) {
42788                 XMEMCPY(cert->skid, req->subjKeyId, req->subjKeyIdSz);
42789                 cert->skidSz = req->subjKeyIdSz;
42790             }
42791             if (req->keyUsageSet)
42792                 cert->keyUsage = req->keyUsage;
42793             /* Extended Key Usage not supported. */
42794     #endif
42795     #ifdef WOLFSSL_CERT_REQ
42796             XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE);
42797             cert->challengePwPrintableString = req->challengePw[0] != 0;
42798     #endif
42799     #ifdef WOLFSSL_ALT_NAMES
42800             cert->altNamesSz = FlattenAltNames(cert->altNames,
42801                     sizeof(cert->altNames), req->altNames);
42802     #endif /* WOLFSSL_ALT_NAMES */
42803         }
42804 
42805         return ret;
42806     }
42807 #endif /* WOLFSSL_CERT_REQ */
42808 
42809 #ifdef WOLFSSL_ALT_NAMES
42810     /* converts WOLFSSL_AN1_TIME to Cert form, returns positive size on
42811      * success */
CertDateFromX509(byte * out,int outSz,WOLFSSL_ASN1_TIME * t)42812     static int CertDateFromX509(byte* out, int outSz, WOLFSSL_ASN1_TIME* t)
42813     {
42814         int sz, i;
42815 
42816         if (t->length + 1 >= outSz) {
42817             return BUFFER_E;
42818         }
42819 
42820         out[0] = t->type;
42821         sz = SetLength(t->length, out + 1) + 1;  /* gen tag */
42822         for (i = 0; i < t->length; i++) {
42823             out[sz + i] = t->data[i];
42824         }
42825         return t->length + sz;
42826     }
42827 #endif /* WOLFSSL_ALT_NAMES */
42828 
42829     /* convert a WOLFSSL_X509 to a Cert structure for writing out */
CertFromX509(Cert * cert,WOLFSSL_X509 * x509)42830     static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
42831     {
42832         int ret;
42833         #ifdef WOLFSSL_CERT_EXT
42834         int i;
42835         #endif
42836 
42837         WOLFSSL_ENTER("wolfSSL_X509_to_Cert()");
42838 
42839         if (x509 == NULL || cert == NULL) {
42840             return BAD_FUNC_ARG;
42841         }
42842 
42843         wc_InitCert(cert);
42844 
42845         cert->version = (int)wolfSSL_X509_get_version(x509);
42846 
42847     #ifdef WOLFSSL_ALT_NAMES
42848         if (x509->notBefore.length > 0) {
42849             cert->beforeDateSz = CertDateFromX509(cert->beforeDate,
42850                         CTC_DATE_SIZE, &x509->notBefore);
42851             if (cert->beforeDateSz <= 0){
42852                 WOLFSSL_MSG("Not before date error");
42853                 return WOLFSSL_FAILURE;
42854             }
42855         }
42856         else {
42857             cert->beforeDateSz = 0;
42858         }
42859 
42860         if (x509->notAfter.length > 0) {
42861             cert->afterDateSz = CertDateFromX509(cert->afterDate,
42862                         CTC_DATE_SIZE, &x509->notAfter);
42863             if (cert->afterDateSz <= 0){
42864                 WOLFSSL_MSG("Not after date error");
42865                 return WOLFSSL_FAILURE;
42866             }
42867         }
42868         else {
42869             cert->afterDateSz = 0;
42870         }
42871 
42872         cert->altNamesSz = FlattenAltNames(cert->altNames,
42873                 sizeof(cert->altNames), x509->altNames);
42874     #endif /* WOLFSSL_ALT_NAMES */
42875 
42876         cert->sigType = wolfSSL_X509_get_signature_type(x509);
42877         cert->keyType = x509->pubKeyOID;
42878         cert->isCA    = wolfSSL_X509_get_isCA(x509);
42879 
42880     #ifdef WOLFSSL_CERT_EXT
42881         if (x509->subjKeyIdSz < CTC_MAX_SKID_SIZE) {
42882             if (x509->subjKeyId) {
42883                 XMEMCPY(cert->skid, x509->subjKeyId, x509->subjKeyIdSz);
42884             }
42885             cert->skidSz = (int)x509->subjKeyIdSz;
42886         }
42887         else {
42888             WOLFSSL_MSG("Subject Key ID too large");
42889             return WOLFSSL_FAILURE;
42890         }
42891 
42892         if (x509->authKeyIdSz < sizeof(cert->akid)) {
42893         #ifdef WOLFSSL_AKID_NAME
42894             cert->rawAkid = 0;
42895             if (x509->authKeyIdSrc) {
42896                 XMEMCPY(cert->akid, x509->authKeyIdSrc, x509->authKeyIdSrcSz);
42897                 cert->akidSz = (int)x509->authKeyIdSrcSz;
42898                 cert->rawAkid = 1;
42899             }
42900             else
42901         #endif
42902             if (x509->authKeyId) {
42903                 XMEMCPY(cert->akid, x509->authKeyId, x509->authKeyIdSz);
42904                 cert->akidSz = (int)x509->authKeyIdSz;
42905             }
42906         }
42907         else {
42908             WOLFSSL_MSG("Auth Key ID too large");
42909             return WOLFSSL_FAILURE;
42910         }
42911 
42912         for (i = 0; i < x509->certPoliciesNb; i++) {
42913             /* copy the smaller of MAX macros, by default they are currently equal*/
42914             if ((int)CTC_MAX_CERTPOL_SZ <= (int)MAX_CERTPOL_SZ) {
42915                 XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
42916                         CTC_MAX_CERTPOL_SZ);
42917             }
42918             else {
42919                 XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
42920                         MAX_CERTPOL_SZ);
42921             }
42922         }
42923         cert->certPoliciesNb = (word16)x509->certPoliciesNb;
42924 
42925         cert->keyUsage = x509->keyUsage;
42926         cert->extKeyUsage = x509->extKeyUsage;
42927         cert->nsCertType = x509->nsCertType;
42928 
42929         if (x509->rawCRLInfo != NULL) {
42930             if (x509->rawCRLInfoSz > CTC_MAX_CRLINFO_SZ) {
42931                 WOLFSSL_MSG("CRL Info too large");
42932                 return WOLFSSL_FAILURE;
42933             }
42934             XMEMCPY(cert->crlInfo, x509->rawCRLInfo, x509->rawCRLInfoSz);
42935             cert->crlInfoSz = x509->rawCRLInfoSz;
42936         }
42937     #endif /* WOLFSSL_CERT_EXT */
42938 
42939     #ifdef WOLFSSL_CERT_REQ
42940         /* copy over challenge password for REQ certs */
42941         XMEMCPY(cert->challengePw, x509->challengePw, CTC_NAME_SIZE);
42942     #endif
42943 
42944         /* set serial number */
42945         if (x509->serialSz > 0) {
42946         #if defined(OPENSSL_EXTRA)
42947             byte serial[EXTERNAL_SERIAL_SIZE];
42948             int  serialSz = EXTERNAL_SERIAL_SIZE;
42949 
42950             ret = wolfSSL_X509_get_serial_number(x509, serial, &serialSz);
42951             if (ret != WOLFSSL_SUCCESS) {
42952                 WOLFSSL_MSG("Serial size error");
42953                 return WOLFSSL_FAILURE;
42954             }
42955 
42956             if (serialSz > EXTERNAL_SERIAL_SIZE ||
42957                     serialSz > CTC_SERIAL_SIZE) {
42958                 WOLFSSL_MSG("Serial size too large error");
42959                 return WOLFSSL_FAILURE;
42960             }
42961             XMEMCPY(cert->serial, serial, serialSz);
42962             cert->serialSz = serialSz;
42963         #else
42964             WOLFSSL_MSG("Getting X509 serial number not supported");
42965             return WOLFSSL_FAILURE;
42966         #endif
42967         }
42968 
42969         /* copy over Name structures */
42970         if (x509->issuerSet)
42971             cert->selfSigned = 0;
42972 
42973     #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
42974         ret = CopyX509NameToCert(&x509->subject, cert->sbjRaw);
42975         if (ret < 0) {
42976             WOLFSSL_MSG("Subject conversion error");
42977             return MEMORY_E;
42978         }
42979         if (cert->selfSigned) {
42980             XMEMCPY(cert->issRaw, cert->sbjRaw, sizeof(CertName));
42981         }
42982         else {
42983             ret = CopyX509NameToCert(&x509->issuer, cert->issRaw);
42984             if (ret < 0) {
42985                 WOLFSSL_MSG("Issuer conversion error");
42986                 return MEMORY_E;
42987             }
42988         }
42989     #endif
42990 
42991         cert->heap = x509->heap;
42992 
42993         (void)ret;
42994         return WOLFSSL_SUCCESS;
42995     }
42996 
42997 
42998     /* returns the sig type to use on success i.e CTC_SHAwRSA and WOLFSSL_FALURE
42999      * on fail case */
wolfSSL_sigTypeFromPKEY(WOLFSSL_EVP_MD * md,WOLFSSL_EVP_PKEY * pkey)43000     static int wolfSSL_sigTypeFromPKEY(WOLFSSL_EVP_MD* md,
43001             WOLFSSL_EVP_PKEY* pkey)
43002     {
43003         int hashType;
43004         int sigType = WOLFSSL_FAILURE;
43005 
43006     #if !defined(NO_PWDBASED) && defined(OPENSSL_EXTRA)
43007         /* Convert key type and hash algorithm to a signature algorithm */
43008         if (wolfSSL_EVP_get_hashinfo(md, &hashType, NULL) == WOLFSSL_FAILURE) {
43009             return WOLFSSL_FAILURE;
43010         }
43011     #else
43012         (void)md;
43013         WOLFSSL_MSG("Cannot get hashinfo when NO_PWDBASED is defined");
43014         return WOLFSSL_FAILURE;
43015     #endif /* !defined(NO_PWDBASED) */
43016 
43017 
43018         if (pkey->type == EVP_PKEY_RSA) {
43019             switch (hashType) {
43020                 case WC_HASH_TYPE_SHA:
43021                     sigType = CTC_SHAwRSA;
43022                     break;
43023                 case WC_HASH_TYPE_SHA224:
43024                     sigType = CTC_SHA224wRSA;
43025                     break;
43026                 case WC_HASH_TYPE_SHA256:
43027                     sigType = CTC_SHA256wRSA;
43028                     break;
43029                 case WC_HASH_TYPE_SHA384:
43030                     sigType = CTC_SHA384wRSA;
43031                     break;
43032                 case WC_HASH_TYPE_SHA512:
43033                     sigType = CTC_SHA512wRSA;
43034                     break;
43035             #ifdef WOLFSSL_SHA3
43036                 case WC_HASH_TYPE_SHA3_224:
43037                     sigType = CTC_SHA3_224wRSA;
43038                     break;
43039                 case WC_HASH_TYPE_SHA3_256:
43040                     sigType = CTC_SHA3_256wRSA;
43041                     break;
43042                 case WC_HASH_TYPE_SHA3_384:
43043                     sigType = CTC_SHA3_384wRSA;
43044                     break;
43045                 case WC_HASH_TYPE_SHA3_512:
43046                     sigType = CTC_SHA3_512wRSA;
43047                     break;
43048             #endif
43049                 default:
43050                     return WOLFSSL_FAILURE;
43051             }
43052         }
43053         else if (pkey->type == EVP_PKEY_EC) {
43054             switch (hashType) {
43055                 case WC_HASH_TYPE_SHA:
43056                     sigType = CTC_SHAwECDSA;
43057                     break;
43058                 case WC_HASH_TYPE_SHA224:
43059                     sigType = CTC_SHA224wECDSA;
43060                     break;
43061                 case WC_HASH_TYPE_SHA256:
43062                     sigType = CTC_SHA256wECDSA;
43063                     break;
43064                 case WC_HASH_TYPE_SHA384:
43065                     sigType = CTC_SHA384wECDSA;
43066                     break;
43067                 case WC_HASH_TYPE_SHA512:
43068                     sigType = CTC_SHA512wECDSA;
43069                     break;
43070             #ifdef WOLFSSL_SHA3
43071                 case WC_HASH_TYPE_SHA3_224:
43072                     sigType = CTC_SHA3_224wECDSA;
43073                     break;
43074                 case WC_HASH_TYPE_SHA3_256:
43075                     sigType = CTC_SHA3_256wECDSA;
43076                     break;
43077                 case WC_HASH_TYPE_SHA3_384:
43078                     sigType = CTC_SHA3_384wECDSA;
43079                     break;
43080                 case WC_HASH_TYPE_SHA3_512:
43081                     sigType = CTC_SHA3_512wECDSA;
43082                     break;
43083             #endif
43084                 default:
43085                     return WOLFSSL_FAILURE;
43086             }
43087         }
43088         else
43089             return WOLFSSL_FAILURE;
43090         return sigType;
43091     }
43092 
43093 
43094     /* generates DER buffer from WOLFSSL_X509
43095      * If req == 1 then creates a request DER buffer
43096      *
43097      * updates derSz with certificate body size on success
43098      * return WOLFSSL_SUCCESS on success
43099      */
wolfssl_x509_make_der(WOLFSSL_X509 * x509,int req,unsigned char * der,int * derSz,int includeSig)43100     static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
43101             unsigned char* der, int* derSz, int includeSig)
43102     {
43103         int ret = WOLFSSL_FAILURE;
43104         int totalLen;
43105         Cert cert;
43106         void* key = NULL;
43107         int type = -1;
43108     #ifndef NO_RSA
43109         RsaKey rsa;
43110     #endif
43111     #ifdef HAVE_ECC
43112         ecc_key ecc;
43113     #endif
43114     #ifndef NO_DSA
43115         DsaKey dsa;
43116     #endif
43117         WC_RNG rng;
43118         word32 idx = 0;
43119 
43120         if (x509 == NULL || der == NULL || derSz == NULL)
43121             return BAD_FUNC_ARG;
43122 
43123     #ifndef WOLFSSL_CERT_REQ
43124         if (req) {
43125             WOLFSSL_MSG("WOLFSSL_CERT_REQ needed for certificate request");
43126             return WOLFSSL_FAILURE;
43127         }
43128     #endif
43129 
43130     #ifdef WOLFSSL_CERT_REQ
43131         if (req) {
43132             if (ReqCertFromX509(&cert, x509) != WOLFSSL_SUCCESS)
43133                 return WOLFSSL_FAILURE;
43134         }
43135         else
43136     #endif
43137         {
43138             /* Create a Cert that has the certificate fields. */
43139             if (CertFromX509(&cert, x509) != WOLFSSL_SUCCESS)
43140                 return WOLFSSL_FAILURE;
43141         }
43142 
43143         /* Create a public key object from requests public key. */
43144     #ifndef NO_RSA
43145         if (x509->pubKeyOID == RSAk) {
43146             type = RSA_TYPE;
43147             ret = wc_InitRsaKey(&rsa, x509->heap);
43148             if (ret != 0)
43149                 return ret;
43150             ret = wc_RsaPublicKeyDecode(x509->pubKey.buffer, &idx, &rsa,
43151                                                            x509->pubKey.length);
43152             if (ret != 0) {
43153                 wc_FreeRsaKey(&rsa);
43154                 return ret;
43155             }
43156             key = (void*)&rsa;
43157         }
43158     #endif
43159     #ifdef HAVE_ECC
43160         if (x509->pubKeyOID == ECDSAk) {
43161             type = ECC_TYPE;
43162             ret = wc_ecc_init(&ecc);
43163             if (ret != 0)
43164                 return ret;
43165             ret = wc_EccPublicKeyDecode(x509->pubKey.buffer, &idx, &ecc,
43166                                                            x509->pubKey.length);
43167             if (ret != 0) {
43168                 wc_ecc_free(&ecc);
43169                 return ret;
43170             }
43171             key = (void*)&ecc;
43172         }
43173     #endif
43174     #ifndef NO_DSA
43175         if (x509->pubKeyOID == DSAk) {
43176             type = DSA_TYPE;
43177             ret = wc_InitDsaKey(&dsa);
43178             if (ret != 0)
43179                 return ret;
43180             ret = wc_DsaPublicKeyDecode(x509->pubKey.buffer, &idx, &dsa,
43181                                                            x509->pubKey.length);
43182             if (ret != 0) {
43183                 wc_FreeDsaKey(&dsa);
43184                 return ret;
43185             }
43186             key = (void*)&dsa;
43187         }
43188     #endif
43189         if (key == NULL) {
43190             WOLFSSL_MSG("No public key found for certificate");
43191             return WOLFSSL_FAILURE;
43192         }
43193 
43194         /* Make the body of the certificate request. */
43195     #ifdef WOLFSSL_CERT_REQ
43196         if (req) {
43197             ret = wc_MakeCertReq_ex(&cert, der, *derSz, type, key);
43198         }
43199         else
43200     #endif
43201         {
43202             ret = wc_InitRng(&rng);
43203             if (ret != 0)
43204                 return WOLFSSL_FAILURE;
43205 
43206             ret = wc_MakeCert_ex(&cert, der, *derSz, type, key, &rng);
43207             wc_FreeRng(&rng);
43208         }
43209         if (ret <= 0) {
43210             ret = WOLFSSL_FAILURE;
43211             goto cleanup;
43212         }
43213 
43214         if ((x509->serialSz == 0) &&
43215                 (cert.serialSz <= EXTERNAL_SERIAL_SIZE) &&
43216                 (cert.serialSz > 0)) {
43217         #if defined(OPENSSL_EXTRA)
43218             WOLFSSL_ASN1_INTEGER *i = wolfSSL_ASN1_INTEGER_new();
43219 
43220             if (i == NULL) {
43221                 WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
43222                 ret = WOLFSSL_FAILURE;
43223                 goto cleanup;
43224             }
43225             else {
43226                 i->length = cert.serialSz + 2;
43227                 i->data[0] = ASN_INTEGER;
43228                 i->data[1] = cert.serialSz;
43229                 XMEMCPY(i->data + 2, cert.serial, cert.serialSz);
43230                 if (wolfSSL_X509_set_serialNumber(x509, i) != WOLFSSL_SUCCESS) {
43231                     WOLFSSL_MSG("Issue setting generated serial number");
43232                     wolfSSL_ASN1_INTEGER_free(i);
43233                     ret = WOLFSSL_FAILURE;
43234                     goto cleanup;
43235                 }
43236                 wolfSSL_ASN1_INTEGER_free(i);
43237             }
43238         #else
43239             WOLFSSL_MSG("ASN1_INTEGER API not in build");
43240 
43241             ret = WOLFSSL_FAILURE;
43242             goto cleanup;
43243         #endif /* OPENSSL_EXTRA */
43244         }
43245 
43246         if (includeSig) {
43247             if (!x509->sig.buffer) {
43248                 WOLFSSL_MSG("No signature buffer");
43249                 ret = WOLFSSL_FAILURE;
43250                 goto cleanup;
43251             }
43252             totalLen = AddSignature(NULL, ret, NULL, x509->sig.length,
43253                                   x509->sigOID);
43254             if (totalLen > *derSz) {
43255                 WOLFSSL_MSG("Output der buffer too short");
43256                 ret = WOLFSSL_FAILURE;
43257                 goto cleanup;
43258             }
43259             ret = AddSignature(der, ret, x509->sig.buffer,
43260                                x509->sig.length, x509->sigOID);
43261         }
43262 
43263         *derSz = ret;
43264         ret = WOLFSSL_SUCCESS;
43265 cleanup:
43266         /* Dispose of the public key object. */
43267     #ifndef NO_RSA
43268         if (x509->pubKeyOID == RSAk)
43269             wc_FreeRsaKey(&rsa);
43270     #endif
43271     #ifdef HAVE_ECC
43272         if (x509->pubKeyOID == ECDSAk)
43273             wc_ecc_free(&ecc);
43274     #endif
43275 
43276         return ret;
43277     }
43278 
43279 
43280     /* signs a der buffer for the WOLFSSL_X509 structure using the PKEY and MD
43281      * hash passed in
43282      *
43283      * WARNING: this free's and replaces the existing DER buffer in the
43284      *          WOLFSSL_X509 with the newly signed buffer.
43285      * returns size of signed buffer on success and negative values on fail
43286      */
wolfSSL_X509_resign_cert(WOLFSSL_X509 * x509,int req,unsigned char * der,int derSz,int certBodySz,WOLFSSL_EVP_MD * md,WOLFSSL_EVP_PKEY * pkey)43287     static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, int req,
43288             unsigned char* der, int derSz, int certBodySz, WOLFSSL_EVP_MD* md,
43289             WOLFSSL_EVP_PKEY* pkey)
43290     {
43291         int ret;
43292         void* key = NULL;
43293         int type = -1;
43294         int sigType;
43295         WC_RNG rng;
43296 
43297         (void)req;
43298         WOLFSSL_ENTER("wolfSSL_X509_resign_cert");
43299 
43300         sigType = wolfSSL_sigTypeFromPKEY(md, pkey);
43301         if (sigType == WOLFSSL_FAILURE) {
43302             WOLFSSL_MSG("Error getting signature type from pkey");
43303             return WOLFSSL_FATAL_ERROR;
43304         }
43305 
43306 
43307         /* Get the private key object and type from pkey. */
43308     #ifndef NO_RSA
43309         if (pkey->type == EVP_PKEY_RSA) {
43310             type = RSA_TYPE;
43311             key = pkey->rsa->internal;
43312         }
43313     #endif
43314     #ifdef HAVE_ECC
43315         if (pkey->type == EVP_PKEY_EC) {
43316             type = ECC_TYPE;
43317             key = pkey->ecc->internal;
43318         }
43319     #endif
43320 
43321         /* Sign the certificate (request) body. */
43322         ret = wc_InitRng(&rng);
43323         if (ret != 0)
43324             return ret;
43325         ret = wc_SignCert_ex(certBodySz, sigType, der, derSz, type, key, &rng);
43326         wc_FreeRng(&rng);
43327         if (ret < 0) {
43328             WOLFSSL_LEAVE("wolfSSL_X509_resign_cert", ret);
43329             return ret;
43330         }
43331         derSz = ret;
43332 
43333         /* Extract signature from buffer */
43334         {
43335             word32 idx = 0;
43336             int    len = 0;
43337 
43338             /* Read top level sequence */
43339             if (GetSequence(der, &idx, &len, derSz) < 0) {
43340                 WOLFSSL_MSG("GetSequence error");
43341                 return WOLFSSL_FATAL_ERROR;
43342             }
43343             /* Move idx to signature */
43344             idx += certBodySz;
43345             /* Read signature algo sequence */
43346             if (GetSequence(der, &idx, &len, derSz) < 0) {
43347                 WOLFSSL_MSG("GetSequence error");
43348                 return WOLFSSL_FATAL_ERROR;
43349             }
43350             idx += len;
43351             /* Read signature bit string */
43352             if (CheckBitString(der, &idx, &len, derSz, 0, NULL) != 0) {
43353                 WOLFSSL_MSG("CheckBitString error");
43354                 return WOLFSSL_FATAL_ERROR;
43355             }
43356             /* Sanity check */
43357             if (idx + len != (word32)derSz) {
43358                 WOLFSSL_MSG("unexpected asn1 structure");
43359                 return WOLFSSL_FATAL_ERROR;
43360             }
43361             x509->sig.length = 0;
43362             if (x509->sig.buffer)
43363                 XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE);
43364             x509->sig.buffer = (byte*)XMALLOC(len, x509->heap,
43365                                               DYNAMIC_TYPE_SIGNATURE);
43366             if (!x509->sig.buffer) {
43367                 WOLFSSL_MSG("malloc error");
43368                 return WOLFSSL_FATAL_ERROR;
43369             }
43370             XMEMCPY(x509->sig.buffer, der + idx, len);
43371             x509->sig.length = len;
43372         }
43373 
43374         /* Put in the new certificate encoding into the x509 object. */
43375         FreeDer(&x509->derCert);
43376         type = CERT_TYPE;
43377     #ifdef WOLFSSL_CERT_REQ
43378         if (req) {
43379             type = CERTREQ_TYPE;
43380         }
43381     #endif
43382         if (AllocDer(&x509->derCert, derSz, type, NULL) != 0)
43383             return WOLFSSL_FATAL_ERROR;
43384         XMEMCPY(x509->derCert->buffer, der, derSz);
43385         x509->derCert->length = derSz;
43386 
43387         return ret;
43388     }
43389 
43390 
43391     #ifndef WC_MAX_X509_GEN
43392         /* able to override max size until dynamic buffer created */
43393         #define WC_MAX_X509_GEN 4096
43394     #endif
43395 
43396     /* returns the size of signature on success */
wolfSSL_X509_sign(WOLFSSL_X509 * x509,WOLFSSL_EVP_PKEY * pkey,const WOLFSSL_EVP_MD * md)43397     int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
43398             const WOLFSSL_EVP_MD* md)
43399     {
43400         int  ret;
43401         /* @TODO dynamic set based on expected cert size */
43402         byte *der = (byte *)XMALLOC(WC_MAX_X509_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43403         int  derSz = WC_MAX_X509_GEN;
43404 
43405         WOLFSSL_ENTER("wolfSSL_X509_sign");
43406 
43407         if (x509 == NULL || pkey == NULL || md == NULL) {
43408             ret = WOLFSSL_FAILURE;
43409             goto out;
43410         }
43411 
43412         x509->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
43413         if ((ret = wolfssl_x509_make_der(x509, 0, der, &derSz, 0)) !=
43414                 WOLFSSL_SUCCESS) {
43415             WOLFSSL_MSG("Unable to make DER for X509");
43416             WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
43417             (void)ret;
43418             ret = WOLFSSL_FAILURE;
43419             goto out;
43420         }
43421 
43422         ret = wolfSSL_X509_resign_cert(x509, 0, der, WC_MAX_X509_GEN, derSz,
43423                 (WOLFSSL_EVP_MD*)md, pkey);
43424         if (ret <= 0) {
43425             WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
43426             ret = WOLFSSL_FAILURE;
43427             goto out;
43428         }
43429 
43430     out:
43431         if (der)
43432             XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43433 
43434         return ret;
43435     }
43436 
43437 #if defined(OPENSSL_EXTRA)
wolfSSL_X509_sign_ctx(WOLFSSL_X509 * x509,WOLFSSL_EVP_MD_CTX * ctx)43438     int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ctx)
43439     {
43440         WOLFSSL_ENTER("wolfSSL_X509_sign_ctx");
43441 
43442         if (!x509 || !ctx || !ctx->pctx || !ctx->pctx->pkey) {
43443             WOLFSSL_MSG("Bad parameter");
43444             return WOLFSSL_FAILURE;
43445         }
43446 
43447         return wolfSSL_X509_sign(x509, ctx->pctx->pkey, wolfSSL_EVP_MD_CTX_md(ctx));
43448     }
43449 #endif /* OPENSSL_EXTRA */
43450 
43451 /* Guarded by either
43452  * A) WOLFSSL_WPAS_SMALL is on or
43453  * B) (OPENSSL_EXTRA or OPENSSL_EXTRA_X509_SMALL) + WOLFSSL_CERT_GEN +
43454  *    (WOLFSSL_CERT_REQ or WOLFSSL_CERT_EXT or OPENSSL_EXTRA) has been
43455  *    defined
43456  */
43457 #if defined(WOLFSSL_WPAS_SMALL) || \
43458     (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
43459     defined(WOLFSSL_CERT_GEN) && \
43460     (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
43461      defined(OPENSSL_EXTRA))
43462 /* Converts from NID_* value to wolfSSL value if needed.
43463  *
43464  * @param [in] nid  Numeric Id of a domain name component.
43465  * @return  Domain name tag values - wolfSSL internal values.
43466  * @return  -1 when nid isn't known.
43467  */
ConvertNIDToWolfSSL(int nid)43468 static int ConvertNIDToWolfSSL(int nid)
43469 {
43470     switch (nid) {
43471         case NID_commonName : return ASN_COMMON_NAME;
43472         case NID_surname :    return ASN_SUR_NAME;
43473         case NID_countryName: return ASN_COUNTRY_NAME;
43474         case NID_localityName: return ASN_LOCALITY_NAME;
43475         case NID_stateOrProvinceName: return ASN_STATE_NAME;
43476         case NID_streetAddress: return ASN_STREET_ADDR;
43477         case NID_organizationName: return ASN_ORG_NAME;
43478         case NID_organizationalUnitName: return ASN_ORGUNIT_NAME;
43479         case NID_emailAddress: return ASN_EMAIL_NAME;
43480         case NID_serialNumber: return ASN_SERIAL_NUMBER;
43481         case NID_businessCategory: return ASN_BUS_CAT;
43482         case NID_domainComponent: return ASN_DOMAIN_COMPONENT;
43483         case NID_postalCode: return ASN_POSTAL_CODE;
43484         default:
43485             WOLFSSL_MSG("Attribute NID not found");
43486             return -1;
43487     }
43488 }
43489 
43490 #if defined(OPENSSL_ALL)
43491 /* Convert ASN1 input string into canonical ASN1 string                     */
43492 /*  , which has the following rules:                                        */
43493 /*   convert to UTF8                                                        */
43494 /*   convert to lower case                                                  */
43495 /*   multi-spaces collapsed                                                 */
43496 /* @param  asn_out a pointer to ASN1_STRING to be converted                 */
43497 /* @param  asn_in  a pointer to input ASN1_STRING                           */
43498 /* @return WOLFSSL_SUCCESS on successful converted, otherwise <=0 error code*/
wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING * asn_out,const WOLFSSL_ASN1_STRING * asn_in)43499 static int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out,
43500                                         const WOLFSSL_ASN1_STRING* asn_in)
43501 {
43502     char* dst;
43503     char* src;
43504     int i, len;
43505 
43506     WOLFSSL_ENTER("wolfSSL_ASN1_STRING_canon");
43507 
43508     /* sanity check */
43509     if (asn_out == NULL || asn_in == NULL) {
43510         WOLFSSL_MSG("invalid function arguments");
43511         return BAD_FUNC_ARG;
43512     }
43513 
43514     switch (asn_in->type) {
43515         case MBSTRING_UTF8:
43516         case V_ASN1_PRINTABLESTRING:
43517              break;
43518         default:
43519            WOLFSSL_MSG("just copy string");
43520            return wolfSSL_ASN1_STRING_copy(asn_out, asn_in);
43521     }
43522     /* type is set as UTF8 */
43523     asn_out->type = MBSTRING_UTF8;
43524     asn_out->length = wolfSSL_ASN1_STRING_to_UTF8(
43525         (unsigned char**)&asn_out->data, (WOLFSSL_ASN1_STRING*)asn_in);
43526 
43527     if (asn_out->length < 0) {
43528         return WOLFSSL_FAILURE;
43529     }
43530     /* point to the last */
43531     dst = asn_out->data + asn_out->length;
43532     /* point to the start */
43533     src = asn_out->data;
43534 
43535     len = asn_out->length;
43536 
43537     /* trimming spaces at the head and tail */
43538     dst--;
43539     for (; (len > 0 && XISSPACE(*dst)); len--) {
43540         dst--;
43541     }
43542     for (; (len > 0 && XISSPACE(*src)); len--) {
43543         src++;
43544     }
43545 
43546     /* point to the start */
43547     dst = asn_out->data;
43548 
43549     for (i = 0; i < len; dst++, i++) {
43550         if (!XISASCII(*src)) {
43551             /* keep non-ascii code */
43552             *dst = *src++;
43553         } else if (XISSPACE(*src)) {
43554             *dst = 0x20; /* space */
43555             /* remove the rest of spaces */
43556             while (XISSPACE(*++src) && i++ < len);
43557         } else {
43558             *dst = XTOLOWER(*src++);
43559         }
43560     }
43561     /* put actual length */
43562     asn_out->length = (int)(dst - asn_out->data);
43563     return WOLFSSL_SUCCESS;
43564 }
43565 
43566 /* This is to convert the x509 name structure into canonical DER format     */
43567 /*  , which has the following rules:                                        */
43568 /*   convert to UTF8                                                        */
43569 /*   convert to lower case                                                  */
43570 /*   multi-spaces collapsed                                                 */
43571 /*   leading SEQUENCE hader is skipped                                      */
43572 /* @param  name a pointer to X509_NAME that is to be converted              */
43573 /* @param  out  a pointer to conveted data                                  */
43574 /* @return a number of converted bytes, otherwise <=0 error code            */
wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME * name,unsigned char ** out)43575 int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out)
43576 {
43577     int  totalBytes = 0, i, idx;
43578     byte *output, *local = NULL;
43579 #ifdef WOLFSSL_SMALL_STACK
43580     EncodedName* names = NULL;
43581 #else
43582     EncodedName  names[MAX_NAME_ENTRIES];
43583 #endif
43584 
43585     if (out == NULL || name == NULL)
43586         return BAD_FUNC_ARG;
43587 
43588 #ifdef WOLFSSL_SMALL_STACK
43589     names = (EncodedName*)XMALLOC(sizeof(EncodedName) * MAX_NAME_ENTRIES, NULL,
43590                                                        DYNAMIC_TYPE_TMP_BUFFER);
43591     if (names == NULL)
43592         return MEMORY_E;
43593 #endif
43594 
43595     XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
43596 
43597     for (i = 0; i < MAX_NAME_ENTRIES; i++) {
43598         WOLFSSL_X509_NAME_ENTRY* entry;
43599         int ret;
43600 
43601         entry = wolfSSL_X509_NAME_get_entry(name, i);
43602         if (entry != NULL && entry->set >= 1) {
43603             const char* nameStr;
43604             WOLFSSL_ASN1_STRING* data;
43605             WOLFSSL_ASN1_STRING* cano_data;
43606 
43607             cano_data = wolfSSL_ASN1_STRING_new();
43608             if (cano_data == NULL) {
43609                 #ifdef WOLFSSL_SMALL_STACK
43610                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43611                 #endif
43612                 return MEMORY_E;
43613             }
43614 
43615             data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
43616             if (data == NULL) {
43617             #ifdef WOLFSSL_SMALL_STACK
43618                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43619             #endif
43620                 wolfSSL_ASN1_STRING_free(cano_data);
43621                 WOLFSSL_MSG("Error getting entry data");
43622                 return WOLFSSL_FATAL_ERROR;
43623             }
43624             if (wolfSSL_ASN1_STRING_canon(cano_data, data) != WOLFSSL_SUCCESS) {
43625                 return WOLFSSL_FAILURE;
43626             }
43627             nameStr = (const char*)wolfSSL_ASN1_STRING_data(cano_data);
43628 
43629             ret = wc_EncodeNameCanonical(&names[i], nameStr, CTC_UTF8,
43630                 ConvertNIDToWolfSSL(entry->nid));
43631             if (ret < 0) {
43632             #ifdef WOLFSSL_SMALL_STACK
43633                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43634             #endif
43635                 wolfSSL_ASN1_STRING_free(cano_data);
43636                 WOLFSSL_MSG("EncodeName failed");
43637                 return WOLFSSL_FATAL_ERROR;
43638             }
43639             totalBytes += ret;
43640             wolfSSL_OPENSSL_free(cano_data->data);
43641             wolfSSL_ASN1_STRING_free(cano_data);
43642         }
43643     }
43644 
43645     /* skip header */
43646     /* check if using buffer passed in */
43647     if (*out == NULL) {
43648         *out = local = (unsigned char*)XMALLOC(totalBytes, NULL,
43649                 DYNAMIC_TYPE_OPENSSL);
43650         if (*out == NULL) {
43651             return MEMORY_E;
43652         }
43653     }
43654     output = *out;
43655     idx = 0;
43656 
43657     for (i = 0; i < MAX_NAME_ENTRIES; i++) {
43658         if (names[i].used) {
43659             XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
43660             idx += names[i].totalLen;
43661         }
43662     }
43663 
43664 #ifdef WOLFSSL_SMALL_STACK
43665     XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43666 #endif
43667 
43668     /* used existing buffer passed in, so increment pointer */
43669     if (local == NULL) {
43670         *out += totalBytes;
43671     }
43672     return totalBytes;
43673 }
43674 #endif /* OPENSSL_ALL */
43675 
43676 /* Converts the x509 name structure into DER format.
43677  *
43678  * out  pointer to either a pre setup buffer or a pointer to null for
43679  *      creating a dynamic buffer. In the case that a pre-existing buffer is
43680  *      used out will be incremented the size of the DER buffer on success.
43681  *
43682  * returns the size of the buffer on success, or negative value with failure
43683  */
wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME * name,unsigned char ** out)43684 int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out)
43685 {
43686     int  totalBytes = 0, i, idx;
43687     byte temp[MAX_SEQ_SZ];
43688     byte *output, *local = NULL;
43689 #ifdef WOLFSSL_SMALL_STACK
43690     EncodedName* names = NULL;
43691 #else
43692     EncodedName  names[MAX_NAME_ENTRIES];
43693 #endif
43694 
43695     if (out == NULL || name == NULL)
43696         return BAD_FUNC_ARG;
43697 
43698 #ifdef WOLFSSL_SMALL_STACK
43699     names = (EncodedName*)XMALLOC(sizeof(EncodedName) * MAX_NAME_ENTRIES, NULL,
43700                                                        DYNAMIC_TYPE_TMP_BUFFER);
43701     if (names == NULL)
43702         return MEMORY_E;
43703 #endif
43704 
43705     XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
43706 
43707     for (i = 0; i < MAX_NAME_ENTRIES; i++) {
43708         WOLFSSL_X509_NAME_ENTRY* entry;
43709         int ret;
43710 
43711         entry = wolfSSL_X509_NAME_get_entry(name, i);
43712         if (entry != NULL && entry->set >= 1) {
43713             const char* nameStr;
43714             int type;
43715             WOLFSSL_ASN1_STRING* data;
43716 
43717             data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
43718             if (data == NULL) {
43719             #ifdef WOLFSSL_SMALL_STACK
43720                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43721             #endif
43722                 WOLFSSL_MSG("Error getting entry data");
43723                 return WOLFSSL_FATAL_ERROR;
43724             }
43725 
43726             nameStr = (const char*)wolfSSL_ASN1_STRING_data(data);
43727             type    = wolfSSL_ASN1_STRING_type(data);
43728 
43729             switch (type) {
43730                 case MBSTRING_UTF8:
43731                     type = CTC_UTF8;
43732                     break;
43733                 case V_ASN1_PRINTABLESTRING:
43734                     type = CTC_PRINTABLE;
43735                     break;
43736                 default:
43737                     WOLFSSL_MSG("Unknown encoding type conversion UTF8 by default");
43738                     type = CTC_UTF8;
43739             }
43740             ret = wc_EncodeName(&names[i], nameStr, type,
43741                 ConvertNIDToWolfSSL(entry->nid));
43742             if (ret < 0) {
43743             #ifdef WOLFSSL_SMALL_STACK
43744                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43745             #endif
43746                 WOLFSSL_MSG("EncodeName failed");
43747                 return WOLFSSL_FATAL_ERROR;
43748             }
43749             totalBytes += ret;
43750         }
43751     }
43752 
43753     /* header */
43754     idx = SetSequence(totalBytes, temp);
43755     if (totalBytes + idx > ASN_NAME_MAX) {
43756 #ifdef WOLFSSL_SMALL_STACK
43757         XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43758 #endif
43759         WOLFSSL_MSG("Total Bytes is greater than ASN_NAME_MAX");
43760         return BUFFER_E;
43761     }
43762 
43763     /* check if using buffer passed in */
43764     if (*out == NULL) {
43765         *out = local = (unsigned char*)XMALLOC(totalBytes + idx, NULL,
43766                 DYNAMIC_TYPE_OPENSSL);
43767         if (*out == NULL) {
43768             return MEMORY_E;
43769         }
43770     }
43771 
43772     /* header */
43773     idx = SetSequence(totalBytes, temp);
43774     if (totalBytes + idx > ASN_NAME_MAX) {
43775 #ifdef WOLFSSL_SMALL_STACK
43776         XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43777 #endif
43778         WOLFSSL_MSG("Total Bytes is greater than ASN_NAME_MAX");
43779         return BUFFER_E;
43780     }
43781 
43782     /* check if using buffer passed in */
43783     if (*out == NULL) {
43784         *out = local = (unsigned char*)XMALLOC(totalBytes + idx, name->heap,
43785                 DYNAMIC_TYPE_OPENSSL);
43786         if (*out == NULL) {
43787             return MEMORY_E;
43788         }
43789     }
43790     output = *out;
43791 
43792     idx = SetSequence(totalBytes, output);
43793     totalBytes += idx;
43794     for (i = 0; i < MAX_NAME_ENTRIES; i++) {
43795         if (names[i].used) {
43796             XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
43797             idx += names[i].totalLen;
43798         }
43799     }
43800 
43801 #ifdef WOLFSSL_SMALL_STACK
43802     XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
43803 #endif
43804 
43805     /* used existing buffer passed in, so increment pointer */
43806     if (local == NULL) {
43807         *out += totalBytes;
43808     }
43809     return totalBytes;
43810 }
43811 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
43812 #endif /* WOLFSSL_CERT_GEN */
43813 
43814 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
43815 
wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME ** name,unsigned char ** in,long length)43816     WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name,
43817                                              unsigned char **in, long length)
43818     {
43819         WOLFSSL_X509_NAME* tmp = NULL;
43820         DecodedCert cert;
43821 
43822         WOLFSSL_ENTER("wolfSSL_d2i_X509_NAME");
43823 
43824         if (!in || !*in || length <= 0) {
43825             WOLFSSL_MSG("Bad argument");
43826             return NULL;
43827         }
43828 
43829         /* Set the X509_NAME buffer as the input data for cert.
43830          * in is NOT a full certificate. Just the name. */
43831         InitDecodedCert(&cert, *in, (word32)length, NULL);
43832 
43833         /* Parse the X509 subject name */
43834         if (GetName(&cert, SUBJECT, (int)length) != 0) {
43835             WOLFSSL_MSG("WOLFSSL_X509_NAME parse error");
43836             goto cleanup;
43837         }
43838 
43839         if (!(tmp = wolfSSL_X509_NAME_new())) {
43840             WOLFSSL_MSG("wolfSSL_X509_NAME_new error");
43841             goto cleanup;
43842         }
43843 
43844         if (wolfSSL_X509_NAME_copy((WOLFSSL_X509_NAME*)cert.subjectName,
43845                     tmp) != WOLFSSL_SUCCESS) {
43846             wolfSSL_X509_NAME_free(tmp);
43847             tmp = NULL;
43848             goto cleanup;
43849         }
43850 
43851         if (name)
43852             *name = tmp;
43853 cleanup:
43854         FreeDecodedCert(&cert);
43855         return tmp;
43856     }
43857 
43858 
43859     /* Compares the two X509 names. If the size of x is larger then y then a
43860      * positive value is returned if x is smaller a negative value is returned.
43861      * In the case that the sizes are equal a the value of strcmp between the
43862      * two names is returned.
43863      *
43864      * x First name for comparison
43865      * y Second name to compare with x
43866      */
wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME * x,const WOLFSSL_X509_NAME * y)43867     int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x,
43868             const WOLFSSL_X509_NAME* y)
43869     {
43870         const char* _x;
43871         const char* _y;
43872         WOLFSSL_ENTER("wolfSSL_X509_NAME_cmp");
43873 
43874         if (x == NULL || y == NULL) {
43875             WOLFSSL_MSG("Bad argument passed in");
43876             return -2;
43877         }
43878 
43879         if (x == y) {
43880             return 0; /* match */
43881         }
43882 
43883         if (x->sz != y->sz) {
43884             return x->sz - y->sz;
43885         }
43886 
43887         /*
43888          * If the name member is not set or is immediately null terminated then
43889          * compare the staticName member
43890          */
43891         _x = (x->name && *x->name) ? x->name : x->staticName;
43892         _y = (y->name && *y->name) ? y->name : y->staticName;
43893 
43894         return XSTRNCMP(_x, _y, x->sz); /* y sz is the same */
43895     }
43896 
43897 #ifndef NO_BIO
43898 
loadX509orX509REQFromPemBio(WOLFSSL_BIO * bp,WOLFSSL_X509 ** x,wc_pem_password_cb * cb,void * u,int type)43899     static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
43900             WOLFSSL_X509 **x, wc_pem_password_cb *cb, void *u, int type)
43901     {
43902         WOLFSSL_X509* x509 = NULL;
43903 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
43904         unsigned char* pem = NULL;
43905         int pemSz;
43906         long  i = 0, l, footerSz;
43907         const char* footer = NULL;
43908 
43909         WOLFSSL_ENTER("loadX509orX509REQFromPemBio");
43910 
43911         if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE)) {
43912             WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG);
43913             return NULL;
43914         }
43915 
43916         if ((l = wolfSSL_BIO_get_len(bp)) <= 0) {
43917     #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
43918             /* No certificate in buffer */
43919             WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
43920     #endif
43921             return NULL;
43922         }
43923 
43924         pemSz = (int)l;
43925         pem   = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
43926         if (pem == NULL)
43927             return NULL;
43928         XMEMSET(pem, 0, pemSz);
43929 
43930         i = 0;
43931         if (wc_PemGetHeaderFooter(type, NULL, &footer) != 0) {
43932             XFREE(pem, 0, DYNAMIC_TYPE_PEM);
43933             return NULL;
43934         }
43935         footerSz = (long)XSTRLEN(footer);
43936 
43937         /* TODO: Inefficient
43938          * reading in one byte at a time until see the footer
43939          */
43940         while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
43941             i++;
43942             if (i > footerSz && XMEMCMP((char *)&pem[i-footerSz], footer,
43943                     footerSz) == 0) {
43944                 if (wolfSSL_BIO_read(bp, (char *)&pem[i], 1) == 1) {
43945                     /* attempt to read newline following footer */
43946                     i++;
43947                     if (pem[i-1] == '\r') {
43948                         /* found \r , Windows line ending is \r\n so try to read one
43949                          * more byte for \n, ignoring return value */
43950                         (void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1);
43951                     }
43952                 }
43953                 break;
43954             }
43955         }
43956     #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
43957         if (l == 0)
43958             WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
43959     #else
43960         (void)l;
43961     #endif
43962         if (i > pemSz) {
43963             WOLFSSL_MSG("Error parsing PEM");
43964         }
43965         else {
43966             pemSz = (int)i;
43967         #ifdef WOLFSSL_CERT_REQ
43968             if (type == CERTREQ_TYPE)
43969                 x509 = wolfSSL_X509_REQ_load_certificate_buffer(pem, pemSz,
43970                                                           WOLFSSL_FILETYPE_PEM);
43971             else
43972         #endif
43973                 x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz,
43974                                                           WOLFSSL_FILETYPE_PEM);
43975         }
43976 
43977         if (x != NULL) {
43978             *x = x509;
43979         }
43980 
43981         XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
43982 
43983 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
43984         (void)bp;
43985         (void)x;
43986         (void)cb;
43987         (void)u;
43988 
43989         return x509;
43990     }
43991 
43992 
wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO * bp,WOLFSSL_X509 ** x,wc_pem_password_cb * cb,void * u)43993     WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
43994                                             wc_pem_password_cb *cb, void *u)
43995     {
43996         return loadX509orX509REQFromPemBio(bp, x, cb, u, CERT_TYPE);
43997     }
43998 
43999 #ifdef WOLFSSL_CERT_REQ
wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO * bp,WOLFSSL_X509 ** x,wc_pem_password_cb * cb,void * u)44000     WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
44001                                                 wc_pem_password_cb *cb, void *u)
44002     {
44003         return loadX509orX509REQFromPemBio(bp, x, cb, u, CERTREQ_TYPE);
44004     }
44005 
44006 #ifndef NO_FILESYSTEM
wolfSSL_PEM_read_X509_REQ(XFILE fp,WOLFSSL_X509 ** x,wc_pem_password_cb * cb,void * u)44007     WOLFSSL_X509* wolfSSL_PEM_read_X509_REQ(XFILE fp, WOLFSSL_X509** x,
44008                                             wc_pem_password_cb* cb, void* u)
44009     {
44010         int err = 0;
44011         WOLFSSL_X509* ret = NULL;
44012         WOLFSSL_BIO* bio = NULL;
44013 
44014         WOLFSSL_ENTER("wolfSSL_PEM_read_X509_REQ");
44015 
44016         if (fp == XBADFILE) {
44017             WOLFSSL_MSG("Invalid file.");
44018             err = 1;
44019         }
44020 
44021         if (err == 0) {
44022             bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
44023             if (bio == NULL) {
44024                 WOLFSSL_MSG("Failed to create new BIO with input file.");
44025                 err = 1;
44026             }
44027         }
44028         if (err == 0 && wolfSSL_BIO_set_fp(bio, fp, BIO_CLOSE)
44029                 != WOLFSSL_SUCCESS) {
44030             WOLFSSL_MSG("Failed to set BIO file pointer.");
44031             err = 1;
44032         }
44033         if (err == 0) {
44034             ret = wolfSSL_PEM_read_bio_X509_REQ(bio, x, cb, u);
44035         }
44036 
44037         if (bio != NULL) {
44038             wolfSSL_BIO_free(bio);
44039         }
44040 
44041         return ret;
44042     }
44043 #endif /* !NO_FILESYSTEM */
44044 #endif /* WOLFSSL_CERT_REQ */
44045 
wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO * bp,WOLFSSL_X509_CRL ** x,wc_pem_password_cb * cb,void * u)44046     WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp,
44047             WOLFSSL_X509_CRL **x, wc_pem_password_cb *cb, void *u)
44048     {
44049 #if defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_CRL)
44050         unsigned char* pem = NULL;
44051         int pemSz;
44052         int derSz;
44053         DerBuffer* der = NULL;
44054         WOLFSSL_X509_CRL* crl = NULL;
44055 
44056         if ((pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
44057             goto err;
44058         }
44059 
44060         pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
44061         if (pem == NULL) {
44062             goto err;
44063         }
44064 
44065         if (wolfSSL_BIO_read(bp, pem, pemSz) != pemSz) {
44066             goto err;
44067         }
44068 
44069         if((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0) {
44070             goto err;
44071         }
44072         derSz = der->length;
44073         if((crl = wolfSSL_d2i_X509_CRL(x, der->buffer, derSz)) == NULL) {
44074             goto err;
44075         }
44076 
44077 err:
44078         if(pem != NULL) {
44079             XFREE(pem, 0, DYNAMIC_TYPE_PEM);
44080         }
44081         if(der != NULL) {
44082             FreeDer(&der);
44083         }
44084 
44085         (void)cb;
44086         (void)u;
44087 
44088         return crl;
44089 #else
44090         (void)bp;
44091         (void)x;
44092         (void)cb;
44093         (void)u;
44094 
44095         return NULL;
44096 #endif
44097     }
44098 
44099 #endif /* !NO_BIO */
44100 
44101 #if !defined(NO_FILESYSTEM)
wolfSSL_PEM_read_X509_ex(XFILE fp,void ** x,wc_pem_password_cb * cb,void * u,int type)44102     static void* wolfSSL_PEM_read_X509_ex(XFILE fp, void **x,
44103         wc_pem_password_cb *cb, void *u, int type)
44104     {
44105         unsigned char* pem = NULL;
44106         int pemSz;
44107         long i = 0, l;
44108         void *newx509;
44109         int derSz;
44110         DerBuffer* der = NULL;
44111 
44112         WOLFSSL_ENTER("wolfSSL_PEM_read_X509");
44113 
44114         if (fp == XBADFILE) {
44115             WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
44116             return NULL;
44117         }
44118         /* Read cert from file */
44119         i = XFTELL(fp);
44120         if (i < 0) {
44121             WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
44122             return NULL;
44123         }
44124 
44125         if (XFSEEK(fp, 0, XSEEK_END) != 0)
44126             return NULL;
44127         l = XFTELL(fp);
44128         if (l < 0)
44129             return NULL;
44130         if (XFSEEK(fp, i, SEEK_SET) != 0)
44131             return NULL;
44132         pemSz = (int)(l - i);
44133 
44134         /* check calculated length */
44135         if (pemSz > MAX_WOLFSSL_FILE_SIZE || pemSz < 0) {
44136             WOLFSSL_MSG("PEM_read_X509_ex file size error");
44137             return NULL;
44138         }
44139 
44140         /* allocate pem buffer */
44141         pem = (unsigned char*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_PEM);
44142         if (pem == NULL)
44143             return NULL;
44144 
44145         if ((int)XFREAD((char *)pem, 1, pemSz, fp) != pemSz)
44146             goto err_exit;
44147 
44148         switch (type) {
44149             case CERT_TYPE:
44150                 newx509 = (void *)wolfSSL_X509_load_certificate_buffer(pem,
44151                     pemSz, WOLFSSL_FILETYPE_PEM);
44152                 break;
44153 
44154         #ifdef HAVE_CRL
44155             case CRL_TYPE:
44156                 if ((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0)
44157                     goto err_exit;
44158                 derSz = der->length;
44159                 newx509 = (void*)wolfSSL_d2i_X509_CRL((WOLFSSL_X509_CRL **)x,
44160                     (const unsigned char *)der->buffer, derSz);
44161                 if (newx509 == NULL)
44162                     goto err_exit;
44163                 FreeDer(&der);
44164                 break;
44165         #endif
44166 
44167             default:
44168                 goto err_exit;
44169         }
44170         if (x != NULL) {
44171             *x = newx509;
44172         }
44173         XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
44174         return newx509;
44175 
44176     err_exit:
44177         if (pem != NULL)
44178             XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
44179         if (der != NULL)
44180             FreeDer(&der);
44181 
44182         /* unused */
44183         (void)cb;
44184         (void)u;
44185         (void)derSz;
44186 
44187         return NULL;
44188     }
44189 
wolfSSL_PEM_read_X509(XFILE fp,WOLFSSL_X509 ** x,wc_pem_password_cb * cb,void * u)44190     WOLFSSL_API WOLFSSL_X509* wolfSSL_PEM_read_X509(XFILE fp, WOLFSSL_X509 **x,
44191                                                     wc_pem_password_cb *cb,
44192                                                     void *u)
44193     {
44194         return (WOLFSSL_X509* )wolfSSL_PEM_read_X509_ex(fp, (void **)x, cb, u, CERT_TYPE);
44195     }
44196 
44197 #ifndef NO_BIO
wolfSSL_PEM_read_PrivateKey(XFILE fp,WOLFSSL_EVP_PKEY ** x,wc_pem_password_cb * cb,void * u)44198     WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp,
44199         WOLFSSL_EVP_PKEY **x, wc_pem_password_cb *cb, void *u)
44200     {
44201         int err = 0;
44202         WOLFSSL_EVP_PKEY* ret = NULL;
44203         WOLFSSL_BIO* bio = NULL;
44204 
44205         WOLFSSL_ENTER("wolfSSL_PEM_read_PrivateKey");
44206 
44207         if (fp == XBADFILE) {
44208             err = 1;
44209         }
44210         if (err == 0) {
44211             bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
44212             err = bio == NULL;
44213         }
44214         if (err == 0) {
44215             err = wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS;
44216         }
44217         if (err == 0) {
44218             ret = wolfSSL_PEM_read_bio_PrivateKey(bio, x, cb, u);
44219         }
44220 
44221         if (bio != NULL) {
44222             wolfSSL_BIO_free(bio);
44223         }
44224 
44225         return ret;
44226     }
44227 #endif
44228 
44229 #if defined(HAVE_CRL)
wolfSSL_PEM_read_X509_CRL(XFILE fp,WOLFSSL_X509_CRL ** crl,wc_pem_password_cb * cb,void * u)44230     WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp, WOLFSSL_X509_CRL **crl,
44231                                                     wc_pem_password_cb *cb, void *u)
44232     {
44233         return (WOLFSSL_X509_CRL* )wolfSSL_PEM_read_X509_ex(fp, (void **)crl, cb, u, CRL_TYPE);
44234     }
44235 #endif
44236 
44237 #ifdef WOLFSSL_CERT_GEN
44238 #ifndef NO_BIO
wolfSSL_PEM_write_X509(XFILE fp,WOLFSSL_X509 * x)44239     int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509* x)
44240     {
44241         int ret;
44242         WOLFSSL_BIO* bio;
44243 
44244         if (x == NULL)
44245             return 0;
44246 
44247         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
44248         if (bio == NULL)
44249             return 0;
44250 
44251         if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
44252             wolfSSL_BIO_free(bio);
44253             bio = NULL;
44254         }
44255 
44256         ret = wolfSSL_PEM_write_bio_X509(bio, x);
44257 
44258         if (bio != NULL)
44259             wolfSSL_BIO_free(bio);
44260 
44261         return ret;
44262     }
44263 #endif /* !NO_BIO */
44264 #endif /* WOLFSSL_CERT_GEN */
44265 #endif /* !NO_FILESYSTEM */
44266 
44267     #define PEM_BEGIN              "-----BEGIN "
44268     #define PEM_BEGIN_SZ           11
44269     #define PEM_END                "-----END "
44270     #define PEM_END_SZ             9
44271     #define PEM_HDR_FIN            "-----"
44272     #define PEM_HDR_FIN_SZ         5
44273     #define PEM_HDR_FIN_EOL_NEWLINE   "-----\n"
44274     #define PEM_HDR_FIN_EOL_NULL_TERM "-----\0"
44275     #define PEM_HDR_FIN_EOL_SZ     6
44276 
44277 #ifndef NO_BIO
44278 
wolfSSL_PEM_read_bio(WOLFSSL_BIO * bio,char ** name,char ** header,unsigned char ** data,long * len)44279     int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header,
44280                              unsigned char **data, long *len)
44281     {
44282         int ret = WOLFSSL_SUCCESS;
44283         char pem[256];
44284         int pemLen;
44285         char* p;
44286         char* nameStr = NULL;
44287         int nameLen = 0;
44288         char* headerStr = NULL;
44289         int headerLen;
44290         int headerFound = 0;
44291         unsigned char* der = NULL;
44292         word32 derLen = 0;
44293 
44294         if (bio == NULL || name == NULL || header == NULL || data == NULL ||
44295                                                                   len == NULL) {
44296             return WOLFSSL_FAILURE;
44297         }
44298 
44299         /* Find header line. */
44300         pem[sizeof(pem) - 1] = '\0';
44301         while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
44302             if (XSTRNCMP(pem, PEM_BEGIN, PEM_BEGIN_SZ) == 0)
44303                 break;
44304         }
44305         if (pemLen <= 0)
44306             ret = WOLFSSL_FAILURE;
44307         /* Have a header line. */
44308         if (ret == WOLFSSL_SUCCESS) {
44309             while (pem[pemLen - 1] == '\r' || pem[pemLen - 1] == '\n')
44310                 pemLen--;
44311             pem[pemLen] = '\0';
44312             if (XSTRNCMP(pem + pemLen - PEM_HDR_FIN_SZ, PEM_HDR_FIN,
44313                                                          PEM_HDR_FIN_SZ) != 0) {
44314                 ret = WOLFSSL_FAILURE;
44315             }
44316         }
44317 
44318         /* Get out name. */
44319         if (ret == WOLFSSL_SUCCESS) {
44320             nameLen = pemLen - PEM_BEGIN_SZ - PEM_HDR_FIN_SZ;
44321             nameStr = (char*)XMALLOC(nameLen + 1, NULL,
44322                                                        DYNAMIC_TYPE_TMP_BUFFER);
44323             if (nameStr == NULL)
44324                 ret = WOLFSSL_FAILURE;
44325         }
44326         if (ret == WOLFSSL_SUCCESS) {
44327             XSTRNCPY(nameStr, pem + PEM_BEGIN_SZ, nameLen);
44328             nameStr[nameLen] = '\0';
44329 
44330             /* Get header of PEM - encryption header. */
44331             headerLen = 0;
44332             while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
44333                 while (pemLen > 0 && (pem[pemLen - 1] == '\r' ||
44334                                                      pem[pemLen - 1] == '\n')) {
44335                     pemLen--;
44336                 }
44337                 pem[pemLen++] = '\n';
44338                 pem[pemLen] = '\0';
44339 
44340                 /* Header separator is a blank line. */
44341                 if (pem[0] == '\n') {
44342                     headerFound = 1;
44343                     break;
44344                 }
44345 
44346                 /* Didn't find a blank line - no header. */
44347                 if (XSTRNCMP(pem, PEM_END, PEM_END_SZ) == 0) {
44348                     der = (unsigned char*)headerStr;
44349                     derLen = headerLen;
44350                     /* Empty header - empty string. */
44351                     headerStr = (char*)XMALLOC(1, NULL,
44352                                                        DYNAMIC_TYPE_TMP_BUFFER);
44353                     if (headerStr == NULL)
44354                         ret = WOLFSSL_FAILURE;
44355                     else
44356                         headerStr[0] = '\0';
44357                     break;
44358                 }
44359 
44360                 p = (char*)XREALLOC(headerStr, headerLen + pemLen + 1, NULL,
44361                                                        DYNAMIC_TYPE_TMP_BUFFER);
44362                 if (p == NULL) {
44363                     ret = WOLFSSL_FAILURE;
44364                     break;
44365                 }
44366 
44367                 headerStr = p;
44368                 XMEMCPY(headerStr + headerLen, pem, pemLen + 1);
44369                 headerLen += pemLen;
44370             }
44371             if (pemLen <= 0)
44372                 ret = WOLFSSL_FAILURE;
44373         }
44374 
44375         /* Get body of PEM - if there was a header */
44376         if (ret == WOLFSSL_SUCCESS && headerFound) {
44377             derLen = 0;
44378             while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
44379                 while (pemLen > 0 && (pem[pemLen - 1] == '\r' ||
44380                                                      pem[pemLen - 1] == '\n')) {
44381                     pemLen--;
44382                 }
44383                 pem[pemLen++] = '\n';
44384                 pem[pemLen] = '\0';
44385 
44386                 if (XSTRNCMP(pem, PEM_END, PEM_END_SZ) == 0)
44387                     break;
44388 
44389                 p = (char*)XREALLOC(der, derLen + pemLen + 1, NULL,
44390                                                        DYNAMIC_TYPE_TMP_BUFFER);
44391                 if (p == NULL) {
44392                     ret = WOLFSSL_FAILURE;
44393                     break;
44394                 }
44395 
44396                 der = (unsigned char*)p;
44397                 XMEMCPY(der + derLen, pem, pemLen + 1);
44398                 derLen += pemLen;
44399             }
44400             if (pemLen <= 0)
44401                 ret = WOLFSSL_FAILURE;
44402         }
44403 
44404         /* Check trailer. */
44405         if (ret == WOLFSSL_SUCCESS) {
44406             if (XSTRNCMP(pem + PEM_END_SZ, nameStr, nameLen) != 0)
44407                 ret = WOLFSSL_FAILURE;
44408         }
44409         if (ret == WOLFSSL_SUCCESS) {
44410             if (XSTRNCMP(pem + PEM_END_SZ + nameLen,
44411                     PEM_HDR_FIN_EOL_NEWLINE,
44412                     PEM_HDR_FIN_EOL_SZ) != 0 &&
44413                 XSTRNCMP(pem + PEM_END_SZ + nameLen,
44414                         PEM_HDR_FIN_EOL_NULL_TERM,
44415                         PEM_HDR_FIN_EOL_SZ) != 0) {
44416                 ret = WOLFSSL_FAILURE;
44417             }
44418         }
44419 
44420         /* Base64 decode body. */
44421         if (ret == WOLFSSL_SUCCESS) {
44422             if (Base64_Decode(der, derLen, der, &derLen) != 0)
44423                 ret = WOLFSSL_FAILURE;
44424         }
44425 
44426         if (ret == WOLFSSL_SUCCESS) {
44427             *name = nameStr;
44428             *header = headerStr;
44429             *data = der;
44430             *len = derLen;
44431             nameStr = NULL;
44432             headerStr = NULL;
44433             der = NULL;
44434         }
44435 
44436         if (nameStr != NULL)
44437             XFREE(nameStr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
44438         if (headerStr != NULL)
44439             XFREE(headerStr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
44440         if (der != NULL)
44441             XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
44442 
44443         return ret;
44444     }
44445 
wolfSSL_PEM_write_bio(WOLFSSL_BIO * bio,const char * name,const char * header,const unsigned char * data,long len)44446     int wolfSSL_PEM_write_bio(WOLFSSL_BIO* bio, const char *name,
44447                               const char *header, const unsigned char *data,
44448                               long len)
44449     {
44450         int err = 0;
44451         int outSz = 0;
44452         int nameLen;
44453         int headerLen;
44454         byte* pem = NULL;
44455         word32 pemLen;
44456         word32 derLen = (word32)len;
44457 
44458         if (bio == NULL || name == NULL || header == NULL || data == NULL)
44459             return 0;
44460 
44461         nameLen = (int)XSTRLEN(name);
44462         headerLen = (int)XSTRLEN(header);
44463 
44464         pemLen = (derLen + 2) / 3 * 4;
44465         pemLen += (pemLen + 63) / 64;
44466 
44467         pem = (byte*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
44468         err = pem == NULL;
44469         if (!err)
44470             err = Base64_Encode(data, derLen, pem, &pemLen) != 0;
44471 
44472         if (!err) {
44473             err = wolfSSL_BIO_write(bio, PEM_BEGIN, PEM_BEGIN_SZ) !=
44474                                                               (int)PEM_BEGIN_SZ;
44475         }
44476         if (!err)
44477             err = wolfSSL_BIO_write(bio, name, nameLen) != nameLen;
44478         if (!err) {
44479             err = wolfSSL_BIO_write(bio, PEM_HDR_FIN_EOL_NEWLINE,
44480                     PEM_HDR_FIN_EOL_SZ) != (int)PEM_HDR_FIN_EOL_SZ;
44481         }
44482         if (!err && headerLen > 0) {
44483             err = wolfSSL_BIO_write(bio, header, headerLen) != headerLen;
44484             /* Blank line after a header and before body. */
44485             if (!err)
44486                 err = wolfSSL_BIO_write(bio, "\n", 1) != 1;
44487             headerLen++;
44488         }
44489         if (!err)
44490             err = wolfSSL_BIO_write(bio, pem, pemLen) != (int)pemLen;
44491         if (!err)
44492             err = wolfSSL_BIO_write(bio, PEM_END, PEM_END_SZ) !=
44493                                                                 (int)PEM_END_SZ;
44494         if (!err)
44495             err = wolfSSL_BIO_write(bio, name, nameLen) != nameLen;
44496         if (!err) {
44497             err = wolfSSL_BIO_write(bio, PEM_HDR_FIN_EOL_NEWLINE,
44498                     PEM_HDR_FIN_EOL_SZ) != (int)PEM_HDR_FIN_EOL_SZ;
44499         }
44500 
44501         if (!err) {
44502             outSz = PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ + headerLen +
44503                              pemLen + PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ;
44504         }
44505 
44506         if (pem != NULL)
44507             XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
44508 
44509         return outSz;
44510     }
44511 
44512 #if !defined(NO_FILESYSTEM)
wolfSSL_PEM_read(XFILE fp,char ** name,char ** header,unsigned char ** data,long * len)44513     int wolfSSL_PEM_read(XFILE fp, char **name, char **header,
44514                          unsigned char **data, long *len)
44515     {
44516         int ret;
44517         WOLFSSL_BIO* bio;
44518 
44519         if (name == NULL || header == NULL || data == NULL || len == NULL)
44520             return WOLFSSL_FAILURE;
44521 
44522         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
44523         if (bio == NULL)
44524             return 0;
44525 
44526         if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
44527             wolfSSL_BIO_free(bio);
44528             bio = NULL;
44529         }
44530 
44531         ret = wolfSSL_PEM_read_bio(bio, name, header, data, len);
44532 
44533         if (bio != NULL)
44534             wolfSSL_BIO_free(bio);
44535 
44536         return ret;
44537     }
44538 
wolfSSL_PEM_write(XFILE fp,const char * name,const char * header,const unsigned char * data,long len)44539     int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header,
44540                           const unsigned char *data, long len)
44541     {
44542         int ret;
44543         WOLFSSL_BIO* bio;
44544 
44545         if (name == NULL || header == NULL || data == NULL)
44546             return 0;
44547 
44548         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
44549         if (bio == NULL)
44550             return 0;
44551 
44552         if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
44553             wolfSSL_BIO_free(bio);
44554             bio = NULL;
44555         }
44556 
44557         ret = wolfSSL_PEM_write_bio(bio, name, header, data, len);
44558 
44559         if (bio != NULL)
44560             wolfSSL_BIO_free(bio);
44561 
44562         return ret;
44563     }
44564 #endif
44565 #endif /* !NO_BIO */
44566 
wolfSSL_PEM_get_EVP_CIPHER_INFO(const char * header,EncryptedInfo * cipher)44567     int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header,
44568                                         EncryptedInfo* cipher)
44569     {
44570         if (header == NULL || cipher == NULL)
44571             return WOLFSSL_FAILURE;
44572 
44573         XMEMSET(cipher, 0, sizeof(*cipher));
44574 
44575         if (wc_EncryptedInfoParse(cipher, &header, XSTRLEN(header)) != 0)
44576             return WOLFSSL_FAILURE;
44577 
44578         return WOLFSSL_SUCCESS;
44579     }
44580 
wolfSSL_PEM_do_header(EncryptedInfo * cipher,unsigned char * data,long * len,wc_pem_password_cb * callback,void * ctx)44581     int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data,
44582                               long* len, wc_pem_password_cb* callback,
44583                               void* ctx)
44584     {
44585         int ret = WOLFSSL_SUCCESS;
44586         char password[NAME_SZ];
44587         int passwordSz;
44588 
44589         if (cipher == NULL || data == NULL || len == NULL || callback == NULL)
44590             return WOLFSSL_FAILURE;
44591 
44592         passwordSz = callback(password, sizeof(password), PEM_PASS_READ, ctx);
44593         if (passwordSz < 0)
44594             ret = WOLFSSL_FAILURE;
44595 
44596         if (ret == WOLFSSL_SUCCESS) {
44597             if (wc_BufferKeyDecrypt(cipher, data, (word32)*len, (byte*)password,
44598                                                      passwordSz, WC_MD5) != 0) {
44599                 ret = WOLFSSL_FAILURE;
44600             }
44601         }
44602 
44603         if (passwordSz > 0)
44604             XMEMSET(password, 0, passwordSz);
44605 
44606         return ret;
44607     }
44608 
44609 #ifndef NO_BIO
44610     /*
44611      * bp : bio to read X509 from
44612      * x  : x509 to write to
44613      * cb : password call back for reading PEM
44614      * u  : password
44615      * _AUX is for working with a trusted X509 certificate
44616      */
wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO * bp,WOLFSSL_X509 ** x,wc_pem_password_cb * cb,void * u)44617     WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp,
44618                                WOLFSSL_X509 **x, wc_pem_password_cb *cb,
44619                                void *u)
44620     {
44621         WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
44622 
44623         /* AUX info is; trusted/rejected uses, friendly name, private key id,
44624          * and potentially a stack of "other" info. wolfSSL does not store
44625          * friendly name or private key id yet in WOLFSSL_X509 for human
44626          * readability and does not support extra trusted/rejected uses for
44627          * root CA. */
44628         return wolfSSL_PEM_read_bio_X509(bp, x, cb, u);
44629     }
44630 #endif /* !NO_BIO */
44631 
44632 
44633 #endif /* OPENSSL_EXTRA || OPENSSL_ALL */
44634 #ifdef OPENSSL_ALL
44635 
44636 #ifndef NO_BIO
44637     /* create and return a new WOLFSSL_X509_PKEY structure or NULL on failure */
wolfSSL_X509_PKEY_new(void * heap)44638     static WOLFSSL_X509_PKEY* wolfSSL_X509_PKEY_new(void* heap)
44639     {
44640         WOLFSSL_X509_PKEY* ret;
44641 
44642         ret = (WOLFSSL_X509_PKEY*)XMALLOC(sizeof(WOLFSSL_X509_PKEY), heap,
44643             DYNAMIC_TYPE_KEY);
44644         if (ret != NULL) {
44645             XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PKEY));
44646             ret->heap = heap;
44647         }
44648         return ret;
44649     }
44650 #endif /* !NO_BIO */
44651 
44652 
44653     /* free up all memory used by "xPkey" passed in */
wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY * xPkey)44654     static void wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY* xPkey)
44655     {
44656         if (xPkey != NULL) {
44657             wolfSSL_EVP_PKEY_free(xPkey->dec_pkey);
44658             XFREE(xPkey, xPkey->heap, DYNAMIC_TYPE_KEY);
44659         }
44660     }
44661 
44662 
44663 #ifndef NO_BIO
44664 
44665 #define PEM_COMPARE_HEADER(start, end, header) \
44666         end - start == XSTR_SIZEOF(header) && XMEMCMP(start, header, \
44667                 XSTR_SIZEOF(header)) == 0
44668 
44669     /**
44670      * This read one structure from bio and returns the read structure
44671      * in the appropriate output parameter (x509, crl, x_pkey). The
44672      * output parameters must be set to NULL.
44673      * @param bio    Input for reading structures
44674      * @param cb     Password callback
44675      * @param x509   Output
44676      * @param crl    Output
44677      * @param x_pkey Output
44678      * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE otherwise
44679      */
wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(WOLFSSL_BIO * bio,wc_pem_password_cb * cb,WOLFSSL_X509 ** x509,WOLFSSL_X509_CRL ** crl,WOLFSSL_X509_PKEY ** x_pkey)44680     static int wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(
44681             WOLFSSL_BIO* bio, wc_pem_password_cb* cb, WOLFSSL_X509** x509,
44682             WOLFSSL_X509_CRL** crl, WOLFSSL_X509_PKEY** x_pkey)
44683     {
44684 
44685 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
44686         char* pem = NULL;
44687         long  i = pem_struct_min_sz, l;
44688         const char* header = NULL;
44689         const char* headerEnd = NULL;
44690         const char* footer = NULL;
44691         const char* footerEnd = NULL;
44692     #ifdef HAVE_CRL
44693         DerBuffer* der = NULL;
44694     #endif
44695         WOLFSSL_BIO* pemBio = NULL;
44696 
44697         if (!bio || !x509 || *x509 || !crl || *crl || !x_pkey || *x_pkey) {
44698             WOLFSSL_MSG("Bad input parameter or output parameters "
44699                         "not set to a NULL value.");
44700             return WOLFSSL_FAILURE;
44701         }
44702 
44703         if ((l = wolfSSL_BIO_get_len(bio)) <= 0) {
44704             /* No certificate in buffer */
44705             WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
44706             return WOLFSSL_FAILURE;
44707         }
44708 
44709         pem = (char*)XMALLOC(l, 0, DYNAMIC_TYPE_PEM);
44710         if (pem == NULL)
44711             return WOLFSSL_FAILURE;
44712 
44713         if (wolfSSL_BIO_read(bio, &pem[0], pem_struct_min_sz) !=
44714                 pem_struct_min_sz) {
44715             WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
44716             goto err;
44717         }
44718 
44719         /* Read the header and footer */
44720         while (i < l && wolfSSL_BIO_read(bio, &pem[i], 1) == 1) {
44721             i++;
44722             if (!header) {
44723                 header = XSTRNSTR(pem, "-----BEGIN ", (unsigned int)i);
44724             }
44725             else if (!headerEnd) {
44726                 headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----BEGIN "),
44727                         "-----",
44728                         (unsigned int)
44729                         (i - (header + XSTR_SIZEOF("-----BEGIN ") - pem)));
44730                 if (headerEnd) {
44731                     headerEnd += XSTR_SIZEOF("-----");
44732                     /* Read in the newline */
44733                     if (wolfSSL_BIO_read(bio, &pem[i], 1) != 1) {
44734                         WOLFSSL_MSG("wolfSSL_BIO_read error");
44735                         goto err;
44736                     }
44737                     i++;
44738                     if (*headerEnd != '\n' && *headerEnd != '\r') {
44739                         WOLFSSL_MSG("Missing newline after header");
44740                         goto err;
44741                     }
44742                 }
44743             }
44744             else if (!footer) {
44745                 footer = XSTRNSTR(headerEnd, "-----END ",
44746                         (unsigned int)(i - (headerEnd - pem)));
44747             }
44748             else if (!footerEnd) {
44749                 footerEnd = XSTRNSTR(footer + XSTR_SIZEOF("-----"),
44750                         "-----", (unsigned int)(i -
44751                             (footer + XSTR_SIZEOF("-----") - pem)));
44752                 if (footerEnd) {
44753                     footerEnd += XSTR_SIZEOF("-----");
44754                     /* Now check that footer matches header */
44755                     if ((headerEnd - (header + XSTR_SIZEOF("-----BEGIN "))) ==
44756                         (footerEnd - (footer + XSTR_SIZEOF("-----END "))) &&
44757                         XMEMCMP(header + XSTR_SIZEOF("-----BEGIN "),
44758                                 footer + XSTR_SIZEOF("-----END "),
44759                         headerEnd - (header + XSTR_SIZEOF("-----BEGIN ")))
44760                             != 0) {
44761                         WOLFSSL_MSG("Header and footer don't match");
44762                         goto err;
44763                     }
44764                     /* header and footer match */
44765                     break;
44766                 }
44767             }
44768         }
44769         if (!footerEnd) {
44770             /* Only check footerEnd since it is set last */
44771             WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
44772             goto err;
44773         }
44774         else {
44775             if (PEM_COMPARE_HEADER(header, headerEnd,
44776                     "-----BEGIN CERTIFICATE-----")) {
44777                 /* We have a certificate */
44778                 WOLFSSL_MSG("Parsing x509 cert");
44779                 *x509 = wolfSSL_X509_load_certificate_buffer(
44780                         (const unsigned char*) header,
44781                         (int)(footerEnd - header), WOLFSSL_FILETYPE_PEM);
44782                 if (!*x509) {
44783                     WOLFSSL_MSG("wolfSSL_X509_load_certificate_buffer error");
44784                     goto err;
44785                 }
44786             }
44787     #ifdef HAVE_CRL
44788             else if (PEM_COMPARE_HEADER(header, headerEnd,
44789                         "-----BEGIN X509 CRL-----")) {
44790                 /* We have a crl */
44791                 WOLFSSL_MSG("Parsing crl");
44792                 if((PemToDer((const unsigned char*) header, footerEnd - header,
44793                         CRL_TYPE, &der, NULL, NULL, NULL)) < 0) {
44794                     WOLFSSL_MSG("PemToDer error");
44795                     goto err;
44796                 }
44797                 *crl = wolfSSL_d2i_X509_CRL(NULL, der->buffer, der->length);
44798                 if (!*crl) {
44799                     WOLFSSL_MSG("wolfSSL_d2i_X509_CRL error");
44800                     goto err;
44801                 }
44802             }
44803     #endif
44804             else {
44805                 WOLFSSL_MSG("Parsing x509 key");
44806 
44807                 if (!(*x_pkey = wolfSSL_X509_PKEY_new(NULL))) {
44808                     WOLFSSL_MSG("wolfSSL_X509_PKEY_new error");
44809                     goto err;
44810                 }
44811 
44812                 if (!(pemBio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
44813                     WOLFSSL_MSG("wolfSSL_BIO_new error");
44814                     goto err;
44815                 }
44816 
44817                 if (wolfSSL_BIO_write(pemBio, header,
44818                         (int)(footerEnd - header)) != footerEnd - header) {
44819                     WOLFSSL_MSG("wolfSSL_BIO_new error");
44820                     goto err;
44821                 }
44822 
44823                 if (wolfSSL_PEM_read_bio_PrivateKey(pemBio,
44824                         &(*x_pkey)->dec_pkey, cb, NULL) == NULL) {
44825                     WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey error");
44826                     goto err;
44827                 }
44828 
44829                 wolfSSL_BIO_free(pemBio);
44830             }
44831         }
44832 
44833         XFREE(pem, 0, DYNAMIC_TYPE_PEM);
44834     #ifdef HAVE_CRL
44835         if (der)
44836             FreeDer(&der);
44837     #endif
44838         return WOLFSSL_SUCCESS;
44839 err:
44840         if (pem)
44841             XFREE(pem, 0, DYNAMIC_TYPE_PEM);
44842     #ifdef HAVE_CRL
44843         if (der)
44844             FreeDer(&der);
44845     #endif
44846         if (*x_pkey) {
44847             wolfSSL_X509_PKEY_free(*x_pkey);
44848             *x_pkey = NULL;
44849         }
44850         if (pemBio)
44851             wolfSSL_BIO_free(pemBio);
44852         return WOLFSSL_FAILURE;
44853 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
44854     }
44855 
WOLF_STACK_OF(WOLFSSL_X509_INFO)44856     WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read(
44857             XFILE fp, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
44858             pem_password_cb* cb, void* u)
44859     {
44860         WOLFSSL_BIO* fileBio = wolfSSL_BIO_new_fp(fp, BIO_NOCLOSE);
44861         WOLF_STACK_OF(WOLFSSL_X509_INFO)* ret = NULL;
44862 
44863         WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read");
44864         if (fileBio != NULL) {
44865             ret = wolfSSL_PEM_X509_INFO_read_bio(fileBio, sk, cb, u);
44866             wolfSSL_BIO_free(fileBio);
44867         }
44868         return ret;
44869     }
44870 
44871     /*
44872      * bio WOLFSSL_BIO to read certificates from
44873      * sk  possible stack to push more X509_INFO structs to. Can be NULL
44874      * cb  callback password for encrypted PEM certificates
44875      * u   user input such as password
44876      *
44877      * returns stack on success and NULL or default stack passed in on fail
44878      */
WOLF_STACK_OF(WOLFSSL_X509_INFO)44879     WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio(
44880         WOLFSSL_BIO* bio, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
44881         wc_pem_password_cb* cb, void* u)
44882     {
44883         WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk = NULL;
44884         int ret = WOLFSSL_SUCCESS;
44885         WOLFSSL_X509_INFO* current = NULL;
44886         WOLFSSL_X509*      x509 = NULL;
44887         WOLFSSL_X509_CRL*  crl  = NULL;
44888         WOLFSSL_X509_PKEY* x_pkey = NULL;
44889 
44890         (void)u;
44891 
44892         WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read_bio");
44893 
44894         /* attempt to use passed in stack or create a new one */
44895         if (sk != NULL) {
44896             localSk = sk;
44897         }
44898         else {
44899             localSk = wolfSSL_sk_X509_INFO_new_null();
44900         }
44901         if (localSk == NULL) {
44902             WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio",
44903                     MEMORY_E);
44904             return NULL;
44905         }
44906 
44907         /* parse through BIO and push new info's found onto stack */
44908         while (1) {
44909             x509 = NULL;
44910             crl  = NULL;
44911             x_pkey = NULL;
44912 
44913             if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bio, cb,
44914                     &x509, &crl, &x_pkey) == WOLFSSL_SUCCESS) {
44915                 if (current == NULL ||
44916                         (x509 && current->x509) ||
44917                         (crl && current->crl) ||
44918                         (x_pkey && current->x_pkey)) {
44919                     /* Need to create new current since existing one already
44920                      * has the member filled or this is the first successful
44921                      * read. */
44922                     current = wolfSSL_X509_INFO_new();
44923                     if (current == NULL) {
44924                         ret = MEMORY_E;
44925                         break;
44926                     }
44927                     if (wolfSSL_sk_X509_INFO_push(localSk, current) !=
44928                             WOLFSSL_SUCCESS) {
44929                         wolfSSL_X509_INFO_free(current);
44930                         current = NULL;
44931                         ret = WOLFSSL_FAILURE;
44932                         break;
44933                     }
44934                 }
44935 
44936                 if (x509) {
44937                     current->x509 = x509;
44938                 }
44939                 else if (crl) {
44940                     current->crl = crl;
44941                 }
44942                 else if (x_pkey) {
44943                     current->x_pkey = x_pkey;
44944                 }
44945                 else {
44946                     WOLFSSL_MSG("No output parameters set");
44947                     ret = WOLFSSL_FAILURE;
44948                     break;
44949                 }
44950             }
44951             else {
44952 #ifdef WOLFSSL_HAVE_ERROR_QUEUE
44953                 int err = (int)wolfSSL_ERR_peek_last_error();
44954                 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
44955                         ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
44956                     /*
44957                      * wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio pushes an
44958                      * ASN_NO_PEM_HEADER error to the error queue on file end.
44959                      * This should not be left for the caller to find so we
44960                      * clear the last error. This also indicates that nothing
44961                      * more was found in the BIO.
44962                      */
44963                     wc_RemoveErrorNode(-1);
44964                 }
44965 #else
44966                 if (wolfSSL_sk_X509_INFO_num(localSk) > 0) {
44967                     WOLFSSL_MSG("At least one X509_INFO object on stack."
44968                                 "Assuming error means EOF or no more PEM"
44969                                 "headers found.");
44970                 }
44971 #endif
44972                 else {
44973                     ret = WOLFSSL_FAILURE;
44974                 }
44975                 break;
44976             }
44977         }
44978         if (ret != WOLFSSL_SUCCESS ||
44979                 wolfSSL_sk_X509_INFO_num(localSk) == 0) {
44980             /* current should always be pushed onto the localsk stack at this
44981              * point. The only case when it isn't is when
44982              * wolfSSL_sk_X509_INFO_push fails but in that case the current
44983              * free is handled inside the loop. */
44984             if (localSk != sk) {
44985                 wolfSSL_sk_pop_free(localSk, NULL);
44986             }
44987             wolfSSL_X509_free(x509);
44988 #ifdef HAVE_CRL
44989             wolfSSL_X509_CRL_free(crl);
44990 #endif
44991             wolfSSL_X509_PKEY_free(x_pkey);
44992             localSk = NULL;
44993         }
44994         WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", ret);
44995         return localSk;
44996     }
44997 #endif /* !NO_BIO */
44998 #endif /* OPENSSL_ALL */
44999 
wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY * ne)45000     void wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY* ne)
45001     {
45002         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_free");
45003         if (ne != NULL) {
45004             wolfSSL_ASN1_OBJECT_free(ne->object);
45005             if (ne->value != NULL) {
45006                 wolfSSL_ASN1_STRING_free(ne->value);
45007             }
45008             XFREE(ne, NULL, DYNAMIC_TYPE_NAME_ENTRY);
45009         }
45010     }
45011 
45012 
wolfSSL_X509_NAME_ENTRY_new(void)45013     WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_new(void)
45014     {
45015         WOLFSSL_X509_NAME_ENTRY* ne;
45016 
45017         ne = (WOLFSSL_X509_NAME_ENTRY*)XMALLOC(sizeof(WOLFSSL_X509_NAME_ENTRY),
45018                 NULL, DYNAMIC_TYPE_NAME_ENTRY);
45019         if (ne != NULL) {
45020             XMEMSET(ne, 0, sizeof(WOLFSSL_X509_NAME_ENTRY));
45021         }
45022 
45023         return ne;
45024     }
45025 
45026 
45027     /* Create a new WOLFSSL_X509_NAME_ENTRY structure based on the text passed
45028      * in. Returns NULL on failure */
wolfSSL_X509_NAME_ENTRY_create_by_txt(WOLFSSL_X509_NAME_ENTRY ** neIn,const char * txt,int type,const unsigned char * data,int dataSz)45029     WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_txt(
45030             WOLFSSL_X509_NAME_ENTRY **neIn, const char *txt, int type,
45031             const unsigned char *data, int dataSz)
45032     {
45033         int nid = -1;
45034         WOLFSSL_X509_NAME_ENTRY* ne = NULL;
45035 
45036         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_txt()");
45037 
45038         if (txt == NULL) {
45039             return NULL;
45040         }
45041 
45042         if (neIn != NULL) {
45043             ne = *neIn;
45044         }
45045 
45046         nid = wolfSSL_OBJ_txt2nid(txt);
45047         if (nid == NID_undef) {
45048             WOLFSSL_MSG("Unable to find text");
45049             ne = NULL;
45050         }
45051         else {
45052             if (ne == NULL) {
45053                 ne = wolfSSL_X509_NAME_ENTRY_new();
45054                 if (ne == NULL) {
45055                     return NULL;
45056                 }
45057             }
45058             ne->nid = nid;
45059             ne->object = wolfSSL_OBJ_nid2obj_ex(nid, ne->object);
45060             ne->value = wolfSSL_ASN1_STRING_type_new(type);
45061             if (ne->value != NULL) {
45062                 if (wolfSSL_ASN1_STRING_set(ne->value, (const void*)data,
45063                                             dataSz) == WOLFSSL_SUCCESS) {
45064                     ne->set = 1;
45065                 }
45066             }
45067         }
45068 
45069         return ne;
45070     }
45071 
45072 
45073     /* Creates a new entry given the NID, type, and data
45074      * "dataSz" is number of bytes in data, if set to -1 then XSTRLEN is used
45075      * "out" can be used to store the new entry data in an existing structure
45076      *       if NULL then a new WOLFSSL_X509_NAME_ENTRY structure is created
45077      * returns a pointer to WOLFSSL_X509_NAME_ENTRY on success and NULL on fail
45078      */
wolfSSL_X509_NAME_ENTRY_create_by_NID(WOLFSSL_X509_NAME_ENTRY ** out,int nid,int type,const unsigned char * data,int dataSz)45079     WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID(
45080             WOLFSSL_X509_NAME_ENTRY** out, int nid, int type,
45081             const unsigned char* data, int dataSz)
45082     {
45083         WOLFSSL_X509_NAME_ENTRY* ne;
45084 
45085 #ifdef WOLFSSL_DEBUG_OPENSSL
45086         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_NID()");
45087 #endif
45088 
45089         if (!data) {
45090             WOLFSSL_MSG("Bad parameter");
45091             return NULL;
45092         }
45093 
45094         if (out == NULL || *out == NULL) {
45095             ne = wolfSSL_X509_NAME_ENTRY_new();
45096             if (ne == NULL) {
45097                 return NULL;
45098             }
45099             if (out != NULL) {
45100                 *out = ne;
45101             }
45102         }
45103         else {
45104             ne = *out;
45105         }
45106 
45107         ne->nid = nid;
45108         ne->object = wolfSSL_OBJ_nid2obj_ex(nid, ne->object);
45109         ne->value = wolfSSL_ASN1_STRING_type_new(type);
45110         if (ne->value != NULL) {
45111             if (wolfSSL_ASN1_STRING_set(ne->value, (const void*)data, dataSz)
45112                     == WOLFSSL_SUCCESS) {
45113                 ne->set = 1;
45114             }
45115         }
45116 
45117         return ne;
45118     }
45119 
45120     /* add all entry of type "nid" to the buffer "fullName" and advance "idx"
45121      * since number of entries is small, a brute force search is used here
45122      * returns the number of entries added
45123      */
AddAllEntry(WOLFSSL_X509_NAME * name,char * fullName,int fullNameSz,int * idx)45124     static int AddAllEntry(WOLFSSL_X509_NAME* name, char* fullName,
45125             int fullNameSz, int* idx)
45126     {
45127         int i;
45128         int ret = 0;
45129 
45130         for (i = 0; i < MAX_NAME_ENTRIES; i++) {
45131             if (name->entry[i].set) {
45132                 WOLFSSL_X509_NAME_ENTRY* e;
45133                 WOLFSSL_ASN1_OBJECT* obj;
45134 
45135                 int sz;
45136                 unsigned char* data;
45137 
45138                 e = &name->entry[i];
45139                 obj = wolfSSL_X509_NAME_ENTRY_get_object(e);
45140                 if (obj == NULL) {
45141                     return BAD_FUNC_ARG;
45142                 }
45143 
45144                 XMEMCPY(fullName + *idx, "/", 1); *idx = *idx + 1;
45145                 sz = (int)XSTRLEN(obj->sName);
45146                 XMEMCPY(fullName + *idx, obj->sName, sz);
45147                 *idx += sz;
45148                 XMEMCPY(fullName + *idx, "=", 1); *idx = *idx + 1;
45149 
45150                 data = wolfSSL_ASN1_STRING_data(e->value);
45151                 if (data != NULL) {
45152                     sz = (int)XSTRLEN((const char*)data);
45153                     XMEMCPY(fullName + *idx, data, sz);
45154                     *idx += sz;
45155                 }
45156 
45157                 ret++;
45158             }
45159         }
45160         (void)fullNameSz;
45161         return ret;
45162     }
45163 
45164 
45165     /* Converts a list of entries in WOLFSSL_X509_NAME struct into a string
45166      * returns 0 on success */
RebuildFullName(WOLFSSL_X509_NAME * name)45167     static int RebuildFullName(WOLFSSL_X509_NAME* name)
45168     {
45169         int totalLen = 0, i, idx, entryCount = 0;
45170         char* fullName;
45171 
45172         if (name == NULL)
45173             return BAD_FUNC_ARG;
45174 
45175         for (i = 0; i < MAX_NAME_ENTRIES; i++) {
45176             if (name->entry[i].set) {
45177                 WOLFSSL_X509_NAME_ENTRY* e;
45178                 WOLFSSL_ASN1_OBJECT* obj;
45179 
45180                 e = &name->entry[i];
45181                 obj = wolfSSL_X509_NAME_ENTRY_get_object(e);
45182                 if (obj == NULL)
45183                     return BAD_FUNC_ARG;
45184 
45185                 totalLen += (int)XSTRLEN(obj->sName) + 2;/*+2 for '/' and '=' */
45186                 totalLen += wolfSSL_ASN1_STRING_length(e->value);
45187             }
45188         }
45189 
45190         fullName = (char*)XMALLOC(totalLen + 1, name->heap, DYNAMIC_TYPE_X509);
45191         if (fullName == NULL)
45192             return MEMORY_E;
45193 
45194         idx = 0;
45195         entryCount = AddAllEntry(name, fullName, totalLen, &idx);
45196         if (entryCount < 0) {
45197             XFREE(fullName, name->heap, DYNAMIC_TYPE_X509);
45198             return entryCount;
45199         }
45200 
45201         if (name->dynamicName) {
45202             XFREE(name->name, name->heap, DYNAMIC_TYPE_X509);
45203         }
45204         fullName[idx] = '\0';
45205         name->name = fullName;
45206         name->dynamicName = 1;
45207         name->sz = idx + 1; /* size includes null terminator */
45208         name->entrySz = entryCount;
45209 
45210         return 0;
45211     }
45212 
45213     /* Copies entry into name. With it being copied freeing entry becomes the
45214      * callers responsibility.
45215      * returns 1 for success and 0 for error */
wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME * name,WOLFSSL_X509_NAME_ENTRY * entry,int idx,int set)45216     int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name,
45217             WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set)
45218     {
45219         WOLFSSL_X509_NAME_ENTRY* current = NULL;
45220         int i;
45221 
45222 #ifdef WOLFSSL_DEBUG_OPENSSL
45223         WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry()");
45224 #endif
45225 
45226         if (name == NULL || entry == NULL || entry->value == NULL) {
45227             WOLFSSL_MSG("NULL argument passed in");
45228             return WOLFSSL_FAILURE;
45229         }
45230 
45231         if (idx >= 0) {
45232             /* place in specific index */
45233 
45234             if (idx >= MAX_NAME_ENTRIES) {
45235                 WOLFSSL_MSG("Error index to insert entry is larger than array");
45236                 return WOLFSSL_FAILURE;
45237             }
45238             i = idx;
45239         }
45240         else {
45241             /* iterate through and find first open spot */
45242             for (i = 0; i < MAX_NAME_ENTRIES; i++) {
45243                 if (name->entry[i].set != 1) { /* not set so overwritten */
45244                     WOLFSSL_MSG("Found place for name entry");
45245                     break;
45246                 }
45247             }
45248 
45249             if (i == MAX_NAME_ENTRIES) {
45250                 WOLFSSL_MSG("No spot found for name entry");
45251                 return WOLFSSL_FAILURE;
45252             }
45253         }
45254 
45255         current = &(name->entry[i]);
45256         if (current->set == 0)
45257             name->entrySz++;
45258         if (wolfSSL_X509_NAME_ENTRY_create_by_NID(&current,
45259                                 entry->nid,
45260                                 wolfSSL_ASN1_STRING_type(entry->value),
45261                                 wolfSSL_ASN1_STRING_data(entry->value),
45262                                 wolfSSL_ASN1_STRING_length(entry->value))
45263                                 == NULL) {
45264             WOLFSSL_MSG("Issue adding the name entry");
45265             if (current->set == 0)
45266                 name->entrySz--;
45267             return WOLFSSL_FAILURE;
45268         }
45269 
45270         if (RebuildFullName(name) != 0)
45271             return WOLFSSL_FAILURE;
45272 
45273         (void)set;
45274         return WOLFSSL_SUCCESS;
45275     }
45276 
wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME * name,const char * field,int type,const unsigned char * bytes,int len,int loc,int set)45277     int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name,
45278                                            const char *field, int type,
45279                                            const unsigned char *bytes, int len,
45280                                            int loc, int set)
45281     {
45282         int ret = WOLFSSL_FAILURE;
45283         int nid;
45284         WOLFSSL_X509_NAME_ENTRY* entry;
45285 
45286         (void)type;
45287         WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_txt");
45288 
45289         if (name == NULL || field == NULL)
45290             return WOLFSSL_FAILURE;
45291 
45292         if ((nid = wolfSSL_OBJ_txt2nid(field)) == NID_undef) {
45293             WOLFSSL_MSG("Unable convert text to NID");
45294             return WOLFSSL_FAILURE;
45295         }
45296 
45297         entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL,
45298                   nid, type, (unsigned char*)bytes, len);
45299         if (entry == NULL)
45300             return WOLFSSL_FAILURE;
45301 
45302         ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
45303         wolfSSL_X509_NAME_ENTRY_free(entry);
45304 
45305         return ret;
45306     }
45307 
wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME * name,int nid,int type,const unsigned char * bytes,int len,int loc,int set)45308     int wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME *name, int nid,
45309                                            int type, const unsigned char *bytes,
45310                                            int len, int loc, int set)
45311     {
45312         int ret;
45313         WOLFSSL_X509_NAME_ENTRY* entry;
45314         WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_NID");
45315         entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes,
45316                 len);
45317         if (entry == NULL)
45318             return WOLFSSL_FAILURE;
45319         ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
45320         wolfSSL_X509_NAME_ENTRY_free(entry);
45321         return ret;
45322     }
45323 
wolfSSL_X509_NAME_delete_entry(WOLFSSL_X509_NAME * name,int loc)45324     WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_delete_entry(
45325             WOLFSSL_X509_NAME *name, int loc)
45326     {
45327         WOLFSSL_X509_NAME_ENTRY* ret;
45328         WOLFSSL_ENTER("wolfSSL_X509_NAME_delete_entry");
45329 
45330         if (!name) {
45331             WOLFSSL_MSG("Bad parameter");
45332             return NULL;
45333         }
45334 
45335         ret = wolfSSL_X509_NAME_get_entry(name, loc);
45336         if (!ret) {
45337             WOLFSSL_MSG("loc entry not found");
45338             return NULL;
45339         }
45340         name->entry[loc].set = 0;
45341         return ret;
45342     }
45343 
45344 #endif /* !NO_CERTS */
45345 
45346     /* NID variables are dependent on compatibility header files currently
45347      *
45348      * returns a pointer to a new WOLFSSL_ASN1_OBJECT struct on success and NULL
45349      *         on fail
45350      */
45351 
wolfSSL_OBJ_nid2obj(int id)45352     WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj(int id)
45353     {
45354         return wolfSSL_OBJ_nid2obj_ex(id, NULL);
45355     }
45356 
45357 
wolfSSL_OBJ_nid2obj_ex(int id,WOLFSSL_ASN1_OBJECT * arg_obj)45358     WOLFSSL_LOCAL WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj_ex(int id,
45359                                                 WOLFSSL_ASN1_OBJECT* arg_obj)
45360     {
45361         word32 oidSz = 0;
45362         int nid = 0;
45363         const byte* oid;
45364         word32 type = 0;
45365         WOLFSSL_ASN1_OBJECT* obj = arg_obj;
45366         byte objBuf[MAX_OID_SZ + MAX_LENGTH_SZ + 1]; /* +1 for object tag */
45367         word32 objSz = 0;
45368         const char* sName = NULL;
45369         int i;
45370 
45371 #ifdef WOLFSSL_DEBUG_OPENSSL
45372         WOLFSSL_ENTER("wolfSSL_OBJ_nid2obj()");
45373 #endif
45374 
45375         for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
45376             if (wolfssl_object_info[i].nid == id) {
45377                 nid = id;
45378                 id = wolfssl_object_info[i].id;
45379                 sName = wolfssl_object_info[i].sName;
45380                 type = wolfssl_object_info[i].type;
45381                 break;
45382             }
45383         }
45384         if (i == (int)WOLFSSL_OBJECT_INFO_SZ) {
45385             WOLFSSL_MSG("NID not in table");
45386         #ifdef WOLFSSL_QT
45387             sName = NULL;
45388             type = id;
45389         #else
45390             return NULL;
45391         #endif
45392         }
45393 
45394     #ifdef HAVE_ECC
45395          if (type == 0 && wc_ecc_get_oid(id, &oid, &oidSz) > 0) {
45396              type = oidCurveType;
45397          }
45398     #endif /* HAVE_ECC */
45399 
45400         if (sName != NULL) {
45401             if (XSTRLEN(sName) > WOLFSSL_MAX_SNAME - 1) {
45402                 WOLFSSL_MSG("Attempted short name is too large");
45403                 return NULL;
45404             }
45405         }
45406 
45407         oid = OidFromId(id, type, &oidSz);
45408 
45409         /* set object ID to buffer */
45410         if (obj == NULL){
45411             obj = wolfSSL_ASN1_OBJECT_new();
45412             if (obj == NULL) {
45413                 WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
45414                 return NULL;
45415             }
45416         }
45417         obj->nid     = nid;
45418         obj->type    = id;
45419         obj->grp     = type;
45420 
45421         obj->sName[0] = '\0';
45422         if (sName != NULL) {
45423             XMEMCPY(obj->sName, (char*)sName, XSTRLEN((char*)sName));
45424         }
45425 
45426         objBuf[0] = ASN_OBJECT_ID; objSz++;
45427         objSz += SetLength(oidSz, objBuf + 1);
45428         if (oidSz) {
45429             XMEMCPY(objBuf + objSz, oid, oidSz);
45430             objSz     += oidSz;
45431         }
45432 
45433         if (obj->objSz == 0 || objSz != obj->objSz) {
45434             obj->objSz = objSz;
45435             if(((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
45436                                                            (obj->obj == NULL)) {
45437                 if (obj->obj != NULL)
45438                     XFREE((byte*)obj->obj, NULL, DYNAMIC_TYPE_ASN1);
45439                 obj->obj = (byte*)XMALLOC(obj->objSz, NULL, DYNAMIC_TYPE_ASN1);
45440                 if (obj->obj == NULL) {
45441                     wolfSSL_ASN1_OBJECT_free(obj);
45442                     return NULL;
45443                 }
45444                 obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA ;
45445             }
45446             else {
45447                 obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA ;
45448             }
45449         }
45450         XMEMCPY((byte*)obj->obj, objBuf, obj->objSz);
45451 
45452         (void)type;
45453 
45454         return obj;
45455     }
45456 
oid_translate_num_to_str(const char * oid)45457     static const char* oid_translate_num_to_str(const char* oid)
45458     {
45459         const struct oid_dict {
45460             const char* num;
45461             const char* desc;
45462         } oid_dict[] = {
45463             { "2.5.29.37.0",       "Any Extended Key Usage" },
45464             { "1.3.6.1.5.5.7.3.1", "TLS Web Server Authentication" },
45465             { "1.3.6.1.5.5.7.3.2", "TLS Web Client Authentication" },
45466             { "1.3.6.1.5.5.7.3.3", "Code Signing" },
45467             { "1.3.6.1.5.5.7.3.4", "E-mail Protection" },
45468             { "1.3.6.1.5.5.7.3.8", "Time Stamping" },
45469             { "1.3.6.1.5.5.7.3.9", "OCSP Signing" },
45470             { NULL, NULL }
45471         };
45472         const struct oid_dict* idx;
45473 
45474         for (idx = oid_dict; idx->num != NULL; idx++) {
45475             if (!XSTRNCMP(oid, idx->num, XSTRLEN(idx->num))) {
45476                 return idx->desc;
45477             }
45478         }
45479         return NULL;
45480     }
45481 
45482     /* If no_name is one then use numerical form, otherwise short name.
45483      *
45484      * Returns the buffer size on success, WOLFSSL_FAILURE on error
45485      */
wolfSSL_OBJ_obj2txt(char * buf,int bufLen,const WOLFSSL_ASN1_OBJECT * a,int no_name)45486     int wolfSSL_OBJ_obj2txt(char *buf, int bufLen, const WOLFSSL_ASN1_OBJECT *a,
45487                             int no_name)
45488     {
45489         int bufSz;
45490         const char* desc;
45491 
45492         WOLFSSL_ENTER("wolfSSL_OBJ_obj2txt()");
45493 
45494         if (buf == NULL || bufLen <= 1 || a == NULL) {
45495             WOLFSSL_MSG("Bad input argument");
45496             return WOLFSSL_FAILURE;
45497         }
45498 
45499         if (no_name == 1) {
45500             int    length;
45501             word32 idx = 0;
45502             byte   tag;
45503 
45504             if (GetASNTag(a->obj, &idx, &tag, a->objSz) != 0) {
45505                 return WOLFSSL_FAILURE;
45506             }
45507 
45508             if (tag != ASN_OBJECT_ID) {
45509                 WOLFSSL_MSG("Bad ASN1 Object");
45510                 return WOLFSSL_FAILURE;
45511             }
45512 
45513             if (GetLength((const byte*)a->obj, &idx, &length,
45514                            a->objSz) < 0 || length < 0) {
45515                 return ASN_PARSE_E;
45516             }
45517 
45518             if (bufLen < MAX_OID_STRING_SZ) {
45519                 bufSz = bufLen - 1;
45520             }
45521             else {
45522                 bufSz = MAX_OID_STRING_SZ;
45523             }
45524 
45525             if ((bufSz = DecodePolicyOID(buf, (word32)bufSz, a->obj + idx,
45526                         (word32)length)) <= 0) {
45527                 WOLFSSL_MSG("Error decoding OID");
45528                 return WOLFSSL_FAILURE;
45529             }
45530 
45531         }
45532         else { /* return long name unless using x509small, then return short name */
45533 #if defined(OPENSSL_EXTRA_X509_SMALL) && !defined(OPENSSL_EXTRA)
45534             const char* name = a->sName;
45535 #else
45536             const char* name = wolfSSL_OBJ_nid2ln(wolfSSL_OBJ_obj2nid(a));
45537 #endif
45538 
45539             if (name == NULL) {
45540                 WOLFSSL_MSG("Name not found");
45541                 return WOLFSSL_FAILURE;
45542             }
45543             if (XSTRLEN(name) + 1 < (word32)bufLen - 1) {
45544                 bufSz = (int)XSTRLEN(name);
45545             }
45546             else {
45547                 bufSz = bufLen - 1;
45548             }
45549             if (bufSz) {
45550                 XMEMCPY(buf, name, bufSz);
45551             }
45552             else if (wolfSSL_OBJ_obj2txt(buf, bufLen, a, 1)) {
45553                 if ((desc = oid_translate_num_to_str(buf))) {
45554                     bufSz = (int)XSTRLEN(desc);
45555                     XMEMCPY(buf, desc, min(bufSz, bufLen));
45556                 }
45557             }
45558             else if (a->type == GEN_DNS || a->type == GEN_EMAIL || a->type == GEN_URI) {
45559                 bufSz = (int)XSTRLEN((const char*)a->obj);
45560                 XMEMCPY(buf, a->obj, min(bufSz, bufLen));
45561             }
45562         }
45563 
45564         buf[bufSz] = '\0';
45565 
45566         return bufSz;
45567     }
45568 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
45569 
45570 #if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
wolfSSL_X509_NAME_get_index_by_OBJ(WOLFSSL_X509_NAME * name,const WOLFSSL_ASN1_OBJECT * obj,int idx)45571     int wolfSSL_X509_NAME_get_index_by_OBJ(WOLFSSL_X509_NAME *name,
45572                                            const WOLFSSL_ASN1_OBJECT *obj,
45573                                            int idx) {
45574         if (!name || idx >= MAX_NAME_ENTRIES ||
45575                 !obj || !obj->obj) {
45576             return -1;
45577         }
45578 
45579         if (idx < 0) {
45580             idx = -1;
45581         }
45582 
45583         for (idx++; idx < MAX_NAME_ENTRIES; idx++) {
45584             /* Find index of desired name */
45585             if (name->entry[idx].set) {
45586                 if (XSTRLEN(obj->sName) == XSTRLEN(name->entry[idx].object->sName) &&
45587                     XSTRNCMP((const char*) obj->sName,
45588                         name->entry[idx].object->sName, obj->objSz - 1) == 0) {
45589                     return idx;
45590                 }
45591             }
45592         }
45593         return -1;
45594     }
45595 #endif
45596 
45597 #if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
45598     defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
45599     defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
45600     defined(WOLFSSL_HAPROXY)
45601 
wolfSSL_CTX_use_certificate(WOLFSSL_CTX * ctx,WOLFSSL_X509 * x)45602     char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x)
45603     {
45604         int ret;
45605 
45606         WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
45607         if (!ctx || !x || !x->derCert) {
45608             WOLFSSL_MSG("Bad parameter");
45609             return WOLFSSL_FAILURE;
45610         }
45611 
45612         FreeDer(&ctx->certificate); /* Make sure previous is free'd */
45613         ret = AllocDer(&ctx->certificate, x->derCert->length, CERT_TYPE,
45614                        ctx->heap);
45615         if (ret != 0)
45616             return WOLFSSL_FAILURE;
45617 
45618         XMEMCPY(ctx->certificate->buffer, x->derCert->buffer,
45619                 x->derCert->length);
45620 #ifdef KEEP_OUR_CERT
45621         if (ctx->ourCert != NULL && ctx->ownOurCert) {
45622             wolfSSL_X509_free(ctx->ourCert);
45623         }
45624         #ifndef WOLFSSL_X509_STORE_CERTS
45625         ctx->ourCert = x;
45626         if (wolfSSL_X509_up_ref(x) != 1) {
45627             return WOLFSSL_FAILURE;
45628         }
45629         #else
45630         ctx->ourCert = wolfSSL_X509_d2i(NULL, x->derCert->buffer,x->derCert->length);
45631         if(ctx->ourCert == NULL){
45632             return WOLFSSL_FAILURE;
45633         }
45634         #endif
45635 
45636         /* We own the cert because either we up its reference counter
45637          * or we create our own copy of the cert object. */
45638         ctx->ownOurCert = 1;
45639 #endif
45640 
45641         /* Update the available options with public keys. */
45642         switch (x->pubKeyOID) {
45643             case RSAk:
45644                 ctx->haveRSA = 1;
45645                 break;
45646         #ifdef HAVE_ED25519
45647             case ED25519k:
45648         #endif
45649         #ifdef HAVE_ED448
45650             case ED448k:
45651         #endif
45652             case ECDSAk:
45653                 ctx->haveECC = 1;
45654         #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
45655                 ctx->pkCurveOID = x->pkCurveOID;
45656         #endif
45657                 break;
45658         }
45659 
45660         return WOLFSSL_SUCCESS;
45661     }
45662 
PushCertToDerBuffer(DerBuffer ** inOutDer,int weOwn,byte * cert,word32 certSz,void * heap)45663     static int PushCertToDerBuffer(DerBuffer** inOutDer, int weOwn,
45664             byte* cert, word32 certSz, void* heap)
45665     {
45666         int ret;
45667         DerBuffer* inChain = NULL;
45668         DerBuffer* der = NULL;
45669         word32 len = 0;
45670         if (inOutDer == NULL)
45671             return BAD_FUNC_ARG;
45672         inChain = *inOutDer;
45673         if (inChain != NULL)
45674             len = inChain->length;
45675         ret = AllocDer(&der, len + CERT_HEADER_SZ + certSz, CERT_TYPE,
45676                 heap);
45677         if (ret != 0) {
45678             WOLFSSL_MSG("AllocDer error");
45679             return ret;
45680         }
45681         if (inChain != NULL)
45682             XMEMCPY(der->buffer, inChain->buffer, len);
45683         c32to24(certSz, der->buffer + len);
45684         XMEMCPY(der->buffer + len + CERT_HEADER_SZ, cert, certSz);
45685         if (weOwn)
45686             FreeDer(inOutDer);
45687         *inOutDer = der;
45688         return WOLFSSL_SUCCESS;
45689     }
45690 
45691     /**
45692      * wolfSSL_CTX_add1_chain_cert makes a copy of the cert so we free it
45693      * on success
45694      */
wolfSSL_CTX_add0_chain_cert(WOLFSSL_CTX * ctx,WOLFSSL_X509 * x509)45695     int wolfSSL_CTX_add0_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
45696     {
45697         WOLFSSL_ENTER("wolfSSL_CTX_add0_chain_cert");
45698         if (wolfSSL_CTX_add1_chain_cert(ctx, x509) != WOLFSSL_SUCCESS) {
45699             return WOLFSSL_FAILURE;
45700         }
45701         wolfSSL_X509_free(x509);
45702         return WOLFSSL_SUCCESS;
45703     }
45704 
wolfSSL_CTX_add1_chain_cert(WOLFSSL_CTX * ctx,WOLFSSL_X509 * x509)45705     int wolfSSL_CTX_add1_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
45706     {
45707         int ret;
45708         WOLFSSL_ENTER("wolfSSL_CTX_add1_chain_cert");
45709         if (ctx == NULL || x509 == NULL || x509->derCert == NULL) {
45710             return WOLFSSL_FAILURE;
45711         }
45712 
45713         if (ctx->certificate == NULL)
45714             ret = wolfSSL_CTX_use_certificate(ctx, x509);
45715         else {
45716             if (wolfSSL_X509_up_ref(x509) != WOLFSSL_SUCCESS) {
45717                 WOLFSSL_MSG("wolfSSL_X509_up_ref error");
45718                 return WOLFSSL_FAILURE;
45719             }
45720             ret = wolfSSL_CTX_load_verify_buffer(ctx, x509->derCert->buffer,
45721                 x509->derCert->length, WOLFSSL_FILETYPE_ASN1);
45722             if (ret == WOLFSSL_SUCCESS) {
45723                 /* push to ctx->certChain */
45724                 ret = PushCertToDerBuffer(&ctx->certChain, 1,
45725                     x509->derCert->buffer, x509->derCert->length, ctx->heap);
45726             }
45727             /* Store cert to free it later */
45728             if (ret == WOLFSSL_SUCCESS && ctx->x509Chain == NULL) {
45729                 ctx->x509Chain = wolfSSL_sk_X509_new();
45730                 if (ctx->x509Chain == NULL) {
45731                     WOLFSSL_MSG("wolfSSL_sk_X509_new error");
45732                     ret =  WOLFSSL_FAILURE;
45733                 }
45734             }
45735             if (ret == WOLFSSL_SUCCESS &&
45736                     wolfSSL_sk_X509_push(ctx->x509Chain, x509)
45737                         != WOLFSSL_SUCCESS) {
45738                 WOLFSSL_MSG("wolfSSL_sk_X509_push error");
45739                 ret = WOLFSSL_FAILURE;
45740             }
45741             if (ret != WOLFSSL_SUCCESS)
45742                 wolfSSL_X509_free(x509); /* Decrease ref counter */
45743         }
45744 
45745         return (ret == WOLFSSL_SUCCESS) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
45746     }
45747 
45748 #ifdef KEEP_OUR_CERT
wolfSSL_add0_chain_cert(WOLFSSL * ssl,WOLFSSL_X509 * x509)45749     int wolfSSL_add0_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
45750     {
45751         int ret;
45752 
45753         WOLFSSL_ENTER("wolfSSL_add0_chain_cert");
45754 
45755         if (ssl == NULL || ssl->ctx == NULL || x509 == NULL ||
45756                 x509->derCert == NULL)
45757             return WOLFSSL_FAILURE;
45758 
45759         if (ssl->buffers.certificate == NULL) {
45760             ret = wolfSSL_use_certificate(ssl, x509);
45761             /* Store cert to free it later */
45762             if (ret == WOLFSSL_SUCCESS) {
45763                 if (ssl->buffers.weOwnCert)
45764                     wolfSSL_X509_free(ssl->ourCert);
45765                 ssl->ourCert = x509;
45766                 ssl->buffers.weOwnCert = 1;
45767             }
45768         }
45769         else {
45770             ret = PushCertToDerBuffer(&ssl->buffers.certChain,
45771                     ssl->buffers.weOwnCertChain, x509->derCert->buffer,
45772                     x509->derCert->length, ssl->heap);
45773             if (ret == WOLFSSL_SUCCESS) {
45774                 ssl->buffers.weOwnCertChain = 1;
45775                 /* Store cert to free it later */
45776                 if (ssl->ourCertChain == NULL) {
45777                     ssl->ourCertChain = wolfSSL_sk_X509_new();
45778                     if (ssl->ourCertChain == NULL) {
45779                         WOLFSSL_MSG("wolfSSL_sk_X509_new error");
45780                         return WOLFSSL_FAILURE;
45781                     }
45782                 }
45783                 if (wolfSSL_sk_X509_push(ssl->ourCertChain, x509)
45784                         != WOLFSSL_SUCCESS) {
45785                     WOLFSSL_MSG("wolfSSL_sk_X509_push error");
45786                     return WOLFSSL_FAILURE;
45787                 }
45788             }
45789         }
45790         return ret == WOLFSSL_SUCCESS ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
45791     }
45792 
wolfSSL_add1_chain_cert(WOLFSSL * ssl,WOLFSSL_X509 * x509)45793     int wolfSSL_add1_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
45794     {
45795         int ret;
45796 
45797         WOLFSSL_ENTER("wolfSSL_add1_chain_cert");
45798         if (ssl == NULL || ssl->ctx == NULL || x509 == NULL ||
45799                 x509->derCert == NULL)
45800             return WOLFSSL_FAILURE;
45801 
45802         if (wolfSSL_X509_up_ref(x509) != WOLFSSL_SUCCESS) {
45803             WOLFSSL_MSG("wolfSSL_X509_up_ref error");
45804             return WOLFSSL_FAILURE;
45805         }
45806         ret = wolfSSL_add0_chain_cert(ssl, x509);
45807         /* Decrease ref counter on error */
45808         if (ret != WOLFSSL_SUCCESS)
45809             wolfSSL_X509_free(x509);
45810         return ret;
45811     }
45812 #endif
45813 
45814     /* Return the corresponding short name for the nid <n>.
45815      * or NULL if short name can't be found.
45816      */
wolfSSL_OBJ_nid2sn(int n)45817     const char * wolfSSL_OBJ_nid2sn(int n) {
45818         const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
45819         size_t i;
45820         WOLFSSL_ENTER("wolfSSL_OBJ_nid2sn");
45821 
45822         if (n == NID_md5) {
45823             /* NID_surname == NID_md5 and NID_surname comes before NID_md5 in
45824              * wolfssl_object_info. As a result, the loop below will incorrectly
45825              * return "SN" instead of "MD5." NID_surname isn't the true OpenSSL
45826              * NID, but other functions rely on this table and modifying it to
45827              * conform with OpenSSL's NIDs isn't trivial. */
45828              return "MD5";
45829         }
45830         for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
45831             if (obj_info->nid == n) {
45832                 return obj_info->sName;
45833             }
45834         }
45835         WOLFSSL_MSG("SN not found");
45836         return NULL;
45837     }
45838 
45839 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
wolfSSL_OBJ_sn2nid(const char * sn)45840     int wolfSSL_OBJ_sn2nid(const char *sn) {
45841         WOLFSSL_ENTER("wolfSSL_OBJ_sn2nid");
45842         if (sn == NULL)
45843             return NID_undef;
45844         return wc_OBJ_sn2nid(sn);
45845     }
45846 #endif
45847 
45848 
45849     /* Gets the NID value that corresponds with the ASN1 object.
45850      *
45851      * o ASN1 object to get NID of
45852      *
45853      * Return NID on success and a negative value on failure
45854      */
wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT * o)45855     int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o)
45856     {
45857         word32 oid = 0;
45858         word32 idx = 0;
45859         int ret;
45860 
45861 #ifdef WOLFSSL_DEBUG_OPENSSL
45862         WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid");
45863 #endif
45864 
45865         if (o == NULL) {
45866             return -1;
45867         }
45868 
45869         #ifdef WOLFSSL_QT
45870         if (o->grp == oidCertExtType) {
45871             /* If nid is an unknown extension, return NID_undef */
45872             if (wolfSSL_OBJ_nid2sn(o->nid) == NULL)
45873                 return NID_undef;
45874         }
45875         #endif
45876 
45877         if (o->nid > 0)
45878             return o->nid;
45879         if ((ret = GetObjectId(o->obj, &idx, &oid, o->grp, o->objSz)) < 0) {
45880             if (ret == ASN_OBJECT_ID_E) {
45881                 /* Put ASN object tag in front and try again */
45882                 int len = SetObjectId(o->objSz, NULL) + o->objSz;
45883                 byte* buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
45884                 if (!buf) {
45885                     WOLFSSL_MSG("malloc error");
45886                     return -1;
45887                 }
45888                 idx = SetObjectId(o->objSz, buf);
45889                 XMEMCPY(buf + idx, o->obj, o->objSz);
45890                 idx = 0;
45891                 ret = GetObjectId(buf, &idx, &oid, o->grp, len);
45892                 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
45893                 if (ret < 0) {
45894                     WOLFSSL_MSG("Issue getting OID of object");
45895                     return -1;
45896                 }
45897             }
45898             else {
45899                 WOLFSSL_MSG("Issue getting OID of object");
45900                 return -1;
45901             }
45902         }
45903 
45904         return oid2nid(oid, o->grp);
45905     }
45906 
45907     /* Returns the long name that corresponds with an ASN1_OBJECT nid value.
45908      *  n : NID value of ASN1_OBJECT to search */
wolfSSL_OBJ_nid2ln(int n)45909     const char* wolfSSL_OBJ_nid2ln(int n)
45910     {
45911         const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
45912         size_t i;
45913         WOLFSSL_ENTER("wolfSSL_OBJ_nid2ln");
45914         for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
45915             if (obj_info->nid == n) {
45916                 return obj_info->lName;
45917             }
45918         }
45919         WOLFSSL_MSG("NID not found in table");
45920         return NULL;
45921     }
45922 
45923     /* Return the corresponding NID for the long name <ln>
45924      * or NID_undef if NID can't be found.
45925      */
wolfSSL_OBJ_ln2nid(const char * ln)45926     int wolfSSL_OBJ_ln2nid(const char *ln)
45927     {
45928         const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
45929         size_t i, lnlen;
45930         WOLFSSL_ENTER("wolfSSL_OBJ_ln2nid");
45931         if (ln && (lnlen = XSTRLEN(ln)) > 0) {
45932             /* Accept input like "/commonName=" */
45933             if (ln[0] == '/') {
45934                 ln++;
45935                 lnlen--;
45936             }
45937             if (lnlen) {
45938                 if (ln[lnlen-1] == '=') {
45939                     lnlen--;
45940                 }
45941                 for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
45942                     if (lnlen == XSTRLEN(obj_info->lName) &&
45943                             XSTRNCMP(ln, obj_info->lName, lnlen) == 0) {
45944                         return obj_info->nid;
45945                     }
45946                 }
45947             }
45948         }
45949         return NID_undef;
45950     }
45951 
45952     /* compares two objects, return 0 if equal */
wolfSSL_OBJ_cmp(const WOLFSSL_ASN1_OBJECT * a,const WOLFSSL_ASN1_OBJECT * b)45953     int wolfSSL_OBJ_cmp(const WOLFSSL_ASN1_OBJECT* a,
45954                         const WOLFSSL_ASN1_OBJECT* b)
45955     {
45956         WOLFSSL_ENTER("wolfSSL_OBJ_cmp");
45957 
45958         if (a && b && a->obj && b->obj) {
45959             if (a->objSz == b->objSz) {
45960                 return XMEMCMP(a->obj, b->obj, a->objSz);
45961             }
45962             else if (a->type == EXT_KEY_USAGE_OID ||
45963                      b->type == EXT_KEY_USAGE_OID) {
45964                 /* Special case for EXT_KEY_USAGE_OID so that
45965                  * cmp will be treated as a substring search */
45966                 /* Used in libest to check for id-kp-cmcRA in
45967                  * EXT_KEY_USAGE extension */
45968                 unsigned int idx;
45969                 const byte* s; /* shorter */
45970                 unsigned int sLen;
45971                 const byte* l; /* longer */
45972                 unsigned int lLen;
45973                 if (a->objSz > b->objSz) {
45974                     s = b->obj; sLen = b->objSz;
45975                     l = a->obj; lLen = a->objSz;
45976                 }
45977                 else {
45978                     s = a->obj; sLen = a->objSz;
45979                     l = b->obj; lLen = b->objSz;
45980                 }
45981                 for (idx = 0; idx <= lLen - sLen; idx++) {
45982                     if (XMEMCMP(l + idx, s, sLen) == 0) {
45983                         /* Found substring */
45984                         return 0;
45985                     }
45986                 }
45987             }
45988         }
45989 
45990         return WOLFSSL_FATAL_ERROR;
45991     }
45992 #endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
45993           WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY */
45994 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
45995     defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
45996     defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
45997     defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
45998     /* Gets the NID value that is related to the OID string passed in. Example
45999      * string would be "2.5.29.14" for subject key ID.
46000      *
46001      * returns NID value on success and NID_undef on error
46002      */
wolfSSL_OBJ_txt2nid(const char * s)46003     int wolfSSL_OBJ_txt2nid(const char* s)
46004     {
46005         unsigned int i;
46006     #ifdef WOLFSSL_CERT_EXT
46007         int ret;
46008         unsigned int sum = 0;
46009         unsigned int outSz = MAX_OID_SZ;
46010         unsigned char out[MAX_OID_SZ];
46011     #endif
46012 
46013         WOLFSSL_ENTER("OBJ_txt2nid");
46014 
46015         if (s == NULL) {
46016             return NID_undef;
46017         }
46018 
46019     #ifdef WOLFSSL_CERT_EXT
46020         ret = EncodePolicyOID(out, &outSz, s, NULL);
46021         if (ret == 0) {
46022             /* sum OID */
46023             for (i = 0; i < outSz; i++) {
46024                 sum += out[i];
46025             }
46026         }
46027     #endif /* WOLFSSL_CERT_EXT */
46028 
46029         /* get the group that the OID's sum is in
46030          * @TODO possible conflict with multiples */
46031         for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
46032             int len;
46033         #ifdef WOLFSSL_CERT_EXT
46034             if (ret == 0) {
46035                 if (wolfssl_object_info[i].id == (int)sum) {
46036                     return wolfssl_object_info[i].nid;
46037                 }
46038             }
46039         #endif
46040 
46041             /* try as a short name */
46042             len = (int)XSTRLEN(s);
46043             if ((int)XSTRLEN(wolfssl_object_info[i].sName) == len &&
46044                 XSTRNCMP(wolfssl_object_info[i].sName, s, len) == 0) {
46045                 return wolfssl_object_info[i].nid;
46046             }
46047 
46048             /* try as a long name */
46049             if ((int)XSTRLEN(wolfssl_object_info[i].lName) == len &&
46050                 XSTRNCMP(wolfssl_object_info[i].lName, s, len) == 0) {
46051                 return wolfssl_object_info[i].nid;
46052             }
46053         }
46054 
46055         return NID_undef;
46056     }
46057 #endif
46058 #if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
46059     defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
46060     defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
46061     defined(WOLFSSL_HAPROXY)
46062 
46063     /* Creates new ASN1_OBJECT from short name, long name, or text
46064      * representation of oid. If no_name is 0, then short name, long name, and
46065      * numerical value of oid are interpreted. If no_name is 1, then only the
46066      * numerical value of the oid is interpreted.
46067      *
46068      * Returns pointer to ASN1_OBJECT on success, or NULL on error.
46069      */
46070 #if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
wolfSSL_OBJ_txt2obj(const char * s,int no_name)46071     WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_txt2obj(const char* s, int no_name)
46072     {
46073         int len, i, ret;
46074         int nid = NID_undef;
46075         unsigned int outSz = MAX_OID_SZ;
46076         unsigned char out[MAX_OID_SZ];
46077         WOLFSSL_ASN1_OBJECT* obj;
46078 
46079         WOLFSSL_ENTER("wolfSSL_OBJ_txt2obj");
46080 
46081         if (s == NULL)
46082             return NULL;
46083 
46084         /* If s is numerical value, try to sum oid */
46085         ret = EncodePolicyOID(out, &outSz, s, NULL);
46086         if (ret == 0 && outSz > 0) {
46087             /* If numerical encode succeeded then just
46088              * create object from that because sums are
46089              * not unique and can cause confusion. */
46090             obj = wolfSSL_ASN1_OBJECT_new();
46091             if (obj == NULL) {
46092                 WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
46093                 return NULL;
46094             }
46095             obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
46096             obj->obj = (byte*)XMALLOC(1 + MAX_LENGTH_SZ + outSz, NULL,
46097                     DYNAMIC_TYPE_ASN1);
46098             if (obj->obj == NULL) {
46099                 wolfSSL_ASN1_OBJECT_free(obj);
46100                 return NULL;
46101             }
46102             obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA ;
46103             i = SetObjectId(outSz, (byte*)obj->obj);
46104             XMEMCPY((byte*)obj->obj + i, out, outSz);
46105             obj->objSz = i + outSz;
46106             return obj;
46107         }
46108 
46109         len = (int)XSTRLEN(s);
46110 
46111         /* TODO: update short names in wolfssl_object_info and check OID sums
46112            are correct */
46113         for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
46114             /* Short name, long name, and numerical value are interpreted */
46115             if (no_name == 0 && ((XSTRNCMP(s, wolfssl_object_info[i].sName, len) == 0) ||
46116                                  (XSTRNCMP(s, wolfssl_object_info[i].lName, len) == 0)))
46117                     nid = wolfssl_object_info[i].nid;
46118         }
46119 
46120         if (nid != NID_undef)
46121             return wolfSSL_OBJ_nid2obj(nid);
46122 
46123         return NULL;
46124     }
46125 #endif
46126 
46127     /* compatibility function. Its intended use is to remove OID's from an
46128      * internal table that have been added with OBJ_create. wolfSSL manages its
46129      * own internal OID values and does not currently support OBJ_create. */
wolfSSL_OBJ_cleanup(void)46130     void wolfSSL_OBJ_cleanup(void)
46131     {
46132         WOLFSSL_ENTER("wolfSSL_OBJ_cleanup()");
46133     }
46134 
46135     #ifndef NO_WOLFSSL_STUB
wolfSSL_OBJ_create(const char * oid,const char * sn,const char * ln)46136     int wolfSSL_OBJ_create(const char *oid, const char *sn, const char *ln)
46137     {
46138         (void)oid;
46139         (void)sn;
46140         (void)ln;
46141         WOLFSSL_STUB("wolfSSL_OBJ_create");
46142         return WOLFSSL_FAILURE;
46143     }
46144     #endif
46145 
wolfSSL_set_verify_depth(WOLFSSL * ssl,int depth)46146     void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth)
46147     {
46148     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
46149         WOLFSSL_ENTER("wolfSSL_set_verify_depth");
46150         ssl->options.verifyDepth = (byte)depth;
46151     #endif
46152     }
46153 
46154 #endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
46155     HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
46156 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
46157     defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
46158     defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
46159     defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY * ne)46160     WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne)
46161     {
46162         WOLFSSL_ASN1_OBJECT* obj = NULL;
46163 
46164 #ifdef WOLFSSL_DEBUG_OPENSSL
46165         WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
46166 #endif
46167         if (ne == NULL) return NULL;
46168         obj = wolfSSL_OBJ_nid2obj_ex(ne->nid, ne->object);
46169         if (obj != NULL) {
46170             obj->nid = ne->nid;
46171             return obj;
46172         }
46173         return NULL;
46174     }
46175 
46176 
46177 #endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
46178     HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
46179 
46180 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
46181     defined(OPENSSL_EXTRA_X509_SMALL)
46182 
46183     /* returns a pointer to the internal entry at location 'loc' on success,
46184      * a null pointer is returned in fail cases */
wolfSSL_X509_NAME_get_entry(WOLFSSL_X509_NAME * name,int loc)46185     WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
46186                                              WOLFSSL_X509_NAME *name, int loc)
46187     {
46188 #ifdef WOLFSSL_DEBUG_OPENSSL
46189         WOLFSSL_ENTER("wolfSSL_X509_NAME_get_entry");
46190 #endif
46191 
46192         if (name == NULL) {
46193             return NULL;
46194         }
46195 
46196         if (loc < 0 || loc >= MAX_NAME_ENTRIES) {
46197             WOLFSSL_MSG("Bad argument");
46198             return NULL;
46199         }
46200 
46201         if (name->entry[loc].set) {
46202 #ifdef WOLFSSL_PYTHON
46203             /* "set" is not only flag use, but also stack index position use in
46204             *  OpenSSL. Python makes tuple based on this number. Therefore,
46205             *  updating "set" by position + 1. "plus 1" means to avoid "not set"
46206             *  zero.
46207             */
46208             name->entry[loc].set = loc + 1;
46209 #endif
46210             return &name->entry[loc];
46211         }
46212         else {
46213             return NULL;
46214         }
46215     }
46216 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
46217 
46218 #ifdef OPENSSL_EXTRA
46219 
wolfSSL_X509_check_private_key(WOLFSSL_X509 * x509,WOLFSSL_EVP_PKEY * key)46220     int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key)
46221     {
46222         WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
46223 
46224         if (!x509 || !key) {
46225             WOLFSSL_MSG("Bad parameter");
46226             return WOLFSSL_FAILURE;
46227         }
46228 
46229     #ifndef NO_CHECK_PRIVATE_KEY
46230         return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz,
46231                 x509->pubKey.buffer, x509->pubKey.length,
46232                 (enum Key_Sum)x509->pubKeyOID) == 1 ?
46233                         WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
46234     #else
46235         /* not compiled in */
46236         return WOLFSSL_SUCCESS;
46237     #endif
46238     }
46239 
46240 /* wolfSSL uses negative values for error states. This function returns an
46241  * unsigned type so the value returned is the absolute value of the error.
46242  */
wolfSSL_ERR_peek_last_error_line(const char ** file,int * line)46243 unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
46244 {
46245     WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
46246 
46247     (void)line;
46248     (void)file;
46249 #ifdef WOLFSSL_HAVE_ERROR_QUEUE
46250     {
46251         int ret;
46252 
46253         if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
46254             WOLFSSL_MSG("Issue peeking at error node in queue");
46255             return 0;
46256         }
46257         printf("ret from peek error node = %d\n", ret);
46258     #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
46259         if (ret == -ASN_NO_PEM_HEADER)
46260             return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
46261     #endif
46262     #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
46263         if (ret == ASN1_R_HEADER_TOO_LONG) {
46264             return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
46265         }
46266     #endif
46267         return (unsigned long)ret;
46268     }
46269 #else
46270     return (unsigned long)(0 - NOT_COMPILED_IN);
46271 #endif
46272 }
46273 
46274 
46275 #ifndef NO_CERTS
wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX * ctx,WOLFSSL_EVP_PKEY * pkey)46276 int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
46277 {
46278     WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey");
46279 
46280     if (ctx == NULL || pkey == NULL) {
46281         return WOLFSSL_FAILURE;
46282     }
46283 
46284     switch (pkey->type) {
46285 #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && !defined(NO_RSA)
46286     case EVP_PKEY_RSA:
46287         WOLFSSL_MSG("populating RSA key");
46288         if (PopulateRSAEvpPkeyDer(pkey) != WOLFSSL_SUCCESS)
46289             return WOLFSSL_FAILURE;
46290         break;
46291 #endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
46292 #if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
46293         defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA)
46294     case EVP_PKEY_DSA:
46295         break;
46296 #endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */
46297 #ifdef HAVE_ECC
46298     case EVP_PKEY_EC:
46299         WOLFSSL_MSG("populating ECC key");
46300         if (ECC_populate_EVP_PKEY(pkey, pkey->ecc)
46301                 != WOLFSSL_SUCCESS)
46302             return WOLFSSL_FAILURE;
46303         break;
46304 #endif
46305     default:
46306         return WOLFSSL_FAILURE;
46307     }
46308 
46309     if (pkey->pkey.ptr != NULL) {
46310         /* ptr for WOLFSSL_EVP_PKEY struct is expected to be DER format */
46311         return wolfSSL_CTX_use_PrivateKey_buffer(ctx,
46312                                        (const unsigned char*)pkey->pkey.ptr,
46313                                        pkey->pkey_sz, SSL_FILETYPE_ASN1);
46314     }
46315 
46316     WOLFSSL_MSG("wolfSSL private key not set");
46317     return BAD_FUNC_ARG;
46318 }
46319 #endif /* !NO_CERTS */
46320 
46321 #endif /* OPENSSL_EXTRA */
46322 
46323 #if defined(HAVE_EX_DATA) && \
46324    (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
46325     defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || \
46326     defined(HAVE_LIGHTY)) || defined(HAVE_EX_DATA) || \
46327     defined(WOLFSSL_WPAS_SMALL)
46328 /**
46329  * get_ex_new_index is a helper function for the following
46330  * xx_get_ex_new_index functions:
46331  *  - wolfSSL_CRYPTO_get_ex_new_index
46332  *  - wolfSSL_CTX_get_ex_new_index
46333  *  - wolfSSL_get_ex_new_index
46334  * Issues a unique index number for the specified class-index.
46335  * Returns an index number greater or equal to zero on success,
46336  * -1 on failure.
46337  */
get_ex_new_index(int class_index)46338 static int get_ex_new_index(int class_index)
46339 {
46340     /* index counter for each class index*/
46341     static int ctx_idx = 0;
46342     static int ssl_idx = 0;
46343     static int x509_idx = 0;
46344 
46345     int index = -1;
46346 
46347     switch(class_index) {
46348         case CRYPTO_EX_INDEX_SSL:
46349             index = ssl_idx++;
46350             break;
46351         case CRYPTO_EX_INDEX_SSL_CTX:
46352             index = ctx_idx++;
46353             break;
46354         case CRYPTO_EX_INDEX_X509:
46355             index = x509_idx++;
46356             break;
46357 
46358         /* following class indexes are not supoprted */
46359         case CRYPTO_EX_INDEX_SSL_SESSION:
46360         case CRYPTO_EX_INDEX_X509_STORE:
46361         case CRYPTO_EX_INDEX_X509_STORE_CTX:
46362         case CRYPTO_EX_INDEX_DH:
46363         case CRYPTO_EX_INDEX_DSA:
46364         case CRYPTO_EX_INDEX_EC_KEY:
46365         case CRYPTO_EX_INDEX_RSA:
46366         case CRYPTO_EX_INDEX_ENGINE:
46367         case CRYPTO_EX_INDEX_UI:
46368         case CRYPTO_EX_INDEX_BIO:
46369         case CRYPTO_EX_INDEX_APP:
46370         case CRYPTO_EX_INDEX_UI_METHOD:
46371         case CRYPTO_EX_INDEX_DRBG:
46372         default:
46373             break;
46374     }
46375     return index;
46376 }
46377 #endif /* HAVE_EX_DATA || WOLFSSL_WPAS_SMALL */
46378 
46379 #if defined(HAVE_EX_DATA) || defined(WOLFSSL_WPAS_SMALL)
wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX * ctx,int idx)46380 void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
46381 {
46382     WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
46383 #ifdef HAVE_EX_DATA
46384     if(ctx != NULL) {
46385         return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
46386     }
46387 #else
46388     (void)ctx;
46389     (void)idx;
46390 #endif
46391     return NULL;
46392 }
46393 
wolfSSL_CTX_get_ex_new_index(long idx,void * arg,void * a,void * b,void * c)46394 int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
46395                                 void* c)
46396 {
46397 
46398     WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
46399     (void)idx;
46400     (void)arg;
46401     (void)a;
46402     (void)b;
46403     (void)c;
46404 
46405     return get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX);
46406 }
46407 
46408 /* Return the index that can be used for the WOLFSSL structure to store
46409  * application data.
46410  *
46411  */
wolfSSL_get_ex_new_index(long argValue,void * arg,WOLFSSL_CRYPTO_EX_new * cb1,WOLFSSL_CRYPTO_EX_dup * cb2,WOLFSSL_CRYPTO_EX_free * cb3)46412 int wolfSSL_get_ex_new_index(long argValue, void* arg,
46413         WOLFSSL_CRYPTO_EX_new* cb1, WOLFSSL_CRYPTO_EX_dup* cb2,
46414         WOLFSSL_CRYPTO_EX_free* cb3)
46415 {
46416 
46417     WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
46418 
46419     (void)argValue;
46420     (void)arg;
46421     (void)cb1;
46422     (void)cb2;
46423     (void)cb3;
46424 
46425     return get_ex_new_index(CRYPTO_EX_INDEX_SSL);
46426 }
46427 
46428 
wolfSSL_CTX_set_ex_data(WOLFSSL_CTX * ctx,int idx,void * data)46429 int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
46430 {
46431     WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
46432     #ifdef HAVE_EX_DATA
46433     if (ctx != NULL)
46434     {
46435         return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
46436     }
46437     #else
46438     (void)ctx;
46439     (void)idx;
46440     (void)data;
46441     #endif
46442     return WOLFSSL_FAILURE;
46443 }
46444 
46445 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
wolfSSL_CTX_set_ex_data_with_cleanup(WOLFSSL_CTX * ctx,int idx,void * data,wolfSSL_ex_data_cleanup_routine_t cleanup_routine)46446 int wolfSSL_CTX_set_ex_data_with_cleanup(
46447     WOLFSSL_CTX* ctx,
46448     int idx,
46449     void* data,
46450     wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
46451 {
46452     WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data_with_cleanup");
46453     if (ctx != NULL)
46454     {
46455         return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ctx->ex_data, idx, data,
46456                                                        cleanup_routine);
46457     }
46458     return WOLFSSL_FAILURE;
46459 }
46460 #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
46461 
46462 #endif /* defined(HAVE_EX_DATA) || defined(WOLFSSL_WPAS_SMALL) */
46463 
46464 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
46465 
46466 /* Returns char* to app data stored in ex[0].
46467  *
46468  * ssl WOLFSSL structure to get app data from
46469  */
wolfSSL_get_app_data(const WOLFSSL * ssl)46470 void* wolfSSL_get_app_data(const WOLFSSL *ssl)
46471 {
46472     /* checkout exdata stuff... */
46473     WOLFSSL_ENTER("wolfSSL_get_app_data");
46474 
46475     return wolfSSL_get_ex_data(ssl, 0);
46476 }
46477 
46478 
46479 /* Set ex array 0 to have app data
46480  *
46481  * ssl WOLFSSL struct to set app data in
46482  * arg data to be stored
46483  *
46484  * Returns WOLFSSL_SUCCESS on success and SSL_FAILURE on failure
46485  */
wolfSSL_set_app_data(WOLFSSL * ssl,void * arg)46486 int wolfSSL_set_app_data(WOLFSSL *ssl, void* arg) {
46487     WOLFSSL_ENTER("wolfSSL_set_app_data");
46488 
46489     return wolfSSL_set_ex_data(ssl, 0, arg);
46490 }
46491 
46492 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
46493 
46494 #if defined(HAVE_EX_DATA) || defined(OPENSSL_EXTRA) || \
46495     defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)
46496 
wolfSSL_set_ex_data(WOLFSSL * ssl,int idx,void * data)46497 int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
46498 {
46499     WOLFSSL_ENTER("wolfSSL_set_ex_data");
46500 #ifdef HAVE_EX_DATA
46501     if (ssl != NULL)
46502     {
46503         return wolfSSL_CRYPTO_set_ex_data(&ssl->ex_data, idx, data);
46504     }
46505 #else
46506     WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
46507     (void)ssl;
46508     (void)idx;
46509     (void)data;
46510 #endif
46511     return WOLFSSL_FAILURE;
46512 }
46513 
46514 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
wolfSSL_set_ex_data_with_cleanup(WOLFSSL * ssl,int idx,void * data,wolfSSL_ex_data_cleanup_routine_t cleanup_routine)46515 int wolfSSL_set_ex_data_with_cleanup(
46516     WOLFSSL* ssl,
46517     int idx,
46518     void* data,
46519     wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
46520 {
46521     WOLFSSL_ENTER("wolfSSL_set_ex_data_with_cleanup");
46522     if (ssl != NULL)
46523     {
46524         return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ssl->ex_data, idx, data,
46525                                                        cleanup_routine);
46526     }
46527     return WOLFSSL_FAILURE;
46528 }
46529 #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
46530 
wolfSSL_get_ex_data(const WOLFSSL * ssl,int idx)46531 void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
46532 {
46533     WOLFSSL_ENTER("wolfSSL_get_ex_data");
46534 #ifdef HAVE_EX_DATA
46535     if (ssl != NULL) {
46536         return wolfSSL_CRYPTO_get_ex_data(&ssl->ex_data, idx);
46537     }
46538 #else
46539     WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
46540     (void)ssl;
46541     (void)idx;
46542 #endif
46543     return 0;
46544 }
46545 
46546 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || WOLFSSL_WPAS_SMALL */
46547 
46548 #ifdef OPENSSL_EXTRA
46549 
46550 #ifndef NO_DSA
46551 #ifndef NO_BIO
wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO * bp,WOLFSSL_DSA ** x,wc_pem_password_cb * cb,void * u)46552 WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x,
46553         wc_pem_password_cb *cb, void *u)
46554 {
46555     WOLFSSL_DSA* dsa;
46556     DsaKey* key;
46557     int    length;
46558     unsigned char*  buf;
46559     word32 bufSz;
46560     int ret;
46561     word32 idx = 0;
46562     DerBuffer* pDer;
46563 
46564     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAparams");
46565 
46566     ret = wolfSSL_BIO_get_mem_data(bp, &buf);
46567     if (ret <= 0) {
46568         WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
46569         return NULL;
46570     }
46571 
46572     bufSz = (word32)ret;
46573 
46574     if (cb != NULL || u != NULL) {
46575         /*
46576          * cb is for a call back when encountering encrypted PEM files
46577          * if cb == NULL and u != NULL then u = null terminated password string
46578          */
46579         WOLFSSL_MSG("Not yet supporting call back or password for encrypted PEM");
46580     }
46581 
46582     if (PemToDer(buf, (long)bufSz, DSA_PARAM_TYPE, &pDer, NULL, NULL,
46583                     NULL) < 0 ) {
46584         WOLFSSL_MSG("Issue converting from PEM to DER");
46585         return NULL;
46586     }
46587 
46588     if (GetSequence(pDer->buffer, &idx, &length, pDer->length) < 0) {
46589         WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
46590         FreeDer(&pDer);
46591         return NULL;
46592     }
46593 
46594     dsa = wolfSSL_DSA_new();
46595     if (dsa == NULL) {
46596         FreeDer(&pDer);
46597         WOLFSSL_MSG("Error creating DSA struct");
46598         return NULL;
46599     }
46600 
46601     key = (DsaKey*)dsa->internal;
46602     if (key == NULL) {
46603         FreeDer(&pDer);
46604         wolfSSL_DSA_free(dsa);
46605         WOLFSSL_MSG("Error finding DSA key struct");
46606         return NULL;
46607     }
46608 
46609     if (GetInt(&key->p,  pDer->buffer, &idx, pDer->length) < 0 ||
46610         GetInt(&key->q,  pDer->buffer, &idx, pDer->length) < 0 ||
46611         GetInt(&key->g,  pDer->buffer, &idx, pDer->length) < 0 ) {
46612         WOLFSSL_MSG("dsa key error");
46613         FreeDer(&pDer);
46614         wolfSSL_DSA_free(dsa);
46615         return NULL;
46616     }
46617 
46618     if (SetIndividualExternal(&dsa->p, &key->p) != WOLFSSL_SUCCESS) {
46619         WOLFSSL_MSG("dsa p key error");
46620         FreeDer(&pDer);
46621         wolfSSL_DSA_free(dsa);
46622         return NULL;
46623     }
46624 
46625     if (SetIndividualExternal(&dsa->q, &key->q) != WOLFSSL_SUCCESS) {
46626         WOLFSSL_MSG("dsa q key error");
46627         FreeDer(&pDer);
46628         wolfSSL_DSA_free(dsa);
46629         return NULL;
46630     }
46631 
46632     if (SetIndividualExternal(&dsa->g, &key->g) != WOLFSSL_SUCCESS) {
46633         WOLFSSL_MSG("dsa g key error");
46634         FreeDer(&pDer);
46635         wolfSSL_DSA_free(dsa);
46636         return NULL;
46637     }
46638 
46639     if (x != NULL) {
46640         *x = dsa;
46641     }
46642 
46643     FreeDer(&pDer);
46644     return dsa;
46645 }
46646 #endif /* !NO_BIO */
46647 #endif /* NO_DSA */
46648 #endif /* OPENSSL_EXTRA */
46649 
46650 #if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
46651     || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
46652 
46653 
46654 #ifndef NO_DH
46655 #ifndef NO_BIO
wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO * bio,WOLFSSL_DH ** x,wc_pem_password_cb * cb,void * u)46656 WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **x,
46657         wc_pem_password_cb *cb, void *u)
46658 {
46659 #ifndef NO_FILESYSTEM
46660     WOLFSSL_DH* localDh = NULL;
46661     unsigned char* mem  = NULL;
46662     word32 size;
46663     long   sz;
46664     int    ret;
46665     DerBuffer *der = NULL;
46666     byte*  p = NULL;
46667     byte*  g = NULL;
46668     word32 pSz = MAX_DH_SIZE;
46669     word32 gSz = MAX_DH_SIZE;
46670     int    memAlloced = 0;
46671 
46672     WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
46673     (void)cb;
46674     (void)u;
46675 
46676     if (bio == NULL) {
46677         WOLFSSL_MSG("Bad Function Argument bio is NULL");
46678         return NULL;
46679     }
46680 
46681     if (bio->type == WOLFSSL_BIO_MEMORY) {
46682         /* Use the buffer directly. */
46683         ret = wolfSSL_BIO_get_mem_data(bio, &mem);
46684         if (mem == NULL || ret <= 0) {
46685             WOLFSSL_MSG("Failed to get data from bio struct");
46686             goto end;
46687         }
46688         size = ret;
46689     }
46690     else if (bio->type == WOLFSSL_BIO_FILE) {
46691         /* Read whole file into a new buffer. */
46692         if (XFSEEK((XFILE)bio->ptr, 0, SEEK_END) != 0)
46693             goto end;
46694         sz = XFTELL((XFILE)bio->ptr);
46695         if (XFSEEK((XFILE)bio->ptr, 0, SEEK_SET) != 0)
46696             goto end;
46697         if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0L) {
46698             WOLFSSL_MSG("PEM_read_bio_DHparams file size error");
46699             goto end;
46700         }
46701         mem = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_PEM);
46702         if (mem == NULL)
46703             goto end;
46704         memAlloced = 1;
46705 
46706         if (wolfSSL_BIO_read(bio, (char *)mem, (int)sz) <= 0)
46707             goto end;
46708         size = (word32)sz;
46709     }
46710     else {
46711         WOLFSSL_MSG("BIO type not supported for reading DH parameters");
46712         goto end;
46713     }
46714 
46715     ret = PemToDer(mem, size, DH_PARAM_TYPE, &der, NULL, NULL, NULL);
46716     if (ret < 0) {
46717         /* Also try X9.42 format */
46718         ret = PemToDer(mem, size, X942_PARAM_TYPE, &der, NULL, NULL, NULL);
46719     }
46720     if (ret != 0)
46721         goto end;
46722 
46723     /* Use the object passed in, otherwise allocate a new object */
46724     if (x != NULL)
46725         localDh = *x;
46726     if (localDh == NULL) {
46727         localDh = wolfSSL_DH_new();
46728         if (localDh == NULL)
46729             goto end;
46730     }
46731 
46732     /* Load data in manually */
46733     p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
46734     g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
46735     if (p == NULL || g == NULL)
46736         goto end;
46737 
46738     /* Extract the p and g as data from the DER encoded DH parameters. */
46739     ret = wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz);
46740     if (ret != 0) {
46741         if (x != NULL && localDh != *x)
46742             XFREE(localDh, NULL, DYNAMIC_TYPE_OPENSSL);
46743         localDh = NULL;
46744         goto end;
46745     }
46746 
46747     if (x != NULL)
46748         *x = localDh;
46749 
46750     /* Put p and g in as big numbers. */
46751     if (localDh->p != NULL) {
46752         wolfSSL_BN_free(localDh->p);
46753         localDh->p = NULL;
46754     }
46755     if (localDh->g != NULL) {
46756         wolfSSL_BN_free(localDh->g);
46757         localDh->g = NULL;
46758     }
46759     localDh->p = wolfSSL_BN_bin2bn(p, pSz, NULL);
46760     localDh->g = wolfSSL_BN_bin2bn(g, gSz, NULL);
46761     if (localDh->p == NULL || localDh->g == NULL) {
46762         if (x != NULL && localDh != *x)
46763             wolfSSL_DH_free(localDh);
46764         localDh = NULL;
46765     }
46766 
46767     if (localDh != NULL && localDh->inSet == 0) {
46768         if (SetDhInternal(localDh) != WOLFSSL_SUCCESS) {
46769             WOLFSSL_MSG("Unable to set internal DH structure");
46770             wolfSSL_DH_free(localDh);
46771             localDh = NULL;
46772         }
46773     }
46774 
46775 end:
46776     if (memAlloced) XFREE(mem, NULL, DYNAMIC_TYPE_PEM);
46777     if (der != NULL) FreeDer(&der);
46778     XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
46779     XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
46780     return localDh;
46781 #else
46782     (void)bio;
46783     (void)x;
46784     (void)cb;
46785     (void)u;
46786     return NULL;
46787 #endif
46788 }
46789 
46790 #ifndef NO_FILESYSTEM
46791 /* Reads DH parameters from a file pointer into WOLFSSL_DH structure.
46792  *
46793  * fp  file pointer to read DH parameter file from
46794  * x   output WOLFSSL_DH to be created and populated from fp
46795  * cb  password callback, to be used to decrypt encrypted DH parameters PEM
46796  * u   context pointer to user-defined data to be received back in password cb
46797  *
46798  * Returns new WOLFSSL_DH structure pointer on success, NULL on failure. */
wolfSSL_PEM_read_DHparams(XFILE fp,WOLFSSL_DH ** x,wc_pem_password_cb * cb,void * u)46799 WOLFSSL_DH *wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH **x,
46800         wc_pem_password_cb *cb, void *u)
46801 {
46802     WOLFSSL_BIO* fbio = NULL;
46803     WOLFSSL_DH* dh = NULL;
46804 
46805     if (fp == NULL) {
46806         WOLFSSL_MSG("DH parameter file cannot be NULL");
46807         return NULL;
46808     }
46809 
46810     fbio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
46811     if (fbio == NULL) {
46812         WOLFSSL_MSG("Unable to create file BIO to process DH PEM");
46813         return NULL;
46814     }
46815 
46816     if (wolfSSL_BIO_set_fp(fbio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
46817         wolfSSL_BIO_free(fbio);
46818         WOLFSSL_MSG("wolfSSL_BIO_set_fp error");
46819         return NULL;
46820     }
46821 
46822     /* wolfSSL_PEM_read_bio_DHparams() sanitizes x, cb, u args */
46823     dh = wolfSSL_PEM_read_bio_DHparams(fbio, x, cb, u);
46824 
46825     wolfSSL_BIO_free(fbio);
46826     return dh;
46827 }
46828 #endif /* !NO_FILESYSTEM */
46829 
46830 #endif /* !NO_BIO */
46831 
46832 #if defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
46833 /* Writes the DH parameters in PEM format from "dh" out to the file pointer
46834  * passed in.
46835  *
46836  * returns WOLFSSL_SUCCESS on success
46837  */
wolfSSL_PEM_write_DHparams(XFILE fp,WOLFSSL_DH * dh)46838 int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh)
46839 {
46840     int ret;
46841     word32 derSz = 0, pemSz = 0;
46842     byte *der, *pem;
46843     DhKey* key;
46844 
46845     WOLFSSL_ENTER("wolfSSL_PEM_write_DHparams");
46846 
46847     if (dh == NULL) {
46848         WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", BAD_FUNC_ARG);
46849         return WOLFSSL_FAILURE;
46850     }
46851 
46852     if (dh->inSet == 0) {
46853         if (SetDhInternal(dh) != WOLFSSL_SUCCESS) {
46854             WOLFSSL_MSG("Unable to set internal DH structure");
46855             return WOLFSSL_FAILURE;
46856         }
46857     }
46858     key = (DhKey*)dh->internal;
46859     ret = wc_DhParamsToDer(key, NULL, &derSz);
46860     if (ret != LENGTH_ONLY_E) {
46861         WOLFSSL_MSG("Failed to get size of DH params");
46862         WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
46863         return WOLFSSL_FAILURE;
46864     }
46865 
46866     der = (byte*)XMALLOC(derSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
46867     if (der == NULL) {
46868         WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", MEMORY_E);
46869         return WOLFSSL_FAILURE;
46870     }
46871     ret = wc_DhParamsToDer(key, der, &derSz);
46872     if (ret <= 0) {
46873         WOLFSSL_MSG("Failed to export DH params");
46874         WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
46875         XFREE(der, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
46876         return WOLFSSL_FAILURE;
46877     }
46878 
46879     /* convert to PEM */
46880     ret = wc_DerToPem(der, derSz, NULL, 0, DH_PARAM_TYPE);
46881     if (ret < 0) {
46882         WOLFSSL_MSG("Failed to convert DH params to PEM");
46883         WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
46884         XFREE(der, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
46885         return ret;
46886     }
46887     pemSz = (word32)ret;
46888 
46889     pem = (byte*)XMALLOC(pemSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
46890     if (pem == NULL) {
46891         WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", MEMORY_E);
46892         XFREE(der, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
46893         return ret;
46894     }
46895     ret = wc_DerToPem(der, derSz, pem, pemSz, DH_PARAM_TYPE);
46896     XFREE(der, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
46897     if (ret < 0) {
46898         WOLFSSL_MSG("Failed to convert DH params to PEM");
46899         WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
46900         XFREE(pem, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
46901         return ret;
46902     }
46903 
46904     ret = (int)XFWRITE(pem, 1, pemSz, fp);
46905     XFREE(pem, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
46906     if (ret <= 0) {
46907         WOLFSSL_MSG("Failed to write to file");
46908         WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
46909         return WOLFSSL_FAILURE;
46910     }
46911 
46912     WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", WOLFSSL_SUCCESS);
46913     return WOLFSSL_SUCCESS;
46914 }
46915 #endif /* WOLFSSL_DH_EXTRA && !NO_FILESYSTEM */
46916 #endif /* !NO_DH */
46917 
46918 #ifndef NO_BIO
46919 
46920 #ifdef WOLFSSL_CERT_GEN
46921 
46922 #ifdef WOLFSSL_CERT_REQ
46923 /* writes the x509 from x to the WOLFSSL_BIO bp
46924  *
46925  * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
46926  */
wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO * bp,WOLFSSL_X509 * x)46927 int wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
46928 {
46929     byte* pem;
46930     int   pemSz = 0;
46931     const unsigned char* der;
46932     int derSz;
46933     int ret;
46934 
46935     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_REQ()");
46936 
46937     if (x == NULL || bp == NULL) {
46938         return WOLFSSL_FAILURE;
46939     }
46940 
46941     der = wolfSSL_X509_get_der(x, &derSz);
46942     if (der == NULL) {
46943         return WOLFSSL_FAILURE;
46944     }
46945 
46946     /* get PEM size */
46947     pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERTREQ_TYPE);
46948     if (pemSz < 0) {
46949         return WOLFSSL_FAILURE;
46950     }
46951 
46952     /* create PEM buffer and convert from DER */
46953     pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
46954     if (pem == NULL) {
46955         return WOLFSSL_FAILURE;
46956     }
46957     if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERTREQ_TYPE) < 0) {
46958         XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
46959         return WOLFSSL_FAILURE;
46960     }
46961 
46962     /* write the PEM to BIO */
46963     ret = wolfSSL_BIO_write(bp, pem, pemSz);
46964     XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
46965 
46966     if (ret <= 0) return WOLFSSL_FAILURE;
46967     return WOLFSSL_SUCCESS;
46968 }
46969 #endif /* WOLFSSL_CERT_REQ */
46970 
46971 
46972 /* writes the x509 from x to the WOLFSSL_BIO bp
46973  *
46974  * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
46975  */
wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO * bp,WOLFSSL_X509 * x)46976 int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
46977 {
46978     byte* pem;
46979     int   pemSz = 0;
46980     const unsigned char* der;
46981     int derSz;
46982     int ret;
46983 
46984     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX()");
46985 
46986     if (bp == NULL || x == NULL) {
46987         WOLFSSL_MSG("NULL argument passed in");
46988         return WOLFSSL_FAILURE;
46989     }
46990 
46991     der = wolfSSL_X509_get_der(x, &derSz);
46992     if (der == NULL) {
46993         return WOLFSSL_FAILURE;
46994     }
46995 
46996     /* get PEM size */
46997     pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERT_TYPE);
46998     if (pemSz < 0) {
46999         return WOLFSSL_FAILURE;
47000     }
47001 
47002     /* create PEM buffer and convert from DER */
47003     pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47004     if (pem == NULL) {
47005         return WOLFSSL_FAILURE;
47006     }
47007     if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
47008         XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47009         return WOLFSSL_FAILURE;
47010     }
47011 
47012     /* write the PEM to BIO */
47013     ret = wolfSSL_BIO_write(bp, pem, pemSz);
47014     XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47015 
47016     if (ret <= 0) return WOLFSSL_FAILURE;
47017     return WOLFSSL_SUCCESS;
47018 }
47019 
wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO * bio,WOLFSSL_X509 * cert)47020 int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert)
47021 {
47022     byte* pem = NULL;
47023     int   pemSz = 0;
47024     /* Get large buffer to hold cert der */
47025     int derSz = X509_BUFFER_SZ;
47026 #ifdef WOLFSSL_SMALL_STACK
47027     byte* der;
47028 #else
47029     byte der[X509_BUFFER_SZ];
47030 #endif
47031     int ret;
47032 
47033     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX()");
47034 
47035     if (bio == NULL || cert == NULL) {
47036         WOLFSSL_MSG("NULL argument passed in");
47037         return WOLFSSL_FAILURE;
47038     }
47039 
47040 #ifdef WOLFSSL_SMALL_STACK
47041     der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47042     if (!der) {
47043         WOLFSSL_MSG("malloc failed");
47044         return WOLFSSL_FAILURE;
47045     }
47046 #endif
47047 
47048     if (wolfssl_x509_make_der(cert, 0, der, &derSz, 1) != WOLFSSL_SUCCESS) {
47049         goto error;
47050     }
47051 
47052     /* get PEM size */
47053     pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERT_TYPE);
47054     if (pemSz < 0) {
47055         goto error;
47056     }
47057 
47058     /* create PEM buffer and convert from DER */
47059     pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47060     if (pem == NULL) {
47061         goto error;
47062     }
47063     if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
47064         goto error;
47065     }
47066 
47067     /* write the PEM to BIO */
47068     ret = wolfSSL_BIO_write(bio, pem, pemSz);
47069     XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47070     #ifdef WOLFSSL_SMALL_STACK
47071     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47072     #endif
47073 
47074     if (ret <= 0) return WOLFSSL_FAILURE;
47075     return WOLFSSL_SUCCESS;
47076 
47077 error:
47078     #ifdef WOLFSSL_SMALL_STACK
47079     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47080     #endif
47081     if (pem)
47082         XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47083     return WOLFSSL_FAILURE;
47084 }
47085 #endif /* WOLFSSL_CERT_GEN */
47086 
47087 #endif /* !NO_BIO */
47088 
47089 #if defined(OPENSSL_EXTRA) && !defined(NO_DH)
47090 /* Initialize ctx->dh with dh's params. Return WOLFSSL_SUCCESS on ok */
wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX * ctx,WOLFSSL_DH * dh)47091 long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
47092 {
47093     int pSz, gSz;
47094     byte *p, *g;
47095     int ret=0;
47096 
47097     WOLFSSL_ENTER("wolfSSL_CTX_set_tmp_dh");
47098 
47099     if(!ctx || !dh)
47100         return BAD_FUNC_ARG;
47101 
47102     /* Get needed size for p and g */
47103     pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
47104     gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
47105 
47106     if(pSz <= 0 || gSz <= 0)
47107         return WOLFSSL_FATAL_ERROR;
47108 
47109     p = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
47110     if(!p)
47111         return MEMORY_E;
47112 
47113     g = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
47114     if(!g) {
47115         XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
47116         return MEMORY_E;
47117     }
47118 
47119     pSz = wolfSSL_BN_bn2bin(dh->p, p);
47120     gSz = wolfSSL_BN_bn2bin(dh->g, g);
47121 
47122     if(pSz >= 0 && gSz >= 0) /* Conversion successful */
47123         ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
47124 
47125     XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
47126     XFREE(g, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
47127 
47128     return pSz > 0 && gSz > 0 ? ret : WOLFSSL_FATAL_ERROR;
47129 }
47130 #endif /* OPENSSL_EXTRA && !NO_DH */
47131 
47132 
47133 /* returns the enum value associated with handshake state
47134  *
47135  * ssl the WOLFSSL structure to get state of
47136  */
wolfSSL_get_state(const WOLFSSL * ssl)47137 int wolfSSL_get_state(const WOLFSSL* ssl)
47138 {
47139     WOLFSSL_ENTER("wolfSSL_get_state");
47140 
47141     if (ssl == NULL) {
47142         WOLFSSL_MSG("Null argument passed in");
47143         return SSL_FAILURE;
47144     }
47145 
47146     return ssl->options.handShakeState;
47147 }
47148 #endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
47149 
47150 #ifdef OPENSSL_EXTRA
wolfSSL_certs_clear(WOLFSSL * ssl)47151 void wolfSSL_certs_clear(WOLFSSL* ssl)
47152 {
47153     WOLFSSL_ENTER("wolfSSL_certs_clear()");
47154 
47155     if (ssl == NULL)
47156         return;
47157 
47158     /* ctx still owns certificate, certChain, key, dh, and cm */
47159     if (ssl->buffers.weOwnCert)
47160         FreeDer(&ssl->buffers.certificate);
47161     ssl->buffers.certificate = NULL;
47162     if (ssl->buffers.weOwnCertChain)
47163         FreeDer(&ssl->buffers.certChain);
47164     ssl->buffers.certChain = NULL;
47165 #ifdef WOLFSSL_TLS13
47166     ssl->buffers.certChainCnt = 0;
47167 #endif
47168     if (ssl->buffers.weOwnKey)
47169         FreeDer(&ssl->buffers.key);
47170     ssl->buffers.key      = NULL;
47171     ssl->buffers.keyType  = 0;
47172     ssl->buffers.keyId    = 0;
47173     ssl->buffers.keyLabel = 0;
47174     ssl->buffers.keySz    = 0;
47175     ssl->buffers.keyDevId = 0;
47176 }
47177 #endif
47178 
47179 #if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
47180     || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
47181 
wolfSSL_ctrl(WOLFSSL * ssl,int cmd,long opt,void * pt)47182 long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt)
47183 {
47184     WOLFSSL_ENTER("wolfSSL_ctrl");
47185     if (ssl == NULL)
47186         return BAD_FUNC_ARG;
47187 
47188     switch (cmd) {
47189         #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
47190         #ifdef HAVE_SNI
47191         case SSL_CTRL_SET_TLSEXT_HOSTNAME:
47192             WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TLSEXT_HOSTNAME.");
47193             if (pt == NULL) {
47194                 WOLFSSL_MSG("Passed in NULL Host Name.");
47195                 break;
47196             }
47197             return wolfSSL_set_tlsext_host_name(ssl, (const char*) pt);
47198         #endif /* HAVE_SNI */
47199         #endif /* WOLFSSL_NGINX || WOLFSSL_QT || OPENSSL_ALL */
47200         default:
47201             WOLFSSL_MSG("Case not implemented.");
47202     }
47203     (void)opt;
47204     (void)pt;
47205     return WOLFSSL_FAILURE;
47206 }
47207 
wolfSSL_CTX_ctrl(WOLFSSL_CTX * ctx,int cmd,long opt,void * pt)47208 long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
47209 {
47210 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
47211     long ctrl_opt;
47212 #endif
47213     long ret = WOLFSSL_SUCCESS;
47214 
47215     WOLFSSL_ENTER("wolfSSL_CTX_ctrl");
47216     if (ctx == NULL)
47217         return WOLFSSL_FAILURE;
47218 
47219     switch (cmd) {
47220     case SSL_CTRL_CHAIN:
47221 #ifdef SESSION_CERTS
47222     {
47223         /*
47224          * We don't care about opt here because a copy of the certificate is
47225          * stored anyway so increasing the reference counter is not necessary.
47226          * Just check to make sure that it is set to one of the correct values.
47227          */
47228         WOLF_STACK_OF(WOLFSSL_X509)* sk = (WOLF_STACK_OF(WOLFSSL_X509)*) pt;
47229         WOLFSSL_X509* x509;
47230         int i;
47231         if (opt != 0 && opt != 1) {
47232             ret = WOLFSSL_FAILURE;
47233             break;
47234         }
47235         /* Clear certificate chain */
47236         FreeDer(&ctx->certChain);
47237         if (sk) {
47238             for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
47239                 x509 = wolfSSL_sk_X509_value(sk, i);
47240                 /* Prevent wolfSSL_CTX_add_extra_chain_cert from freeing cert */
47241                 if (wolfSSL_X509_up_ref(x509) != 1) {
47242                     WOLFSSL_MSG("Error increasing reference count");
47243                     continue;
47244                 }
47245                 if (wolfSSL_CTX_add_extra_chain_cert(ctx, x509) !=
47246                         WOLFSSL_SUCCESS) {
47247                     WOLFSSL_MSG("Error adding certificate to context");
47248                     /* Decrease reference count on failure */
47249                     wolfSSL_X509_free(x509);
47250                 }
47251             }
47252         }
47253         /* Free previous chain */
47254         wolfSSL_sk_X509_pop_free(ctx->x509Chain, NULL);
47255         ctx->x509Chain = sk;
47256         if (sk && opt == 1) {
47257             /* up all refs when opt == 1 */
47258             for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
47259                 x509 = wolfSSL_sk_X509_value(sk, i);
47260                 if (wolfSSL_X509_up_ref(x509) != 1) {
47261                     WOLFSSL_MSG("Error increasing reference count");
47262                     continue;
47263                 }
47264             }
47265         }
47266     }
47267 #else
47268         WOLFSSL_MSG("Session certificates not compiled in");
47269         ret = WOLFSSL_FAILURE;
47270 #endif
47271         break;
47272 
47273 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
47274     case SSL_CTRL_OPTIONS:
47275         WOLFSSL_MSG("Entering Case: SSL_CTRL_OPTIONS.");
47276         ctrl_opt = wolfSSL_CTX_set_options(ctx, opt);
47277 
47278         #ifdef WOLFSSL_QT
47279         /* Set whether to use client or server cipher preference */
47280         if ((ctrl_opt & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE)
47281                      == WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
47282             WOLFSSL_MSG("Using Server's Cipher Preference.");
47283             ctx->useClientOrder = FALSE;
47284         } else {
47285             WOLFSSL_MSG("Using Client's Cipher Preference.");
47286             ctx->useClientOrder = TRUE;
47287         }
47288         #endif /* WOLFSSL_QT */
47289 
47290         return ctrl_opt;
47291 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
47292     case SSL_CTRL_EXTRA_CHAIN_CERT:
47293         WOLFSSL_MSG("Entering Case: SSL_CTRL_EXTRA_CHAIN_CERT.");
47294         if (pt == NULL) {
47295             WOLFSSL_MSG("Passed in x509 pointer NULL.");
47296             ret = WOLFSSL_FAILURE;
47297             break;
47298         }
47299         return wolfSSL_CTX_add_extra_chain_cert(ctx, (WOLFSSL_X509*)pt);
47300 
47301 #ifndef NO_DH
47302     case SSL_CTRL_SET_TMP_DH:
47303         WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_DH.");
47304         if (pt == NULL) {
47305             WOLFSSL_MSG("Passed in DH pointer NULL.");
47306             ret = WOLFSSL_FAILURE;
47307             break;
47308         }
47309         return wolfSSL_CTX_set_tmp_dh(ctx, (WOLFSSL_DH*)pt);
47310 #endif
47311 
47312 #ifdef HAVE_ECC
47313     case SSL_CTRL_SET_TMP_ECDH:
47314         WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_ECDH.");
47315         if (pt == NULL) {
47316             WOLFSSL_MSG("Passed in ECDH pointer NULL.");
47317             ret = WOLFSSL_FAILURE;
47318             break;
47319         }
47320         return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx, (WOLFSSL_EC_KEY*)pt);
47321 #endif
47322     case SSL_CTRL_MODE:
47323         wolfSSL_CTX_set_mode(ctx,opt);
47324         break;
47325     case SSL_CTRL_SET_MIN_PROTO_VERSION:
47326         WOLFSSL_MSG("set min proto version");
47327         return wolfSSL_CTX_set_min_proto_version(ctx, (int)opt);
47328     case SSL_CTRL_SET_MAX_PROTO_VERSION:
47329         WOLFSSL_MSG("set max proto version");
47330         return wolfSSL_CTX_set_max_proto_version(ctx, (int)opt);
47331     case SSL_CTRL_GET_MIN_PROTO_VERSION:
47332         WOLFSSL_MSG("get min proto version");
47333         return wolfSSL_CTX_get_min_proto_version(ctx);
47334     case SSL_CTRL_GET_MAX_PROTO_VERSION:
47335         WOLFSSL_MSG("get max proto version");
47336         return wolfSSL_CTX_get_max_proto_version(ctx);
47337     default:
47338         WOLFSSL_MSG("CTX_ctrl cmd not implemented");
47339         ret = WOLFSSL_FAILURE;
47340         break;
47341     }
47342 
47343     (void)ctx;
47344     (void)cmd;
47345     (void)opt;
47346     (void)pt;
47347     WOLFSSL_LEAVE("wolfSSL_CTX_ctrl", (int)ret);
47348     return ret;
47349 }
47350 
47351 #ifndef WOLFSSL_NO_STUB
wolfSSL_CTX_callback_ctrl(WOLFSSL_CTX * ctx,int cmd,void (* fp)(void))47352 long wolfSSL_CTX_callback_ctrl(WOLFSSL_CTX* ctx, int cmd, void (*fp)(void))
47353 {
47354     (void) ctx;
47355     (void) cmd;
47356     (void) fp;
47357     WOLFSSL_STUB("wolfSSL_CTX_callback_ctrl");
47358     return WOLFSSL_FAILURE;
47359 
47360 }
47361 #endif /* WOLFSSL_NO_STUB */
47362 
47363 #ifndef NO_WOLFSSL_STUB
wolfSSL_CTX_clear_extra_chain_certs(WOLFSSL_CTX * ctx)47364 long wolfSSL_CTX_clear_extra_chain_certs(WOLFSSL_CTX* ctx)
47365 {
47366     return wolfSSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS, 0l, NULL);
47367 }
47368 #endif
47369 
47370 /* Returns the verifyCallback from the ssl structure if successful.
47371 Returns NULL otherwise. */
wolfSSL_get_verify_callback(WOLFSSL * ssl)47372 VerifyCallback wolfSSL_get_verify_callback(WOLFSSL* ssl)
47373 {
47374     WOLFSSL_ENTER("wolfSSL_get_verify_callback()");
47375     if (ssl) {
47376         return ssl->verifyCallback;
47377     }
47378     return NULL;
47379 }
47380 
47381 #ifndef NO_BIO
47382 
47383 #if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
47384     !defined(NO_RSA) && !defined(HAVE_USER_RSA)
47385 /* Converts an rsa key from a bio buffer into an internal rsa structure.
47386 Returns a pointer to the new WOLFSSL_RSA structure. */
wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO * bio,WOLFSSL_RSA ** out)47387 WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out)
47388 {
47389     const unsigned char* bioMem = NULL;
47390     int bioMemSz = 0;
47391     WOLFSSL_RSA* key = NULL;
47392     unsigned char *maxKeyBuf = NULL;
47393     unsigned char* bufPtr = NULL;
47394     unsigned char* extraBioMem = NULL;
47395     int extraBioMemSz = 0;
47396     int derLength = 0;
47397     int j = 0, i = 0;
47398 
47399     WOLFSSL_ENTER("wolfSSL_d2i_RSAPrivateKey_bio()");
47400 
47401     if (bio == NULL) {
47402         WOLFSSL_MSG("Bad Function Argument");
47403         return NULL;
47404     }
47405     (void)out;
47406 
47407     bioMemSz = wolfSSL_BIO_get_len(bio);
47408     if (bioMemSz <= 0) {
47409         WOLFSSL_MSG("wolfSSL_BIO_get_len() failure");
47410         return NULL;
47411     }
47412 
47413     bioMem = (unsigned char*)XMALLOC(bioMemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47414     if (bioMem == NULL) {
47415         WOLFSSL_MSG("Malloc failure");
47416         return NULL;
47417     }
47418 
47419     maxKeyBuf = (unsigned char*)XMALLOC(4096, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47420     if (maxKeyBuf == NULL) {
47421         WOLFSSL_MSG("Malloc failure");
47422         XFREE((unsigned char*)bioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47423         return NULL;
47424     }
47425     bufPtr = maxKeyBuf;
47426     if (wolfSSL_BIO_read(bio, (unsigned char*)bioMem, (int)bioMemSz) == bioMemSz) {
47427         const byte* bioMemPt = bioMem; /* leave bioMem pointer unaltered */
47428         if ((key = wolfSSL_d2i_RSAPrivateKey(NULL, &bioMemPt, bioMemSz)) == NULL) {
47429             XFREE((unsigned char*)bioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47430             XFREE((unsigned char*)maxKeyBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47431             return NULL;
47432         }
47433 
47434         /* This function is used to get the total length of the rsa key. */
47435         derLength = wolfSSL_i2d_RSAPrivateKey(key, &bufPtr);
47436 
47437         /* Write extra data back into bio object if necessary. */
47438         extraBioMemSz = (bioMemSz - derLength);
47439         if (extraBioMemSz > 0) {
47440             extraBioMem = (unsigned char *)XMALLOC(extraBioMemSz, NULL,
47441                                                        DYNAMIC_TYPE_TMP_BUFFER);
47442             if (extraBioMem == NULL) {
47443                 WOLFSSL_MSG("Malloc failure");
47444                 XFREE((unsigned char*)extraBioMem, bio->heap,
47445                                                        DYNAMIC_TYPE_TMP_BUFFER);
47446                 XFREE((unsigned char*)bioMem, bio->heap,
47447                                                        DYNAMIC_TYPE_TMP_BUFFER);
47448                 XFREE((unsigned char*)maxKeyBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47449                 return NULL;
47450             }
47451 
47452             for (i = derLength; i < bioMemSz; i++) {
47453                 *(extraBioMem + j) = *(bioMem + i);
47454                 j++;
47455             }
47456 
47457             wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz);
47458             if (wolfSSL_BIO_get_len(bio) <= 0) {
47459                 WOLFSSL_MSG("Failed to write memory to bio");
47460                 XFREE((unsigned char*)extraBioMem, bio->heap,
47461                                                        DYNAMIC_TYPE_TMP_BUFFER);
47462                 XFREE((unsigned char*)bioMem, bio->heap,
47463                                                        DYNAMIC_TYPE_TMP_BUFFER);
47464                 XFREE((unsigned char*)maxKeyBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47465                 return NULL;
47466             }
47467             XFREE((unsigned char*)extraBioMem, bio->heap,
47468                                                        DYNAMIC_TYPE_TMP_BUFFER);
47469         }
47470 
47471         if (out != NULL && key != NULL) {
47472             *out = key;
47473         }
47474     }
47475     XFREE((unsigned char*)bioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47476     XFREE((unsigned char*)maxKeyBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47477     return key;
47478 }
47479 #endif /* !HAVE_FAST_RSA && WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
47480 
47481 #endif /* !NO_BIO */
47482 
47483 
47484 /* Adds the ASN1 certificate to the user ctx.
47485 Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/
wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX * ctx,int derSz,const unsigned char * der)47486 int wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX *ctx, int derSz,
47487                                                        const unsigned char *der)
47488 {
47489     WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_ASN1()");
47490     if (der != NULL && ctx != NULL) {
47491         if (wolfSSL_CTX_use_certificate_buffer(ctx, der, derSz,
47492                                       WOLFSSL_FILETYPE_ASN1) == WOLFSSL_SUCCESS) {
47493             return WOLFSSL_SUCCESS;
47494         }
47495 
47496     }
47497     return WOLFSSL_FAILURE;
47498 }
47499 
47500 
47501 #if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
47502     !defined(NO_RSA) && !defined(HAVE_USER_RSA)
47503 /* Adds the rsa private key to the user ctx.
47504 Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/
wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX * ctx,WOLFSSL_RSA * rsa)47505 int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa)
47506 {
47507     int ret;
47508     int derSize;
47509     unsigned char *maxDerBuf;
47510     unsigned char* key = NULL;
47511 
47512     WOLFSSL_ENTER("wolfSSL_CTX_use_RSAPrivateKey()");
47513 
47514     if (ctx == NULL || rsa == NULL) {
47515         WOLFSSL_MSG("one or more inputs were NULL");
47516         return BAD_FUNC_ARG;
47517     }
47518     maxDerBuf = (unsigned char*)XMALLOC(4096, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47519     if (maxDerBuf == NULL) {
47520         WOLFSSL_MSG("Malloc failure");
47521         return MEMORY_E;
47522     }
47523     key = maxDerBuf;
47524     /* convert RSA struct to der encoded buffer and get the size */
47525     if ((derSize = wolfSSL_i2d_RSAPrivateKey(rsa, &key)) <= 0) {
47526         WOLFSSL_MSG("wolfSSL_i2d_RSAPrivateKey() failure");
47527         XFREE(maxDerBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47528         return WOLFSSL_FAILURE;
47529     }
47530     ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, (const unsigned char*)maxDerBuf,
47531                                                     derSize, SSL_FILETYPE_ASN1);
47532     if (ret != WOLFSSL_SUCCESS) {
47533         WOLFSSL_MSG("wolfSSL_CTX_USE_PrivateKey_buffer() failure");
47534         XFREE(maxDerBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47535         return WOLFSSL_FAILURE;
47536     }
47537     XFREE(maxDerBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
47538     return ret;
47539 }
47540 #endif /* NO_RSA && !HAVE_FAST_RSA */
47541 
47542 
47543 #ifndef NO_BIO
47544 /* Converts EVP_PKEY data from a bio buffer to a WOLFSSL_EVP_PKEY structure.
47545 Returns pointer to private EVP_PKEY struct upon success, NULL if there
47546 is a failure.*/
wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO * bio,WOLFSSL_EVP_PKEY ** out)47547 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio,
47548                                                          WOLFSSL_EVP_PKEY** out)
47549 {
47550     unsigned char* mem = NULL;
47551     int memSz = 0;
47552     WOLFSSL_EVP_PKEY* key = NULL;
47553     int i = 0, j = 0;
47554     unsigned char* extraBioMem = NULL;
47555     int extraBioMemSz = 0;
47556     int derLength = 0;
47557 
47558     WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey_bio()");
47559 
47560     if (bio == NULL) {
47561         return NULL;
47562     }
47563     (void)out;
47564 
47565     memSz = wolfSSL_BIO_get_len(bio);
47566     if (memSz <= 0) {
47567         WOLFSSL_MSG("wolfSSL_BIO_get_len() failure");
47568         return NULL;
47569     }
47570 
47571     mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47572     if (mem == NULL) {
47573         WOLFSSL_MSG("Malloc failure");
47574         return NULL;
47575     }
47576 
47577     if (wolfSSL_BIO_read(bio, (unsigned char*)mem, memSz) == memSz) {
47578         /* Determines key type and returns the new private EVP_PKEY object */
47579         if ((key = wolfSSL_d2i_PrivateKey_EVP(NULL, &mem, (long)memSz)) == NULL) {
47580             WOLFSSL_MSG("wolfSSL_d2i_PrivateKey_EVP() failure");
47581             XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47582             return NULL;
47583         }
47584 
47585         /* Write extra data back into bio object if necessary. */
47586         derLength = key->pkey_sz;
47587         extraBioMemSz = (memSz - derLength);
47588         if (extraBioMemSz > 0) {
47589             extraBioMem = (unsigned char *)XMALLOC(extraBioMemSz, NULL,
47590                                                        DYNAMIC_TYPE_TMP_BUFFER);
47591             if (extraBioMem == NULL) {
47592                 WOLFSSL_MSG("Malloc failure");
47593                 XFREE((unsigned char*)extraBioMem, bio->heap,
47594                                                        DYNAMIC_TYPE_TMP_BUFFER);
47595                 XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47596                 return NULL;
47597             }
47598 
47599             for (i = derLength; i < memSz; i++) {
47600                 *(extraBioMem + j) = *(mem + i);
47601                 j++;
47602             }
47603 
47604             wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz);
47605             if (wolfSSL_BIO_get_len(bio) <= 0) {
47606                 WOLFSSL_MSG("Failed to write memory to bio");
47607                 XFREE((unsigned char*)extraBioMem, bio->heap,
47608                                                        DYNAMIC_TYPE_TMP_BUFFER);
47609                 XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47610                 return NULL;
47611             }
47612             XFREE((unsigned char*)extraBioMem, bio->heap,
47613                                                        DYNAMIC_TYPE_TMP_BUFFER);
47614         }
47615 
47616         if (out != NULL) {
47617             *out = key;
47618         }
47619     }
47620     XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
47621     return key;
47622 }
47623 #endif /* !NO_BIO */
47624 
47625 #endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */
47626 
47627 
47628 #if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) || \
47629     defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) || defined(WOLFSSL_WPAS_SMALL)
47630 
47631 /* Converts a DER encoded private key to a WOLFSSL_EVP_PKEY structure.
47632  * returns a pointer to a new WOLFSSL_EVP_PKEY structure on success and NULL
47633  * on fail */
wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY ** out,unsigned char ** in,long inSz)47634 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** out,
47635                                                   unsigned char** in, long inSz)
47636 {
47637     WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey_EVP");
47638     return d2iGenericKey(out, (const unsigned char**)in, inSz, 1);
47639 }
47640 
47641 #endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT || WOLFSSL_WPAS_SMALL*/
47642 
47643 
47644 /* stunnel compatibility functions*/
47645 #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
47646                              defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
47647                              defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
wolfSSL_ERR_remove_thread_state(void * pid)47648 void wolfSSL_ERR_remove_thread_state(void* pid)
47649 {
47650     (void) pid;
47651     return;
47652 }
47653 
47654 #ifndef NO_FILESYSTEM
47655 /***TBD ***/
wolfSSL_print_all_errors_fp(XFILE fp)47656 void wolfSSL_print_all_errors_fp(XFILE fp)
47657 {
47658     (void)fp;
47659 }
47660 #endif /* !NO_FILESYSTEM */
47661 
47662 #endif /* OPENSSL_ALL || OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
47663     HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH */
47664 
47665 
47666 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
47667     defined(HAVE_EX_DATA)
wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION * session,int idx,void * data)47668 int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
47669 {
47670     WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
47671 #ifdef HAVE_EX_DATA
47672     session = GetSessionPtr(session);
47673     if (session != NULL) {
47674         return wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx, data);
47675     }
47676 #else
47677     (void)session;
47678     (void)idx;
47679     (void)data;
47680 #endif
47681     return WOLFSSL_FAILURE;
47682 }
47683 
47684 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
wolfSSL_SESSION_set_ex_data_with_cleanup(WOLFSSL_SESSION * session,int idx,void * data,wolfSSL_ex_data_cleanup_routine_t cleanup_routine)47685 int wolfSSL_SESSION_set_ex_data_with_cleanup(
47686     WOLFSSL_SESSION* session,
47687     int idx,
47688     void* data,
47689     wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
47690 {
47691     WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data_with_cleanup");
47692     if(session != NULL) {
47693         return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&session->ex_data, idx,
47694                                                        data, cleanup_routine);
47695     }
47696     return WOLFSSL_FAILURE;
47697 }
47698 #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
47699 
wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION * session,int idx)47700 void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
47701 {
47702     WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data");
47703 #ifdef HAVE_EX_DATA
47704     if (session != NULL) {
47705         return wolfSSL_CRYPTO_get_ex_data(&session->ex_data, idx);
47706     }
47707 #else
47708     (void)session;
47709     (void)idx;
47710 #endif
47711     return NULL;
47712 }
47713 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_EX_DATA */
47714 
47715 #if defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
47716         defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
47717         defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)
47718 
WOLF_STACK_OF(WOLFSSL_X509_NAME)47719 WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new(wolf_sk_compare_cb cb)
47720 {
47721     WOLFSSL_STACK* sk;
47722     (void)cb;
47723 
47724     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_new");
47725 
47726     sk = wolfSSL_sk_new_node(NULL);
47727     if (sk != NULL) {
47728         sk->type = STACK_TYPE_X509_NAME;
47729 #ifdef OPENSSL_ALL
47730         sk->comp = cb;
47731 #endif
47732     }
47733 
47734     return sk;
47735 }
47736 
wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF (WOLFSSL_X509_NAME)* sk)47737 int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk)
47738 {
47739     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
47740 
47741     if (sk == NULL)
47742         return BAD_FUNC_ARG;
47743 
47744     return (int)sk->num;
47745 }
47746 
47747 /* Getter function for WOLFSSL_X509_NAME pointer
47748  *
47749  * sk is the stack to retrieve pointer from
47750  * i  is the index value in stack
47751  *
47752  * returns a pointer to a WOLFSSL_X509_NAME structure on success and NULL on
47753  *         fail
47754  */
wolfSSL_sk_X509_NAME_value(const STACK_OF (WOLFSSL_X509_NAME)* sk,int i)47755 WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(const STACK_OF(WOLFSSL_X509_NAME)* sk,
47756     int i)
47757 {
47758     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
47759     return (WOLFSSL_X509_NAME*)wolfSSL_sk_value(sk, i);
47760 }
47761 
wolfSSL_sk_X509_NAME_pop(WOLF_STACK_OF (WOLFSSL_X509_NAME)* sk)47762 WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
47763 {
47764     WOLFSSL_STACK* node;
47765     WOLFSSL_X509_NAME* name;
47766 
47767     if (sk == NULL) {
47768         return NULL;
47769     }
47770 
47771     node = sk->next;
47772     name = sk->data.name;
47773 
47774     if (node != NULL) { /* update sk and remove node from stack */
47775         sk->data.name = node->data.name;
47776         sk->next = node->next;
47777         XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
47778     }
47779     else { /* last x509 in stack */
47780         sk->data.name = NULL;
47781     }
47782 
47783     if (sk->num > 0) {
47784         sk->num -= 1;
47785     }
47786 
47787     return name;
47788 }
47789 
wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF (WOLFSSL_X509_NAME)* sk,void (* f)(WOLFSSL_X509_NAME *))47790 void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
47791     void (*f) (WOLFSSL_X509_NAME*))
47792 {
47793     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
47794     wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
47795 }
47796 
47797 /* Free only the sk structure, NOT X509_NAME members */
wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF (WOLFSSL_X509_NAME)* sk)47798 void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
47799 {
47800     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_free");
47801     wolfSSL_sk_free(sk);
47802 }
47803 
wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF (WOLFSSL_X509_NAME)* sk,WOLFSSL_X509_NAME * name)47804 int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
47805     WOLFSSL_X509_NAME* name)
47806 {
47807     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_push");
47808 
47809     return wolfSSL_sk_push(sk, name);
47810 }
47811 
47812 /* return index of found, or negative to indicate not found */
wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF (WOLFSSL_X509_NAME)* sk,WOLFSSL_X509_NAME * name)47813 int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk,
47814     WOLFSSL_X509_NAME *name)
47815 {
47816     int i;
47817 
47818     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_find");
47819 
47820     if (sk == NULL)
47821         return BAD_FUNC_ARG;
47822 
47823     for (i = 0; sk; i++, sk = sk->next) {
47824         if (wolfSSL_X509_NAME_cmp(sk->data.name, name) == 0) {
47825             return i;
47826         }
47827     }
47828     return -1;
47829 }
47830 
47831 #endif /* OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
47832             HAVE_LIGHTY || WOLFSSL_HAPROXY ||
47833             WOLFSSL_OPENSSH || HAVE_SBLIM_SFCB */
47834 
47835 /* Note: This is a huge section of API's - through
47836  *       wolfSSL_X509_OBJECT_get0_X509_CRL */
47837 #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
47838     (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
47839     defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
47840     defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
wolfSSL_SESSION_get_ex_new_index(long idx,void * data,void * cb1,void * cb2,CRYPTO_free_func * cb3)47841 int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1,
47842        void* cb2, CRYPTO_free_func* cb3)
47843 {
47844     WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_new_index");
47845     (void)idx;
47846     (void)cb1;
47847     (void)cb2;
47848     (void)cb3;
47849     if (XSTRNCMP((const char*)data, "redirect index", 14) == 0) {
47850         return 0;
47851     }
47852     else if (XSTRNCMP((const char*)data, "addr index", 10) == 0) {
47853         return 1;
47854     }
47855     return WOLFSSL_FAILURE;
47856 }
47857 
wolfSSL_CRYPTO_set_mem_functions(wolfSSL_Malloc_cb m,wolfSSL_Realloc_cb r,wolfSSL_Free_cb f)47858 int wolfSSL_CRYPTO_set_mem_functions(
47859         wolfSSL_Malloc_cb  m,
47860         wolfSSL_Realloc_cb r,
47861         wolfSSL_Free_cb    f)
47862 {
47863 #ifdef USE_WOLFSSL_MEMORY
47864     if (wolfSSL_SetAllocators(m, f, r) == 0)
47865         return WOLFSSL_SUCCESS;
47866     else
47867         return WOLFSSL_FAILURE;
47868 #else
47869     (void)m;
47870     (void)r;
47871     (void)f;
47872     WOLFSSL_MSG("wolfSSL allocator callback functions not compiled in");
47873     return WOLFSSL_FAILURE;
47874 #endif
47875 }
47876 
47877 #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST) && !defined(NO_DH)
wolfSSL_DH_generate_parameters(int prime_len,int generator,void (* callback)(int,int,void *),void * cb_arg)47878 WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
47879                            void (*callback) (int, int, void *), void *cb_arg)
47880 {
47881     WOLFSSL_DH* dh;
47882 
47883     WOLFSSL_ENTER("wolfSSL_DH_generate_parameters");
47884     (void)callback;
47885     (void)cb_arg;
47886 
47887     if ((dh = wolfSSL_DH_new()) == NULL) {
47888         WOLFSSL_MSG("wolfSSL_DH_new error");
47889         return NULL;
47890     }
47891 
47892     if (wolfSSL_DH_generate_parameters_ex(dh, prime_len, generator, NULL)
47893             != WOLFSSL_SUCCESS) {
47894         WOLFSSL_MSG("wolfSSL_DH_generate_parameters_ex error");
47895         wolfSSL_DH_free(dh);
47896         return NULL;
47897     }
47898 
47899     return dh;
47900 }
47901 
wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH * dh,int prime_len,int generator,void (* callback)(int,int,void *))47902 int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, int generator,
47903                            void (*callback) (int, int, void *))
47904 {
47905     DhKey* key;
47906 
47907     WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex");
47908     (void)callback;
47909     (void)generator;
47910 
47911     if (dh == NULL) {
47912         WOLFSSL_MSG("Bad parameter");
47913         return WOLFSSL_FAILURE;
47914     }
47915 
47916     if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
47917         WOLFSSL_MSG("No RNG to use");
47918         return WOLFSSL_FAILURE;
47919     }
47920 
47921     /* Don't need SetDhInternal call since we are generating
47922      * parameters ourselves */
47923 
47924     key = (DhKey*)dh->internal;
47925 
47926     /* Free so that mp_init's don't leak */
47927     wc_FreeDhKey(key);
47928 
47929     if (wc_DhGenerateParams(&globalRNG, prime_len, key) != 0) {
47930         WOLFSSL_MSG("wc_DhGenerateParams error");
47931         return WOLFSSL_FAILURE;
47932     }
47933     dh->inSet = 1;
47934 
47935     WOLFSSL_MSG("wolfSSL does not support using a custom generator.");
47936 
47937     if (SetDhExternal(dh) != WOLFSSL_SUCCESS) {
47938         WOLFSSL_MSG("SetDhExternal error");
47939         return WOLFSSL_FAILURE;
47940     }
47941 
47942     return WOLFSSL_SUCCESS;
47943 }
47944 #endif /* WOLFSSL_KEY_GEN && !HAVE_SELFTEST && !NO_DH */
47945 
wolfSSL_ERR_load_ERR_strings(void)47946 int wolfSSL_ERR_load_ERR_strings(void)
47947 {
47948     return WOLFSSL_SUCCESS;
47949 }
47950 
wolfSSL_ERR_load_crypto_strings(void)47951 void wolfSSL_ERR_load_crypto_strings(void)
47952 {
47953     WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
47954     /* Do nothing */
47955     return;
47956 }
47957 
47958 #ifndef NO_WOLFSSL_STUB
wolfSSL_FIPS_mode(void)47959 int wolfSSL_FIPS_mode(void)
47960 {
47961     WOLFSSL_ENTER("wolfSSL_FIPS_mode");
47962     WOLFSSL_STUB("FIPS_mode");
47963 
47964     return WOLFSSL_FAILURE;
47965 }
47966 #endif
47967 
47968 #ifndef NO_WOLFSSL_STUB
wolfSSL_FIPS_mode_set(int r)47969 int wolfSSL_FIPS_mode_set(int r)
47970 {
47971     (void)r;
47972     WOLFSSL_ENTER("wolfSSL_FIPS_mode_set");
47973     WOLFSSL_STUB("FIPS_mode_set");
47974 
47975     return WOLFSSL_FAILURE;
47976 }
47977 #endif
47978 
wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER * c,int * alg_bits)47979 int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
47980 {
47981     int ret = WOLFSSL_FAILURE;
47982     WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
47983 
47984     #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
47985     (void)alg_bits;
47986     if (c!= NULL)
47987         ret = c->bits;
47988     #else
47989     if (c != NULL && c->ssl != NULL) {
47990         ret = 8 * c->ssl->specs.key_size;
47991         if (alg_bits != NULL) {
47992             *alg_bits = ret;
47993         }
47994     }
47995     #endif
47996     return ret;
47997 }
47998 
47999 #if defined(OPENSSL_ALL)
wolfSSL_X509_INFO_new(void)48000 WOLFSSL_X509_INFO* wolfSSL_X509_INFO_new(void)
48001 {
48002     WOLFSSL_X509_INFO* info;
48003     info = (WOLFSSL_X509_INFO*)XMALLOC(sizeof(WOLFSSL_X509_INFO), NULL,
48004         DYNAMIC_TYPE_X509);
48005     if (info) {
48006         XMEMSET(info, 0, sizeof(*info));
48007     }
48008     return info;
48009 }
48010 
wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO * info)48011 void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info)
48012 {
48013     if (info == NULL)
48014         return;
48015 
48016     if (info->x509) {
48017         wolfSSL_X509_free(info->x509);
48018         info->x509 = NULL;
48019     }
48020 #ifdef HAVE_CRL
48021     if (info->crl) {
48022         wolfSSL_X509_CRL_free(info->crl);
48023         info->crl = NULL;
48024     }
48025 #endif
48026     wolfSSL_X509_PKEY_free(info->x_pkey);
48027     info->x_pkey = NULL;
48028 
48029     XFREE(info, NULL, DYNAMIC_TYPE_X509);
48030 }
48031 #endif
48032 
wolfSSL_sk_X509_INFO_new_null(void)48033 WOLFSSL_STACK* wolfSSL_sk_X509_INFO_new_null(void)
48034 {
48035     WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
48036     if (sk) {
48037         sk->type = STACK_TYPE_X509_INFO;
48038     }
48039     return sk;
48040 }
48041 
48042 /* returns value less than 0 on fail to match
48043  * On a successful match the priority level found is returned
48044  */
wolfSSL_sk_SSL_CIPHER_find(WOLF_STACK_OF (WOLFSSL_CIPHER)* sk,const WOLFSSL_CIPHER * toFind)48045 int wolfSSL_sk_SSL_CIPHER_find(
48046         WOLF_STACK_OF(WOLFSSL_CIPHER)* sk, const WOLFSSL_CIPHER* toFind)
48047 {
48048     WOLFSSL_STACK* next;
48049     int i, sz;
48050 
48051     if (sk == NULL || toFind == NULL) {
48052         return WOLFSSL_FATAL_ERROR;
48053     }
48054 
48055     sz   = wolfSSL_sk_SSL_CIPHER_num(sk);
48056     next = sk;
48057     for (i = 0; i < sz && next != NULL; i++) {
48058         if (next->data.cipher.cipherSuite0 == toFind->cipherSuite0 &&
48059                 next->data.cipher.cipherSuite == toFind->cipherSuite) {
48060             return sz - i; /* reverse because stack pushed highest on first */
48061         }
48062         next = next->next;
48063     }
48064     return WOLFSSL_FATAL_ERROR;
48065 }
48066 
48067 /* free's all nodes in the stack and there data */
wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF (WOLFSSL_CIPHER)* sk)48068 void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
48069 {
48070     WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_free");
48071     wolfSSL_sk_free(sk);
48072 }
48073 
wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF (WOLFSSL_X509_INFO)* sk)48074 int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
48075 {
48076     WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_num");
48077 
48078     return wolfSSL_sk_num(sk);
48079 }
48080 
wolfSSL_sk_X509_INFO_value(const WOLF_STACK_OF (WOLFSSL_X509_INFO)* sk,int i)48081 WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value(
48082         const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk, int i)
48083 {
48084     WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_value");
48085 
48086     return (WOLFSSL_X509_INFO *)wolfSSL_sk_value(sk, i);
48087 }
48088 
wolfSSL_sk_X509_INFO_pop(WOLF_STACK_OF (WOLFSSL_X509_INFO)* sk)48089 WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(
48090         WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk)
48091 {
48092     WOLFSSL_STACK* node;
48093     WOLFSSL_X509_INFO* info;
48094 
48095     if (sk == NULL) {
48096         return NULL;
48097     }
48098 
48099     node = sk->next;
48100     info = sk->data.info;
48101 
48102     if (node != NULL) { /* update sk and remove node from stack */
48103         sk->data.info = node->data.info;
48104         sk->next = node->next;
48105         wolfSSL_sk_free_node(node);
48106     }
48107     else { /* last x509 in stack */
48108         sk->data.info = NULL;
48109     }
48110 
48111     if (sk->num > 0) {
48112         sk->num -= 1;
48113     }
48114 
48115     return info;
48116 }
48117 
48118 #if defined(OPENSSL_ALL)
wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF (WOLFSSL_X509_INFO)* sk,void (* f)(WOLFSSL_X509_INFO *))48119 void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
48120     void (*f) (WOLFSSL_X509_INFO*))
48121 {
48122     WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_pop_free");
48123     wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
48124 }
48125 
wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF (WOLFSSL_X509_INFO)* sk)48126 void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
48127 {
48128     WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_free");
48129     wolfSSL_sk_free(sk);
48130 }
48131 
48132 /* Adds the WOLFSSL_X509_INFO to the stack "sk". "sk" takes control of "in" and
48133  * tries to free it when the stack is free'd.
48134  *
48135  * return 1 on success 0 on fail
48136  */
wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF (WOLFSSL_X509_INFO)* sk,WOLFSSL_X509_INFO * in)48137 int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
48138                                                       WOLFSSL_X509_INFO* in)
48139 {
48140     return wolfSSL_sk_push(sk, in);
48141 }
48142 
48143 /* Creates a duplicate of WOLF_STACK_OF(WOLFSSL_X509_NAME).
48144  * Returns a new WOLF_STACK_OF(WOLFSSL_X509_NAME) or NULL on failure */
WOLF_STACK_OF(WOLFSSL_X509_NAME)48145 WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list(
48146     WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
48147 {
48148     int i;
48149     const int num = wolfSSL_sk_X509_NAME_num(sk);
48150     WOLF_STACK_OF(WOLFSSL_X509_NAME) *copy;
48151     WOLFSSL_X509_NAME *name;
48152 
48153     WOLFSSL_ENTER("wolfSSL_dup_CA_list");
48154 
48155     copy = wolfSSL_sk_X509_NAME_new(sk->comp);
48156     if (copy == NULL) {
48157         WOLFSSL_MSG("Memory error");
48158         return NULL;
48159     }
48160 
48161     for (i = 0; i < num; i++) {
48162         name = wolfSSL_X509_NAME_dup(wolfSSL_sk_X509_NAME_value(sk, i));
48163         if (name == NULL || 0 != wolfSSL_sk_X509_NAME_push(copy, name)) {
48164             WOLFSSL_MSG("Memory error");
48165             wolfSSL_sk_X509_NAME_pop_free(copy, wolfSSL_X509_NAME_free);
48166             return NULL;
48167         }
48168     }
48169 
48170     return copy;
48171 }
48172 
wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF (WOLFSSL_X509_OBJECT)* sk,int i)48173 void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i)
48174 {
48175     WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_value");
48176     for (; sk != NULL && i > 0; i--)
48177         sk = sk->next;
48178 
48179     if (i != 0 || sk == NULL)
48180         return NULL;
48181     return sk->data.x509_obj;
48182 }
48183 
wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF (WOLFSSL_X509_OBJECT)* s)48184 int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s)
48185 {
48186     WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_num");
48187     if (s) {
48188         return (int)s->num;
48189     } else {
48190         return 0;
48191     }
48192 }
48193 
wolfSSL_sk_X509_NAME_set_cmp_func(WOLF_STACK_OF (WOLFSSL_X509_NAME)* sk,wolf_sk_compare_cb cb)48194 int wolfSSL_sk_X509_NAME_set_cmp_func(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
48195     wolf_sk_compare_cb cb)
48196 {
48197     WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_set_cmp_func");
48198 
48199     if (sk == NULL)
48200         return BAD_FUNC_ARG;
48201 
48202     sk->comp = cb;
48203     return 0;
48204 }
48205 #endif /* OPENSSL_ALL */
48206 
48207 #ifndef NO_BIO
48208 
48209 #if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
48210 /* Helper function for X509_NAME_print_ex. Sets *buf to string for domain
48211    name attribute based on NID. Returns size of buf */
get_dn_attr_by_nid(int n,const char ** buf)48212 static int get_dn_attr_by_nid(int n, const char** buf)
48213 {
48214     int len = 0;
48215     const char *str;
48216 
48217     switch(n)
48218     {
48219         case NID_commonName :
48220             str = "CN";
48221             len = 2;
48222             break;
48223         case NID_countryName:
48224             str = "C";
48225             len = 1;
48226             break;
48227         case NID_localityName:
48228             str = "L";
48229             len = 1;
48230             break;
48231         case NID_stateOrProvinceName:
48232             str = "ST";
48233             len = 2;
48234             break;
48235         case NID_organizationName:
48236             str = "O";
48237             len = 1;
48238             break;
48239         case NID_organizationalUnitName:
48240             str = "OU";
48241             len = 2;
48242             break;
48243         case NID_emailAddress:
48244             str = "emailAddress";
48245             len = 12;
48246             break;
48247         default:
48248             WOLFSSL_MSG("Attribute type not found");
48249             str = NULL;
48250 
48251     }
48252     if (buf != NULL)
48253         *buf = str;
48254     return len;
48255 }
48256 #endif
48257 
48258 /*
48259  * The BIO output of  wolfSSL_X509_NAME_print_ex does NOT include the null terminator
48260  */
wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO * bio,WOLFSSL_X509_NAME * name,int indent,unsigned long flags)48261 int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
48262                 int indent, unsigned long flags)
48263 {
48264 #if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
48265     int count = 0, len = 0, totalSz = 0, tmpSz = 0;
48266     char tmp[ASN_NAME_MAX+1];
48267     char fullName[ASN_NAME_MAX+2];
48268     const char *buf = NULL;
48269     WOLFSSL_X509_NAME_ENTRY* ne;
48270     WOLFSSL_ASN1_STRING* str;
48271 #endif
48272     int i;
48273     (void)flags;
48274     WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
48275 
48276     for (i = 0; i < indent; i++) {
48277         if (wolfSSL_BIO_write(bio, " ", 1) != 1)
48278             return WOLFSSL_FAILURE;
48279     }
48280 
48281     if ((name == NULL) || (name->sz == 0))
48282         return WOLFSSL_FAILURE;
48283 
48284 #if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
48285     /* If XN_FLAG_DN_REV is present, print X509_NAME in reverse order */
48286     if (flags == (XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV)) {
48287         fullName[0] = '\0';
48288         count = wolfSSL_X509_NAME_entry_count(name);
48289         for (i = 0; i < count; i++) {
48290             ne = wolfSSL_X509_NAME_get_entry(name, count - i - 1);
48291             if (ne == NULL)
48292                 return WOLFSSL_FAILURE;
48293 
48294             str = wolfSSL_X509_NAME_ENTRY_get_data(ne);
48295             if (str == NULL)
48296                 return WOLFSSL_FAILURE;
48297 
48298             len = get_dn_attr_by_nid(ne->nid, &buf);
48299             if (len == 0 || buf == NULL)
48300                 return WOLFSSL_FAILURE;
48301 
48302             tmpSz = str->length + len + 2; /* + 2 for '=' and comma */
48303             if (tmpSz > ASN_NAME_MAX) {
48304                 WOLFSSL_MSG("Size greater than ASN_NAME_MAX");
48305                 return WOLFSSL_FAILURE;
48306             }
48307 
48308             if (i < count - 1) {
48309                 /* tmpSz+1 for last null char */
48310                 XSNPRINTF(tmp, tmpSz+1, "%s=%s,", buf, str->data);
48311                 XSTRNCAT(fullName, tmp, tmpSz+1);
48312             }
48313             else {
48314                 XSNPRINTF(tmp, tmpSz, "%s=%s", buf, str->data);
48315                 XSTRNCAT(fullName, tmp, tmpSz-1);
48316                 tmpSz--; /* Don't include null char in tmpSz */
48317             }
48318             totalSz += tmpSz;
48319         }
48320         if (wolfSSL_BIO_write(bio, fullName, totalSz) != totalSz)
48321             return WOLFSSL_FAILURE;
48322         return WOLFSSL_SUCCESS;
48323     }
48324 #else
48325     if (flags == XN_FLAG_RFC2253) {
48326         if ((name->sz < 3) ||
48327             (wolfSSL_BIO_write(bio, name->name + 1, name->sz - 2)
48328                                                             != name->sz - 2))
48329             return WOLFSSL_FAILURE;
48330     }
48331 #endif /* WOLFSSL_APACHE_HTTPD || OPENSSL_ALL || WOLFSSL_NGINX */
48332     else {
48333         if ((name->sz < 2) ||
48334             (wolfSSL_BIO_write(bio, name->name, name->sz - 1) != name->sz - 1))
48335         return WOLFSSL_FAILURE;
48336     }
48337     return WOLFSSL_SUCCESS;
48338 }
48339 
48340 #ifndef NO_FILESYSTEM
wolfSSL_X509_NAME_print_ex_fp(XFILE file,WOLFSSL_X509_NAME * name,int indent,unsigned long flags)48341 int wolfSSL_X509_NAME_print_ex_fp(XFILE file, WOLFSSL_X509_NAME* name,
48342         int indent, unsigned long flags)
48343 {
48344     WOLFSSL_BIO* bio;
48345     int ret;
48346 
48347     WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex_fp");
48348 
48349     if (!(bio = wolfSSL_BIO_new_fp(file, BIO_NOCLOSE))) {
48350         WOLFSSL_MSG("wolfSSL_BIO_new_fp error");
48351         return WOLFSSL_FAILURE;
48352     }
48353 
48354     ret = wolfSSL_X509_NAME_print_ex(bio, name, indent, flags);
48355 
48356     wolfSSL_BIO_free(bio);
48357 
48358     return ret;
48359 }
48360 #endif /* NO_FILESYSTEM */
48361 #endif /* !NO_BIO */
48362 
48363 #ifndef NO_WOLFSSL_STUB
wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509 * x)48364 WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
48365 {
48366     (void)x;
48367     WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
48368     WOLFSSL_STUB("X509_get0_pubkey_bitstr");
48369 
48370     return NULL;
48371 }
48372 #endif
48373 
48374 #ifndef NO_WOLFSSL_STUB
wolfSSL_CTX_add_session(WOLFSSL_CTX * ctx,WOLFSSL_SESSION * session)48375 int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
48376 {
48377     (void)ctx;
48378     (void)session;
48379     WOLFSSL_ENTER("wolfSSL_CTX_add_session");
48380     WOLFSSL_STUB("SSL_CTX_add_session");
48381 
48382     return WOLFSSL_SUCCESS;
48383 }
48384 #endif
48385 
48386 
wolfSSL_version(WOLFSSL * ssl)48387 int wolfSSL_version(WOLFSSL* ssl)
48388 {
48389     WOLFSSL_ENTER("wolfSSL_version");
48390     if (ssl->version.major == SSLv3_MAJOR) {
48391         switch (ssl->version.minor) {
48392             case SSLv3_MINOR :
48393                 return SSL3_VERSION;
48394             case TLSv1_MINOR :
48395                 return TLS1_VERSION;
48396             case TLSv1_1_MINOR :
48397                 return TLS1_1_VERSION;
48398             case TLSv1_2_MINOR :
48399                 return TLS1_2_VERSION;
48400             case TLSv1_3_MINOR :
48401                 return TLS1_3_VERSION;
48402             default:
48403                 return WOLFSSL_FAILURE;
48404         }
48405     }
48406     else if (ssl->version.major == DTLS_MAJOR) {
48407         switch (ssl->version.minor) {
48408             case DTLS_MINOR :
48409                 return DTLS1_VERSION;
48410             case DTLSv1_2_MINOR :
48411                 return DTLS1_2_VERSION;
48412             default:
48413                 return WOLFSSL_FAILURE;
48414         }
48415     }
48416     return WOLFSSL_FAILURE;
48417 }
48418 
48419 #ifdef HAVE_SNI
wolfSSL_set_tlsext_host_name(WOLFSSL * ssl,const char * host_name)48420 int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
48421 {
48422     int ret;
48423     WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
48424     ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
48425             host_name, (word16)XSTRLEN(host_name));
48426     WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
48427     return ret;
48428 }
48429 
48430 
48431 #ifndef NO_WOLFSSL_SERVER
wolfSSL_get_servername(WOLFSSL * ssl,byte type)48432 const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
48433 {
48434     void * serverName = NULL;
48435     if (ssl == NULL)
48436         return NULL;
48437     TLSX_SNI_GetRequest(ssl->extensions, type, &serverName);
48438     return (const char *)serverName;
48439 }
48440 #endif /* NO_WOLFSSL_SERVER */
48441 #endif /* HAVE_SNI */
48442 
wolfSSL_set_SSL_CTX(WOLFSSL * ssl,WOLFSSL_CTX * ctx)48443 WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
48444 {
48445     if (ssl && ctx && SetSSL_CTX(ssl, ctx, 0) == WOLFSSL_SUCCESS)
48446         return ssl->ctx;
48447     return NULL;
48448 }
48449 
48450 
wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX * ctx)48451 VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
48452 {
48453     WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
48454     if(ctx)
48455         return ctx->verifyCallback;
48456     return NULL;
48457 }
48458 
48459 
48460 #ifdef HAVE_SNI
48461 
wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX * ctx,CallbackSniRecv cb)48462 void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
48463 {
48464     WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
48465     if (ctx)
48466         ctx->sniRecvCb = cb;
48467 }
48468 
wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX * ctx,CallbackSniRecv cb)48469 int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
48470                                                CallbackSniRecv cb)
48471 {
48472     WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
48473     if (ctx) {
48474         ctx->sniRecvCb = cb;
48475         return WOLFSSL_SUCCESS;
48476     }
48477     return WOLFSSL_FAILURE;
48478 }
48479 
wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX * ctx,void * arg)48480 int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
48481 {
48482     WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
48483     if (ctx) {
48484         ctx->sniRecvCbArg = arg;
48485         return WOLFSSL_SUCCESS;
48486     }
48487     return WOLFSSL_FAILURE;
48488 }
48489 
48490 #endif /* HAVE_SNI */
48491 
48492 
48493 #ifndef NO_BIO
wolfSSL_ERR_load_BIO_strings(void)48494 void wolfSSL_ERR_load_BIO_strings(void) {
48495     WOLFSSL_ENTER("ERR_load_BIO_strings");
48496     /* do nothing */
48497 }
48498 #endif
48499 
48500 #ifndef NO_WOLFSSL_STUB
48501 /* Set THREADID callback, return 1 on success, 0 on error */
wolfSSL_THREADID_set_callback(void (* threadid_func)(WOLFSSL_CRYPTO_THREADID *))48502 int wolfSSL_THREADID_set_callback(
48503         void(*threadid_func)(WOLFSSL_CRYPTO_THREADID*))
48504 {
48505     WOLFSSL_ENTER("wolfSSL_THREADID_set_callback");
48506     WOLFSSL_STUB("CRYPTO_THREADID_set_callback");
48507     (void)threadid_func;
48508     return 1;
48509 }
48510 #endif
48511 
48512 #ifndef NO_WOLFSSL_STUB
wolfSSL_THREADID_set_numeric(void * id,unsigned long val)48513 void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
48514 {
48515     WOLFSSL_ENTER("wolfSSL_THREADID_set_numeric");
48516     WOLFSSL_STUB("CRYPTO_THREADID_set_numeric");
48517     (void)id;
48518     (void)val;
48519     return;
48520 }
48521 #endif
48522 
48523 #ifdef OPENSSL_ALL
wolfSSL_X509_OBJECT_get_type(const WOLFSSL_X509_OBJECT * obj)48524 WOLFSSL_X509_LOOKUP_TYPE wolfSSL_X509_OBJECT_get_type(
48525         const WOLFSSL_X509_OBJECT* obj)
48526 {
48527     if (obj == NULL)
48528         return WOLFSSL_X509_LU_NONE;
48529     return obj->type;
48530 }
48531 
wolfSSL_X509_OBJECT_new(void)48532 WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_new(void)
48533 {
48534     WOLFSSL_X509_OBJECT* ret = (WOLFSSL_X509_OBJECT*)
48535             XMALLOC(sizeof(WOLFSSL_X509_OBJECT), NULL, DYNAMIC_TYPE_OPENSSL);
48536     if (ret != NULL)
48537         XMEMSET(ret, 0, sizeof(WOLFSSL_X509_OBJECT));
48538     return ret;
48539 }
48540 
wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT * obj)48541 void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj)
48542 {
48543     WOLFSSL_ENTER("wolfSSL_X509_OBJECT_free");
48544     if (obj != NULL) {
48545         if (obj->type == WOLFSSL_X509_LU_X509) {
48546             wolfSSL_X509_free(obj->data.x509);
48547         }
48548         else {
48549             /* We don't free as this will point to
48550              * store->cm->crl which we don't own */
48551             WOLFSSL_MSG("Not free'ing CRL in WOLFSSL_X509_OBJECT");
48552         }
48553         XFREE(obj, NULL, DYNAMIC_TYPE_OPENSSL);
48554     }
48555 }
48556 #endif /* OPENSSL_ALL */
48557 
48558 #ifndef NO_WOLFSSL_STUB
wolfSSL_sk_X509_OBJECT_delete(WOLF_STACK_OF (WOLFSSL_X509_OBJECT)* sk,int i)48559 WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete(
48560     WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i)
48561 {
48562     WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_delete");
48563     WOLFSSL_STUB("wolfSSL_sk_X509_OBJECT_delete");
48564     (void)sk;
48565     (void)i;
48566     return NULL;
48567 }
48568 #endif
48569 
wolfSSL_X509_OBJECT_get0_X509(const WOLFSSL_X509_OBJECT * obj)48570 WOLFSSL_X509 *wolfSSL_X509_OBJECT_get0_X509(const WOLFSSL_X509_OBJECT *obj)
48571 {
48572     if (obj != NULL && obj->type == WOLFSSL_X509_LU_X509)
48573         return obj->data.x509;
48574     return NULL;
48575 }
48576 
wolfSSL_X509_OBJECT_get0_X509_CRL(WOLFSSL_X509_OBJECT * obj)48577 WOLFSSL_X509_CRL *wolfSSL_X509_OBJECT_get0_X509_CRL(WOLFSSL_X509_OBJECT *obj)
48578 {
48579     if (obj != NULL && obj->type == WOLFSSL_X509_LU_CRL)
48580         return obj->data.crl;
48581     return NULL;
48582 }
48583 
48584 #endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
48585         * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
48586         * HAVE_SBLIM_SFCB)) */
48587 
48588 
48589 #if defined(OPENSSL_EXTRA)
48590 
wolfSSL_CRYPTO_memcmp(const void * a,const void * b,size_t size)48591 int wolfSSL_CRYPTO_memcmp(const void *a, const void *b, size_t size)
48592 {
48593     if (!a || !b)
48594         return 0;
48595     return ConstantCompare((const byte*)a, (const byte*)b, (int)size);
48596 }
48597 
wolfSSL_sk_X509_num(const WOLF_STACK_OF (WOLFSSL_X509)* s)48598 int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s)
48599 {
48600     WOLFSSL_ENTER("wolfSSL_sk_X509_num");
48601 
48602     if (s == NULL)
48603         return -1;
48604     return (int)s->num;
48605 }
48606 
wolfSSL_ERR_peek_last_error(void)48607 unsigned long wolfSSL_ERR_peek_last_error(void)
48608 {
48609     WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
48610 
48611 #ifdef WOLFSSL_HAVE_ERROR_QUEUE
48612     {
48613         int ret;
48614 
48615         if ((ret = wc_PeekErrorNode(-1, NULL, NULL, NULL)) < 0) {
48616             WOLFSSL_MSG("Issue peeking at error node in queue");
48617             return 0;
48618         }
48619         if (ret == -ASN_NO_PEM_HEADER)
48620             return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
48621     #if defined(WOLFSSL_PYTHON)
48622         if (ret == ASN1_R_HEADER_TOO_LONG)
48623             return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
48624     #endif
48625         return (unsigned long)ret;
48626     }
48627 #else
48628     return (unsigned long)(0 - NOT_COMPILED_IN);
48629 #endif
48630 }
48631 
48632 #endif /* OPENSSL_EXTRA */
48633 
wolfSSL_get_SSL_CTX(WOLFSSL * ssl)48634 WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
48635 {
48636     WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
48637     return ssl->ctx;
48638 }
48639 
48640 #if defined(OPENSSL_ALL) || \
48641     defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
48642     defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
48643 
wolfSSL_SESSION_get_id(WOLFSSL_SESSION * sess,unsigned int * idLen)48644 const byte* wolfSSL_SESSION_get_id(WOLFSSL_SESSION* sess, unsigned int* idLen)
48645 {
48646     WOLFSSL_ENTER("wolfSSL_SESSION_get_id");
48647     sess = GetSessionPtr(sess);
48648     if (sess == NULL || idLen == NULL) {
48649         WOLFSSL_MSG("Bad func args. Please provide idLen");
48650         return NULL;
48651     }
48652     *idLen = sess->sessionIDSz;
48653     return sess->sessionID;
48654 }
48655 
48656 #if (defined(HAVE_SESSION_TICKET) || defined(SESSION_CERTS)) && \
48657     !defined(NO_FILESYSTEM)
48658 
48659 #ifndef NO_BIO
48660 
48661 #if defined(SESSION_CERTS) || \
48662    (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
48663 /* returns a pointer to the protocol used by the session */
wolfSSL_SESSION_get_protocol(const WOLFSSL_SESSION * in)48664 static const char* wolfSSL_SESSION_get_protocol(const WOLFSSL_SESSION* in)
48665 {
48666     return wolfSSL_internal_get_version((ProtocolVersion*)&in->version);
48667 }
48668 #endif
48669 
48670 /* returns true (non 0) if the session has EMS (extended master secret) */
wolfSSL_SESSION_haveEMS(const WOLFSSL_SESSION * in)48671 static int wolfSSL_SESSION_haveEMS(const WOLFSSL_SESSION* in)
48672 {
48673     if (in == NULL)
48674         return 0;
48675     return in->haveEMS;
48676 }
48677 
48678 #if defined(HAVE_SESSION_TICKET)
48679 /* prints out the ticket to bio passed in
48680  * return WOLFSSL_SUCCESS on success
48681  */
wolfSSL_SESSION_print_ticket(WOLFSSL_BIO * bio,const WOLFSSL_SESSION * in,const char * tab)48682 static int wolfSSL_SESSION_print_ticket(WOLFSSL_BIO* bio,
48683         const WOLFSSL_SESSION* in, const char* tab)
48684 {
48685     unsigned short i, j, z, sz;
48686     short tag = 0;
48687     byte* pt;
48688 
48689 
48690     if (in == NULL || bio == NULL) {
48691         return BAD_FUNC_ARG;
48692     }
48693 
48694     sz = in->ticketLen;
48695     pt = in->ticket;
48696 
48697     if (wolfSSL_BIO_printf(bio, "%s\n", (sz == 0)? " NONE": "") <= 0)
48698         return WOLFSSL_FAILURE;
48699 
48700     for (i = 0; i < sz;) {
48701         char asc[16];
48702 
48703         if (sz - i < 16) {
48704             if (wolfSSL_BIO_printf(bio, "%s%04X -", tab, tag + (sz - i)) <= 0)
48705                 return WOLFSSL_FAILURE;
48706         }
48707         else {
48708             if (wolfSSL_BIO_printf(bio, "%s%04X -", tab, tag) <= 0)
48709                 return WOLFSSL_FAILURE;
48710         }
48711         for (j = 0; i < sz && j < 8; j++,i++) {
48712             asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
48713             if (wolfSSL_BIO_printf(bio, " %02X", pt[i]) <= 0)
48714                 return WOLFSSL_FAILURE;
48715         }
48716 
48717         if (i < sz) {
48718             asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
48719             if (wolfSSL_BIO_printf(bio, "-%02X", pt[i]) <= 0)
48720                 return WOLFSSL_FAILURE;
48721             j++;
48722             i++;
48723         }
48724 
48725         for (; i < sz && j < 16; j++,i++) {
48726             asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
48727             if (wolfSSL_BIO_printf(bio, " %02X", pt[i]) <= 0)
48728                 return WOLFSSL_FAILURE;
48729         }
48730 
48731         /* pad out spacing */
48732         for (z = j; z < 17; z++) {
48733             if (wolfSSL_BIO_printf(bio, "   ") <= 0)
48734                 return WOLFSSL_FAILURE;
48735         }
48736 
48737         for (z = 0; z < j; z++) {
48738             if (wolfSSL_BIO_printf(bio, "%c", asc[z]) <= 0)
48739                 return WOLFSSL_FAILURE;
48740         }
48741         if (wolfSSL_BIO_printf(bio, "\n") <= 0)
48742             return WOLFSSL_FAILURE;
48743 
48744         tag += 16;
48745     }
48746     return WOLFSSL_SUCCESS;
48747 }
48748 #endif /* HAVE_SESSION_TICKET */
48749 
48750 
48751 /* prints out the session information in human readable form
48752  * return WOLFSSL_SUCCESS on success
48753  */
wolfSSL_SESSION_print(WOLFSSL_BIO * bp,const WOLFSSL_SESSION * x)48754 int wolfSSL_SESSION_print(WOLFSSL_BIO *bp, const WOLFSSL_SESSION *x)
48755 {
48756     const unsigned char* pt;
48757     unsigned char buf[SECRET_LEN];
48758     unsigned int sz = 0, i;
48759     int ret;
48760     WOLFSSL_SESSION* session = GetSessionPtr(x);
48761 
48762     if (session == NULL) {
48763         return WOLFSSL_FAILURE;
48764     }
48765 
48766     if (wolfSSL_BIO_printf(bp, "%s\n", "SSL-Session:") <= 0)
48767         return WOLFSSL_FAILURE;
48768 
48769 #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
48770                                defined(HAVE_SESSION_TICKET))
48771     if (wolfSSL_BIO_printf(bp, "    Protocol  : %s\n",
48772             wolfSSL_SESSION_get_protocol(session)) <= 0)
48773         return WOLFSSL_FAILURE;
48774 #endif
48775 
48776     if (wolfSSL_BIO_printf(bp, "    Cipher    : %s\n",
48777             wolfSSL_SESSION_CIPHER_get_name(session)) <= 0)
48778         return WOLFSSL_FAILURE;
48779 
48780     pt = wolfSSL_SESSION_get_id(session, &sz);
48781     if (wolfSSL_BIO_printf(bp, "    Session-ID: ") <= 0)
48782         return WOLFSSL_FAILURE;
48783 
48784     for (i = 0; i < sz; i++) {
48785         if (wolfSSL_BIO_printf(bp, "%02X", pt[i]) <= 0)
48786             return WOLFSSL_FAILURE;
48787     }
48788     if (wolfSSL_BIO_printf(bp, "\n") <= 0)
48789         return WOLFSSL_FAILURE;
48790 
48791     if (wolfSSL_BIO_printf(bp, "    Session-ID-ctx: \n") <= 0)
48792         return WOLFSSL_FAILURE;
48793 
48794     ret = wolfSSL_SESSION_get_master_key(session, buf, sizeof(buf));
48795     if (wolfSSL_BIO_printf(bp, "    Master-Key: ") <= 0)
48796         return WOLFSSL_FAILURE;
48797 
48798     if (ret > 0) {
48799         sz = (unsigned int)ret;
48800         for (i = 0; i < sz; i++) {
48801             if (wolfSSL_BIO_printf(bp, "%02X", buf[i]) <= 0)
48802                 return WOLFSSL_FAILURE;
48803         }
48804     }
48805     if (wolfSSL_BIO_printf(bp, "\n") <= 0)
48806         return WOLFSSL_FAILURE;
48807 
48808     /* @TODO PSK identity hint and SRP */
48809 
48810     if (wolfSSL_BIO_printf(bp, "    TLS session ticket:") <= 0)
48811         return WOLFSSL_FAILURE;
48812 
48813 #ifdef HAVE_SESSION_TICKET
48814     if (wolfSSL_SESSION_print_ticket(bp, session, "    ") != WOLFSSL_SUCCESS)
48815         return WOLFSSL_FAILURE;
48816 #endif
48817 
48818 #if !defined(NO_SESSION_CACHE) && (defined(OPENSSL_EXTRA) || \
48819         defined(HAVE_EXT_CACHE))
48820     if (wolfSSL_BIO_printf(bp, "    Start Time: %ld\n",
48821                 wolfSSL_SESSION_get_time(session)) <= 0)
48822         return WOLFSSL_FAILURE;
48823 
48824     if (wolfSSL_BIO_printf(bp, "    Timeout   : %ld (sec)\n",
48825             wolfSSL_SESSION_get_timeout(session)) <= 0)
48826         return WOLFSSL_FAILURE;
48827 #endif /* !NO_SESSION_CACHE && OPENSSL_EXTRA || HAVE_EXT_CACHE */
48828 
48829     /* @TODO verify return code print */
48830 
48831     if (wolfSSL_BIO_printf(bp, "    Extended master secret: %s\n",
48832             (wolfSSL_SESSION_haveEMS(session) == 0)? "no" : "yes") <= 0)
48833         return WOLFSSL_FAILURE;
48834 
48835     return WOLFSSL_SUCCESS;
48836 }
48837 
48838 #endif /* !NO_BIO */
48839 #endif /* (HAVE_SESSION_TICKET || SESSION_CERTS) && !NO_FILESYSTEM */
48840 
48841 #endif /* OPENSSL_ALL || OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
48842 
48843 #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)) \
48844     || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
48845 
48846 /* TODO: Doesn't currently track SSL_VERIFY_CLIENT_ONCE */
wolfSSL_get_verify_mode(const WOLFSSL * ssl)48847 int wolfSSL_get_verify_mode(const WOLFSSL* ssl) {
48848     int mode = 0;
48849     WOLFSSL_ENTER("wolfSSL_get_verify_mode");
48850 
48851     if (!ssl) {
48852         return WOLFSSL_FAILURE;
48853     }
48854 
48855     if (ssl->options.verifyNone) {
48856         mode = WOLFSSL_VERIFY_NONE;
48857     }
48858     else {
48859         if (ssl->options.verifyPeer) {
48860             mode |= WOLFSSL_VERIFY_PEER;
48861         }
48862         if (ssl->options.failNoCert) {
48863             mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
48864         }
48865         if (ssl->options.failNoCertxPSK) {
48866             mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
48867         }
48868 #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
48869         if (ssl->options.verifyPostHandshake) {
48870             mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
48871         }
48872 #endif
48873     }
48874 
48875     WOLFSSL_LEAVE("wolfSSL_get_verify_mode", mode);
48876     return mode;
48877 }
48878 
wolfSSL_CTX_get_verify_mode(const WOLFSSL_CTX * ctx)48879 int wolfSSL_CTX_get_verify_mode(const WOLFSSL_CTX* ctx)
48880 {
48881     int mode = 0;
48882     WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
48883 
48884     if (!ctx) {
48885         return WOLFSSL_FAILURE;
48886     }
48887 
48888     if (ctx->verifyNone) {
48889         mode = WOLFSSL_VERIFY_NONE;
48890     }
48891     else {
48892         if (ctx->verifyPeer) {
48893             mode |= WOLFSSL_VERIFY_PEER;
48894         }
48895         if (ctx->failNoCert) {
48896             mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
48897         }
48898         if (ctx->failNoCertxPSK) {
48899             mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
48900         }
48901 #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
48902         if (ctx->verifyPostHandshake) {
48903             mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
48904         }
48905 #endif
48906     }
48907 
48908     WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
48909     return mode;
48910 }
48911 
48912 #endif
48913 #if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
48914 /* return 1 if success, 0 if error
48915  * output keys are little endian format
48916  */
wolfSSL_EC25519_generate_key(unsigned char * priv,unsigned int * privSz,unsigned char * pub,unsigned int * pubSz)48917 int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
48918                                  unsigned char *pub, unsigned int *pubSz)
48919 {
48920 #ifndef WOLFSSL_KEY_GEN
48921     WOLFSSL_MSG("No Key Gen built in");
48922     (void) priv;
48923     (void) privSz;
48924     (void) pub;
48925     (void) pubSz;
48926     return WOLFSSL_FAILURE;
48927 #else /* WOLFSSL_KEY_GEN */
48928     int ret = WOLFSSL_FAILURE;
48929     int initTmpRng = 0;
48930     WC_RNG *rng = NULL;
48931 #ifdef WOLFSSL_SMALL_STACK
48932     WC_RNG *tmpRNG = NULL;
48933 #else
48934     WC_RNG tmpRNG[1];
48935 #endif
48936 
48937     WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
48938 
48939     if (priv == NULL || privSz == NULL || *privSz < CURVE25519_KEYSIZE ||
48940         pub == NULL || pubSz == NULL || *pubSz < CURVE25519_KEYSIZE) {
48941         WOLFSSL_MSG("Bad arguments");
48942         return WOLFSSL_FAILURE;
48943     }
48944 
48945 #ifdef WOLFSSL_SMALL_STACK
48946     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
48947     if (tmpRNG == NULL)
48948         return WOLFSSL_FAILURE;
48949 #endif
48950     if (wc_InitRng(tmpRNG) == 0) {
48951         rng = tmpRNG;
48952         initTmpRng = 1;
48953     }
48954     else {
48955         WOLFSSL_MSG("Bad RNG Init, trying global");
48956         if (initGlobalRNG == 0)
48957             WOLFSSL_MSG("Global RNG no Init");
48958         else
48959             rng = &globalRNG;
48960     }
48961 
48962     if (rng) {
48963         curve25519_key key;
48964 
48965         if (wc_curve25519_init(&key) != MP_OKAY)
48966             WOLFSSL_MSG("wc_curve25519_init failed");
48967         else if (wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key)!=MP_OKAY)
48968             WOLFSSL_MSG("wc_curve25519_make_key failed");
48969         /* export key pair */
48970         else if (wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
48971                                                  pubSz, EC25519_LITTLE_ENDIAN)
48972                  != MP_OKAY)
48973             WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
48974         else
48975             ret = WOLFSSL_SUCCESS;
48976 
48977         wc_curve25519_free(&key);
48978     }
48979 
48980     if (initTmpRng)
48981         wc_FreeRng(tmpRNG);
48982 
48983 #ifdef WOLFSSL_SMALL_STACK
48984     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
48985 #endif
48986 
48987     return ret;
48988 #endif /* WOLFSSL_KEY_GEN */
48989 }
48990 
48991 /* return 1 if success, 0 if error
48992  * input and output keys are little endian format
48993  */
wolfSSL_EC25519_shared_key(unsigned char * shared,unsigned int * sharedSz,const unsigned char * priv,unsigned int privSz,const unsigned char * pub,unsigned int pubSz)48994 int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
48995                                const unsigned char *priv, unsigned int privSz,
48996                                const unsigned char *pub, unsigned int pubSz)
48997 {
48998 #ifndef WOLFSSL_KEY_GEN
48999     WOLFSSL_MSG("No Key Gen built in");
49000     (void) shared;
49001     (void) sharedSz;
49002     (void) priv;
49003     (void) privSz;
49004     (void) pub;
49005     (void) pubSz;
49006     return WOLFSSL_FAILURE;
49007 #else /* WOLFSSL_KEY_GEN */
49008     int ret = WOLFSSL_FAILURE;
49009     curve25519_key privkey, pubkey;
49010 
49011     WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
49012 
49013     if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE25519_KEYSIZE ||
49014         priv == NULL || privSz < CURVE25519_KEYSIZE ||
49015         pub == NULL || pubSz < CURVE25519_KEYSIZE) {
49016         WOLFSSL_MSG("Bad arguments");
49017         return WOLFSSL_FAILURE;
49018     }
49019 
49020     /* import private key */
49021     if (wc_curve25519_init(&privkey) != MP_OKAY) {
49022         WOLFSSL_MSG("wc_curve25519_init privkey failed");
49023         return ret;
49024     }
49025     if (wc_curve25519_import_private_ex(priv, privSz, &privkey,
49026                                         EC25519_LITTLE_ENDIAN) != MP_OKAY) {
49027         WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
49028         wc_curve25519_free(&privkey);
49029         return ret;
49030     }
49031 
49032     /* import public key */
49033     if (wc_curve25519_init(&pubkey) != MP_OKAY) {
49034         WOLFSSL_MSG("wc_curve25519_init pubkey failed");
49035         wc_curve25519_free(&privkey);
49036         return ret;
49037     }
49038     if (wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
49039                                        EC25519_LITTLE_ENDIAN) != MP_OKAY) {
49040         WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
49041         wc_curve25519_free(&privkey);
49042         wc_curve25519_free(&pubkey);
49043         return ret;
49044     }
49045 
49046     if (wc_curve25519_shared_secret_ex(&privkey, &pubkey,
49047                                        shared, sharedSz,
49048                                        EC25519_LITTLE_ENDIAN) != MP_OKAY)
49049         WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
49050     else
49051         ret = WOLFSSL_SUCCESS;
49052 
49053     wc_curve25519_free(&privkey);
49054     wc_curve25519_free(&pubkey);
49055 
49056     return ret;
49057 #endif /* WOLFSSL_KEY_GEN */
49058 }
49059 #endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
49060 
49061 #if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
49062 /* return 1 if success, 0 if error
49063  * output keys are little endian format
49064  */
wolfSSL_ED25519_generate_key(unsigned char * priv,unsigned int * privSz,unsigned char * pub,unsigned int * pubSz)49065 int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
49066                                  unsigned char *pub, unsigned int *pubSz)
49067 {
49068 #ifndef WOLFSSL_KEY_GEN
49069     WOLFSSL_MSG("No Key Gen built in");
49070     (void) priv;
49071     (void) privSz;
49072     (void) pub;
49073     (void) pubSz;
49074     return WOLFSSL_FAILURE;
49075 #elif !defined(HAVE_ED25519_KEY_EXPORT)
49076     WOLFSSL_MSG("No ED25519 key export built in");
49077     (void) priv;
49078     (void) privSz;
49079     (void) pub;
49080     (void) pubSz;
49081     return WOLFSSL_FAILURE;
49082 #else /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */
49083     int ret = WOLFSSL_FAILURE;
49084     int initTmpRng = 0;
49085     WC_RNG *rng = NULL;
49086 #ifdef WOLFSSL_SMALL_STACK
49087     WC_RNG *tmpRNG = NULL;
49088 #else
49089     WC_RNG tmpRNG[1];
49090 #endif
49091 
49092     WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
49093 
49094     if (priv == NULL || privSz == NULL || *privSz < ED25519_PRV_KEY_SIZE ||
49095         pub == NULL || pubSz == NULL || *pubSz < ED25519_PUB_KEY_SIZE) {
49096         WOLFSSL_MSG("Bad arguments");
49097         return WOLFSSL_FAILURE;
49098     }
49099 
49100 #ifdef WOLFSSL_SMALL_STACK
49101     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
49102     if (tmpRNG == NULL)
49103         return WOLFSSL_FATAL_ERROR;
49104 #endif
49105     if (wc_InitRng(tmpRNG) == 0) {
49106         rng = tmpRNG;
49107         initTmpRng = 1;
49108     }
49109     else {
49110         WOLFSSL_MSG("Bad RNG Init, trying global");
49111         if (initGlobalRNG == 0)
49112             WOLFSSL_MSG("Global RNG no Init");
49113         else
49114             rng = &globalRNG;
49115     }
49116 
49117     if (rng) {
49118         ed25519_key key;
49119 
49120         if (wc_ed25519_init(&key) != MP_OKAY)
49121             WOLFSSL_MSG("wc_ed25519_init failed");
49122         else if (wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key)!=MP_OKAY)
49123             WOLFSSL_MSG("wc_ed25519_make_key failed");
49124         /* export private key */
49125         else if (wc_ed25519_export_key(&key, priv, privSz, pub, pubSz)!=MP_OKAY)
49126             WOLFSSL_MSG("wc_ed25519_export_key failed");
49127         else
49128             ret = WOLFSSL_SUCCESS;
49129 
49130         wc_ed25519_free(&key);
49131     }
49132 
49133     if (initTmpRng)
49134         wc_FreeRng(tmpRNG);
49135 
49136 #ifdef WOLFSSL_SMALL_STACK
49137     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
49138 #endif
49139 
49140     return ret;
49141 #endif /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */
49142 }
49143 
49144 /* return 1 if success, 0 if error
49145  * input and output keys are little endian format
49146  * priv is a buffer containing private and public part of key
49147  */
wolfSSL_ED25519_sign(const unsigned char * msg,unsigned int msgSz,const unsigned char * priv,unsigned int privSz,unsigned char * sig,unsigned int * sigSz)49148 int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
49149                          const unsigned char *priv, unsigned int privSz,
49150                          unsigned char *sig, unsigned int *sigSz)
49151 {
49152 #if !defined(HAVE_ED25519_SIGN) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED25519_KEY_IMPORT)
49153 #if !defined(HAVE_ED25519_SIGN)
49154     WOLFSSL_MSG("No ED25519 sign built in");
49155 #elif !defined(WOLFSSL_KEY_GEN)
49156      WOLFSSL_MSG("No Key Gen built in");
49157 #elif !defined(HAVE_ED25519_KEY_IMPORT)
49158      WOLFSSL_MSG("No ED25519 Key import built in");
49159 #endif
49160     (void) msg;
49161     (void) msgSz;
49162     (void) priv;
49163     (void) privSz;
49164     (void) sig;
49165     (void) sigSz;
49166     return WOLFSSL_FAILURE;
49167 #else /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
49168     ed25519_key key;
49169     int ret = WOLFSSL_FAILURE;
49170 
49171     WOLFSSL_ENTER("wolfSSL_ED25519_sign");
49172 
49173     if (priv == NULL || privSz != ED25519_PRV_KEY_SIZE ||
49174         msg == NULL || sig == NULL || *sigSz < ED25519_SIG_SIZE) {
49175         WOLFSSL_MSG("Bad arguments");
49176         return WOLFSSL_FAILURE;
49177     }
49178 
49179     /* import key */
49180     if (wc_ed25519_init(&key) != MP_OKAY) {
49181         WOLFSSL_MSG("wc_curve25519_init failed");
49182         return ret;
49183     }
49184     if (wc_ed25519_import_private_key(priv, privSz/2,
49185                                       priv+(privSz/2), ED25519_PUB_KEY_SIZE,
49186                                       &key) != MP_OKAY){
49187         WOLFSSL_MSG("wc_ed25519_import_private failed");
49188         wc_ed25519_free(&key);
49189         return ret;
49190     }
49191 
49192     if (wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY)
49193         WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
49194     else
49195         ret = WOLFSSL_SUCCESS;
49196 
49197     wc_ed25519_free(&key);
49198 
49199     return ret;
49200 #endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
49201 }
49202 
49203 /* return 1 if success, 0 if error
49204  * input and output keys are little endian format
49205  * pub is a buffer containing public part of key
49206  */
wolfSSL_ED25519_verify(const unsigned char * msg,unsigned int msgSz,const unsigned char * pub,unsigned int pubSz,const unsigned char * sig,unsigned int sigSz)49207 int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
49208                            const unsigned char *pub, unsigned int pubSz,
49209                            const unsigned char *sig, unsigned int sigSz)
49210 {
49211 #if !defined(HAVE_ED25519_VERIFY) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED25519_KEY_IMPORT)
49212 #if !defined(HAVE_ED25519_VERIFY)
49213     WOLFSSL_MSG("No ED25519 verify built in");
49214 #elif !defined(WOLFSSL_KEY_GEN)
49215      WOLFSSL_MSG("No Key Gen built in");
49216 #elif !defined(HAVE_ED25519_KEY_IMPORT)
49217      WOLFSSL_MSG("No ED25519 Key import built in");
49218 #endif
49219     (void) msg;
49220     (void) msgSz;
49221     (void) pub;
49222     (void) pubSz;
49223     (void) sig;
49224     (void) sigSz;
49225     return WOLFSSL_FAILURE;
49226 #else /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
49227     ed25519_key key;
49228     int ret = WOLFSSL_FAILURE, check = 0;
49229 
49230     WOLFSSL_ENTER("wolfSSL_ED25519_verify");
49231 
49232     if (pub == NULL || pubSz != ED25519_PUB_KEY_SIZE ||
49233         msg == NULL || sig == NULL || sigSz != ED25519_SIG_SIZE) {
49234         WOLFSSL_MSG("Bad arguments");
49235         return WOLFSSL_FAILURE;
49236     }
49237 
49238     /* import key */
49239     if (wc_ed25519_init(&key) != MP_OKAY) {
49240         WOLFSSL_MSG("wc_curve25519_init failed");
49241         return ret;
49242     }
49243     if (wc_ed25519_import_public(pub, pubSz, &key) != MP_OKAY){
49244         WOLFSSL_MSG("wc_ed25519_import_public failed");
49245         wc_ed25519_free(&key);
49246         return ret;
49247     }
49248 
49249     if ((ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz,
49250                                      &check, &key)) != MP_OKAY) {
49251         WOLFSSL_MSG("wc_ed25519_verify_msg failed");
49252     }
49253     else if (!check)
49254         WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
49255     else
49256         ret = WOLFSSL_SUCCESS;
49257 
49258     wc_ed25519_free(&key);
49259 
49260     return ret;
49261 #endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
49262 }
49263 
49264 #endif /* OPENSSL_EXTRA && HAVE_ED25519 */
49265 
49266 #if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448)
49267 /* return 1 if success, 0 if error
49268  * output keys are little endian format
49269  */
wolfSSL_EC448_generate_key(unsigned char * priv,unsigned int * privSz,unsigned char * pub,unsigned int * pubSz)49270 int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz,
49271                                unsigned char *pub, unsigned int *pubSz)
49272 {
49273 #ifndef WOLFSSL_KEY_GEN
49274     WOLFSSL_MSG("No Key Gen built in");
49275     (void) priv;
49276     (void) privSz;
49277     (void) pub;
49278     (void) pubSz;
49279     return WOLFSSL_FAILURE;
49280 #else /* WOLFSSL_KEY_GEN */
49281     int ret = WOLFSSL_FAILURE;
49282     int initTmpRng = 0;
49283     WC_RNG *rng = NULL;
49284 #ifdef WOLFSSL_SMALL_STACK
49285     WC_RNG *tmpRNG = NULL;
49286 #else
49287     WC_RNG tmpRNG[1];
49288 #endif
49289 
49290     WOLFSSL_ENTER("wolfSSL_EC448_generate_key");
49291 
49292     if (priv == NULL || privSz == NULL || *privSz < CURVE448_KEY_SIZE ||
49293         pub == NULL || pubSz == NULL || *pubSz < CURVE448_KEY_SIZE) {
49294         WOLFSSL_MSG("Bad arguments");
49295         return WOLFSSL_FAILURE;
49296     }
49297 
49298 #ifdef WOLFSSL_SMALL_STACK
49299     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
49300     if (tmpRNG == NULL)
49301         return WOLFSSL_FAILURE;
49302 #endif
49303     if (wc_InitRng(tmpRNG) == 0) {
49304         rng = tmpRNG;
49305         initTmpRng = 1;
49306     }
49307     else {
49308         WOLFSSL_MSG("Bad RNG Init, trying global");
49309         if (initGlobalRNG == 0)
49310             WOLFSSL_MSG("Global RNG no Init");
49311         else
49312             rng = &globalRNG;
49313     }
49314 
49315     if (rng) {
49316         curve448_key key;
49317 
49318         if (wc_curve448_init(&key) != MP_OKAY)
49319             WOLFSSL_MSG("wc_curve448_init failed");
49320         else if (wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key)!=MP_OKAY)
49321             WOLFSSL_MSG("wc_curve448_make_key failed");
49322         /* export key pair */
49323         else if (wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz,
49324                                                EC448_LITTLE_ENDIAN)
49325                  != MP_OKAY)
49326             WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed");
49327         else
49328             ret = WOLFSSL_SUCCESS;
49329 
49330         wc_curve448_free(&key);
49331     }
49332 
49333     if (initTmpRng)
49334         wc_FreeRng(tmpRNG);
49335 
49336 #ifdef WOLFSSL_SMALL_STACK
49337     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
49338 #endif
49339 
49340     return ret;
49341 #endif /* WOLFSSL_KEY_GEN */
49342 }
49343 
49344 /* return 1 if success, 0 if error
49345  * input and output keys are little endian format
49346  */
wolfSSL_EC448_shared_key(unsigned char * shared,unsigned int * sharedSz,const unsigned char * priv,unsigned int privSz,const unsigned char * pub,unsigned int pubSz)49347 int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz,
49348                              const unsigned char *priv, unsigned int privSz,
49349                              const unsigned char *pub, unsigned int pubSz)
49350 {
49351 #ifndef WOLFSSL_KEY_GEN
49352     WOLFSSL_MSG("No Key Gen built in");
49353     (void) shared;
49354     (void) sharedSz;
49355     (void) priv;
49356     (void) privSz;
49357     (void) pub;
49358     (void) pubSz;
49359     return WOLFSSL_FAILURE;
49360 #else /* WOLFSSL_KEY_GEN */
49361     int ret = WOLFSSL_FAILURE;
49362     curve448_key privkey, pubkey;
49363 
49364     WOLFSSL_ENTER("wolfSSL_EC448_shared_key");
49365 
49366     if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE448_KEY_SIZE ||
49367             priv == NULL || privSz < CURVE448_KEY_SIZE ||
49368             pub == NULL || pubSz < CURVE448_KEY_SIZE) {
49369         WOLFSSL_MSG("Bad arguments");
49370         return WOLFSSL_FAILURE;
49371     }
49372 
49373     /* import private key */
49374     if (wc_curve448_init(&privkey) != MP_OKAY) {
49375         WOLFSSL_MSG("wc_curve448_init privkey failed");
49376         return ret;
49377     }
49378     if (wc_curve448_import_private_ex(priv, privSz, &privkey,
49379                                       EC448_LITTLE_ENDIAN) != MP_OKAY) {
49380         WOLFSSL_MSG("wc_curve448_import_private_ex failed");
49381         wc_curve448_free(&privkey);
49382         return ret;
49383     }
49384 
49385     /* import public key */
49386     if (wc_curve448_init(&pubkey) != MP_OKAY) {
49387         WOLFSSL_MSG("wc_curve448_init pubkey failed");
49388         wc_curve448_free(&privkey);
49389         return ret;
49390     }
49391     if (wc_curve448_import_public_ex(pub, pubSz, &pubkey,
49392                                      EC448_LITTLE_ENDIAN) != MP_OKAY) {
49393         WOLFSSL_MSG("wc_curve448_import_public_ex failed");
49394         wc_curve448_free(&privkey);
49395         wc_curve448_free(&pubkey);
49396         return ret;
49397     }
49398 
49399     if (wc_curve448_shared_secret_ex(&privkey, &pubkey, shared, sharedSz,
49400                                      EC448_LITTLE_ENDIAN) != MP_OKAY)
49401         WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
49402     else
49403         ret = WOLFSSL_SUCCESS;
49404 
49405     wc_curve448_free(&privkey);
49406     wc_curve448_free(&pubkey);
49407 
49408     return ret;
49409 #endif /* WOLFSSL_KEY_GEN */
49410 }
49411 #endif /* OPENSSL_EXTRA && HAVE_CURVE448 */
49412 
49413 #if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
49414 /* return 1 if success, 0 if error
49415  * output keys are little endian format
49416  */
wolfSSL_ED448_generate_key(unsigned char * priv,unsigned int * privSz,unsigned char * pub,unsigned int * pubSz)49417 int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz,
49418                                unsigned char *pub, unsigned int *pubSz)
49419 {
49420 #ifndef WOLFSSL_KEY_GEN
49421     WOLFSSL_MSG("No Key Gen built in");
49422     (void) priv;
49423     (void) privSz;
49424     (void) pub;
49425     (void) pubSz;
49426     return WOLFSSL_FAILURE;
49427 #elif !defined(HAVE_ED448_KEY_EXPORT)
49428     WOLFSSL_MSG("No ED448 key export built in");
49429     (void) priv;
49430     (void) privSz;
49431     (void) pub;
49432     (void) pubSz;
49433     return WOLFSSL_FAILURE;
49434 #else /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
49435     int ret = WOLFSSL_FAILURE;
49436     int initTmpRng = 0;
49437     WC_RNG *rng = NULL;
49438 #ifdef WOLFSSL_SMALL_STACK
49439     WC_RNG *tmpRNG = NULL;
49440 #else
49441     WC_RNG tmpRNG[1];
49442 #endif
49443 
49444     WOLFSSL_ENTER("wolfSSL_ED448_generate_key");
49445 
49446     if (priv == NULL || privSz == NULL || *privSz < ED448_PRV_KEY_SIZE ||
49447             pub == NULL || pubSz == NULL || *pubSz < ED448_PUB_KEY_SIZE) {
49448         WOLFSSL_MSG("Bad arguments");
49449         return WOLFSSL_FAILURE;
49450     }
49451 
49452 #ifdef WOLFSSL_SMALL_STACK
49453     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
49454     if (tmpRNG == NULL)
49455         return WOLFSSL_FATAL_ERROR;
49456 #endif
49457     if (wc_InitRng(tmpRNG) == 0) {
49458         rng = tmpRNG;
49459         initTmpRng = 1;
49460     }
49461     else {
49462         WOLFSSL_MSG("Bad RNG Init, trying global");
49463         if (initGlobalRNG == 0)
49464             WOLFSSL_MSG("Global RNG no Init");
49465         else
49466             rng = &globalRNG;
49467     }
49468 
49469     if (rng) {
49470         ed448_key key;
49471 
49472         if (wc_ed448_init(&key) != MP_OKAY)
49473             WOLFSSL_MSG("wc_ed448_init failed");
49474         else if (wc_ed448_make_key(rng, ED448_KEY_SIZE, &key) != MP_OKAY)
49475             WOLFSSL_MSG("wc_ed448_make_key failed");
49476         /* export private key */
49477         else if (wc_ed448_export_key(&key, priv, privSz, pub, pubSz) != MP_OKAY)
49478             WOLFSSL_MSG("wc_ed448_export_key failed");
49479         else
49480             ret = WOLFSSL_SUCCESS;
49481 
49482         wc_ed448_free(&key);
49483     }
49484 
49485     if (initTmpRng)
49486         wc_FreeRng(tmpRNG);
49487 
49488 #ifdef WOLFSSL_SMALL_STACK
49489     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
49490 #endif
49491 
49492     return ret;
49493 #endif /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
49494 }
49495 
49496 /* return 1 if success, 0 if error
49497  * input and output keys are little endian format
49498  * priv is a buffer containing private and public part of key
49499  */
wolfSSL_ED448_sign(const unsigned char * msg,unsigned int msgSz,const unsigned char * priv,unsigned int privSz,unsigned char * sig,unsigned int * sigSz)49500 int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
49501                        const unsigned char *priv, unsigned int privSz,
49502                        unsigned char *sig, unsigned int *sigSz)
49503 {
49504 #if !defined(HAVE_ED448_SIGN) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED448_KEY_IMPORT)
49505 #if !defined(HAVE_ED448_SIGN)
49506     WOLFSSL_MSG("No ED448 sign built in");
49507 #elif !defined(WOLFSSL_KEY_GEN)
49508     WOLFSSL_MSG("No Key Gen built in");
49509 #elif !defined(HAVE_ED448_KEY_IMPORT)
49510     WOLFSSL_MSG("No ED448 Key import built in");
49511 #endif
49512     (void) msg;
49513     (void) msgSz;
49514     (void) priv;
49515     (void) privSz;
49516     (void) sig;
49517     (void) sigSz;
49518     return WOLFSSL_FAILURE;
49519 #else /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
49520     ed448_key key;
49521     int ret = WOLFSSL_FAILURE;
49522 
49523     WOLFSSL_ENTER("wolfSSL_ED448_sign");
49524 
49525     if (priv == NULL || privSz != ED448_PRV_KEY_SIZE || msg == NULL ||
49526             sig == NULL || *sigSz < ED448_SIG_SIZE) {
49527         WOLFSSL_MSG("Bad arguments");
49528         return WOLFSSL_FAILURE;
49529     }
49530 
49531     /* import key */
49532     if (wc_ed448_init(&key) != MP_OKAY) {
49533         WOLFSSL_MSG("wc_curve448_init failed");
49534         return ret;
49535     }
49536     if (wc_ed448_import_private_key(priv, privSz/2, priv+(privSz/2),
49537                                     ED448_PUB_KEY_SIZE, &key) != MP_OKAY){
49538         WOLFSSL_MSG("wc_ed448_import_private failed");
49539         wc_ed448_free(&key);
49540         return ret;
49541     }
49542 
49543     if (wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key, NULL, 0) != MP_OKAY)
49544         WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
49545     else
49546         ret = WOLFSSL_SUCCESS;
49547 
49548     wc_ed448_free(&key);
49549 
49550     return ret;
49551 #endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
49552 }
49553 
49554 /* return 1 if success, 0 if error
49555  * input and output keys are little endian format
49556  * pub is a buffer containing public part of key
49557  */
wolfSSL_ED448_verify(const unsigned char * msg,unsigned int msgSz,const unsigned char * pub,unsigned int pubSz,const unsigned char * sig,unsigned int sigSz)49558 int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
49559                          const unsigned char *pub, unsigned int pubSz,
49560                          const unsigned char *sig, unsigned int sigSz)
49561 {
49562 #if !defined(HAVE_ED448_VERIFY) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED448_KEY_IMPORT)
49563 #if !defined(HAVE_ED448_VERIFY)
49564     WOLFSSL_MSG("No ED448 verify built in");
49565 #elif !defined(WOLFSSL_KEY_GEN)
49566     WOLFSSL_MSG("No Key Gen built in");
49567 #elif !defined(HAVE_ED448_KEY_IMPORT)
49568     WOLFSSL_MSG("No ED448 Key import built in");
49569 #endif
49570     (void) msg;
49571     (void) msgSz;
49572     (void) pub;
49573     (void) pubSz;
49574     (void) sig;
49575     (void) sigSz;
49576     return WOLFSSL_FAILURE;
49577 #else /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
49578     ed448_key key;
49579     int ret = WOLFSSL_FAILURE, check = 0;
49580 
49581     WOLFSSL_ENTER("wolfSSL_ED448_verify");
49582 
49583     if (pub == NULL || pubSz != ED448_PUB_KEY_SIZE || msg == NULL ||
49584             sig == NULL || sigSz != ED448_SIG_SIZE) {
49585         WOLFSSL_MSG("Bad arguments");
49586         return WOLFSSL_FAILURE;
49587     }
49588 
49589     /* import key */
49590     if (wc_ed448_init(&key) != MP_OKAY) {
49591         WOLFSSL_MSG("wc_curve448_init failed");
49592         return ret;
49593     }
49594     if (wc_ed448_import_public(pub, pubSz, &key) != MP_OKAY){
49595         WOLFSSL_MSG("wc_ed448_import_public failed");
49596         wc_ed448_free(&key);
49597         return ret;
49598     }
49599 
49600     if ((ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
49601                                    &key, NULL, 0)) != MP_OKAY) {
49602         WOLFSSL_MSG("wc_ed448_verify_msg failed");
49603     }
49604     else if (!check)
49605         WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)");
49606     else
49607         ret = WOLFSSL_SUCCESS;
49608 
49609     wc_ed448_free(&key);
49610 
49611     return ret;
49612 #endif /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN */
49613 }
49614 
49615 #endif /* OPENSSL_EXTRA && HAVE_ED448 */
49616 
49617 #ifdef WOLFSSL_JNI
49618 
wolfSSL_set_jobject(WOLFSSL * ssl,void * objPtr)49619 int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
49620 {
49621     WOLFSSL_ENTER("wolfSSL_set_jobject");
49622     if (ssl != NULL)
49623     {
49624         ssl->jObjectRef = objPtr;
49625         return WOLFSSL_SUCCESS;
49626     }
49627     return WOLFSSL_FAILURE;
49628 }
49629 
wolfSSL_get_jobject(WOLFSSL * ssl)49630 void* wolfSSL_get_jobject(WOLFSSL* ssl)
49631 {
49632     WOLFSSL_ENTER("wolfSSL_get_jobject");
49633     if (ssl != NULL)
49634         return ssl->jObjectRef;
49635     return NULL;
49636 }
49637 
49638 #endif /* WOLFSSL_JNI */
49639 
49640 
49641 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX * ctx,WOLF_EVENT ** events,int maxEvents,WOLF_EVENT_FLAG flags,int * eventCount)49642 int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents,
49643     WOLF_EVENT_FLAG flags, int* eventCount)
49644 {
49645     if (ctx == NULL) {
49646         return BAD_FUNC_ARG;
49647     }
49648 
49649     return wolfAsync_EventQueuePoll(&ctx->event_queue, NULL,
49650                                         events, maxEvents, flags, eventCount);
49651 }
49652 
wolfSSL_AsyncPoll(WOLFSSL * ssl,WOLF_EVENT_FLAG flags)49653 int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
49654 {
49655     int ret, eventCount = 0;
49656     WOLF_EVENT* events[1];
49657 
49658     if (ssl == NULL) {
49659         return BAD_FUNC_ARG;
49660     }
49661 
49662     ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, ssl,
49663         events, sizeof(events)/sizeof(*events), flags, &eventCount);
49664     if (ret == 0) {
49665         ret = eventCount;
49666     }
49667 
49668     return ret;
49669 }
49670 #endif /* WOLFSSL_ASYNC_CRYPT */
49671 
49672 #ifdef OPENSSL_EXTRA
wolfSSL_ERR_peek_error_line_data(const char ** file,int * line,const char ** data,int * flags)49673 unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
49674                                                const char **data, int *flags)
49675 {
49676     WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
49677 
49678     (void)line;
49679     (void)file;
49680 
49681     /* No data or flags stored - error display only in Nginx. */
49682     if (data != NULL) {
49683         *data = "";
49684     }
49685     if (flags != NULL) {
49686         *flags = 0;
49687     }
49688 
49689 #ifdef WOLFSSL_HAVE_ERROR_QUEUE
49690     {
49691         int ret = 0;
49692 
49693         while (1) {
49694             ret = wc_PeekErrorNode(-1, file, NULL, line);
49695             if (ret == BAD_MUTEX_E || ret == BAD_FUNC_ARG || ret == BAD_STATE_E) {
49696                 WOLFSSL_MSG("Issue peeking at error node in queue");
49697                 return 0;
49698             }
49699             /* OpenSSL uses positive error codes */
49700             if (ret < 0) {
49701                 ret = -ret;
49702             }
49703 
49704             if (ret == -ASN_NO_PEM_HEADER)
49705                 return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
49706         #ifdef OPENSSL_ALL
49707             /* PARSE_ERROR is returned if an HTTP request is detected. */
49708             if (ret == -SSL_R_HTTP_REQUEST)
49709                 return (ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST;
49710         #endif
49711         #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
49712             if (ret == ASN1_R_HEADER_TOO_LONG) {
49713                 return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
49714             }
49715         #endif
49716             if (ret != -WANT_READ && ret != -WANT_WRITE &&
49717                     ret != -ZERO_RETURN && ret != -WOLFSSL_ERROR_ZERO_RETURN &&
49718                     ret != -SOCKET_PEER_CLOSED_E && ret != -SOCKET_ERROR_E)
49719                 break;
49720 
49721             wc_RemoveErrorNode(-1);
49722         }
49723 
49724         return (unsigned long)ret;
49725     }
49726 #else
49727     return (unsigned long)(0 - NOT_COMPILED_IN);
49728 #endif
49729 }
49730 #endif
49731 
49732 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
49733 
49734 #if !defined(WOLFSSL_USER_IO)
49735 /* converts an IPv6 or IPv4 address into an octet string for use with rfc3280
49736  * example input would be "127.0.0.1" and the returned value would be 7F000001
49737  */
wolfSSL_a2i_IPADDRESS(const char * ipa)49738 WOLFSSL_ASN1_STRING* wolfSSL_a2i_IPADDRESS(const char* ipa)
49739 {
49740     int ipaSz = WOLFSSL_IP4_ADDR_LEN;
49741     char buf[WOLFSSL_IP6_ADDR_LEN + 1]; /* plus 1 for terminator */
49742     int  af = WOLFSSL_IP4;
49743     WOLFSSL_ASN1_STRING *ret = NULL;
49744 
49745     if (ipa == NULL)
49746         return NULL;
49747 
49748     if (XSTRSTR(ipa, ":") != NULL) {
49749         af = WOLFSSL_IP6;
49750         ipaSz = WOLFSSL_IP6_ADDR_LEN;
49751     }
49752 
49753     buf[WOLFSSL_IP6_ADDR_LEN] = '\0';
49754     if (XINET_PTON(af, ipa, (void*)buf) != 1) {
49755         WOLFSSL_MSG("Error parsing IP address");
49756         return NULL;
49757     }
49758 
49759     ret = wolfSSL_ASN1_STRING_new();
49760     if (ret != NULL) {
49761         if (wolfSSL_ASN1_STRING_set(ret, buf, ipaSz) != WOLFSSL_SUCCESS) {
49762             WOLFSSL_MSG("Error setting the string");
49763             wolfSSL_ASN1_STRING_free(ret);
49764             ret = NULL;
49765         }
49766     }
49767 
49768     return ret;
49769 }
49770 #endif /* !WOLFSSL_USER_IO */
49771 
49772 /* Is the specified cipher suite a fake one used an an extension proxy? */
SCSV_Check(byte suite0,byte suite)49773 static WC_INLINE int SCSV_Check(byte suite0, byte suite)
49774 {
49775     (void)suite0;
49776     (void)suite;
49777 #ifdef HAVE_RENEGOTIATION_INDICATION
49778     if (suite0 == CIPHER_BYTE && suite == TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
49779         return 1;
49780 #endif
49781     return 0;
49782 }
49783 
sslCipherMinMaxCheck(const WOLFSSL * ssl,byte suite0,byte suite)49784 static WC_INLINE int sslCipherMinMaxCheck(const WOLFSSL *ssl, byte suite0,
49785         byte suite)
49786 {
49787     const CipherSuiteInfo* cipher_names = GetCipherNames();
49788     int cipherSz = GetCipherNamesSize();
49789     int i;
49790     for (i = 0; i < cipherSz; i++)
49791         if (cipher_names[i].cipherSuite0 == suite0 &&
49792                 cipher_names[i].cipherSuite == suite)
49793             break;
49794     if (i == cipherSz)
49795         return 1;
49796     /* Check min version */
49797     if (cipher_names[i].minor < ssl->options.minDowngrade) {
49798         if (ssl->options.minDowngrade <= TLSv1_2_MINOR &&
49799                 cipher_names[i].minor >= TLSv1_MINOR)
49800             /* 1.0 ciphersuites are in general available in 1.1 and
49801              * 1.1 ciphersuites are in general available in 1.2 */
49802             return 0;
49803         return 1;
49804     }
49805     /* Check max version */
49806     switch (cipher_names[i].minor) {
49807     case SSLv3_MINOR :
49808         return ssl->options.mask & WOLFSSL_OP_NO_SSLv3;
49809     case TLSv1_MINOR :
49810         return ssl->options.mask & WOLFSSL_OP_NO_TLSv1;
49811     case TLSv1_1_MINOR :
49812         return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1;
49813     case TLSv1_2_MINOR :
49814         return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2;
49815     case TLSv1_3_MINOR :
49816         return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3;
49817     default:
49818         WOLFSSL_MSG("Unrecognized minor version");
49819         return 1;
49820     }
49821 }
49822 
49823 /* returns a pointer to internal cipher suite list. Should not be free'd by
49824  * caller.
49825  */
WOLF_STACK_OF(WOLFSSL_CIPHER)49826 WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
49827 {
49828     WOLF_STACK_OF(WOLFSSL_CIPHER)* ret = NULL;
49829     Suites* suites;
49830 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
49831     const CipherSuiteInfo* cipher_names = GetCipherNames();
49832     int cipherSz = GetCipherNamesSize();
49833 #endif
49834 
49835     WOLFSSL_ENTER("wolfSSL_get_ciphers_compat");
49836     if (ssl == NULL || (ssl->suites == NULL && ssl->ctx->suites == NULL)) {
49837         return NULL;
49838     }
49839 
49840     if (ssl->suites != NULL) {
49841         if (ssl->suites->suiteSz == 0 &&
49842                 InitSSL_Suites((WOLFSSL*)ssl) != WOLFSSL_SUCCESS) {
49843             WOLFSSL_MSG("Suite initialization failure");
49844             return NULL;
49845         }
49846         suites = ssl->suites;
49847     }
49848     else {
49849         suites = ssl->ctx->suites;
49850     }
49851 
49852     /* check if stack needs populated */
49853     if (suites->stack == NULL) {
49854         int i;
49855 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
49856         int j;
49857 
49858         /* higher priority of cipher suite will be on top of stack */
49859         for (i = suites->suiteSz - 2; i >=0; i-=2) {
49860 #else
49861         for (i = 0; i < suites->suiteSz; i+=2) {
49862 #endif
49863             WOLFSSL_STACK* add;
49864 
49865             /* A couple of suites are placeholders for special options,
49866              * skip those. */
49867             if (SCSV_Check(suites->suites[i], suites->suites[i+1])
49868                     || sslCipherMinMaxCheck(ssl, suites->suites[i],
49869                                             suites->suites[i+1])) {
49870                 continue;
49871             }
49872 
49873             add = wolfSSL_sk_new_node(ssl->heap);
49874             if (add != NULL) {
49875                 add->type = STACK_TYPE_CIPHER;
49876                 add->data.cipher.cipherSuite0 = suites->suites[i];
49877                 add->data.cipher.cipherSuite  = suites->suites[i+1];
49878                 add->data.cipher.ssl          = ssl;
49879 #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
49880                 for (j = 0; j < cipherSz; j++) {
49881                     if (cipher_names[j].cipherSuite0 ==
49882                             add->data.cipher.cipherSuite0 &&
49883                             cipher_names[j].cipherSuite ==
49884                                     add->data.cipher.cipherSuite) {
49885                         add->data.cipher.offset = j;
49886                         break;
49887                     }
49888                 }
49889 #endif
49890                 #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
49891                 /* in_stack is checked in wolfSSL_CIPHER_description */
49892                 add->data.cipher.in_stack     = 1;
49893                 #endif
49894 
49895                 add->next = ret;
49896                 if (ret != NULL) {
49897                     add->num = ret->num + 1;
49898                 }
49899                 else {
49900                     add->num = 1;
49901                 }
49902                 ret = add;
49903             }
49904         }
49905         suites->stack = ret;
49906     }
49907     return suites->stack;
49908 }
49909 #endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
49910 
49911 #if defined(HAVE_EX_DATA) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) \
49912      || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)                   \
49913      || defined(HAVE_LIGHTY))
49914 
49915 int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a, void *b, void *c)
49916 {
49917 
49918     WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index");
49919     (void)idx;
49920     (void)arg;
49921     (void)a;
49922     (void)b;
49923     (void)c;
49924 
49925     return get_ex_new_index(CRYPTO_EX_INDEX_X509);
49926 }
49927 #endif
49928 
49929 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
49930     defined(WOLFSSL_WPAS_SMALL)
49931 void *wolfSSL_X509_get_ex_data(X509 *x509, int idx)
49932 {
49933     WOLFSSL_ENTER("wolfSSL_X509_get_ex_data");
49934 #ifdef HAVE_EX_DATA
49935     if (x509 != NULL) {
49936         return wolfSSL_CRYPTO_get_ex_data(&x509->ex_data, idx);
49937     }
49938 #else
49939     (void)x509;
49940     (void)idx;
49941 #endif
49942     return NULL;
49943 }
49944 
49945 int wolfSSL_X509_set_ex_data(X509 *x509, int idx, void *data)
49946 {
49947     WOLFSSL_ENTER("wolfSSL_X509_set_ex_data");
49948 #ifdef HAVE_EX_DATA
49949     if (x509 != NULL)
49950     {
49951         return wolfSSL_CRYPTO_set_ex_data(&x509->ex_data, idx, data);
49952     }
49953 #else
49954     (void)x509;
49955     (void)idx;
49956     (void)data;
49957 #endif
49958     return WOLFSSL_FAILURE;
49959 }
49960 
49961 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
49962 int wolfSSL_X509_set_ex_data_with_cleanup(
49963     X509 *x509,
49964     int idx,
49965     void *data,
49966     wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
49967 {
49968     WOLFSSL_ENTER("wolfSSL_X509_set_ex_data_with_cleanup");
49969     if (x509 != NULL)
49970     {
49971         return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&x509->ex_data, idx,
49972                                                        data, cleanup_routine);
49973     }
49974     return WOLFSSL_FAILURE;
49975 }
49976 #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
49977 
49978 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || WOLFSSL_WPAS_SMALL */
49979 
49980 
49981 #ifndef NO_ASN
49982 int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen,
49983                     unsigned int flags, char **peername)
49984 {
49985     int         ret;
49986     DecodedCert dCert;
49987 
49988     WOLFSSL_ENTER("wolfSSL_X509_check_host");
49989 
49990     /* flags and peername not needed for Nginx. */
49991     (void)flags;
49992     (void)peername;
49993 
49994     if ((x == NULL) || (chk == NULL)) {
49995         WOLFSSL_MSG("Invalid parameter");
49996         return WOLFSSL_FAILURE;
49997     }
49998 
49999     if (flags == WOLFSSL_NO_WILDCARDS) {
50000         WOLFSSL_MSG("X509_CHECK_FLAG_NO_WILDCARDS not yet implemented");
50001         return WOLFSSL_FAILURE;
50002     }
50003     if (flags == WOLFSSL_NO_PARTIAL_WILDCARDS) {
50004         WOLFSSL_MSG("X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS not yet implemented");
50005         return WOLFSSL_FAILURE;
50006     }
50007 
50008     InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL);
50009     ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL);
50010     if (ret != 0) {
50011         FreeDecodedCert(&dCert);
50012         return WOLFSSL_FAILURE;
50013     }
50014 
50015     ret = CheckHostName(&dCert, (char *)chk, chklen);
50016     FreeDecodedCert(&dCert);
50017     if (ret != 0)
50018         return WOLFSSL_FAILURE;
50019     return WOLFSSL_SUCCESS;
50020 }
50021 
50022 
50023 int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc,
50024         unsigned int flags)
50025 {
50026     int ret = WOLFSSL_FAILURE;
50027     DecodedCert dCert;
50028 
50029     WOLFSSL_ENTER("wolfSSL_X509_check_ip_asc");
50030 
50031     /* flags not yet implemented */
50032     (void)flags;
50033 
50034     if ((x == NULL) || (x->derCert == NULL) || (ipasc == NULL)) {
50035         WOLFSSL_MSG("Invalid parameter");
50036     }
50037     else {
50038         ret = WOLFSSL_SUCCESS;
50039     }
50040 
50041     if (ret == WOLFSSL_SUCCESS) {
50042         InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL);
50043         ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL);
50044         if (ret != 0) {
50045             ret = WOLFSSL_FAILURE;
50046         }
50047         else {
50048             ret = CheckIPAddr(&dCert, ipasc);
50049             if (ret != 0) {
50050                 ret = WOLFSSL_FAILURE;
50051             }
50052             else {
50053                 ret = WOLFSSL_SUCCESS;
50054             }
50055         }
50056         FreeDecodedCert(&dCert);
50057     }
50058 
50059     return ret;
50060 }
50061 #endif
50062 
50063 #if defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
50064 int wolfSSL_X509_check_email(WOLFSSL_X509 *x, const char *chk, size_t chkLen,
50065                              unsigned int flags)
50066 {
50067     WOLFSSL_X509_NAME *subjName;
50068     int emailLen;
50069     char *emailBuf;
50070 
50071     (void)flags;
50072 
50073     WOLFSSL_ENTER("wolfSSL_X509_check_email");
50074 
50075     if ((x == NULL) || (chk == NULL)) {
50076         WOLFSSL_MSG("Invalid parameter");
50077         return WOLFSSL_FAILURE;
50078     }
50079 
50080     subjName = wolfSSL_X509_get_subject_name(x);
50081     if (subjName == NULL)
50082         return WOLFSSL_FAILURE;
50083 
50084     /* Call with NULL buffer to get required length. */
50085     emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, NID_emailAddress,
50086                                                  NULL, 0);
50087     if (emailLen < 0)
50088         return WOLFSSL_FAILURE;
50089 
50090     ++emailLen; /* Add 1 for the NUL. */
50091 
50092     emailBuf = (char*)XMALLOC(emailLen, x->heap, DYNAMIC_TYPE_OPENSSL);
50093     if (emailBuf == NULL)
50094         return WOLFSSL_FAILURE;
50095 
50096     emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, NID_emailAddress,
50097                                                  emailBuf, emailLen);
50098     if (emailLen < 0) {
50099         XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
50100         return WOLFSSL_FAILURE;
50101     }
50102 
50103     if (chkLen == 0)
50104         chkLen = XSTRLEN(chk);
50105 
50106     if (chkLen != (size_t)emailLen
50107      || XSTRNCMP(chk, emailBuf, chkLen)) {
50108         XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
50109         return WOLFSSL_FAILURE;
50110     }
50111 
50112     XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
50113     return WOLFSSL_SUCCESS;
50114 }
50115 #endif /* OPENSSL_EXTRA && WOLFSSL_CERT_GEN */
50116 
50117 
50118 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
50119     || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || defined(HAVE_SECRET_CALLBACK)
50120 long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
50121 {
50122     WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_timeout");
50123 
50124     if (ctx == NULL)
50125         return 0;
50126 
50127     return ctx->timeout;
50128 }
50129 
50130 
50131 /* returns the time in seconds of the current timeout */
50132 long wolfSSL_get_timeout(WOLFSSL* ssl)
50133 {
50134     WOLFSSL_ENTER("wolfSSL_get_timeout");
50135 
50136     if (ssl == NULL)
50137         return 0;
50138     return ssl->timeout;
50139 }
50140 #endif
50141 
50142 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
50143     || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
50144 
50145 int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
50146         const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len)
50147 {
50148     WOLFSSL_ENTER("wolfSSL_X509_NAME_digest");
50149 
50150     if (name == NULL || type == NULL)
50151         return WOLFSSL_FAILURE;
50152 
50153 #if !defined(NO_FILESYSTEM) && !defined(NO_PWDBASED)
50154     return wolfSSL_EVP_Digest((unsigned char*)name->name,
50155                               name->sz, md, len, type, NULL);
50156 #else
50157     (void)md;
50158     (void)len;
50159     return NOT_COMPILED_IN;
50160 #endif
50161 }
50162 
50163 #ifdef HAVE_ECC
50164 int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
50165 {
50166     WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_tmp_ecdh");
50167 
50168     if (ctx == NULL || ecdh == NULL)
50169         return BAD_FUNC_ARG;
50170 
50171     ctx->ecdhCurveOID = ecdh->group->curve_oid;
50172 
50173     return WOLFSSL_SUCCESS;
50174 }
50175 #endif
50176 
50177 /* Assumes that the session passed in is from the cache. */
50178 int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
50179 {
50180     WOLFSSL_ENTER("wolfSSL_SSL_CTX_remove_session");
50181 
50182     if (ctx == NULL || s == NULL)
50183         return BAD_FUNC_ARG;
50184 
50185 #ifdef HAVE_EXT_CACHE
50186     if (!ctx->internalCacheOff)
50187 #endif
50188     {
50189         /* Don't remove session just timeout session. */
50190         s->timeout = 0;
50191     }
50192 
50193 #ifdef HAVE_EXT_CACHE
50194     if (ctx->rem_sess_cb != NULL)
50195         ctx->rem_sess_cb(ctx, s);
50196 #endif
50197 
50198     return 0;
50199 }
50200 
50201 #ifndef NO_BIO
50202 BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
50203 {
50204     WOLFSSL_ENTER("wolfSSL_SSL_get_rbio");
50205     /* Nginx sets the buffer size if the read BIO is different to write BIO.
50206      * The setting buffer size doesn't do anything so return NULL for both.
50207      */
50208     if (s == NULL)
50209         return NULL;
50210 
50211     return s->biord;
50212 }
50213 BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s)
50214 {
50215     WOLFSSL_ENTER("wolfSSL_SSL_get_wbio");
50216     (void)s;
50217     /* Nginx sets the buffer size if the read BIO is different to write BIO.
50218      * The setting buffer size doesn't do anything so return NULL for both.
50219      */
50220     if (s == NULL)
50221         return NULL;
50222 
50223     return s->biowr;
50224 }
50225 #endif /* !NO_BIO */
50226 
50227 int wolfSSL_SSL_do_handshake(WOLFSSL *s)
50228 {
50229     WOLFSSL_ENTER("wolfSSL_SSL_do_handshake");
50230 
50231     if (s == NULL)
50232         return WOLFSSL_FAILURE;
50233 
50234     if (s->options.side == WOLFSSL_CLIENT_END) {
50235     #ifndef NO_WOLFSSL_CLIENT
50236         return wolfSSL_connect(s);
50237     #else
50238         WOLFSSL_MSG("Client not compiled in");
50239         return WOLFSSL_FAILURE;
50240     #endif
50241     }
50242 
50243 #ifndef NO_WOLFSSL_SERVER
50244     return wolfSSL_accept(s);
50245 #else
50246     WOLFSSL_MSG("Server not compiled in");
50247     return WOLFSSL_FAILURE;
50248 #endif
50249 }
50250 
50251 #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
50252 int wolfSSL_SSL_in_init(const WOLFSSL *ssl)
50253 #else
50254 int wolfSSL_SSL_in_init(WOLFSSL *ssl)
50255 #endif
50256 {
50257     WOLFSSL_ENTER("SSL_in_init");
50258 
50259     if (ssl == NULL)
50260         return WOLFSSL_FAILURE;
50261 
50262     if (ssl->options.side == WOLFSSL_CLIENT_END) {
50263         return ssl->options.connectState < SECOND_REPLY_DONE;
50264     }
50265     return ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
50266 }
50267 
50268 int wolfSSL_SSL_in_connect_init(WOLFSSL* ssl)
50269 {
50270     WOLFSSL_ENTER("SSL_connect_init");
50271 
50272     if (ssl == NULL)
50273         return WOLFSSL_FAILURE;
50274 
50275     if (ssl->options.side == WOLFSSL_CLIENT_END) {
50276         return ssl->options.connectState > CONNECT_BEGIN &&
50277             ssl->options.connectState < SECOND_REPLY_DONE;
50278     }
50279 
50280     return ssl->options.acceptState > ACCEPT_BEGIN &&
50281         ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
50282 }
50283 
50284 #ifndef NO_SESSION_CACHE
50285 
50286 WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl)
50287 {
50288     WOLFSSL_SESSION *session;
50289 
50290     WOLFSSL_ENTER("wolfSSL_SSL_get0_session");
50291 
50292     if (ssl == NULL) {
50293         return NULL;
50294     }
50295 
50296     session = wolfSSL_get_session((WOLFSSL*)ssl);
50297 
50298 #ifdef HAVE_EXT_CACHE
50299     ((WOLFSSL*)ssl)->extSession = session;
50300 #endif
50301 
50302     return session;
50303 }
50304 
50305 #endif /* NO_SESSION_CACHE */
50306 
50307 #ifndef NO_BIO
50308 int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1,
50309         char *buf, int size)
50310 {
50311     int readNextLine;
50312     int lineLen;
50313     int len;
50314     byte isNumCheck;
50315     word32 outLen;
50316     const int extraTagSz = MAX_LENGTH_SZ + 1;
50317     byte intTag[MAX_LENGTH_SZ + 1];
50318     int idx = 0;
50319 
50320     WOLFSSL_ENTER("wolfSSL_a2i_ASN1_INTEGER");
50321 
50322     if (!bio || !asn1 || !buf || size <= 0) {
50323         WOLFSSL_MSG("Bad parameter");
50324         return WOLFSSL_FAILURE;
50325     }
50326 
50327     /* Reset asn1 */
50328     if (asn1->isDynamic && asn1->data) {
50329         XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
50330         asn1->isDynamic = 0;
50331     }
50332     XMEMSET(asn1->intData, 0, WOLFSSL_ASN1_INTEGER_MAX);
50333     asn1->data = asn1->intData;
50334     asn1->length = 0;
50335     asn1->negative = 0;
50336     asn1->type = V_ASN1_INTEGER;
50337 
50338     lineLen = wolfSSL_BIO_gets(bio, buf, size);
50339     do {
50340         readNextLine = 0;
50341         if (lineLen <= 0) {
50342             WOLFSSL_MSG("wolfSSL_BIO_gets error");
50343             return WOLFSSL_FAILURE;
50344         }
50345         while (lineLen && (buf[lineLen-1] == '\n' || buf[lineLen-1] == '\r'))
50346             lineLen--;
50347         if (buf[lineLen-1] == '\\')
50348             readNextLine = 1;
50349         /* Ignore none-hex chars at the end of the line */
50350         outLen = 1;
50351         while (lineLen && Base16_Decode((byte*)buf + lineLen - 1, 1,
50352                 &isNumCheck, &outLen) == ASN_INPUT_E)
50353             lineLen--;
50354         if (!lineLen || lineLen % 2) {
50355             WOLFSSL_MSG("Invalid line length");
50356             return WOLFSSL_FAILURE;
50357         }
50358         len = asn1->length + (lineLen/2);
50359         /* Check if it will fit in static memory and
50360          * save space for the ASN tag in front */
50361         if (len > (int)(WOLFSSL_ASN1_INTEGER_MAX - extraTagSz)) {
50362             /* Allocate mem for data */
50363             if (asn1->isDynamic) {
50364                 byte* tmp = (byte*)XREALLOC(asn1->data, len + extraTagSz, NULL,
50365                         DYNAMIC_TYPE_OPENSSL);
50366                 if (!tmp) {
50367                     WOLFSSL_MSG("realloc error");
50368                     return WOLFSSL_FAILURE;
50369                 }
50370                 asn1->data = tmp;
50371             }
50372             else {
50373                 /* Up to this point asn1->data pointed to asn1->intData.
50374                  * Now that the size has grown larger than intData can handle
50375                  * the asn1 structure moves to a dynamic type with isDynamic
50376                  * flag being set and asn1->data being malloc'd. */
50377                 asn1->data = (byte*)XMALLOC(len + extraTagSz, NULL,
50378                         DYNAMIC_TYPE_OPENSSL);
50379                 if (!asn1->data) {
50380                     WOLFSSL_MSG("malloc error");
50381                     return WOLFSSL_FAILURE;
50382                 }
50383                 asn1->isDynamic = 1;
50384                 XMEMCPY(asn1->data, asn1->intData, asn1->length);
50385             }
50386         }
50387         len = lineLen/2;
50388         if (Base16_Decode((byte*)buf, lineLen, asn1->data + asn1->length,
50389                 (word32*)&len) != 0) {
50390             WOLFSSL_MSG("Base16_Decode error");
50391             return WOLFSSL_FAILURE;
50392         }
50393         asn1->length += len;
50394     } while (readNextLine);
50395 
50396     /* Write ASN tag */
50397     idx = SetASNInt(asn1->length, asn1->data[0], intTag);
50398     XMEMMOVE(asn1->data + idx, asn1->data, asn1->length);
50399     XMEMCPY(asn1->data, intTag, idx);
50400     asn1->dataMax = asn1->length += idx;
50401 
50402     return WOLFSSL_SUCCESS;
50403 }
50404 
50405 int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a)
50406 {
50407     word32 idx = 1;
50408     int len = 0;
50409     byte buf[512];
50410     word32 bufLen = 512;
50411 
50412     WOLFSSL_ENTER("wolfSSL_i2a_ASN1_INTEGER");
50413 
50414     if (bp == NULL || a == NULL)
50415         return WOLFSSL_FAILURE;
50416 
50417     /* Skip ASN.1 INTEGER (type) byte. */
50418     if (a->data[idx] == 0x80 || /* Indefinite length, can't determine length */
50419             GetLength(a->data, &idx, &len, a->length) < 0) {
50420         return 0;
50421     }
50422 
50423     /* Zero length integer is the value zero. */
50424     if (len == 0) {
50425         return wolfSSL_BIO_write(bp, "00", 2);
50426     }
50427 
50428     if (Base16_Encode(a->data + idx, len, buf, &bufLen) != 0 ||
50429             bufLen <= 0) {
50430         return 0;
50431     }
50432 
50433     return wolfSSL_BIO_write(bp, buf, bufLen - 1); /* Don't write out NULL char */
50434 }
50435 #endif /* !NO_BIO */
50436 
50437 
50438 #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
50439 /* Expected return values from implementations of OpenSSL ticket key callback.
50440  */
50441 #define TICKET_KEY_CB_RET_FAILURE    -1
50442 #define TICKET_KEY_CB_RET_NOT_FOUND   0
50443 #define TICKET_KEY_CB_RET_OK          1
50444 #define TICKET_KEY_CB_RET_RENEW       2
50445 
50446 /* Implementation of session ticket encryption/decryption using OpenSSL
50447  * callback to initialize the cipher and HMAC.
50448  *
50449  * ssl           The SSL/TLS object.
50450  * keyName       The key name - used to identify the key to be used.
50451  * iv            The IV to use.
50452  * mac           The MAC of the encrypted data.
50453  * enc           Encrypt ticket.
50454  * encTicket     The ticket data.
50455  * encTicketLen  The length of the ticket data.
50456  * encLen        The encrypted/decrypted ticket length - output length.
50457  * ctx           Ignored. Application specific data.
50458  * returns WOLFSSL_TICKET_RET_OK to indicate success,
50459  *         WOLFSSL_TICKET_RET_CREATE if a new ticket is required and
50460  *         WOLFSSL_TICKET_RET_FATAL on error.
50461  */
50462 static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
50463         unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
50464         unsigned char iv[WOLFSSL_TICKET_IV_SZ],
50465         unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
50466         int enc, unsigned char* encTicket,
50467         int encTicketLen, int* encLen, void* ctx)
50468 {
50469     byte                    digest[WC_MAX_DIGEST_SIZE];
50470     WOLFSSL_EVP_CIPHER_CTX  evpCtx;
50471     WOLFSSL_HMAC_CTX        hmacCtx;
50472     unsigned int            mdSz = 0;
50473     int                     len = 0;
50474     int                     ret = WOLFSSL_TICKET_RET_FATAL;
50475     int                     res;
50476 
50477     (void)ctx;
50478 
50479     WOLFSSL_ENTER("wolfSSL_TicketKeyCb");
50480 
50481     if (ssl == NULL || ssl->ctx == NULL || ssl->ctx->ticketEncWrapCb == NULL) {
50482         WOLFSSL_MSG("Bad parameter");
50483         return WOLFSSL_TICKET_RET_FATAL;
50484     }
50485 
50486     /* Initialize the cipher and HMAC. */
50487     wolfSSL_EVP_CIPHER_CTX_init(&evpCtx);
50488     if (wolfSSL_HMAC_CTX_Init(&hmacCtx) != WOLFSSL_SUCCESS) {
50489         WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init error");
50490         return WOLFSSL_TICKET_RET_FATAL;
50491     }
50492     res = ssl->ctx->ticketEncWrapCb(ssl, keyName,
50493             iv, &evpCtx, &hmacCtx, enc);
50494     if (res != TICKET_KEY_CB_RET_OK && res != TICKET_KEY_CB_RET_RENEW) {
50495         WOLFSSL_MSG("Ticket callback error");
50496         return WOLFSSL_TICKET_RET_FATAL;
50497     }
50498 
50499     if (enc)
50500     {
50501         /* Encrypt in place. */
50502         if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
50503                                       encTicket, encTicketLen))
50504             goto end;
50505         encTicketLen = len;
50506         if (!wolfSSL_EVP_EncryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
50507             goto end;
50508         /* Total length of encrypted data. */
50509         encTicketLen += len;
50510         *encLen = encTicketLen;
50511 
50512         /* HMAC the encrypted data into the parameter 'mac'. */
50513         if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen))
50514             goto end;
50515 #ifdef WOLFSSL_SHA512
50516         /* Check for SHA512, which would overrun the mac buffer */
50517         if (hmacCtx.hmac.macType == WC_SHA512)
50518             goto end;
50519 #endif
50520         if (!wolfSSL_HMAC_Final(&hmacCtx, mac, &mdSz))
50521             goto end;
50522     }
50523     else
50524     {
50525         /* HMAC the encrypted data and compare it to the passed in data. */
50526         if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen))
50527             goto end;
50528         if (!wolfSSL_HMAC_Final(&hmacCtx, digest, &mdSz))
50529             goto end;
50530         if (XMEMCMP(mac, digest, mdSz) != 0)
50531             goto end;
50532 
50533         /* Decrypt the ticket data in place. */
50534         if (!wolfSSL_EVP_CipherUpdate(&evpCtx, encTicket, &len,
50535                                       encTicket, encTicketLen))
50536             goto end;
50537         encTicketLen = len;
50538         if (!wolfSSL_EVP_DecryptFinal(&evpCtx, &encTicket[encTicketLen], &len))
50539             goto end;
50540         /* Total length of decrypted data. */
50541         *encLen = encTicketLen + len;
50542     }
50543 
50544     ret = (res == TICKET_KEY_CB_RET_RENEW) ? WOLFSSL_TICKET_RET_CREATE :
50545                                              WOLFSSL_TICKET_RET_OK;
50546 end:
50547     return ret;
50548 }
50549 
50550 /* Set the callback to use when encrypting/decrypting tickets.
50551  *
50552  * ctx  The SSL/TLS context object.
50553  * cb   The OpenSSL session ticket callback.
50554  * returns WOLFSSL_SUCCESS to indicate success.
50555  */
50556 int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, ticketCompatCb cb)
50557 {
50558 
50559     /* Set the ticket encryption callback to be a wrapper around OpenSSL
50560      * callback.
50561      */
50562     ctx->ticketEncCb = wolfSSL_TicketKeyCb;
50563     ctx->ticketEncWrapCb = cb;
50564 
50565     return WOLFSSL_SUCCESS;
50566 }
50567 
50568 #endif /* HAVE_SESSION_TICKET */
50569 
50570 #endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
50571     OPENSSL_EXTRA || HAVE_LIGHTY */
50572 
50573 #if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
50574     !defined(NO_WOLFSSL_SERVER)
50575 /* Serialize the session ticket encryption keys.
50576  *
50577  * @param [in]  ctx     SSL/TLS context object.
50578  * @param [in]  keys    Buffer to hold session ticket keys.
50579  * @param [in]  keylen  Length of buffer.
50580  * @return  WOLFSSL_SUCCESS on success.
50581  * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
50582  *          correct length.
50583  */
50584 long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
50585      unsigned char *keys, int keylen)
50586 {
50587     if (ctx == NULL || keys == NULL) {
50588         return WOLFSSL_FAILURE;
50589     }
50590     if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
50591         return WOLFSSL_FAILURE;
50592     }
50593 
50594     XMEMCPY(keys, ctx->ticketKeyCtx.name, WOLFSSL_TICKET_NAME_SZ);
50595     keys += WOLFSSL_TICKET_NAME_SZ;
50596     XMEMCPY(keys, ctx->ticketKeyCtx.key[0], WOLFSSL_TICKET_KEY_SZ);
50597     keys += WOLFSSL_TICKET_KEY_SZ;
50598     XMEMCPY(keys, ctx->ticketKeyCtx.key[1], WOLFSSL_TICKET_KEY_SZ);
50599     keys += WOLFSSL_TICKET_KEY_SZ;
50600     c32toa(ctx->ticketKeyCtx.expirary[0], keys);
50601     keys += OPAQUE32_LEN;
50602     c32toa(ctx->ticketKeyCtx.expirary[1], keys);
50603 
50604     return WOLFSSL_SUCCESS;
50605 }
50606 
50607 /* Deserialize the session ticket encryption keys.
50608  *
50609  * @param [in]  ctx     SSL/TLS context object.
50610  * @param [in]  keys    Session ticket keys.
50611  * @param [in]  keylen  Length of data.
50612  * @return  WOLFSSL_SUCCESS on success.
50613  * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
50614  *          correct length.
50615  */
50616 long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
50617      unsigned char *keys, int keylen)
50618 {
50619     if (ctx == NULL || keys == NULL) {
50620         return WOLFSSL_FAILURE;
50621     }
50622     if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
50623         return WOLFSSL_FAILURE;
50624     }
50625 
50626     XMEMCPY(ctx->ticketKeyCtx.name, keys, WOLFSSL_TICKET_NAME_SZ);
50627     keys += WOLFSSL_TICKET_NAME_SZ;
50628     XMEMCPY(ctx->ticketKeyCtx.key[0], keys, WOLFSSL_TICKET_KEY_SZ);
50629     keys += WOLFSSL_TICKET_KEY_SZ;
50630     XMEMCPY(ctx->ticketKeyCtx.key[1], keys, WOLFSSL_TICKET_KEY_SZ);
50631     keys += WOLFSSL_TICKET_KEY_SZ;
50632     ato32(keys, &ctx->ticketKeyCtx.expirary[0]);
50633     keys += OPAQUE32_LEN;
50634     ato32(keys, &ctx->ticketKeyCtx.expirary[1]);
50635 
50636     return WOLFSSL_SUCCESS;
50637 }
50638 #endif
50639 
50640 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
50641 #ifdef HAVE_OCSP
50642 /* Not an OpenSSL API. */
50643 int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response)
50644 {
50645     *response = ssl->ocspResp;
50646     return ssl->ocspRespSz;
50647 }
50648 
50649 /* Not an OpenSSL API. */
50650 char* wolfSSL_get_ocsp_url(WOLFSSL* ssl)
50651 {
50652     return ssl->url;
50653 }
50654 
50655 /* Not an OpenSSL API. */
50656 int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url)
50657 {
50658     if (ssl == NULL)
50659         return WOLFSSL_FAILURE;
50660 
50661     ssl->url = url;
50662     return WOLFSSL_SUCCESS;
50663 }
50664 #endif /* OCSP */
50665 #endif /* OPENSSL_ALL || WOLFSSL_NGINX  || WOLFSSL_HAPROXY */
50666 
50667 #if defined(HAVE_OCSP) && !defined(NO_ASN_TIME)
50668 int wolfSSL_get_ocsp_producedDate(
50669     WOLFSSL *ssl,
50670     byte *producedDate,
50671     size_t producedDate_space,
50672     int *producedDateFormat)
50673 {
50674     if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) &&
50675         (ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME))
50676         return BAD_FUNC_ARG;
50677 
50678     if ((producedDate == NULL) || (producedDateFormat == NULL))
50679         return BAD_FUNC_ARG;
50680 
50681     if (XSTRLEN((char *)ssl->ocspProducedDate) >= producedDate_space)
50682         return BUFFER_E;
50683 
50684     XSTRNCPY((char *)producedDate, (const char *)ssl->ocspProducedDate, producedDate_space);
50685     *producedDateFormat = ssl->ocspProducedDateFormat;
50686 
50687     return 0;
50688 }
50689 
50690 int wolfSSL_get_ocsp_producedDate_tm(WOLFSSL *ssl, struct tm *produced_tm) {
50691     int idx = 0;
50692 
50693     if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) &&
50694         (ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME))
50695         return BAD_FUNC_ARG;
50696 
50697     if (produced_tm == NULL)
50698         return BAD_FUNC_ARG;
50699 
50700     if (ExtractDate(ssl->ocspProducedDate,
50701             (unsigned char)ssl->ocspProducedDateFormat, produced_tm, &idx))
50702         return 0;
50703     else
50704         return ASN_PARSE_E;
50705 }
50706 #endif
50707 
50708 
50709 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
50710     defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
50711 int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, WOLF_STACK_OF(X509)** chain)
50712 {
50713     word32         idx;
50714     word32         length;
50715     WOLFSSL_STACK* node;
50716     WOLFSSL_STACK* last = NULL;
50717 
50718     if (ctx == NULL || chain == NULL) {
50719         chain = NULL;
50720         return WOLFSSL_FAILURE;
50721     }
50722     if (ctx->x509Chain != NULL) {
50723         *chain = ctx->x509Chain;
50724         return WOLFSSL_SUCCESS;
50725     }
50726 
50727     /* If there are no chains then success! */
50728     *chain = NULL;
50729     if (ctx->certChain == NULL || ctx->certChain->length == 0) {
50730         return WOLFSSL_SUCCESS;
50731     }
50732 
50733     /* Create a new stack of WOLFSSL_X509 object from chain buffer. */
50734     for (idx = 0; idx < ctx->certChain->length; ) {
50735         node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
50736                                        DYNAMIC_TYPE_OPENSSL);
50737         if (node == NULL)
50738             return WOLFSSL_FAILURE;
50739         node->next = NULL;
50740 
50741         /* 3 byte length | X509 DER data */
50742         ato24(ctx->certChain->buffer + idx, &length);
50743         idx += 3;
50744 
50745         /* Create a new X509 from DER encoded data. */
50746         node->data.x509 = wolfSSL_X509_d2i(NULL, ctx->certChain->buffer + idx,
50747             length);
50748         if (node->data.x509 == NULL) {
50749             XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
50750             /* Return as much of the chain as we created. */
50751             ctx->x509Chain = *chain;
50752             return WOLFSSL_FAILURE;
50753         }
50754         idx += length;
50755 
50756         /* Add object to the end of the stack. */
50757         if (last == NULL) {
50758             node->num = 1;
50759             *chain = node;
50760         }
50761         else {
50762             (*chain)->num++;
50763             last->next = node;
50764         }
50765 
50766         last = node;
50767     }
50768 
50769     ctx->x509Chain = *chain;
50770 
50771     return WOLFSSL_SUCCESS;
50772 }
50773 
50774 int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb)
50775 {
50776     if (ctx == NULL || ctx->cm == NULL || cb == NULL)
50777         return WOLFSSL_FAILURE;
50778 
50779 #if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
50780                                ||  defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
50781     if (ctx->cm->ocsp_stapling == NULL)
50782         return WOLFSSL_FAILURE;
50783 
50784     *cb = ctx->cm->ocsp_stapling->statusCb;
50785 #else
50786     (void)cb;
50787     *cb = NULL;
50788 #endif
50789 
50790     return WOLFSSL_SUCCESS;
50791 
50792 }
50793 
50794 int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb)
50795 {
50796     if (ctx == NULL || ctx->cm == NULL)
50797         return WOLFSSL_FAILURE;
50798 
50799 #if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
50800                                ||  defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
50801     /* Ensure stapling is on for callback to be used. */
50802     wolfSSL_CTX_EnableOCSPStapling(ctx);
50803 
50804     if (ctx->cm->ocsp_stapling == NULL)
50805         return WOLFSSL_FAILURE;
50806 
50807     ctx->cm->ocsp_stapling->statusCb = cb;
50808 #else
50809     (void)cb;
50810 #endif
50811 
50812     return WOLFSSL_SUCCESS;
50813 }
50814 
50815 int wolfSSL_CTX_get0_chain_certs(WOLFSSL_CTX *ctx,
50816         WOLF_STACK_OF(WOLFSSL_X509) **sk)
50817 {
50818     WOLFSSL_ENTER("wolfSSL_CTX_get0_chain_certs");
50819     if (ctx == NULL || sk == NULL) {
50820         WOLFSSL_MSG("Bad parameter");
50821         return WOLFSSL_FAILURE;
50822     }
50823     *sk = ctx->x509Chain;
50824     return WOLFSSL_SUCCESS;
50825 }
50826 
50827 #ifdef KEEP_OUR_CERT
50828 int wolfSSL_get0_chain_certs(WOLFSSL *ssl,
50829         WOLF_STACK_OF(WOLFSSL_X509) **sk)
50830 {
50831     WOLFSSL_ENTER("wolfSSL_get0_chain_certs");
50832     if (ssl == NULL || sk == NULL) {
50833         WOLFSSL_MSG("Bad parameter");
50834         return WOLFSSL_FAILURE;
50835     }
50836     *sk = ssl->ourCertChain;
50837     return WOLFSSL_SUCCESS;
50838 }
50839 #endif
50840 
50841 /**
50842  * Find the issuing cert of the input cert. On a self-signed cert this
50843  * function will return an error.
50844  * @param issuer The issuer x509 struct is returned here
50845  * @param cm     The cert manager that is queried for the issuer
50846  * @param x      This cert's issuer will be queried in cm
50847  * @return       WOLFSSL_SUCCESS on success
50848  *               WOLFSSL_FAILURE on error
50849  */
50850 static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
50851         WOLFSSL_X509 *x)
50852 {
50853     Signer* ca = NULL;
50854 #ifdef WOLFSSL_SMALL_STACK
50855     DecodedCert* cert = NULL;
50856 #else
50857     DecodedCert  cert[1];
50858 #endif
50859 
50860     if (cm == NULL || x == NULL || x->derCert == NULL) {
50861         WOLFSSL_MSG("No cert DER buffer or NULL cm. Defining "
50862                     "WOLFSSL_SIGNER_DER_CERT could solve the issue");
50863         return WOLFSSL_FAILURE;
50864     }
50865 
50866 #ifdef WOLFSSL_SMALL_STACK
50867     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
50868     if (cert == NULL)
50869         return WOLFSSL_FAILURE;
50870 #endif
50871 
50872     /* Use existing CA retrieval APIs that use DecodedCert. */
50873     InitDecodedCert(cert, x->derCert->buffer, x->derCert->length, NULL);
50874     if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0
50875             && !cert->selfSigned) {
50876     #ifndef NO_SKID
50877         if (cert->extAuthKeyIdSet)
50878             ca = GetCA(cm, cert->extAuthKeyId);
50879         if (ca == NULL)
50880             ca = GetCAByName(cm, cert->issuerHash);
50881     #else /* NO_SKID */
50882         ca = GetCA(cm, cert->issuerHash);
50883     #endif /* NO SKID */
50884     }
50885     FreeDecodedCert(cert);
50886 #ifdef WOLFSSL_SMALL_STACK
50887     XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
50888 #endif
50889 
50890     if (ca == NULL)
50891         return WOLFSSL_FAILURE;
50892 
50893 #ifdef WOLFSSL_SIGNER_DER_CERT
50894     /* populate issuer with Signer DER */
50895     if (wolfSSL_X509_d2i(issuer, ca->derCert->buffer,
50896             ca->derCert->length) == NULL)
50897         return WOLFSSL_FAILURE;
50898 #else
50899     /* Create an empty certificate as CA doesn't have a certificate. */
50900     *issuer = (WOLFSSL_X509 *)XMALLOC(sizeof(WOLFSSL_X509), 0,
50901         DYNAMIC_TYPE_OPENSSL);
50902     if (*issuer == NULL)
50903         return WOLFSSL_FAILURE;
50904 
50905     InitX509((*issuer), 1, NULL);
50906 #endif
50907 
50908     return WOLFSSL_SUCCESS;
50909 }
50910 
50911 void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
50912 {
50913     WOLFSSL_STACK *curr;
50914 
50915     while (sk != NULL) {
50916         curr = sk;
50917         sk = sk->next;
50918 
50919         XFREE(curr, NULL, DYNAMIC_TYPE_OPENSSL);
50920     }
50921 }
50922 
50923 WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
50924 {
50925     WOLFSSL_STACK* list = NULL;
50926     char*          url;
50927 
50928     if (x == NULL || x->authInfoSz == 0)
50929         return NULL;
50930 
50931     list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK) + x->authInfoSz + 1,
50932                                    NULL, DYNAMIC_TYPE_OPENSSL);
50933     if (list == NULL)
50934         return NULL;
50935 
50936     url = (char*)list;
50937     url += sizeof(WOLFSSL_STACK);
50938     XMEMCPY(url, x->authInfo, x->authInfoSz);
50939     url[x->authInfoSz] = '\0';
50940 
50941     list->data.string = url;
50942     list->next = NULL;
50943 
50944     return list;
50945 }
50946 
50947 int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject)
50948 {
50949     WOLFSSL_X509_NAME *issuerName = wolfSSL_X509_get_issuer_name(subject);
50950     WOLFSSL_X509_NAME *subjectName = wolfSSL_X509_get_subject_name(issuer);
50951 
50952     if (issuerName == NULL || subjectName == NULL)
50953         return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
50954 
50955     /* Literal matching of encoded names and key ids. */
50956     if (issuerName->sz != subjectName->sz ||
50957            XMEMCMP(issuerName->name, subjectName->name, subjectName->sz) != 0) {
50958         return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
50959     }
50960 
50961     if (subject->authKeyId != NULL && issuer->subjKeyId != NULL) {
50962         if (subject->authKeyIdSz != issuer->subjKeyIdSz ||
50963                 XMEMCMP(subject->authKeyId, issuer->subjKeyId,
50964                         issuer->subjKeyIdSz) != 0) {
50965             return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
50966         }
50967     }
50968 
50969     return X509_V_OK;
50970 }
50971 
50972 WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void)
50973 {
50974     WOLF_STACK_OF(WOLFSSL_STRING)* ret = wolfSSL_sk_new_node(NULL);
50975 
50976     if (ret) {
50977         ret->type = STACK_TYPE_STRING;
50978     }
50979 
50980     return ret;
50981 }
50982 
50983 void wolfSSL_WOLFSSL_STRING_free(WOLFSSL_STRING s)
50984 {
50985     WOLFSSL_ENTER("wolfSSL_WOLFSSL_STRING_free");
50986 
50987     if (s != NULL)
50988         XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL);
50989 }
50990 
50991 void wolfSSL_sk_WOLFSSL_STRING_free(WOLF_STACK_OF(WOLFSSL_STRING)* sk)
50992 {
50993     WOLFSSL_STACK* tmp;
50994     WOLFSSL_ENTER("wolfSSL_sk_WOLFSSL_STRING_free");
50995 
50996     if (sk == NULL)
50997         return;
50998 
50999     /* parse through stack freeing each node */
51000     while (sk) {
51001         tmp = sk->next;
51002         XFREE(sk->data.string, NULL, DYNAMIC_TYPE_OPENSSL);
51003         XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
51004         sk = tmp;
51005     }
51006 }
51007 
51008 WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings,
51009     int idx)
51010 {
51011     for (; idx > 0 && strings != NULL; idx--)
51012         strings = strings->next;
51013     if (strings == NULL)
51014         return NULL;
51015     return strings->data.string;
51016 }
51017 
51018 int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings)
51019 {
51020     if (strings)
51021         return (int)strings->num;
51022     return 0;
51023 }
51024 
51025 #endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
51026 
51027 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
51028 WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x)
51029 {
51030     WOLFSSL_ENTER("wolfSSL_X509_dup");
51031 
51032     if (x == NULL || x->derCert == NULL) {
51033         WOLFSSL_MSG("Error: NULL certificate passed in");
51034         return NULL;
51035     }
51036 
51037     return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length);
51038 }
51039 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
51040 
51041 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
51042     defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
51043 #ifdef HAVE_ALPN
51044 void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
51045                                 unsigned int *len)
51046 {
51047     word16 nameLen;
51048 
51049     if (ssl != NULL && data != NULL && len != NULL) {
51050         TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
51051         *len = nameLen;
51052     }
51053 }
51054 
51055 int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
51056                               const unsigned char *in, unsigned int inLen,
51057                               const unsigned char *clientNames,
51058                               unsigned int clientLen)
51059 {
51060     unsigned int i, j;
51061     byte lenIn, lenClient;
51062 
51063     if (out == NULL || outLen == NULL || in == NULL || clientNames == NULL)
51064         return OPENSSL_NPN_UNSUPPORTED;
51065 
51066     for (i = 0; i < inLen; i += lenIn) {
51067         lenIn = in[i++];
51068         for (j = 0; j < clientLen; j += lenClient) {
51069             lenClient = clientNames[j++];
51070 
51071             if (lenIn != lenClient)
51072                 continue;
51073 
51074             if (XMEMCMP(in + i, clientNames + j, lenIn) == 0) {
51075                 *out = (unsigned char *)(in + i);
51076                 *outLen = lenIn;
51077                 return OPENSSL_NPN_NEGOTIATED;
51078             }
51079         }
51080     }
51081 
51082     *out = (unsigned char *)clientNames + 1;
51083     *outLen = clientNames[0];
51084     return OPENSSL_NPN_NO_OVERLAP;
51085 }
51086 
51087 void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
51088                                     int (*cb) (WOLFSSL *ssl,
51089                                                const unsigned char **out,
51090                                                unsigned char *outlen,
51091                                                const unsigned char *in,
51092                                                unsigned int inlen,
51093                                                void *arg), void *arg)
51094 {
51095     if (ctx != NULL) {
51096         ctx->alpnSelect = cb;
51097         ctx->alpnSelectArg = arg;
51098     }
51099 }
51100 
51101 void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s,
51102                                            int (*cb) (WOLFSSL *ssl,
51103                                                       const unsigned char
51104                                                       **out,
51105                                                       unsigned int *outlen,
51106                                                       void *arg), void *arg)
51107 {
51108     (void)s;
51109     (void)cb;
51110     (void)arg;
51111     WOLFSSL_STUB("wolfSSL_CTX_set_next_protos_advertised_cb");
51112 }
51113 
51114 void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s,
51115                                       int (*cb) (WOLFSSL *ssl,
51116                                                  unsigned char **out,
51117                                                  unsigned char *outlen,
51118                                                  const unsigned char *in,
51119                                                  unsigned int inlen,
51120                                                  void *arg), void *arg)
51121 {
51122     (void)s;
51123     (void)cb;
51124     (void)arg;
51125     WOLFSSL_STUB("wolfSSL_CTX_set_next_proto_select_cb");
51126 }
51127 
51128 void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char **data,
51129                                     unsigned *len)
51130 {
51131     (void)s;
51132     (void)data;
51133     (void)len;
51134     WOLFSSL_STUB("wolfSSL_get0_next_proto_negotiated");
51135 }
51136 #endif /* HAVE_ALPN */
51137 
51138 #endif /* WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
51139 
51140 #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
51141 int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
51142 {
51143     int idx, start = 0, len;
51144     word16 curve;
51145     char name[MAX_CURVE_NAME_SZ];
51146 
51147     if (ctx == NULL || names == NULL) {
51148         WOLFSSL_MSG("ctx or names was NULL");
51149         return WOLFSSL_FAILURE;
51150     }
51151 
51152     /* Disable all curves so that only the ones the user wants are enabled. */
51153     ctx->disabledCurves = 0xFFFFFFFFUL;
51154     for (idx = 1; names[idx-1] != '\0'; idx++) {
51155         if (names[idx] != ':' && names[idx] != '\0')
51156             continue;
51157 
51158         len = idx - start;
51159         if (len > MAX_CURVE_NAME_SZ - 1)
51160             return WOLFSSL_FAILURE;
51161 
51162         XMEMCPY(name, names + start, len);
51163         name[len] = 0;
51164 
51165         if ((XSTRNCMP(name, "prime256v1", len) == 0) ||
51166                                       (XSTRNCMP(name, "secp256r1", len) == 0) ||
51167                                       (XSTRNCMP(name, "P-256", len) == 0)) {
51168             curve = WOLFSSL_ECC_SECP256R1;
51169         }
51170         else if ((XSTRNCMP(name, "secp384r1", len) == 0) ||
51171                                           (XSTRNCMP(name, "P-384", len) == 0)) {
51172             curve = WOLFSSL_ECC_SECP384R1;
51173         }
51174         else if ((XSTRNCMP(name, "secp521r1", len) == 0) ||
51175                                           (XSTRNCMP(name, "P-521", len) == 0)) {
51176             curve = WOLFSSL_ECC_SECP521R1;
51177         }
51178         else if (XSTRNCMP(name, "X25519", len) == 0) {
51179             curve = WOLFSSL_ECC_X25519;
51180         }
51181         else if (XSTRNCMP(name, "X448", len) == 0) {
51182             curve = WOLFSSL_ECC_X448;
51183         }
51184         else {
51185         #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
51186             int   ret;
51187             const ecc_set_type *eccSet;
51188 
51189             ret = wc_ecc_get_curve_idx_from_name(name);
51190             if (ret < 0) {
51191                 WOLFSSL_MSG("Could not find name in set");
51192                 return WOLFSSL_FAILURE;
51193             }
51194 
51195             eccSet = wc_ecc_get_curve_params(ret);
51196             if (eccSet == NULL) {
51197                 WOLFSSL_MSG("NULL set returned");
51198                 return WOLFSSL_FAILURE;
51199             }
51200 
51201             curve = GetCurveByOID(eccSet->oidSum);
51202         #else
51203             WOLFSSL_MSG("API not present to search farther using name");
51204             return WOLFSSL_FAILURE;
51205         #endif
51206         }
51207 
51208         if (curve >= (sizeof(word32) * WOLFSSL_BIT_SIZE)) {
51209             /* shift left more than size of ctx->disabledCurves causes static
51210              * analysis report */
51211             WOLFSSL_MSG("curve value is too large for upcoming shift");
51212             return WOLFSSL_FAILURE;
51213         }
51214 
51215     #if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT)
51216         /* set the supported curve so client TLS extension contains only the
51217          * desired curves */
51218         if (wolfSSL_CTX_UseSupportedCurve(ctx, curve) != WOLFSSL_SUCCESS) {
51219             WOLFSSL_MSG("Unable to set supported curve");
51220             return WOLFSSL_FAILURE;
51221         }
51222     #endif
51223 
51224         /* Switch the bit to off and therefore is enabled. */
51225         ctx->disabledCurves &= ~(1U << curve);
51226         start = idx + 1;
51227     }
51228 
51229     return WOLFSSL_SUCCESS;
51230 }
51231 
51232 int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
51233 {
51234     if (ssl == NULL) {
51235         return WOLFSSL_FAILURE;
51236     }
51237     return wolfSSL_CTX_set1_curves_list(ssl->ctx, names);
51238 }
51239 #endif /* OPENSSL_EXTRA && HAVE_ECC */
51240 
51241 #ifdef OPENSSL_EXTRA
51242 /* Sets a callback for when sending and receiving protocol messages.
51243  * This callback is copied to all WOLFSSL objects created from the ctx.
51244  *
51245  * ctx WOLFSSL_CTX structure to set callback in
51246  * cb  callback to use
51247  *
51248  * return WOLFSSL_SUCCESS on success and SSL_FAILURE with error case
51249  */
51250 int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb)
51251 {
51252     WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback");
51253     if (ctx == NULL) {
51254         WOLFSSL_MSG("Null ctx passed in");
51255         return WOLFSSL_FAILURE;
51256     }
51257 
51258     ctx->protoMsgCb = cb;
51259     return WOLFSSL_SUCCESS;
51260 }
51261 
51262 
51263 /* Sets a callback for when sending and receiving protocol messages.
51264  *
51265  * ssl WOLFSSL structure to set callback in
51266  * cb  callback to use
51267  *
51268  * return WOLFSSL_SUCCESS on success and SSL_FAILURE with error case
51269  */
51270 int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb)
51271 {
51272     WOLFSSL_ENTER("wolfSSL_set_msg_callback");
51273 
51274     if (ssl == NULL) {
51275         return SSL_FAILURE;
51276     }
51277 
51278     if (cb != NULL) {
51279         ssl->toInfoOn = 1;
51280     }
51281 
51282     ssl->protoMsgCb = cb;
51283     return WOLFSSL_SUCCESS;
51284 }
51285 
51286 
51287 /* set the user argument to pass to the msg callback when called
51288  * return WOLFSSL_SUCCESS on success */
51289 int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg)
51290 {
51291     WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback_arg");
51292     if (ctx == NULL) {
51293         WOLFSSL_MSG("Null WOLFSSL_CTX passed in");
51294         return WOLFSSL_FAILURE;
51295     }
51296 
51297     ctx->protoMsgCtx = arg;
51298     return WOLFSSL_SUCCESS;
51299 }
51300 
51301 
51302 int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg)
51303 {
51304     WOLFSSL_ENTER("wolfSSL_set_msg_callback_arg");
51305     if (ssl == NULL)
51306         return WOLFSSL_FAILURE;
51307 
51308     ssl->protoMsgCtx = arg;
51309     return WOLFSSL_SUCCESS;
51310 }
51311 
51312 void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file, int line)
51313 {
51314     void *ret;
51315     (void)file;
51316     (void)line;
51317 
51318     if (data == NULL || siz >= INT_MAX)
51319         return NULL;
51320 
51321     ret = OPENSSL_malloc(siz);
51322     if (ret == NULL) {
51323         return NULL;
51324     }
51325     return XMEMCPY(ret, data, siz);
51326 }
51327 
51328 void wolfSSL_OPENSSL_cleanse(void *ptr, size_t len)
51329 {
51330     if (ptr)
51331         ForceZero(ptr, (word32)len);
51332 }
51333 
51334 int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p,
51335                             unsigned int p_len)
51336 {
51337     WOLFSSL_ENTER("wolfSSL_CTX_set_alpn_protos");
51338     if (ctx == NULL)
51339         return BAD_FUNC_ARG;
51340     if (ctx->alpn_cli_protos != NULL) {
51341         XFREE((void*)ctx->alpn_cli_protos, ctx->heap, DYNAMIC_TYPE_OPENSSL);
51342     }
51343 
51344     ctx->alpn_cli_protos = (const unsigned char*)XMALLOC(p_len,
51345         ctx->heap, DYNAMIC_TYPE_OPENSSL);
51346     if (ctx->alpn_cli_protos == NULL) {
51347 #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
51348         /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
51349          * the function reverses the return value convention.
51350          */
51351         return 1;
51352 #else
51353         return WOLFSSL_FAILURE;
51354 #endif
51355     }
51356     XMEMCPY((void*)ctx->alpn_cli_protos, p, p_len);
51357     ctx->alpn_cli_protos_len = p_len;
51358 
51359 #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
51360     /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
51361      * the function reverses the return value convention.
51362      */
51363     return 0;
51364 #else
51365     return WOLFSSL_SUCCESS;
51366 #endif
51367 }
51368 
51369 
51370 #ifdef HAVE_ALPN
51371 #ifndef NO_BIO
51372 /* Sets the ALPN extension protos
51373  *
51374  * example format is
51375  * unsigned char p[] = {
51376  *      8, 'h', 't', 't', 'p', '/', '1', '.', '1'
51377  * };
51378  *
51379  * returns WOLFSSL_SUCCESS on success */
51380 int wolfSSL_set_alpn_protos(WOLFSSL* ssl,
51381         const unsigned char* p, unsigned int p_len)
51382 {
51383     WOLFSSL_BIO* bio;
51384     char* pt;
51385 
51386     unsigned int sz;
51387     unsigned int idx = 0;
51388     int alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
51389     WOLFSSL_ENTER("wolfSSL_set_alpn_protos");
51390 
51391     if (ssl == NULL || p_len <= 1) {
51392 #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
51393         /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
51394          * the function reverses the return value convention.
51395          */
51396         return 1;
51397 #else
51398         return WOLFSSL_FAILURE;
51399 #endif
51400     }
51401 
51402     bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
51403     if (bio == NULL) {
51404 #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
51405         /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
51406          * the function reverses the return value convention.
51407          */
51408         return 1;
51409 #else
51410         return WOLFSSL_FAILURE;
51411 #endif
51412     }
51413 
51414     /* convert into comma separated list */
51415     while (idx < p_len - 1) {
51416         unsigned int i;
51417 
51418         sz = p[idx++];
51419         if (idx + sz > p_len) {
51420             WOLFSSL_MSG("Bad list format");
51421             wolfSSL_BIO_free(bio);
51422     #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
51423             /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
51424              * the function reverses the return value convention.
51425              */
51426             return 1;
51427     #else
51428             return WOLFSSL_FAILURE;
51429     #endif
51430         }
51431         if (sz > 0) {
51432             for (i = 0; i < sz; i++) {
51433                 wolfSSL_BIO_write(bio, &p[idx++], 1);
51434             }
51435             if (idx < p_len - 1)
51436                 wolfSSL_BIO_write(bio, ",", 1);
51437         }
51438     }
51439     wolfSSL_BIO_write(bio, "\0", 1);
51440 
51441     /* clears out all current ALPN extensions set */
51442     TLSX_Remove(&ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL, ssl->heap);
51443 
51444     if ((sz = wolfSSL_BIO_get_mem_data(bio, &pt)) > 0) {
51445         wolfSSL_UseALPN(ssl, pt, sz, alpn_opt);
51446     }
51447     wolfSSL_BIO_free(bio);
51448 #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
51449     /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
51450      * the function reverses the return value convention.
51451      */
51452     return 0;
51453 #else
51454     return WOLFSSL_SUCCESS;
51455 #endif
51456 }
51457 #endif /* !NO_BIO */
51458 #endif /* HAVE_ALPN */
51459 #endif /* OPENSSL_EXTRA */
51460 
51461 #if defined(OPENSSL_EXTRA)
51462 
51463 #ifndef NO_BIO
51464 #define WOLFSSL_BIO_INCLUDED
51465 #include "src/bio.c"
51466 #endif
51467 
51468 word32 nid2oid(int nid, int grp)
51469 {
51470     /* get OID type */
51471     switch (grp) {
51472         /* oidHashType */
51473         case oidHashType:
51474             switch (nid) {
51475             #ifdef WOLFSSL_MD2
51476                 case NID_md2:
51477                     return MD2h;
51478             #endif
51479             #ifndef NO_MD5
51480                 case NID_md5:
51481                     return MD5h;
51482             #endif
51483             #ifndef NO_SHA
51484                 case NID_sha1:
51485                     return SHAh;
51486             #endif
51487                 case NID_sha224:
51488                     return SHA224h;
51489             #ifndef NO_SHA256
51490                 case NID_sha256:
51491                     return SHA256h;
51492             #endif
51493             #ifdef WOLFSSL_SHA384
51494                 case NID_sha384:
51495                     return SHA384h;
51496             #endif
51497             #ifdef WOLFSSL_SHA512
51498                 case NID_sha512:
51499                     return SHA512h;
51500             #endif
51501             }
51502             break;
51503 
51504         /*  oidSigType */
51505         case oidSigType:
51506             switch (nid) {
51507             #ifndef NO_DSA
51508                 case NID_dsaWithSHA1:
51509                     return CTC_SHAwDSA;
51510                 case NID_dsa_with_SHA256:
51511                     return CTC_SHA256wDSA;
51512             #endif /* NO_DSA */
51513             #ifndef NO_RSA
51514                 case NID_md2WithRSAEncryption:
51515                     return CTC_MD2wRSA;
51516                 case NID_md5WithRSAEncryption:
51517                     return CTC_MD5wRSA;
51518                 case NID_sha1WithRSAEncryption:
51519                     return CTC_SHAwRSA;
51520                 case NID_sha224WithRSAEncryption:
51521                     return CTC_SHA224wRSA;
51522                 case NID_sha256WithRSAEncryption:
51523                     return CTC_SHA256wRSA;
51524                 case NID_sha384WithRSAEncryption:
51525                     return CTC_SHA384wRSA;
51526                 case NID_sha512WithRSAEncryption:
51527                     return CTC_SHA512wRSA;
51528                 #ifdef WOLFSSL_SHA3
51529                 case NID_RSA_SHA3_224:
51530                     return CTC_SHA3_224wRSA;
51531                 case NID_RSA_SHA3_256:
51532                     return CTC_SHA3_256wRSA;
51533                 case NID_RSA_SHA3_384:
51534                     return CTC_SHA3_384wRSA;
51535                 case NID_RSA_SHA3_512:
51536                     return CTC_SHA3_512wRSA;
51537                 #endif
51538             #endif /* NO_RSA */
51539             #ifdef HAVE_ECC
51540                 case NID_ecdsa_with_SHA1:
51541                     return CTC_SHAwECDSA;
51542                 case NID_ecdsa_with_SHA224:
51543                     return CTC_SHA224wECDSA;
51544                 case NID_ecdsa_with_SHA256:
51545                     return CTC_SHA256wECDSA;
51546                 case NID_ecdsa_with_SHA384:
51547                     return CTC_SHA384wECDSA;
51548                 case NID_ecdsa_with_SHA512:
51549                     return CTC_SHA512wECDSA;
51550                 #ifdef WOLFSSL_SHA3
51551                 case NID_ecdsa_with_SHA3_224:
51552                     return CTC_SHA3_224wECDSA;
51553                 case NID_ecdsa_with_SHA3_256:
51554                     return CTC_SHA3_256wECDSA;
51555                 case NID_ecdsa_with_SHA3_384:
51556                     return CTC_SHA3_384wECDSA;
51557                 case NID_ecdsa_with_SHA3_512:
51558                     return CTC_SHA3_512wECDSA;
51559                 #endif
51560             #endif /* HAVE_ECC */
51561             }
51562             break;
51563 
51564         /* oidKeyType */
51565         case oidKeyType:
51566             switch (nid) {
51567             #ifndef NO_DSA
51568                 case NID_dsa:
51569                     return DSAk;
51570             #endif /* NO_DSA */
51571             #ifndef NO_RSA
51572                 case NID_rsaEncryption:
51573                     return RSAk;
51574             #endif /* NO_RSA */
51575             #ifdef HAVE_ECC
51576                 case NID_X9_62_id_ecPublicKey:
51577                     return ECDSAk;
51578             #endif /* HAVE_ECC */
51579             }
51580             break;
51581 
51582 
51583     #ifdef HAVE_ECC
51584         case oidCurveType:
51585             switch (nid) {
51586             case NID_X9_62_prime192v1:
51587                 return ECC_SECP192R1_OID;
51588             case NID_X9_62_prime192v2:
51589                 return ECC_PRIME192V2_OID;
51590             case NID_X9_62_prime192v3:
51591                 return ECC_PRIME192V3_OID;
51592             case NID_X9_62_prime239v1:
51593                 return ECC_PRIME239V1_OID;
51594             case NID_X9_62_prime239v2:
51595                 return ECC_PRIME239V2_OID;
51596             case NID_X9_62_prime239v3:
51597                 return ECC_PRIME239V3_OID;
51598             case NID_X9_62_prime256v1:
51599                 return ECC_SECP256R1_OID;
51600             case NID_secp112r1:
51601                 return ECC_SECP112R1_OID;
51602             case NID_secp112r2:
51603                 return ECC_SECP112R2_OID;
51604             case NID_secp128r1:
51605                 return ECC_SECP128R1_OID;
51606             case NID_secp128r2:
51607                 return ECC_SECP128R2_OID;
51608             case NID_secp160r1:
51609                 return ECC_SECP160R1_OID;
51610             case NID_secp160r2:
51611                 return ECC_SECP160R2_OID;
51612             case NID_secp224r1:
51613                 return ECC_SECP224R1_OID;
51614             case NID_secp384r1:
51615                 return ECC_SECP384R1_OID;
51616             case NID_secp521r1:
51617                 return ECC_SECP521R1_OID;
51618             case NID_secp160k1:
51619                 return ECC_SECP160K1_OID;
51620             case NID_secp192k1:
51621                 return ECC_SECP192K1_OID;
51622             case NID_secp224k1:
51623                 return ECC_SECP224K1_OID;
51624             case NID_secp256k1:
51625                 return ECC_SECP256K1_OID;
51626             case NID_brainpoolP160r1:
51627                 return ECC_BRAINPOOLP160R1_OID;
51628             case NID_brainpoolP192r1:
51629                 return ECC_BRAINPOOLP192R1_OID;
51630             case NID_brainpoolP224r1:
51631                 return ECC_BRAINPOOLP224R1_OID;
51632             case NID_brainpoolP256r1:
51633                 return ECC_BRAINPOOLP256R1_OID;
51634             case NID_brainpoolP320r1:
51635                 return ECC_BRAINPOOLP320R1_OID;
51636             case NID_brainpoolP384r1:
51637                 return ECC_BRAINPOOLP384R1_OID;
51638             case NID_brainpoolP512r1:
51639                 return ECC_BRAINPOOLP512R1_OID;
51640             }
51641             break;
51642     #endif /* HAVE_ECC */
51643 
51644         /* oidBlkType */
51645         case oidBlkType:
51646             switch (nid) {
51647             #ifdef WOLFSSL_AES_128
51648                 case AES128CBCb:
51649                     return AES128CBCb;
51650             #endif
51651             #ifdef WOLFSSL_AES_192
51652                 case AES192CBCb:
51653                     return AES192CBCb;
51654             #endif
51655             #ifdef WOLFSSL_AES_256
51656                 case AES256CBCb:
51657                     return AES256CBCb;
51658             #endif
51659             #ifndef NO_DES3
51660                 case NID_des:
51661                     return DESb;
51662                 case NID_des3:
51663                     return DES3b;
51664             #endif
51665             }
51666             break;
51667 
51668     #ifdef HAVE_OCSP
51669         case oidOcspType:
51670             switch (nid) {
51671                 case NID_id_pkix_OCSP_basic:
51672                     return OCSP_BASIC_OID;
51673                 case OCSP_NONCE_OID:
51674                     return OCSP_NONCE_OID;
51675             }
51676             break;
51677     #endif /* HAVE_OCSP */
51678 
51679         /* oidCertExtType */
51680         case oidCertExtType:
51681             switch (nid) {
51682                 case NID_basic_constraints:
51683                     return BASIC_CA_OID;
51684                 case NID_subject_alt_name:
51685                     return ALT_NAMES_OID;
51686                 case NID_crl_distribution_points:
51687                     return CRL_DIST_OID;
51688                 case NID_info_access:
51689                     return AUTH_INFO_OID;
51690                 case NID_authority_key_identifier:
51691                     return AUTH_KEY_OID;
51692                 case NID_subject_key_identifier:
51693                     return SUBJ_KEY_OID;
51694                 case NID_inhibit_any_policy:
51695                     return INHIBIT_ANY_OID;
51696                 case NID_key_usage:
51697                     return KEY_USAGE_OID;
51698                 case NID_name_constraints:
51699                     return NAME_CONS_OID;
51700                 case NID_certificate_policies:
51701                     return CERT_POLICY_OID;
51702                 case NID_ext_key_usage:
51703                     return EXT_KEY_USAGE_OID;
51704             }
51705             break;
51706 
51707         /* oidCertAuthInfoType */
51708         case oidCertAuthInfoType:
51709             switch (nid) {
51710                 case NID_ad_OCSP:
51711                     return AIA_OCSP_OID;
51712                 case NID_ad_ca_issuers:
51713                     return AIA_CA_ISSUER_OID;
51714             }
51715             break;
51716 
51717         /* oidCertPolicyType */
51718         case oidCertPolicyType:
51719             switch (nid) {
51720                 case NID_any_policy:
51721                     return CP_ANY_OID;
51722             }
51723             break;
51724 
51725         /* oidCertAltNameType */
51726         case oidCertAltNameType:
51727             switch (nid) {
51728                 case NID_hw_name_oid:
51729                     return HW_NAME_OID;
51730             }
51731             break;
51732 
51733         /* oidCertKeyUseType */
51734         case oidCertKeyUseType:
51735             switch (nid) {
51736                 case NID_anyExtendedKeyUsage:
51737                     return EKU_ANY_OID;
51738                 case EKU_SERVER_AUTH_OID:
51739                     return EKU_SERVER_AUTH_OID;
51740                 case EKU_CLIENT_AUTH_OID:
51741                     return EKU_CLIENT_AUTH_OID;
51742                 case EKU_OCSP_SIGN_OID:
51743                     return EKU_OCSP_SIGN_OID;
51744             }
51745             break;
51746 
51747         /* oidKdfType */
51748         case oidKdfType:
51749             switch (nid) {
51750                 case PBKDF2_OID:
51751                     return PBKDF2_OID;
51752             }
51753             break;
51754 
51755         /* oidPBEType */
51756         case oidPBEType:
51757             switch (nid) {
51758                 case PBE_SHA1_RC4_128:
51759                     return PBE_SHA1_RC4_128;
51760                 case PBE_SHA1_DES:
51761                     return PBE_SHA1_DES;
51762                 case PBE_SHA1_DES3:
51763                     return PBE_SHA1_DES3;
51764             }
51765             break;
51766 
51767         /* oidKeyWrapType */
51768         case oidKeyWrapType:
51769             switch (nid) {
51770             #ifdef WOLFSSL_AES_128
51771                 case AES128_WRAP:
51772                     return AES128_WRAP;
51773             #endif
51774             #ifdef WOLFSSL_AES_192
51775                 case AES192_WRAP:
51776                     return AES192_WRAP;
51777             #endif
51778             #ifdef WOLFSSL_AES_256
51779                 case AES256_WRAP:
51780                     return AES256_WRAP;
51781             #endif
51782             }
51783             break;
51784 
51785         /* oidCmsKeyAgreeType */
51786         case oidCmsKeyAgreeType:
51787             switch (nid) {
51788                 #ifndef NO_SHA
51789                 case dhSinglePass_stdDH_sha1kdf_scheme:
51790                     return dhSinglePass_stdDH_sha1kdf_scheme;
51791                 #endif
51792                 #ifdef WOLFSSL_SHA224
51793                 case dhSinglePass_stdDH_sha224kdf_scheme:
51794                     return dhSinglePass_stdDH_sha224kdf_scheme;
51795                 #endif
51796                 #ifndef NO_SHA256
51797                 case dhSinglePass_stdDH_sha256kdf_scheme:
51798                     return dhSinglePass_stdDH_sha256kdf_scheme;
51799                 #endif
51800                 #ifdef WOLFSSL_SHA384
51801                 case dhSinglePass_stdDH_sha384kdf_scheme:
51802                     return dhSinglePass_stdDH_sha384kdf_scheme;
51803                 #endif
51804                 #ifdef WOLFSSL_SHA512
51805                 case dhSinglePass_stdDH_sha512kdf_scheme:
51806                     return dhSinglePass_stdDH_sha512kdf_scheme;
51807                 #endif
51808             }
51809             break;
51810 
51811         default:
51812             WOLFSSL_MSG("NID not in table");
51813             /* MSVC warns without the cast */
51814             return (word32)-1;
51815     }
51816 
51817     /* MSVC warns without the cast */
51818     return (word32)-1;
51819 }
51820 
51821 int oid2nid(word32 oid, int grp)
51822 {
51823     size_t i;
51824     /* get OID type */
51825     switch (grp) {
51826         /* oidHashType */
51827         case oidHashType:
51828             switch (oid) {
51829             #ifdef WOLFSSL_MD2
51830                 case MD2h:
51831                     return NID_md2;
51832             #endif
51833             #ifndef NO_MD5
51834                 case MD5h:
51835                     return NID_md5;
51836             #endif
51837             #ifndef NO_SHA
51838                 case SHAh:
51839                     return NID_sha1;
51840             #endif
51841                 case SHA224h:
51842                     return NID_sha224;
51843             #ifndef NO_SHA256
51844                 case SHA256h:
51845                     return NID_sha256;
51846             #endif
51847             #ifdef WOLFSSL_SHA384
51848                 case SHA384h:
51849                     return NID_sha384;
51850             #endif
51851             #ifdef WOLFSSL_SHA512
51852                 case SHA512h:
51853                     return NID_sha512;
51854             #endif
51855             }
51856             break;
51857 
51858         /*  oidSigType */
51859         case oidSigType:
51860             switch (oid) {
51861             #ifndef NO_DSA
51862                 case CTC_SHAwDSA:
51863                     return NID_dsaWithSHA1;
51864                 case CTC_SHA256wDSA:
51865                     return NID_dsa_with_SHA256;
51866             #endif /* NO_DSA */
51867             #ifndef NO_RSA
51868                 case CTC_MD2wRSA:
51869                     return NID_md2WithRSAEncryption;
51870                 case CTC_MD5wRSA:
51871                     return NID_md5WithRSAEncryption;
51872                 case CTC_SHAwRSA:
51873                     return NID_sha1WithRSAEncryption;
51874                 case CTC_SHA224wRSA:
51875                     return NID_sha224WithRSAEncryption;
51876                 case CTC_SHA256wRSA:
51877                     return NID_sha256WithRSAEncryption;
51878                 case CTC_SHA384wRSA:
51879                     return NID_sha384WithRSAEncryption;
51880                 case CTC_SHA512wRSA:
51881                     return NID_sha512WithRSAEncryption;
51882                 #ifdef WOLFSSL_SHA3
51883                 case CTC_SHA3_224wRSA:
51884                     return NID_RSA_SHA3_224;
51885                 case CTC_SHA3_256wRSA:
51886                     return NID_RSA_SHA3_256;
51887                 case CTC_SHA3_384wRSA:
51888                     return NID_RSA_SHA3_384;
51889                 case CTC_SHA3_512wRSA:
51890                     return NID_RSA_SHA3_512;
51891                 #endif
51892             #endif /* NO_RSA */
51893             #ifdef HAVE_ECC
51894                 case CTC_SHAwECDSA:
51895                     return NID_ecdsa_with_SHA1;
51896                 case CTC_SHA224wECDSA:
51897                     return NID_ecdsa_with_SHA224;
51898                 case CTC_SHA256wECDSA:
51899                     return NID_ecdsa_with_SHA256;
51900                 case CTC_SHA384wECDSA:
51901                     return NID_ecdsa_with_SHA384;
51902                 case CTC_SHA512wECDSA:
51903                     return NID_ecdsa_with_SHA512;
51904                 #ifdef WOLFSSL_SHA3
51905                 case CTC_SHA3_224wECDSA:
51906                     return NID_ecdsa_with_SHA3_224;
51907                 case CTC_SHA3_256wECDSA:
51908                     return NID_ecdsa_with_SHA3_256;
51909                 case CTC_SHA3_384wECDSA:
51910                     return NID_ecdsa_with_SHA3_384;
51911                 case CTC_SHA3_512wECDSA:
51912                     return NID_ecdsa_with_SHA3_512;
51913                 #endif
51914             #endif /* HAVE_ECC */
51915             }
51916             break;
51917 
51918         /* oidKeyType */
51919         case oidKeyType:
51920             switch (oid) {
51921             #ifndef NO_DSA
51922                 case DSAk:
51923                     return NID_dsa;
51924             #endif /* NO_DSA */
51925             #ifndef NO_RSA
51926                 case RSAk:
51927                     return NID_rsaEncryption;
51928             #endif /* NO_RSA */
51929             #ifdef HAVE_ECC
51930                 case ECDSAk:
51931                     return NID_X9_62_id_ecPublicKey;
51932             #endif /* HAVE_ECC */
51933             }
51934             break;
51935 
51936 
51937     #ifdef HAVE_ECC
51938         case oidCurveType:
51939             switch (oid) {
51940             case ECC_SECP192R1_OID:
51941                 return NID_X9_62_prime192v1;
51942             case ECC_PRIME192V2_OID:
51943                 return NID_X9_62_prime192v2;
51944             case ECC_PRIME192V3_OID:
51945                 return NID_X9_62_prime192v3;
51946             case ECC_PRIME239V1_OID:
51947                 return NID_X9_62_prime239v1;
51948             case ECC_PRIME239V2_OID:
51949                 return NID_X9_62_prime239v2;
51950             case ECC_PRIME239V3_OID:
51951                 return NID_X9_62_prime239v3;
51952             case ECC_SECP256R1_OID:
51953                 return NID_X9_62_prime256v1;
51954             case ECC_SECP112R1_OID:
51955                 return NID_secp112r1;
51956             case ECC_SECP112R2_OID:
51957                 return NID_secp112r2;
51958             case ECC_SECP128R1_OID:
51959                 return NID_secp128r1;
51960             case ECC_SECP128R2_OID:
51961                 return NID_secp128r2;
51962             case ECC_SECP160R1_OID:
51963                 return NID_secp160r1;
51964             case ECC_SECP160R2_OID:
51965                 return NID_secp160r2;
51966             case ECC_SECP224R1_OID:
51967                 return NID_secp224r1;
51968             case ECC_SECP384R1_OID:
51969                 return NID_secp384r1;
51970             case ECC_SECP521R1_OID:
51971                 return NID_secp521r1;
51972             case ECC_SECP160K1_OID:
51973                 return NID_secp160k1;
51974             case ECC_SECP192K1_OID:
51975                 return NID_secp192k1;
51976             case ECC_SECP224K1_OID:
51977                 return NID_secp224k1;
51978             case ECC_SECP256K1_OID:
51979                 return NID_secp256k1;
51980             case ECC_BRAINPOOLP160R1_OID:
51981                 return NID_brainpoolP160r1;
51982             case ECC_BRAINPOOLP192R1_OID:
51983                 return NID_brainpoolP192r1;
51984             case ECC_BRAINPOOLP224R1_OID:
51985                 return NID_brainpoolP224r1;
51986             case ECC_BRAINPOOLP256R1_OID:
51987                 return NID_brainpoolP256r1;
51988             case ECC_BRAINPOOLP320R1_OID:
51989                 return NID_brainpoolP320r1;
51990             case ECC_BRAINPOOLP384R1_OID:
51991                 return NID_brainpoolP384r1;
51992             case ECC_BRAINPOOLP512R1_OID:
51993                 return NID_brainpoolP512r1;
51994             }
51995             break;
51996     #endif /* HAVE_ECC */
51997 
51998         /* oidBlkType */
51999         case oidBlkType:
52000             switch (oid) {
52001             #ifdef WOLFSSL_AES_128
52002                 case AES128CBCb:
52003                     return AES128CBCb;
52004             #endif
52005             #ifdef WOLFSSL_AES_192
52006                 case AES192CBCb:
52007                     return AES192CBCb;
52008             #endif
52009             #ifdef WOLFSSL_AES_256
52010                 case AES256CBCb:
52011                     return AES256CBCb;
52012             #endif
52013             #ifndef NO_DES3
52014                 case DESb:
52015                     return NID_des;
52016                 case DES3b:
52017                     return NID_des3;
52018             #endif
52019             }
52020             break;
52021 
52022     #ifdef HAVE_OCSP
52023         case oidOcspType:
52024             switch (oid) {
52025                 case OCSP_BASIC_OID:
52026                     return NID_id_pkix_OCSP_basic;
52027                 case OCSP_NONCE_OID:
52028                     return OCSP_NONCE_OID;
52029             }
52030             break;
52031     #endif /* HAVE_OCSP */
52032 
52033         /* oidCertExtType */
52034         case oidCertExtType:
52035             switch (oid) {
52036                 case BASIC_CA_OID:
52037                     return NID_basic_constraints;
52038                 case ALT_NAMES_OID:
52039                     return NID_subject_alt_name;
52040                 case CRL_DIST_OID:
52041                     return NID_crl_distribution_points;
52042                 case AUTH_INFO_OID:
52043                     return NID_info_access;
52044                 case AUTH_KEY_OID:
52045                     return NID_authority_key_identifier;
52046                 case SUBJ_KEY_OID:
52047                     return NID_subject_key_identifier;
52048                 case INHIBIT_ANY_OID:
52049                     return NID_inhibit_any_policy;
52050                 case KEY_USAGE_OID:
52051                     return NID_key_usage;
52052                 case NAME_CONS_OID:
52053                     return NID_name_constraints;
52054                 case CERT_POLICY_OID:
52055                     return NID_certificate_policies;
52056                 case EXT_KEY_USAGE_OID:
52057                     return NID_ext_key_usage;
52058             }
52059             break;
52060 
52061         /* oidCertAuthInfoType */
52062         case oidCertAuthInfoType:
52063             switch (oid) {
52064                 case AIA_OCSP_OID:
52065                     return NID_ad_OCSP;
52066                 case AIA_CA_ISSUER_OID:
52067                     return NID_ad_ca_issuers;
52068             }
52069             break;
52070 
52071         /* oidCertPolicyType */
52072         case oidCertPolicyType:
52073             switch (oid) {
52074                 case CP_ANY_OID:
52075                     return NID_any_policy;
52076             }
52077             break;
52078 
52079         /* oidCertAltNameType */
52080         case oidCertAltNameType:
52081             switch (oid) {
52082                 case HW_NAME_OID:
52083                     return NID_hw_name_oid;
52084             }
52085             break;
52086 
52087         /* oidCertKeyUseType */
52088         case oidCertKeyUseType:
52089             switch (oid) {
52090                 case EKU_ANY_OID:
52091                     return NID_anyExtendedKeyUsage;
52092                 case EKU_SERVER_AUTH_OID:
52093                     return EKU_SERVER_AUTH_OID;
52094                 case EKU_CLIENT_AUTH_OID:
52095                     return EKU_CLIENT_AUTH_OID;
52096                 case EKU_OCSP_SIGN_OID:
52097                     return EKU_OCSP_SIGN_OID;
52098             }
52099             break;
52100 
52101         /* oidKdfType */
52102         case oidKdfType:
52103             switch (oid) {
52104                 case PBKDF2_OID:
52105                     return PBKDF2_OID;
52106             }
52107             break;
52108 
52109         /* oidPBEType */
52110         case oidPBEType:
52111             switch (oid) {
52112                 case PBE_SHA1_RC4_128:
52113                     return PBE_SHA1_RC4_128;
52114                 case PBE_SHA1_DES:
52115                     return PBE_SHA1_DES;
52116                 case PBE_SHA1_DES3:
52117                     return PBE_SHA1_DES3;
52118             }
52119             break;
52120 
52121         /* oidKeyWrapType */
52122         case oidKeyWrapType:
52123             switch (oid) {
52124             #ifdef WOLFSSL_AES_128
52125                 case AES128_WRAP:
52126                     return AES128_WRAP;
52127             #endif
52128             #ifdef WOLFSSL_AES_192
52129                 case AES192_WRAP:
52130                     return AES192_WRAP;
52131             #endif
52132             #ifdef WOLFSSL_AES_256
52133                 case AES256_WRAP:
52134                     return AES256_WRAP;
52135             #endif
52136             }
52137             break;
52138 
52139         /* oidCmsKeyAgreeType */
52140         case oidCmsKeyAgreeType:
52141             switch (oid) {
52142                 #ifndef NO_SHA
52143                 case dhSinglePass_stdDH_sha1kdf_scheme:
52144                     return dhSinglePass_stdDH_sha1kdf_scheme;
52145                 #endif
52146                 #ifdef WOLFSSL_SHA224
52147                 case dhSinglePass_stdDH_sha224kdf_scheme:
52148                     return dhSinglePass_stdDH_sha224kdf_scheme;
52149                 #endif
52150                 #ifndef NO_SHA256
52151                 case dhSinglePass_stdDH_sha256kdf_scheme:
52152                     return dhSinglePass_stdDH_sha256kdf_scheme;
52153                 #endif
52154                 #ifdef WOLFSSL_SHA384
52155                 case dhSinglePass_stdDH_sha384kdf_scheme:
52156                     return dhSinglePass_stdDH_sha384kdf_scheme;
52157                 #endif
52158                 #ifdef WOLFSSL_SHA512
52159                 case dhSinglePass_stdDH_sha512kdf_scheme:
52160                     return dhSinglePass_stdDH_sha512kdf_scheme;
52161                 #endif
52162             }
52163             break;
52164 
52165 #ifdef WOLFSSL_CERT_REQ
52166         case oidCsrAttrType:
52167             switch (oid) {
52168                 case PKCS9_CONTENT_TYPE_OID:
52169                     return NID_pkcs9_contentType;
52170                 case CHALLENGE_PASSWORD_OID:
52171                     return NID_pkcs9_challengePassword;
52172                 case SERIAL_NUMBER_OID:
52173                     return NID_serialNumber;
52174             }
52175             break;
52176 #endif
52177 
52178         default:
52179             WOLFSSL_MSG("NID not in table");
52180     }
52181     /* If not found in above switch then try the table */
52182     for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
52183         if (wolfssl_object_info[i].id == (int)oid) {
52184             return wolfssl_object_info[i].nid;
52185         }
52186     }
52187 
52188     return -1;
52189 }
52190 
52191 /* when calling SetIndividualInternal, mpi should be cleared by caller if no
52192  * longer used. ie mp_free(mpi). This is to free data when fastmath is
52193  * disabled since a copy of mpi is made by this function and placed into bn.
52194  */
52195 int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi)
52196 {
52197     WOLFSSL_MSG("Entering SetIndividualInternal");
52198 
52199     if (bn == NULL || bn->internal == NULL) {
52200         WOLFSSL_MSG("bn NULL error");
52201         return WOLFSSL_FATAL_ERROR;
52202     }
52203 
52204     if (mpi == NULL) {
52205         WOLFSSL_MSG("mpi NULL error");
52206         return WOLFSSL_FATAL_ERROR;
52207     }
52208 
52209     if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
52210         WOLFSSL_MSG("mp_copy error");
52211         return WOLFSSL_FATAL_ERROR;
52212     }
52213 
52214     return WOLFSSL_SUCCESS;
52215 }
52216 
52217 
52218 #ifndef NO_ASN
52219 WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai,
52220                                        WOLFSSL_BIGNUM *bn)
52221 {
52222     mp_int mpi;
52223     word32 idx = 0;
52224     int ret;
52225 
52226     WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_to_BN");
52227 
52228     if (ai == NULL) {
52229         return NULL;
52230     }
52231 
52232     ret = GetInt(&mpi, ai->data, &idx, ai->dataMax);
52233     if (ret != 0) {
52234     #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
52235         ret = mp_init(&mpi); /* must init mpi */
52236         if (ret != MP_OKAY) {
52237             return NULL;
52238         }
52239         /* Serial number in QT starts at index 0 of data */
52240         if (mp_read_unsigned_bin(&mpi, (byte*)ai->data, ai->length) != 0) {
52241                 mp_clear(&mpi);
52242                 return NULL;
52243             }
52244     #else
52245         /* expecting ASN1 format for INTEGER */
52246         WOLFSSL_LEAVE("wolfSSL_ASN1_INTEGER_to_BN", ret);
52247         return NULL;
52248     #endif
52249     }
52250 
52251     /* mp_clear needs called because mpi is copied and causes memory leak with
52252      * --disable-fastmath */
52253     ret = SetIndividualExternal(&bn, &mpi);
52254     mp_clear(&mpi);
52255 
52256     if (ret != WOLFSSL_SUCCESS) {
52257         return NULL;
52258     }
52259     return bn;
52260 }
52261 #endif /* !NO_ASN */
52262 
52263 #if !defined(NO_DSA) && !defined(NO_DH)
52264 WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *dsa)
52265 {
52266     WOLFSSL_DH* dh;
52267     DhKey*      key;
52268 
52269     WOLFSSL_ENTER("wolfSSL_DSA_dup_DH");
52270 
52271     if (dsa == NULL) {
52272         return NULL;
52273     }
52274 
52275     dh = wolfSSL_DH_new();
52276     if (dh == NULL) {
52277         return NULL;
52278     }
52279     key = (DhKey*)dh->internal;
52280 
52281     if (dsa->p != NULL &&
52282         SetIndividualInternal(((WOLFSSL_DSA*)dsa)->p, &key->p) != WOLFSSL_SUCCESS) {
52283         WOLFSSL_MSG("rsa p key error");
52284         wolfSSL_DH_free(dh);
52285         return NULL;
52286     }
52287     if (dsa->g != NULL &&
52288         SetIndividualInternal(((WOLFSSL_DSA*)dsa)->g, &key->g) != WOLFSSL_SUCCESS) {
52289         WOLFSSL_MSG("rsa g key error");
52290         wolfSSL_DH_free(dh);
52291         return NULL;
52292     }
52293 
52294     if (SetIndividualExternal(&dh->p, &key->p) != WOLFSSL_SUCCESS) {
52295         WOLFSSL_MSG("dsa p key error");
52296         wolfSSL_DH_free(dh);
52297         return NULL;
52298     }
52299     if (SetIndividualExternal(&dh->g, &key->g) != WOLFSSL_SUCCESS) {
52300         WOLFSSL_MSG("dsa g key error");
52301         wolfSSL_DH_free(dh);
52302         return NULL;
52303     }
52304 
52305     return dh;
52306 }
52307 #endif /* !NO_DSA && !NO_DH */
52308 
52309 
52310 #ifndef NO_RSA
52311 #if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
52312 /* Openssl -> WolfSSL */
52313 int SetRsaInternal(WOLFSSL_RSA* rsa)
52314 {
52315     RsaKey* key;
52316     WOLFSSL_MSG("Entering SetRsaInternal");
52317 
52318     if (rsa == NULL || rsa->internal == NULL) {
52319         WOLFSSL_MSG("rsa key NULL error");
52320         return WOLFSSL_FATAL_ERROR;
52321     }
52322 
52323     key = (RsaKey*)rsa->internal;
52324 
52325     if (rsa->n != NULL) {
52326         if (SetIndividualInternal(rsa->n, &key->n) != WOLFSSL_SUCCESS) {
52327             WOLFSSL_MSG("rsa n key error");
52328             return WOLFSSL_FATAL_ERROR;
52329         }
52330     }
52331 
52332     if (rsa->e != NULL) {
52333         if (SetIndividualInternal(rsa->e, &key->e) != WOLFSSL_SUCCESS) {
52334             WOLFSSL_MSG("rsa e key error");
52335             return WOLFSSL_FATAL_ERROR;
52336         }
52337     }
52338 
52339     /* public key */
52340     key->type = RSA_PUBLIC;
52341 
52342     if (rsa->d != NULL) {
52343         if (SetIndividualInternal(rsa->d, &key->d) != WOLFSSL_SUCCESS) {
52344             WOLFSSL_MSG("rsa d key error");
52345             return WOLFSSL_FATAL_ERROR;
52346         }
52347 
52348         /* private key */
52349         key->type = RSA_PRIVATE;
52350     }
52351 
52352     if (rsa->p != NULL &&
52353         SetIndividualInternal(rsa->p, &key->p) != WOLFSSL_SUCCESS) {
52354         WOLFSSL_MSG("rsa p key error");
52355         return WOLFSSL_FATAL_ERROR;
52356     }
52357 
52358     if (rsa->q != NULL &&
52359         SetIndividualInternal(rsa->q, &key->q) != WOLFSSL_SUCCESS) {
52360         WOLFSSL_MSG("rsa q key error");
52361         return WOLFSSL_FATAL_ERROR;
52362     }
52363 
52364 #ifndef RSA_LOW_MEM
52365     if (rsa->dmp1 != NULL &&
52366         SetIndividualInternal(rsa->dmp1, &key->dP) != WOLFSSL_SUCCESS) {
52367         WOLFSSL_MSG("rsa dP key error");
52368         return WOLFSSL_FATAL_ERROR;
52369     }
52370 
52371     if (rsa->dmq1 != NULL &&
52372         SetIndividualInternal(rsa->dmq1, &key->dQ) != WOLFSSL_SUCCESS) {
52373         WOLFSSL_MSG("rsa dQ key error");
52374         return WOLFSSL_FATAL_ERROR;
52375     }
52376 
52377     if (rsa->iqmp != NULL &&
52378         SetIndividualInternal(rsa->iqmp, &key->u) != WOLFSSL_SUCCESS) {
52379         WOLFSSL_MSG("rsa u key error");
52380         return WOLFSSL_FATAL_ERROR;
52381     }
52382 #endif /* !RSA_LOW_MEM */
52383 
52384     rsa->inSet = 1;
52385 
52386     return WOLFSSL_SUCCESS;
52387 }
52388 
52389 
52390 /* WOLFSSL_SUCCESS on ok */
52391 #ifndef NO_WOLFSSL_STUB
52392 int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bn)
52393 {
52394     (void)rsa;
52395     (void)bn;
52396     WOLFSSL_STUB("RSA_blinding_on");
52397     WOLFSSL_MSG("wolfSSL_RSA_blinding_on");
52398 
52399     return WOLFSSL_SUCCESS;  /* on by default */
52400 }
52401 #endif
52402 
52403 /* If not using old FIPS or CAVP selftest or not using fast or user RSA, able
52404  * to check RSA key. */
52405 #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(HAVE_FAST_RSA) && \
52406     !defined(HAVE_USER_RSA) && (!defined(HAVE_FIPS) || \
52407     (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))) && \
52408     !defined(HAVE_SELFTEST) && !defined(HAVE_INTEL_QA) && \
52409     defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_NO_RSA_KEY_CHECK)
52410 int wolfSSL_RSA_check_key(const WOLFSSL_RSA* rsa)
52411 {
52412     int ret = WOLFSSL_SUCCESS;
52413 
52414     WOLFSSL_ENTER("wolfSSL_RSA_check_key");
52415 
52416     if (rsa == NULL || rsa->internal == NULL) {
52417         ret = WOLFSSL_FAILURE;
52418     }
52419 
52420     if (ret == WOLFSSL_SUCCESS && wc_CheckRsaKey((RsaKey*)rsa->internal) != 0) {
52421         ret = WOLFSSL_FAILURE;
52422     }
52423 
52424     WOLFSSL_LEAVE("wolfSSL_RSA_check_key", ret);
52425 
52426     return ret;
52427 }
52428 #endif
52429 
52430 /* return compliant with OpenSSL
52431  *   size of encrypted data if success , -1 if error
52432  */
52433 int wolfSSL_RSA_public_encrypt(int len, const unsigned char* fr,
52434                             unsigned char* to, WOLFSSL_RSA* rsa, int padding)
52435 {
52436     int initTmpRng = 0;
52437     WC_RNG *rng = NULL;
52438     int outLen;
52439     int ret = 0;
52440 #ifdef WOLFSSL_SMALL_STACK
52441     WC_RNG* tmpRNG = NULL;
52442 #else
52443     WC_RNG  _tmpRNG[1];
52444     WC_RNG* tmpRNG = _tmpRNG;
52445 #endif
52446 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
52447     int  mgf = WC_MGF1NONE;
52448     enum wc_HashType hash = WC_HASH_TYPE_NONE;
52449     int pad_type;
52450 #endif
52451 
52452     WOLFSSL_ENTER("RSA_public_encrypt");
52453 
52454 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
52455     switch (padding) {
52456     case RSA_PKCS1_PADDING:
52457         pad_type = WC_RSA_PKCSV15_PAD;
52458         break;
52459     case RSA_PKCS1_OAEP_PADDING:
52460         pad_type = WC_RSA_OAEP_PAD;
52461         hash = WC_HASH_TYPE_SHA;
52462         mgf = WC_MGF1SHA1;
52463         break;
52464     case RSA_PKCS1_PSS_PADDING:
52465         pad_type = WC_RSA_PSS_PAD;
52466         hash = WC_HASH_TYPE_SHA256;
52467         mgf  = WC_MGF1SHA256;
52468         break;
52469     case RSA_NO_PADDING:
52470         pad_type = WC_RSA_NO_PAD;
52471         break;
52472     default:
52473         WOLFSSL_MSG("RSA_public_encrypt unsupported padding");
52474         return WOLFSSL_FAILURE;
52475     }
52476 #endif
52477 
52478     if (rsa->inSet == 0) {
52479         if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
52480             WOLFSSL_MSG("SetRsaInternal failed");
52481             return WOLFSSL_FAILURE;
52482         }
52483     }
52484 
52485     outLen = wolfSSL_RSA_size(rsa);
52486     if (outLen == 0) {
52487         WOLFSSL_MSG("Bad RSA size");
52488     }
52489 
52490     rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRNG, &initTmpRng);
52491     if (rng) {
52492 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
52493         ret = wc_RsaPublicEncrypt_ex(fr, len, to, outLen,
52494                              (RsaKey*)rsa->internal, rng, pad_type,
52495                              hash, mgf, NULL, 0);
52496 #else
52497         if (padding == RSA_PKCS1_PADDING) {
52498             ret = wc_RsaPublicEncrypt(fr, len, to, outLen,
52499                                 (RsaKey*)rsa->internal, rng);
52500         }
52501         else {
52502             WOLFSSL_MSG("RSA_public_encrypt pad type not supported in FIPS");
52503             ret = WOLFSSL_FAILURE;
52504         }
52505 #endif
52506     }
52507 
52508     if (initTmpRng)
52509         wc_FreeRng(tmpRNG);
52510 #ifdef WOLFSSL_SMALL_STACK
52511     if (tmpRNG)
52512         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
52513 #endif
52514 
52515     WOLFSSL_LEAVE("RSA_public_encrypt", ret);
52516 
52517     if (ret <= 0) {
52518         ret = WOLFSSL_FAILURE;
52519     }
52520     return ret;
52521 }
52522 
52523 
52524 
52525 /* return compliant with OpenSSL
52526  *   size of plain recovered data if success , -1 if error
52527  */
52528 int wolfSSL_RSA_private_decrypt(int len, const unsigned char* fr,
52529                             unsigned char* to, WOLFSSL_RSA* rsa, int padding)
52530 {
52531     int outLen;
52532     int ret = 0;
52533   #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
52534     int mgf = WC_MGF1NONE;
52535     enum wc_HashType hash = WC_HASH_TYPE_NONE;
52536     int pad_type;
52537   #endif
52538 
52539     WOLFSSL_ENTER("RSA_private_decrypt");
52540 
52541 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
52542     switch (padding) {
52543     case RSA_PKCS1_PADDING:
52544         pad_type = WC_RSA_PKCSV15_PAD;
52545         break;
52546     case RSA_PKCS1_OAEP_PADDING:
52547         pad_type = WC_RSA_OAEP_PAD;
52548         hash = WC_HASH_TYPE_SHA;
52549         mgf = WC_MGF1SHA1;
52550         break;
52551     case RSA_PKCS1_PSS_PADDING:
52552         pad_type = WC_RSA_PSS_PAD;
52553         hash = WC_HASH_TYPE_SHA256;
52554         mgf  = WC_MGF1SHA256;
52555         break;
52556     case RSA_NO_PADDING:
52557         pad_type = WC_RSA_NO_PAD;
52558         break;
52559     default:
52560         WOLFSSL_MSG("RSA_private_decrypt unsupported padding");
52561         return WOLFSSL_FAILURE;
52562     }
52563 #endif
52564 
52565     if (rsa->inSet == 0) {
52566         if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
52567             WOLFSSL_MSG("SetRsaInternal failed");
52568             return WOLFSSL_FAILURE;
52569         }
52570     }
52571 
52572     outLen = wolfSSL_RSA_size(rsa);
52573     if (outLen == 0) {
52574         WOLFSSL_MSG("Bad RSA size");
52575     }
52576 
52577     /* size of 'to' buffer must be size of RSA key */
52578 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA)
52579     ret = wc_RsaPrivateDecrypt_ex(fr, len, to, outLen,
52580                             (RsaKey*)rsa->internal, pad_type,
52581                             hash, mgf, NULL, 0);
52582 #else
52583     if (padding == RSA_PKCS1_PADDING) {
52584         ret = wc_RsaPrivateDecrypt(fr, len, to, outLen,
52585                                 (RsaKey*)rsa->internal);
52586     }
52587     else {
52588         WOLFSSL_MSG("RSA_private_decrypt pad type not supported in FIPS");
52589         ret = WOLFSSL_FAILURE;
52590     }
52591 #endif
52592 
52593     if (ret <= 0) {
52594         ret = WOLFSSL_FAILURE;
52595     }
52596     WOLFSSL_LEAVE("RSA_private_decrypt", ret);
52597 
52598     return ret;
52599 }
52600 
52601 int wolfSSL_RSA_public_decrypt(int flen, const unsigned char* from,
52602                           unsigned char* to, WOLFSSL_RSA* rsa, int padding)
52603 {
52604     int ret = 0;
52605 #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
52606     (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2))
52607     int pad_type;
52608 #endif
52609 
52610     WOLFSSL_ENTER("RSA_public_decrypt");
52611 
52612     if (rsa == NULL || rsa->internal == NULL || from == NULL) {
52613         WOLFSSL_MSG("Bad function arguments");
52614         return WOLFSSL_FAILURE;
52615     }
52616 
52617 #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
52618     (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2))
52619     switch (padding) {
52620     case RSA_PKCS1_PADDING:
52621         pad_type = WC_RSA_PKCSV15_PAD;
52622         break;
52623     case RSA_PKCS1_OAEP_PADDING:
52624         pad_type = WC_RSA_OAEP_PAD;
52625         break;
52626     case RSA_PKCS1_PSS_PADDING:
52627         pad_type = WC_RSA_PSS_PAD;
52628         break;
52629     case RSA_NO_PADDING:
52630         pad_type = WC_RSA_NO_PAD;
52631         break;
52632     default:
52633         WOLFSSL_MSG("RSA_public_decrypt unsupported padding");
52634         return WOLFSSL_FAILURE;
52635     }
52636 #endif
52637 
52638     if (rsa->inSet == 0) {
52639         WOLFSSL_MSG("No RSA internal set, do it");
52640 
52641         if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
52642             WOLFSSL_MSG("SetRsaInternal failed");
52643             return WOLFSSL_FAILURE;
52644         }
52645     }
52646 
52647 #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
52648     (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2))
52649     /* size of 'to' buffer must be size of RSA key */
52650     ret = wc_RsaSSL_Verify_ex(from, flen, to, wolfSSL_RSA_size(rsa),
52651                                (RsaKey*)rsa->internal, pad_type);
52652 #else
52653     /* For FIPS v1/v2 only PKCSV15 padding is supported */
52654     if (padding == RSA_PKCS1_PADDING) {
52655         ret = wc_RsaSSL_Verify(from, flen, to, wolfSSL_RSA_size(rsa),
52656             (RsaKey*)rsa->internal);
52657     }
52658     else {
52659         WOLFSSL_MSG("RSA_public_decrypt pad type not supported in FIPS");
52660         ret = WOLFSSL_FAILURE;
52661     }
52662 #endif
52663 
52664     WOLFSSL_LEAVE("RSA_public_decrypt", ret);
52665 
52666     if (ret <= 0) {
52667         ret = WOLFSSL_FAILURE;
52668     }
52669     return ret;
52670 }
52671 
52672 /* RSA private encrypt calls wc_RsaSSL_Sign. Similar function set up as RSA
52673  * public decrypt.
52674  *
52675  * len  Length of input buffer
52676  * in   Input buffer to sign
52677  * out  Output buffer (expected to be greater than or equal to RSA key size)
52678  * rsa     Key to use for encryption
52679  * padding Type of RSA padding to use.
52680  */
52681 int wolfSSL_RSA_private_encrypt(int len, const unsigned char* in,
52682                             unsigned char* out, WOLFSSL_RSA* rsa, int padding)
52683 {
52684     int sz = 0;
52685     WC_RNG* rng = NULL;
52686 #if !defined(WC_RSA_BLINDING) || defined(HAVE_USER_RSA)
52687     WC_RNG rng_lcl;
52688 #endif
52689     RsaKey* key;
52690 
52691     WOLFSSL_MSG("wolfSSL_RSA_private_encrypt");
52692 
52693     if (len < 0 || rsa == NULL || rsa->internal == NULL || in == NULL) {
52694         WOLFSSL_MSG("Bad function arguments");
52695         return 0;
52696     }
52697 
52698     if (
52699     #ifdef WC_RSA_PSS
52700         padding != RSA_PKCS1_PSS_PADDING &&
52701     #endif
52702     #ifdef WC_RSA_NO_PADDING
52703         padding != RSA_NO_PADDING &&
52704     #endif
52705         padding != RSA_PKCS1_PADDING) {
52706         WOLFSSL_MSG("wolfSSL_RSA_private_encrypt unsupported padding");
52707         return 0;
52708     }
52709 
52710     if (rsa->inSet == 0)
52711     {
52712         WOLFSSL_MSG("Setting internal RSA structure");
52713 
52714         if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
52715             WOLFSSL_MSG("SetRsaInternal failed");
52716             return 0;
52717         }
52718     }
52719 
52720     key = (RsaKey*)rsa->internal;
52721 #if defined(WC_RSA_BLINDING) && !defined(HAVE_USER_RSA)
52722     rng = key->rng;
52723 #else
52724     rng = &rng_lcl;
52725     #ifndef HAVE_FIPS
52726     if (wc_InitRng_ex(rng, key->heap, INVALID_DEVID) != 0)
52727     #else
52728     if (wc_InitRng(rng) != 0)
52729     #endif
52730     {
52731         WOLFSSL_MSG("Error with random number");
52732         return SSL_FATAL_ERROR;
52733     }
52734 #endif
52735 
52736     /* size of output buffer must be size of RSA key */
52737     switch (padding) {
52738         case RSA_PKCS1_PADDING:
52739             sz = wc_RsaSSL_Sign(in, (word32)len, out, wolfSSL_RSA_size(rsa),
52740                     key, rng);
52741             break;
52742     #ifdef WC_RSA_PSS
52743         case RSA_PKCS1_PSS_PADDING:
52744             sz = wc_RsaPSS_Sign(in, (word32)len, out, wolfSSL_RSA_size(rsa),
52745                     WC_HASH_TYPE_NONE, WC_MGF1NONE, key, rng);
52746             break;
52747     #endif
52748     #ifdef WC_RSA_NO_PADDING
52749         case RSA_NO_PADDING:
52750         {
52751             word32 outLen = (word32)len;
52752             sz = wc_RsaFunction(in, (word32)len, out, &outLen,
52753                     RSA_PRIVATE_ENCRYPT, key, rng);
52754             if (sz == 0)
52755                 sz = (int)outLen;
52756             break;
52757         }
52758     #endif
52759         default:
52760             sz = BAD_FUNC_ARG;
52761             break;
52762     }
52763 
52764     #if !defined(WC_RSA_BLINDING) || defined(HAVE_USER_RSA)
52765     if (wc_FreeRng(rng) != 0) {
52766         WOLFSSL_MSG("Error freeing random number generator");
52767         return SSL_FATAL_ERROR;
52768     }
52769     #endif
52770     if (sz <= 0) {
52771         WOLFSSL_LEAVE("wolfSSL_RSA_private_encrypt", sz);
52772         return 0;
52773     }
52774 
52775     return sz;
52776 }
52777 #endif /* HAVE_USER_RSA */
52778 #endif
52779 
52780 
52781 /* frees all nodes in the current threads error queue
52782  *
52783  * id  thread id. ERR_remove_state is depreciated and id is ignored. The
52784  *     current threads queue will be free'd.
52785  */
52786 void wolfSSL_ERR_remove_state(unsigned long id)
52787 {
52788     WOLFSSL_ENTER("wolfSSL_ERR_remove_state");
52789     (void)id;
52790     if (wc_ERR_remove_state() != 0) {
52791         WOLFSSL_MSG("Error with removing the state");
52792     }
52793 }
52794 
52795 
52796 WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
52797 {
52798     static int ctx;  /* wolfcrypt doesn't now need ctx */
52799 
52800     WOLFSSL_MSG("wolfSSL_BN_CTX_new");
52801     return (WOLFSSL_BN_CTX*)&ctx;
52802 
52803 }
52804 
52805 void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
52806 {
52807     (void)ctx;
52808     WOLFSSL_MSG("wolfSSL_BN_CTX_init");
52809 }
52810 
52811 
52812 void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
52813 {
52814     (void)ctx;
52815     WOLFSSL_MSG("wolfSSL_BN_CTX_free");
52816     /* do free since static ctx that does nothing */
52817 }
52818 
52819 /* WOLFSSL_SUCCESS on ok */
52820 int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
52821                   const WOLFSSL_BIGNUM* b)
52822 {
52823     WOLFSSL_MSG("wolfSSL_BN_sub");
52824 
52825     if (r == NULL || a == NULL || b == NULL)
52826         return 0;
52827 
52828     if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
52829                (mp_int*)r->internal) == MP_OKAY)
52830         return WOLFSSL_SUCCESS;
52831 
52832     WOLFSSL_MSG("wolfSSL_BN_sub mp_sub failed");
52833     return 0;
52834 }
52835 
52836 WOLFSSL_API int wolfSSL_BN_mul(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b,
52837     WOLFSSL_BN_CTX *ctx)
52838 {
52839     int ret = WOLFSSL_SUCCESS;
52840 
52841     (void)ctx;
52842 
52843     WOLFSSL_ENTER("wolfSSL_BN_mul");
52844 
52845     if (r == NULL || a == NULL || b == NULL || r->internal == NULL ||
52846         a->internal == NULL || b->internal == NULL) {
52847         ret = WOLFSSL_FAILURE;
52848     }
52849 
52850     if (ret == WOLFSSL_SUCCESS) {
52851         ret = mp_mul((mp_int*)a->internal, (mp_int*)b->internal,
52852                      (mp_int*)r->internal);
52853         if (ret == MP_OKAY) {
52854             ret = WOLFSSL_SUCCESS;
52855         }
52856         else {
52857             ret = WOLFSSL_FAILURE;
52858         }
52859     }
52860 
52861     WOLFSSL_LEAVE("wolfSSL_BN_mul", ret);
52862 
52863     return ret;
52864 }
52865 
52866 int wolfSSL_BN_div(WOLFSSL_BIGNUM* dv, WOLFSSL_BIGNUM* rem,
52867                    const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* d,
52868                    WOLFSSL_BN_CTX* ctx)
52869 {
52870     int ret = WOLFSSL_SUCCESS;
52871 
52872     (void)ctx;
52873 
52874     WOLFSSL_ENTER("wolfSSL_BN_div");
52875 
52876     if (dv == NULL || rem == NULL || a == NULL || d == NULL ||
52877         dv->internal == NULL || rem->internal == NULL || a->internal == NULL ||
52878         d->internal == NULL) {
52879         ret = WOLFSSL_FAILURE;
52880     }
52881 
52882     if (ret == WOLFSSL_SUCCESS) {
52883         ret = mp_div((mp_int*)a->internal, (mp_int*)d->internal,
52884                      (mp_int*)dv->internal, (mp_int*)rem->internal);
52885         if (ret == MP_OKAY) {
52886             ret = WOLFSSL_SUCCESS;
52887         }
52888         else {
52889             ret = WOLFSSL_FAILURE;
52890         }
52891     }
52892 
52893     WOLFSSL_LEAVE("wolfSSL_BN_div", ret);
52894 
52895     return ret;
52896 }
52897 
52898 #if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) /* Needed to get mp_gcd. */
52899 int wolfSSL_BN_gcd(WOLFSSL_BIGNUM* r, WOLFSSL_BIGNUM* a, WOLFSSL_BIGNUM* b,
52900                    WOLFSSL_BN_CTX* ctx)
52901 {
52902     int ret = WOLFSSL_SUCCESS;
52903 
52904     (void)ctx;
52905 
52906     WOLFSSL_ENTER("wolfSSL_BN_gcd");
52907 
52908     if (r == NULL || a == NULL || b == NULL || r->internal == NULL ||
52909         a->internal == NULL || b->internal == NULL) {
52910         ret = WOLFSSL_FAILURE;
52911     }
52912 
52913     if (ret == WOLFSSL_SUCCESS) {
52914         ret = mp_gcd((mp_int*)a->internal, (mp_int*)b->internal,
52915                      (mp_int*)r->internal);
52916         if (ret == MP_OKAY) {
52917             ret = WOLFSSL_SUCCESS;
52918         }
52919         else {
52920             ret = WOLFSSL_FAILURE;
52921         }
52922     }
52923 
52924     WOLFSSL_LEAVE("wolfSSL_BN_gcd", ret);
52925 
52926     return ret;
52927 }
52928 #endif /* !NO_RSA && WOLFSSL_KEY_GEN */
52929 
52930 /* WOLFSSL_SUCCESS on ok */
52931 int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
52932                   const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
52933 {
52934     (void)c;
52935     WOLFSSL_MSG("wolfSSL_BN_mod");
52936 
52937     if (r == NULL || a == NULL || b == NULL)
52938         return 0;
52939 
52940     if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
52941                (mp_int*)r->internal) == MP_OKAY)
52942         return WOLFSSL_SUCCESS;
52943 
52944     WOLFSSL_MSG("wolfSSL_BN_mod mp_mod failed");
52945     return 0;
52946 }
52947 
52948 
52949 /* r = (a^p) % m */
52950 int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
52951       const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
52952 {
52953     int ret;
52954 
52955     WOLFSSL_ENTER("wolfSSL_BN_mod_exp");
52956 
52957     (void) ctx;
52958     if (r == NULL || a == NULL || p == NULL || m == NULL) {
52959         WOLFSSL_MSG("Bad Argument");
52960         return WOLFSSL_FAILURE;
52961     }
52962 
52963     if ((ret = mp_exptmod((mp_int*)a->internal,(mp_int*)p->internal,
52964                (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
52965         return WOLFSSL_SUCCESS;
52966     }
52967 
52968     WOLFSSL_LEAVE("wolfSSL_BN_mod_exp", ret);
52969     (void)ret;
52970 
52971     return WOLFSSL_FAILURE;
52972 }
52973 
52974 /* r = (a * p) % m */
52975 int wolfSSL_BN_mod_mul(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
52976         const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
52977 {
52978     int ret;
52979 
52980     WOLFSSL_ENTER("wolfSSL_BN_mod_mul");
52981 
52982     (void) ctx;
52983     if (r == NULL || a == NULL || p == NULL || m == NULL) {
52984         WOLFSSL_MSG("Bad Argument");
52985         return SSL_FAILURE;
52986     }
52987 
52988     if ((ret = mp_mulmod((mp_int*)a->internal,(mp_int*)p->internal,
52989                (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
52990         return WOLFSSL_SUCCESS;
52991     }
52992 
52993     WOLFSSL_LEAVE("wolfSSL_BN_mod_mul", ret);
52994     (void)ret;
52995 
52996     return SSL_FAILURE;
52997 }
52998 
52999 const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
53000 {
53001     WOLFSSL_MSG("wolfSSL_BN_value_one");
53002 
53003     if (bn_one == NULL) {
53004         bn_one = wolfSSL_BN_new();
53005         if (bn_one) {
53006             if (mp_set_int((mp_int*)bn_one->internal, 1) != MP_OKAY) {
53007                 /* handle error by freeing BN and returning NULL */
53008                 wolfSSL_BN_free(bn_one);
53009                 bn_one = NULL;
53010             }
53011         }
53012     }
53013 
53014     return bn_one;
53015 }
53016 
53017 /* return compliant with OpenSSL
53018  *   size of BIGNUM in bytes, 0 if error */
53019 int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
53020 {
53021     WOLFSSL_ENTER("wolfSSL_BN_num_bytes");
53022 
53023     if (bn == NULL || bn->internal == NULL)
53024         return WOLFSSL_FAILURE;
53025 
53026     return mp_unsigned_bin_size((mp_int*)bn->internal);
53027 }
53028 
53029 /* return compliant with OpenSSL
53030  *   size of BIGNUM in bits, 0 if error */
53031 int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
53032 {
53033     WOLFSSL_ENTER("wolfSSL_BN_num_bits");
53034 
53035     if (bn == NULL || bn->internal == NULL)
53036         return WOLFSSL_FAILURE;
53037 
53038     return mp_count_bits((mp_int*)bn->internal);
53039 }
53040 
53041 int wolfSSL_BN_is_negative(const WOLFSSL_BIGNUM* bn)
53042 {
53043     if (bn == NULL)
53044         return WOLFSSL_FAILURE;
53045 
53046     return mp_isneg((mp_int*)bn->internal);
53047 }
53048 
53049 WOLFSSL_API void wolfSSL_BN_zero(WOLFSSL_BIGNUM* bn)
53050 {
53051     if (bn == NULL || bn->internal == NULL) {
53052         return;
53053     }
53054 
53055     mp_zero((mp_int*)bn->internal);
53056 }
53057 
53058 WOLFSSL_API int wolfSSL_BN_one(WOLFSSL_BIGNUM* bn)
53059 {
53060     int ret = WOLFSSL_SUCCESS;
53061 
53062     if (bn == NULL || bn->internal == NULL) {
53063         return WOLFSSL_FAILURE;
53064     }
53065 
53066     if (ret == WOLFSSL_SUCCESS) {
53067         ret = wolfSSL_BN_set_word(bn, 1);
53068     }
53069 
53070     return ret;
53071 }
53072 
53073 /* return compliant with OpenSSL
53074  *   1 if BIGNUM is zero, 0 else */
53075 int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
53076 {
53077     WOLFSSL_MSG("wolfSSL_BN_is_zero");
53078 
53079     if (bn == NULL || bn->internal == NULL)
53080         return WOLFSSL_FAILURE;
53081 
53082     if (mp_iszero((mp_int*)bn->internal) == MP_YES)
53083         return WOLFSSL_SUCCESS;
53084 
53085     return WOLFSSL_FAILURE;
53086 }
53087 
53088 /* return compliant with OpenSSL
53089  *   1 if BIGNUM is one, 0 else */
53090 int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
53091 {
53092     WOLFSSL_MSG("wolfSSL_BN_is_one");
53093 
53094     if (bn == NULL || bn->internal == NULL)
53095         return WOLFSSL_FAILURE;
53096 
53097     if (mp_cmp_d((mp_int*)bn->internal, 1) == MP_EQ)
53098         return WOLFSSL_SUCCESS;
53099 
53100     return WOLFSSL_FAILURE;
53101 }
53102 
53103 /* return compliant with OpenSSL
53104  *   1 if BIGNUM is odd, 0 else */
53105 int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
53106 {
53107     WOLFSSL_MSG("wolfSSL_BN_is_odd");
53108 
53109     if (bn == NULL || bn->internal == NULL)
53110         return WOLFSSL_FAILURE;
53111 
53112     if (mp_isodd((mp_int*)bn->internal) == MP_YES)
53113         return WOLFSSL_SUCCESS;
53114 
53115     return WOLFSSL_FAILURE;
53116 }
53117 
53118 /* return compliant with OpenSSL
53119  *   1 if BIGNUM is word, 0 else */
53120 int wolfSSL_BN_is_word(const WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
53121 {
53122     WOLFSSL_MSG("wolfSSL_BN_is_word");
53123 
53124     if (bn == NULL || bn->internal == NULL) {
53125         WOLFSSL_MSG("bn NULL error");
53126         return WOLFSSL_FAILURE;
53127     }
53128 
53129     if (w <= MP_MASK) {
53130         if (mp_isword((mp_int*)bn->internal, (mp_digit)w) == MP_YES) {
53131             return WOLFSSL_SUCCESS;
53132         }
53133     } else {
53134         int ret;
53135         mp_int w_mp;
53136         if (mp_init(&w_mp) != MP_OKAY)
53137             return WOLFSSL_FAILURE;
53138         if (mp_set_int(&w_mp, w) != MP_OKAY)
53139             return WOLFSSL_FAILURE;
53140         ret = mp_cmp((mp_int *)bn->internal, &w_mp);
53141         mp_free(&w_mp);
53142         if (ret == MP_EQ)
53143             return WOLFSSL_SUCCESS;
53144     }
53145 
53146     return WOLFSSL_FAILURE;
53147 }
53148 
53149 /* return compliant with OpenSSL
53150  *   -1 if a < b, 0 if a == b and 1 if a > b
53151  */
53152 int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
53153 {
53154     int ret;
53155 
53156     WOLFSSL_MSG("wolfSSL_BN_cmp");
53157 
53158     if (a == NULL || a->internal == NULL || b == NULL || b->internal == NULL)
53159         return WOLFSSL_FATAL_ERROR;
53160 
53161     ret = mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
53162 
53163     return (ret == MP_EQ ? 0 : (ret == MP_GT ? 1 : -1));
53164 }
53165 
53166 /* return compliant with OpenSSL
53167  *   length of BIGNUM in bytes, -1 if error */
53168 int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
53169 {
53170     WOLFSSL_MSG("wolfSSL_BN_bn2bin");
53171 
53172     if (bn == NULL || bn->internal == NULL) {
53173         WOLFSSL_MSG("NULL bn error");
53174         return WOLFSSL_FATAL_ERROR;
53175     }
53176 
53177     if (r == NULL)
53178         return mp_unsigned_bin_size((mp_int*)bn->internal);
53179 
53180     if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
53181         WOLFSSL_MSG("mp_to_unsigned_bin error");
53182         return WOLFSSL_FATAL_ERROR;
53183     }
53184 
53185     return mp_unsigned_bin_size((mp_int*)bn->internal);
53186 }
53187 
53188 
53189 WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
53190                             WOLFSSL_BIGNUM* ret)
53191 {
53192     int weOwn = 0;
53193 
53194     WOLFSSL_MSG("wolfSSL_BN_bin2bn");
53195 
53196     /* if ret is null create a BN */
53197     if (ret == NULL) {
53198         ret = wolfSSL_BN_new();
53199         weOwn = 1;
53200         if (ret == NULL)
53201             return NULL;
53202     }
53203 
53204     /* check ret and ret->internal then read in value */
53205     if (ret && ret->internal) {
53206         if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
53207             WOLFSSL_MSG("mp_read_unsigned_bin failure");
53208             if (weOwn)
53209                 wolfSSL_BN_free(ret);
53210             return NULL;
53211         }
53212     } else {
53213         /* This may be overly defensive */
53214         if (weOwn)
53215             wolfSSL_BN_free(ret);
53216         return NULL;
53217     }
53218 
53219     return ret;
53220 }
53221 
53222 /* return compliant with OpenSSL
53223  *   1 if success, 0 if error */
53224 #ifndef NO_WOLFSSL_STUB
53225 int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
53226 {
53227     (void)bn;
53228     (void)n;
53229     WOLFSSL_ENTER("wolfSSL_BN_mask_bits");
53230     WOLFSSL_STUB("BN_mask_bits");
53231     return SSL_FAILURE;
53232 }
53233 #endif
53234 
53235 /* WOLFSSL_SUCCESS on ok */
53236 int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
53237 {
53238     int           ret    = WOLFSSL_FAILURE;
53239     int           len;
53240     int           initTmpRng = 0;
53241     WC_RNG*       rng    = NULL;
53242 #ifdef WOLFSSL_SMALL_STACK
53243     WC_RNG*       tmpRNG = NULL;
53244     byte*         buff   = NULL;
53245 #else
53246     WC_RNG        tmpRNG[1];
53247     byte          buff[1024];
53248 #endif
53249 
53250     (void)top;
53251     (void)bottom;
53252     WOLFSSL_MSG("wolfSSL_BN_rand");
53253 
53254     if (bits <= 0) {
53255         return WOLFSSL_FAILURE;
53256     }
53257 
53258     len = bits / 8;
53259     if (bits % 8)
53260         len++;
53261 
53262     /* has to be a length of at least 1 since we set buf[0] and buf[len-1] */
53263     if (len < 1) {
53264         return WOLFSSL_FAILURE;
53265     }
53266 
53267 #ifdef WOLFSSL_SMALL_STACK
53268     buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
53269     tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
53270     if (buff == NULL || tmpRNG == NULL) {
53271         XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
53272         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
53273         return ret;
53274     }
53275 #endif
53276 
53277     if (bn == NULL || bn->internal == NULL)
53278         WOLFSSL_MSG("Bad function arguments");
53279     else if (wc_InitRng(tmpRNG) == 0) {
53280         rng = tmpRNG;
53281         initTmpRng = 1;
53282     }
53283     else if (initGlobalRNG)
53284         rng = &globalRNG;
53285 
53286     if (rng) {
53287         if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
53288             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
53289         else {
53290             buff[0]     |= 0x80 | 0x40;
53291             buff[len-1] |= 0x01;
53292 
53293             if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
53294                 WOLFSSL_MSG("mp read bin failed");
53295             else
53296                 ret = WOLFSSL_SUCCESS;
53297         }
53298     }
53299 
53300     if (initTmpRng)
53301         wc_FreeRng(tmpRNG);
53302 
53303 #ifdef WOLFSSL_SMALL_STACK
53304     XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
53305     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
53306 #endif
53307 
53308     return ret;
53309 }
53310 
53311 /**
53312  * N = length of range input var
53313  * Generate N-bit length numbers until generated number is less than range
53314  * @param r     Output number
53315  * @param range The upper limit of generated output
53316  * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
53317  */
53318 int wolfSSL_BN_rand_range(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *range)
53319 {
53320     int n;
53321     int iter = 0;
53322     WOLFSSL_MSG("wolfSSL_BN_rand_range");
53323 
53324     if (r == NULL || range == NULL) {
53325         WOLFSSL_MSG("Bad parameter");
53326         return WOLFSSL_FAILURE;
53327     }
53328 
53329     n = wolfSSL_BN_num_bits(range);
53330 
53331     if (n <= 1) {
53332         wolfSSL_BN_zero(r);
53333     }
53334     else {
53335         do {
53336             if (iter >= 100) {
53337                 WOLFSSL_MSG("wolfSSL_BN_rand_range too many iterations");
53338                 return WOLFSSL_FAILURE;
53339             }
53340             iter++;
53341             if (wolfSSL_BN_pseudo_rand(r, n, -1, 0) == WOLFSSL_FAILURE) {
53342                 WOLFSSL_MSG("wolfSSL_BN_rand error");
53343                 return WOLFSSL_FAILURE;
53344             }
53345         } while(wolfSSL_BN_cmp(r, range) >= 0);
53346     }
53347     return WOLFSSL_SUCCESS;
53348 }
53349 
53350 /* WOLFSSL_SUCCESS on ok
53351  * code is same as wolfSSL_BN_rand except for how top and bottom is handled.
53352  * top -1 then leave most sig bit alone
53353  * top 0 then most sig is set to 1
53354  * top is 1 then first two most sig bits are 1
53355  *
53356  * bottom is hot then odd number */
53357 int wolfSSL_BN_pseudo_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
53358 {
53359     int           ret    = 0;
53360     int           len;
53361     int           initTmpRng = 0;
53362     WC_RNG*       rng    = NULL;
53363 #ifdef WOLFSSL_SMALL_STACK
53364     WC_RNG*       tmpRNG = NULL;
53365     byte*         buff   = NULL;
53366 #else
53367     WC_RNG        tmpRNG[1];
53368     byte          buff[1024];
53369 #endif
53370 
53371     WOLFSSL_ENTER("wolfSSL_BN_pseudo_rand");
53372 
53373     if (bits <= 0) {
53374         return WOLFSSL_FAILURE;
53375     }
53376 
53377     len = bits / 8;
53378     if (bits % 8)
53379         len++;
53380 
53381     /* has to be a length of at least 1 since we set buf[0] and buf[len-1] */
53382     if (top == 1 || top == 0 || bottom == 1) {
53383         if (len < 1) {
53384             return WOLFSSL_FAILURE;
53385         }
53386     }
53387 
53388 #ifdef WOLFSSL_SMALL_STACK
53389     buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
53390     tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
53391     if (buff == NULL || tmpRNG == NULL) {
53392         XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
53393         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
53394         return ret;
53395     }
53396 #endif
53397 
53398     if (bn == NULL || bn->internal == NULL)
53399         WOLFSSL_MSG("Bad function arguments");
53400     else if (wc_InitRng(tmpRNG) == 0) {
53401         rng = tmpRNG;
53402         initTmpRng = 1;
53403     }
53404     else if (initGlobalRNG)
53405         rng = &globalRNG;
53406 
53407     if (rng) {
53408         if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
53409             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
53410         else {
53411             switch (top) {
53412                 case -1:
53413                     break;
53414 
53415                 case 0:
53416                     buff[0] |= 0x80;
53417                     break;
53418 
53419                 case 1:
53420                     buff[0] |= 0x80 | 0x40;
53421                     break;
53422             }
53423 
53424             if (bottom == 1) {
53425                 buff[len-1] |= 0x01;
53426             }
53427 
53428             if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
53429                 WOLFSSL_MSG("mp read bin failed");
53430             else
53431                 ret = WOLFSSL_SUCCESS;
53432         }
53433     }
53434 
53435     if (initTmpRng)
53436         wc_FreeRng(tmpRNG);
53437 
53438 #ifdef WOLFSSL_SMALL_STACK
53439     XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
53440     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
53441 #endif
53442 
53443     return ret;
53444 }
53445 
53446 /* return code compliant with OpenSSL :
53447  *   1 if bit set, 0 else
53448  */
53449 int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
53450 {
53451     if (bn == NULL || bn->internal == NULL) {
53452         WOLFSSL_MSG("bn NULL error");
53453         return WOLFSSL_FAILURE;
53454     }
53455 
53456     return mp_is_bit_set((mp_int*)bn->internal, (mp_digit)n);
53457 }
53458 
53459 /* return code compliant with OpenSSL :
53460  *   1 if success, 0 else
53461  */
53462 int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n)
53463 {
53464     if (bn == NULL || bn->internal == NULL) {
53465         WOLFSSL_MSG("bn NULL error");
53466         return WOLFSSL_FAILURE;
53467     }
53468 
53469     if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) {
53470         WOLFSSL_MSG("mp_set_bit error");
53471         return WOLFSSL_FAILURE;
53472     }
53473 
53474     return WOLFSSL_SUCCESS;
53475 }
53476 
53477 
53478 int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n)
53479 {
53480     int ret = WOLFSSL_FAILURE;
53481 #ifndef WOLFSSL_SMALL_STACK
53482     mp_int tmp[1];
53483 #else
53484     mp_int* tmp = NULL;
53485 #endif
53486 
53487     if (bn == NULL || bn->internal == NULL) {
53488         WOLFSSL_MSG("bn NULL error");
53489         goto end;
53490     }
53491     if (mp_is_bit_set((mp_int*)bn->internal, n)) {
53492 #ifdef WOLFSSL_SMALL_STACK
53493        tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
53494        if (tmp == NULL) {
53495            goto end;
53496        }
53497 #endif
53498         if (mp_init(tmp) != MP_OKAY) {
53499             goto end;
53500         }
53501         if (mp_set_bit(tmp, n) != MP_OKAY) {
53502             goto cleanup;
53503         }
53504         if (mp_sub((mp_int*)bn->internal, tmp, (mp_int*)bn->internal) != MP_OKAY) {
53505             goto cleanup;
53506         }
53507     } else {
53508         goto end;
53509     }
53510 
53511     ret = WOLFSSL_SUCCESS;
53512 cleanup:
53513     mp_clear(tmp);
53514 
53515 end:
53516 #ifdef WOLFSSL_SMALL_STACK
53517     if (tmp)
53518         XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
53519 #endif
53520     return ret;
53521 }
53522 
53523 
53524 /* WOLFSSL_SUCCESS on ok */
53525 /* Note on use: this function expects str to be an even length. It is
53526  * converting pairs of bytes into 8-bit values. As an example, the RSA
53527  * public exponent is commonly 0x010001. To get it to convert, you need
53528  * to pass in the string "010001", it will fail if you use "10001". This
53529  * is an affect of how Base16_Decode() works.
53530  */
53531 int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
53532 {
53533     int     ret     = 0;
53534     word32  decSz   = 1024;
53535 #ifdef WOLFSSL_SMALL_STACK
53536     byte*   decoded;
53537 #else
53538     byte    decoded[1024];
53539 #endif
53540     int     weOwn = 0;
53541     int     strLen;
53542 
53543     WOLFSSL_MSG("wolfSSL_BN_hex2bn");
53544 
53545 #ifdef WOLFSSL_SMALL_STACK
53546     decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_DER);
53547     if (decoded == NULL)
53548         return ret;
53549 #endif
53550 
53551     if (str == NULL || str[0] == '\0') {
53552         WOLFSSL_MSG("Bad function argument");
53553         ret = WOLFSSL_FAILURE;
53554     } else {
53555         strLen = (int)XSTRLEN(str);
53556         /* ignore trailing new lines */
53557         while (str[strLen-1] == '\n' && strLen > 0) strLen--;
53558 
53559         if (Base16_Decode((byte*)str, strLen, decoded, &decSz) < 0)
53560             WOLFSSL_MSG("Bad Base16_Decode error");
53561         else if (bn == NULL)
53562             ret = decSz;
53563         else {
53564             if (*bn == NULL) {
53565                 *bn = wolfSSL_BN_new();
53566                 if (*bn != NULL) {
53567                     weOwn = 1;
53568                 }
53569             }
53570 
53571             if (*bn == NULL)
53572                 WOLFSSL_MSG("BN new failed");
53573             else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL) {
53574                 WOLFSSL_MSG("Bad bin2bn error");
53575                 if (weOwn == 1) {
53576                     wolfSSL_BN_free(*bn); /* Free new BN */
53577                 }
53578             }
53579             else
53580                 ret = WOLFSSL_SUCCESS;
53581         }
53582     }
53583 
53584 #ifdef WOLFSSL_SMALL_STACK
53585     XFREE(decoded, NULL, DYNAMIC_TYPE_DER);
53586 #endif
53587 
53588     return ret;
53589 }
53590 
53591 
53592 WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
53593 {
53594     WOLFSSL_BIGNUM* ret;
53595 
53596     WOLFSSL_MSG("wolfSSL_BN_dup");
53597 
53598     if (bn == NULL || bn->internal == NULL) {
53599         WOLFSSL_MSG("bn NULL error");
53600         return NULL;
53601     }
53602 
53603     ret = wolfSSL_BN_new();
53604     if (ret == NULL) {
53605         WOLFSSL_MSG("bn new error");
53606         return NULL;
53607     }
53608 
53609     if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
53610         WOLFSSL_MSG("mp_copy error");
53611         wolfSSL_BN_free(ret);
53612         return NULL;
53613     }
53614 
53615     ret->neg = bn->neg;
53616 
53617     return ret;
53618 }
53619 
53620 
53621 WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
53622 {
53623     WOLFSSL_MSG("wolfSSL_BN_copy");
53624 
53625     if (r == NULL || bn == NULL) {
53626         WOLFSSL_MSG("r or bn NULL error");
53627         return NULL;
53628     }
53629 
53630     if (mp_copy((mp_int*)bn->internal, (mp_int*)r->internal) != MP_OKAY) {
53631         WOLFSSL_MSG("mp_copy error");
53632         return NULL;
53633     }
53634 
53635     r->neg = bn->neg;
53636 
53637     return r;
53638 }
53639 
53640 /* return code compliant with OpenSSL :
53641  *   1 if success, 0 else
53642  */
53643 int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, unsigned long w)
53644 {
53645     WOLFSSL_MSG("wolfSSL_BN_set_word");
53646 
53647     if (bn == NULL) {
53648         WOLFSSL_MSG("bn NULL error");
53649         return WOLFSSL_FAILURE;
53650     }
53651 
53652     if (mp_set_int((mp_int*)bn->internal, w) != MP_OKAY) {
53653         WOLFSSL_MSG("mp_init_set_int error");
53654         return WOLFSSL_FAILURE;
53655     }
53656 
53657     return WOLFSSL_SUCCESS;
53658 }
53659 
53660 static WOLFSSL_BN_ULONG wolfSSL_BN_get_word_1(mp_int *mp) {
53661 #if DIGIT_BIT >= (SIZEOF_LONG * CHAR_BIT)
53662     return (WOLFSSL_BN_ULONG)mp->dp[0];
53663 #else
53664     WOLFSSL_BN_ULONG ret = 0UL;
53665     int digit_i;
53666 
53667     for (digit_i = 0; digit_i < mp->used; ++digit_i)
53668         ret |= ((WOLFSSL_BN_ULONG)mp->dp[digit_i]) << (DIGIT_BIT * digit_i);
53669 
53670     return ret;
53671 #endif
53672 }
53673 
53674 /* Returns the big number as an unsigned long if possible.
53675  *
53676  * bn  big number structure to get value from
53677  *
53678  * Returns value or 0xFFFFFFFFL if bigger than unsigned long.
53679  */
53680 WOLFSSL_BN_ULONG wolfSSL_BN_get_word(const WOLFSSL_BIGNUM* bn)
53681 {
53682     WOLFSSL_MSG("wolfSSL_BN_get_word");
53683 
53684     if (bn == NULL) {
53685         WOLFSSL_MSG("Invalid argument");
53686         return 0;
53687     }
53688 
53689     if (wolfSSL_BN_num_bytes(bn) > (int)sizeof(unsigned long)) {
53690         WOLFSSL_MSG("bignum is larger than unsigned long");
53691         return 0xFFFFFFFFL;
53692     }
53693 
53694     return wolfSSL_BN_get_word_1((mp_int*)bn->internal);
53695 }
53696 
53697 /* return code compliant with OpenSSL :
53698  *   number length in decimal if success, 0 if error
53699  */
53700 #ifndef NO_WOLFSSL_STUB
53701 int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
53702 {
53703     (void)bn;
53704     (void)str;
53705 
53706     WOLFSSL_MSG("wolfSSL_BN_dec2bn");
53707     WOLFSSL_STUB("BN_dec2bn");
53708     return SSL_FAILURE;
53709 }
53710 #endif
53711 
53712 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
53713 char *wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn)
53714 {
53715     int len = 0;
53716     char *buf;
53717 
53718     WOLFSSL_MSG("wolfSSL_BN_bn2dec");
53719 
53720     if (bn == NULL || bn->internal == NULL) {
53721         WOLFSSL_MSG("bn NULL error");
53722         return NULL;
53723     }
53724 
53725     if (mp_radix_size((mp_int*)bn->internal, MP_RADIX_DEC, &len) != MP_OKAY) {
53726         WOLFSSL_MSG("mp_radix_size failure");
53727         return NULL;
53728     }
53729 
53730     buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
53731     if (buf == NULL) {
53732         WOLFSSL_MSG("BN_bn2dec malloc buffer failure");
53733         return NULL;
53734     }
53735 
53736     if (mp_todecimal((mp_int*)bn->internal, buf) != MP_OKAY) {
53737         XFREE(buf, NULL, DYNAMIC_TYPE_ECC);
53738         return NULL;
53739     }
53740 
53741     return buf;
53742 }
53743 #else
53744 char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
53745 {
53746     (void)bn;
53747 
53748     WOLFSSL_MSG("wolfSSL_BN_bn2dec");
53749 
53750     return NULL;
53751 }
53752 #endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
53753 
53754 /* Internal function for adding/subtracting an unsigned long from a
53755  * WOLFSSL_BIGNUM. To add, pass "sub" as 0. To subtract, pass it as 1.
53756  * Returns 1 (WOLFSSL_SUCCESS) on success and 0 (WOLFSSL_FAILURE) on failure.
53757  */
53758 static int wolfSSL_BN_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w,
53759                                    int sub)
53760 {
53761     int ret = WOLFSSL_SUCCESS;
53762     int rc = 0;
53763     mp_int w_mp;
53764 
53765     XMEMSET(&w_mp, 0, sizeof(mp_int));
53766 
53767     if (bn == NULL || bn->internal == NULL) {
53768         WOLFSSL_MSG("bn NULL error");
53769         ret = WOLFSSL_FAILURE;
53770     }
53771 
53772     if (ret == WOLFSSL_SUCCESS) {
53773         if (w <= MP_MASK) {
53774             if (sub == 1) {
53775                 rc = mp_sub_d((mp_int*)bn->internal, (mp_digit)w,
53776                               (mp_int*)bn->internal);
53777             }
53778             else {
53779                 rc = mp_add_d((mp_int*)bn->internal, (mp_digit)w,
53780                               (mp_int*)bn->internal);
53781             }
53782             if (rc != MP_OKAY) {
53783                 WOLFSSL_MSG("mp_add/sub_d error");
53784                 ret = WOLFSSL_FAILURE;
53785             }
53786         }
53787         else {
53788             if (mp_init(&w_mp) != MP_OKAY) {
53789                 ret = WOLFSSL_FAILURE;
53790             }
53791             if (ret == WOLFSSL_SUCCESS) {
53792                 if (mp_set_int(&w_mp, w) != MP_OKAY) {
53793                     ret = WOLFSSL_FAILURE;
53794                 }
53795             }
53796             if (ret == WOLFSSL_SUCCESS) {
53797                 if (sub == 1) {
53798                     rc = mp_sub((mp_int *)bn->internal, &w_mp,
53799                                 (mp_int *)bn->internal);
53800                 }
53801                 else {
53802                     rc = mp_add((mp_int *)bn->internal, &w_mp,
53803                                 (mp_int *)bn->internal);
53804                 }
53805                 if (rc != MP_OKAY) {
53806                     WOLFSSL_MSG("mp_add/sub error");
53807                     ret = WOLFSSL_FAILURE;
53808                 }
53809             }
53810         }
53811     }
53812 
53813     mp_free(&w_mp);
53814 
53815     return ret;
53816 }
53817 
53818 /* return code compliant with OpenSSL :
53819  *   1 if success, 0 else
53820  */
53821 int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
53822 {
53823     int ret;
53824 
53825     WOLFSSL_ENTER("wolfSSL_BN_add_word");
53826 
53827     ret = wolfSSL_BN_add_word_int(bn, w, 0);
53828 
53829     WOLFSSL_LEAVE("wolfSSL_BN_add_word", ret);
53830 
53831     return ret;
53832 }
53833 
53834 /* return code compliant with OpenSSL :
53835  *   1 if success, 0 else
53836  */
53837 WOLFSSL_API int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
53838 {
53839     int ret;
53840 
53841     WOLFSSL_ENTER("wolfSSL_BN_sub_word");
53842 
53843     ret = wolfSSL_BN_add_word_int(bn, w, 1);
53844 
53845     WOLFSSL_LEAVE("wolfSSL_BN_sub_word", ret);
53846 
53847     return ret;
53848 }
53849 
53850 /* return code compliant with OpenSSL :
53851  *   1 if success, 0 else
53852  */
53853 int wolfSSL_BN_lshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
53854 {
53855     WOLFSSL_MSG("wolfSSL_BN_lshift");
53856 
53857     if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
53858         WOLFSSL_MSG("bn NULL error");
53859         return WOLFSSL_FAILURE;
53860     }
53861 
53862     if (mp_mul_2d((mp_int*)bn->internal, n, (mp_int*)r->internal) != MP_OKAY) {
53863         WOLFSSL_MSG("mp_mul_2d error");
53864         return WOLFSSL_FAILURE;
53865     }
53866 
53867     return WOLFSSL_SUCCESS;
53868 }
53869 
53870 /* return code compliant with OpenSSL :
53871  *   1 if success, 0 else
53872  */
53873 int wolfSSL_BN_rshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
53874 {
53875     WOLFSSL_MSG("wolfSSL_BN_rshift");
53876 
53877     if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
53878         WOLFSSL_MSG("bn NULL error");
53879         return WOLFSSL_FAILURE;
53880     }
53881 
53882     if (mp_div_2d((mp_int*)bn->internal, n,
53883                   (mp_int*)r->internal, NULL) != MP_OKAY) {
53884         WOLFSSL_MSG("mp_mul_2d error");
53885         return WOLFSSL_FAILURE;
53886     }
53887 
53888     return WOLFSSL_SUCCESS;
53889 }
53890 
53891 /* return code compliant with OpenSSL :
53892  *   1 if success, 0 else
53893  */
53894 int wolfSSL_BN_add(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b)
53895 {
53896     WOLFSSL_MSG("wolfSSL_BN_add");
53897 
53898     if (r == NULL || r->internal == NULL || a == NULL || a->internal == NULL ||
53899         b == NULL || b->internal == NULL) {
53900         WOLFSSL_MSG("bn NULL error");
53901         return WOLFSSL_FAILURE;
53902     }
53903 
53904     if (mp_add((mp_int*)a->internal, (mp_int*)b->internal,
53905                (mp_int*)r->internal) != MP_OKAY) {
53906         WOLFSSL_MSG("mp_add_d error");
53907         return WOLFSSL_FAILURE;
53908     }
53909 
53910     return WOLFSSL_SUCCESS;
53911 }
53912 
53913 /* r = a + b (mod m) */
53914 int wolfSSL_BN_mod_add(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
53915                        const WOLFSSL_BIGNUM *b, const WOLFSSL_BIGNUM *m,
53916                        WOLFSSL_BN_CTX *ctx)
53917 {
53918     (void)ctx;
53919     WOLFSSL_MSG("wolfSSL_BN_add");
53920 
53921     if (r == NULL || r->internal == NULL ||
53922             a == NULL || a->internal == NULL ||
53923             b == NULL || b->internal == NULL ||
53924             m == NULL || m->internal == NULL) {
53925         WOLFSSL_MSG("bn NULL error");
53926         return WOLFSSL_FAILURE;
53927     }
53928 
53929     if (mp_addmod((mp_int*)a->internal, (mp_int*)b->internal,
53930                   (mp_int*)m->internal, (mp_int*)r->internal) != MP_OKAY) {
53931         WOLFSSL_MSG("mp_add_d error");
53932         return WOLFSSL_FAILURE;
53933     }
53934 
53935     return WOLFSSL_SUCCESS;
53936 }
53937 
53938 #if defined(WOLFSSL_KEY_GEN) && (!defined(NO_RSA) || !defined(NO_DH) || !defined(NO_DSA))
53939 
53940 int wolfSSL_BN_generate_prime_ex(WOLFSSL_BIGNUM* prime, int bits,
53941     int safe, const WOLFSSL_BIGNUM* add, const WOLFSSL_BIGNUM* rem,
53942     WOLFSSL_BN_GENCB* cb)
53943 {
53944     int ret = WOLFSSL_SUCCESS;
53945 #ifdef WOLFSSL_SMALL_STACK
53946     WC_RNG* rng = NULL;
53947 #else
53948     WC_RNG rng[1];
53949 #endif
53950 
53951     (void)cb;
53952 
53953     WOLFSSL_ENTER("wolfSSL_BN_generate_prime_ex");
53954 
53955     if (safe == 1 || add != NULL || rem != NULL) {
53956         /* These parameters aren't supported, yet. */
53957         ret = WOLFSSL_FAILURE;
53958     }
53959 
53960     if (prime == NULL || prime->internal == NULL) {
53961         ret = WOLFSSL_FAILURE;
53962     }
53963 
53964 #ifdef WOLFSSL_SMALL_STACK
53965     if (ret == WOLFSSL_SUCCESS) {
53966         rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
53967         if (rng == NULL) {
53968             ret = WOLFSSL_FAILURE;
53969         }
53970     }
53971 #endif
53972     if (ret == WOLFSSL_SUCCESS) {
53973         XMEMSET(rng, 0, sizeof(WC_RNG));
53974         if (wc_InitRng(rng) != 0) {
53975             ret = WOLFSSL_FAILURE;
53976         }
53977     }
53978 
53979     if (ret == WOLFSSL_SUCCESS) {
53980         if (mp_rand_prime((mp_int*)prime->internal, (bits + 7) / 8, rng, NULL)
53981                 != MP_OKAY) {
53982             ret = WOLFSSL_FAILURE;
53983         }
53984     }
53985 
53986     wc_FreeRng(rng);
53987 #ifdef WOLFSSL_SMALL_STACK
53988     if (rng != NULL)
53989         XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
53990 #endif
53991 
53992     WOLFSSL_LEAVE("wolfSSL_BN_generate_prime_ex", ret);
53993 
53994     return ret;
53995 }
53996 
53997 /* return code compliant with OpenSSL :
53998  *   1 if prime, 0 if not, -1 if error
53999  */
54000 int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int nbchecks,
54001                            WOLFSSL_BN_CTX *ctx, WOLFSSL_BN_GENCB *cb)
54002 {
54003     WC_RNG*        rng    = NULL;
54004 #ifdef WOLFSSL_SMALL_STACK
54005     WC_RNG*        tmpRNG = NULL;
54006 #else
54007     WC_RNG         tmpRNG[1];
54008 #endif
54009     int            initTmpRng = 0;
54010     int            res = MP_NO;
54011 
54012     (void)ctx;
54013     (void)cb;
54014 
54015     WOLFSSL_MSG("wolfSSL_BN_is_prime_ex");
54016 
54017     if (bn == NULL || bn->internal == NULL) {
54018         WOLFSSL_MSG("bn NULL error");
54019         return WOLFSSL_FATAL_ERROR;
54020     }
54021 
54022 #ifdef WOLFSSL_SMALL_STACK
54023     tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
54024     if (tmpRNG == NULL)
54025         return WOLFSSL_FAILURE;
54026 #endif
54027     if (wc_InitRng(tmpRNG) == 0) {
54028         rng = tmpRNG;
54029         initTmpRng = 1;
54030     }
54031     else {
54032         WOLFSSL_MSG("Bad RNG Init, trying global");
54033         if (initGlobalRNG == 0) {
54034             WOLFSSL_MSG("Global RNG no Init");
54035         }
54036         else
54037             rng = &globalRNG;
54038     }
54039 
54040     if (rng) {
54041         if (mp_prime_is_prime_ex((mp_int*)bn->internal,
54042                                  nbchecks, &res, rng) != MP_OKAY) {
54043             WOLFSSL_MSG("mp_prime_is_prime_ex error");
54044             res = MP_NO;
54045         }
54046     }
54047 
54048     if (initTmpRng)
54049         wc_FreeRng(tmpRNG);
54050 #ifdef WOLFSSL_SMALL_STACK
54051     XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
54052 #endif
54053 
54054     if (res != MP_YES) {
54055         WOLFSSL_MSG("mp_prime_is_prime_ex not prime");
54056         return WOLFSSL_FAILURE;
54057     }
54058 
54059     return WOLFSSL_SUCCESS;
54060 }
54061 
54062 /* return code compliant with OpenSSL :
54063  *   (bn mod w) if success, -1 if error
54064  */
54065 WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn,
54066                                      WOLFSSL_BN_ULONG w)
54067 {
54068     WOLFSSL_BN_ULONG ret = 0;
54069 
54070     WOLFSSL_MSG("wolfSSL_BN_mod_word");
54071 
54072     if (bn == NULL || bn->internal == NULL) {
54073         WOLFSSL_MSG("bn NULL error");
54074         return (WOLFSSL_BN_ULONG)WOLFSSL_FATAL_ERROR;
54075     }
54076 
54077     if (w <= MP_MASK) {
54078         mp_digit bn_ret;
54079         if (mp_mod_d((mp_int*)bn->internal, (mp_digit)w, &bn_ret) != MP_OKAY) {
54080             WOLFSSL_MSG("mp_add_d error");
54081             return (WOLFSSL_BN_ULONG)WOLFSSL_FATAL_ERROR;
54082         }
54083         ret = (WOLFSSL_BN_ULONG)bn_ret;
54084     } else {
54085         int mp_ret;
54086         mp_int w_mp, r_mp;
54087         if (mp_init(&w_mp) != MP_OKAY)
54088             return (unsigned long)WOLFSSL_FAILURE;
54089         if (mp_init(&r_mp) != MP_OKAY)
54090             return (unsigned long)WOLFSSL_FAILURE;
54091         if (mp_set_int(&w_mp, w) != MP_OKAY)
54092             return (unsigned long)WOLFSSL_FAILURE;
54093         mp_ret = mp_mod((mp_int *)bn->internal, &w_mp, &r_mp);
54094         ret = wolfSSL_BN_get_word_1(&r_mp);
54095         mp_free(&r_mp);
54096         mp_free(&w_mp);
54097         if (mp_ret != MP_OKAY) {
54098             WOLFSSL_MSG("mp_mod error");
54099             return (WOLFSSL_BN_ULONG)WOLFSSL_FAILURE;
54100         }
54101     }
54102 
54103     return ret;
54104 }
54105 #endif /* WOLFSSL_KEY_GEN && (!NO_RSA || !NO_DH || !NO_DSA) */
54106 
54107 char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
54108 {
54109     int len = 0;
54110     char *buf;
54111 
54112     WOLFSSL_ENTER("wolfSSL_BN_bn2hex");
54113 
54114     if (bn == NULL || bn->internal == NULL) {
54115         WOLFSSL_MSG("bn NULL error");
54116         return NULL;
54117     }
54118 
54119     if (mp_radix_size((mp_int*)bn->internal, MP_RADIX_HEX, &len) != MP_OKAY) {
54120         WOLFSSL_MSG("mp_radix_size failure");
54121         return NULL;
54122     }
54123 
54124     buf = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
54125     if (buf == NULL) {
54126         WOLFSSL_MSG("BN_bn2hex malloc buffer failure");
54127         return NULL;
54128     }
54129 
54130     if (mp_tohex((mp_int*)bn->internal, buf) != MP_OKAY) {
54131         XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
54132         return NULL;
54133     }
54134 
54135     return buf;
54136 }
54137 
54138 #ifndef NO_FILESYSTEM
54139 /* return code compliant with OpenSSL :
54140  *   1 if success, 0 if error
54141  */
54142 int wolfSSL_BN_print_fp(XFILE fp, const WOLFSSL_BIGNUM *bn)
54143 {
54144     char *buf;
54145 
54146     WOLFSSL_ENTER("wolfSSL_BN_print_fp");
54147 
54148     if (fp == XBADFILE || bn == NULL || bn->internal == NULL) {
54149         WOLFSSL_MSG("bn NULL error");
54150         return WOLFSSL_FAILURE;
54151     }
54152 
54153     buf = wolfSSL_BN_bn2hex(bn);
54154     if (buf == NULL) {
54155         WOLFSSL_MSG("wolfSSL_BN_bn2hex failure");
54156         return WOLFSSL_FAILURE;
54157     }
54158 
54159     XFPRINTF(fp, "%s", buf);
54160     XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
54161 
54162     return WOLFSSL_SUCCESS;
54163 }
54164 #endif /* !NO_FILESYSTEM */
54165 
54166 
54167 WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx)
54168 {
54169     /* ctx is not used, return new Bignum */
54170     (void)ctx;
54171 
54172     WOLFSSL_ENTER("wolfSSL_BN_CTX_get");
54173 
54174     return wolfSSL_BN_new();
54175 }
54176 
54177 #ifndef NO_WOLFSSL_STUB
54178 void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx)
54179 {
54180     (void)ctx;
54181 
54182     WOLFSSL_ENTER("wolfSSL_BN_CTX_start");
54183     WOLFSSL_STUB("BN_CTX_start");
54184     WOLFSSL_MSG("wolfSSL_BN_CTX_start TBD");
54185 }
54186 #endif
54187 
54188 
54189 WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse(WOLFSSL_BIGNUM *r,
54190                                        WOLFSSL_BIGNUM *a,
54191                                        const WOLFSSL_BIGNUM *n,
54192                                        WOLFSSL_BN_CTX *ctx)
54193 {
54194     int dynamic = 0;
54195 
54196     /* ctx is not used */
54197     (void)ctx;
54198 
54199     WOLFSSL_ENTER("wolfSSL_BN_mod_inverse");
54200 
54201     /* check parameter */
54202     if (r == NULL) {
54203         r = wolfSSL_BN_new();
54204         if (r == NULL){
54205             WOLFSSL_MSG("WolfSSL_BN_new() failed");
54206             return NULL;
54207         }
54208         dynamic = 1;
54209     }
54210 
54211     if (a == NULL) {
54212         WOLFSSL_MSG("a NULL error");
54213         if (dynamic == 1) {
54214             wolfSSL_BN_free(r);
54215         }
54216         return NULL;
54217     }
54218 
54219     if (n == NULL) {
54220         WOLFSSL_MSG("n NULL error");
54221         if (dynamic == 1) {
54222             wolfSSL_BN_free(r);
54223         }
54224         return NULL;
54225     }
54226 
54227     /* Compute inverse of a modulo n and return r */
54228     if (mp_invmod((mp_int *)a->internal,(mp_int *)n->internal,
54229                   (mp_int*)r->internal) == MP_VAL){
54230         WOLFSSL_MSG("mp_invmod() error");
54231         if (dynamic == 1) {
54232             wolfSSL_BN_free(r);
54233         }
54234         return NULL;
54235     }
54236 
54237     return  r;
54238 }
54239 #endif  /* OPENSSL_EXTRA */
54240 #if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
54241     !defined(NO_ASN)
54242 #ifndef NO_BIO
54243 static int unprintable_char(char c)
54244 {
54245     const unsigned char last_unprintable = 31;
54246     const unsigned char LF = 10;
54247     const unsigned char CR = 13;
54248 
54249     if (c <= last_unprintable && c != LF && c != CR) {
54250         return 1;
54251     }
54252     return 0;
54253 }
54254 
54255 int wolfSSL_ASN1_STRING_print(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str)
54256 {
54257     int i;
54258 
54259     WOLFSSL_ENTER("wolfSSL_ASN1_STRING_print");
54260     if (out == NULL || str == NULL)
54261            return WOLFSSL_FAILURE;
54262 
54263     for (i=0; i < str->length; i++) {
54264         if (unprintable_char(str->data[i])) {
54265             str->data[i] = '.';
54266         }
54267     }
54268 
54269     if (wolfSSL_BIO_write(out, str->data, str->length) != str->length){
54270         return WOLFSSL_FAILURE;
54271     }
54272 
54273     return str->length;
54274 }
54275 #endif /* !NO_BIO */
54276 #endif /* (WOLFSSL_QT || OPENSSL_ALL || OPENSSL_EXTRA) && !NO_ASN */
54277 
54278 #if defined(OPENSSL_EXTRA)
54279 int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509)
54280 {
54281     WOLFSSL_ENTER("X509_check_ca");
54282 
54283     if (x509 == NULL)
54284         return WOLFSSL_FAILURE;
54285     if (x509->isCa)
54286         return 1;
54287     if (x509->extKeyUsageCrit)
54288         return 4;
54289 
54290     return 0;
54291 }
54292 
54293 
54294 const char *wolfSSL_ASN1_tag2str(int tag)
54295 {
54296     static const char *const tag_label[31] = {
54297         "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", "NULL",
54298         "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", "ENUMERATED",
54299         "<ASN1 11>", "UTF8STRING", "<ASN1 13>", "<ASN1 14>", "<ASN1 15>",
54300         "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING", "T61STRING",
54301         "VIDEOTEXTSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME",
54302         "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "UNIVERSALSTRING",
54303         "<ASN1 29>", "BMPSTRING"
54304     };
54305 
54306     if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
54307         tag &= ~0x100;
54308     if (tag < 0 || tag > 30)
54309         return "(unknown)";
54310     return tag_label[tag];
54311 }
54312 
54313 #ifndef NO_BIO
54314 static int check_esc_char(char c, char *esc)
54315 {
54316     char *ptr;
54317 
54318     ptr = esc;
54319     while(*ptr != 0){
54320         if (c == *ptr)
54321             return 1;
54322         ptr++;
54323     }
54324     return 0;
54325 }
54326 
54327 int wolfSSL_ASN1_STRING_print_ex(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str,
54328                                  unsigned long flags)
54329 {
54330     size_t str_len = 0, type_len = 0;
54331     unsigned char *typebuf = NULL;
54332     const char *hash="#";
54333 
54334     WOLFSSL_ENTER("wolfSSL_ASN1_STRING_PRINT_ex");
54335     if (out == NULL || str == NULL)
54336         return WOLFSSL_FAILURE;
54337 
54338     /* add ASN1 type tag */
54339     if (flags & ASN1_STRFLGS_SHOW_TYPE){
54340         const char *tag = wolfSSL_ASN1_tag2str(str->type);
54341         /* colon len + tag len + null*/
54342         type_len = XSTRLEN(tag) + 2;
54343         typebuf = (unsigned char *)XMALLOC(type_len , NULL, DYNAMIC_TYPE_TMP_BUFFER);
54344         if (typebuf == NULL){
54345             WOLFSSL_MSG("memory alloc failed.");
54346             return WOLFSSL_FAILURE;
54347         }
54348         XMEMSET(typebuf, 0, type_len);
54349         XSNPRINTF((char*)typebuf, (size_t)type_len , "%s:", tag);
54350         type_len--;
54351     }
54352 
54353     /* dump hex */
54354     if (flags & ASN1_STRFLGS_DUMP_ALL){
54355         char hex_tmp[4];
54356         char *str_ptr, *str_end;
54357 
54358         if (type_len > 0){
54359             if (wolfSSL_BIO_write(out, typebuf, (int)type_len) != (int)type_len){
54360                 XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
54361                 return WOLFSSL_FAILURE;
54362             }
54363             str_len += type_len;
54364         }
54365         if (wolfSSL_BIO_write(out, hash, 1) != 1){
54366             goto err_exit;
54367         }
54368         str_len++;
54369         if (flags & ASN1_STRFLGS_DUMP_DER){
54370             ByteToHexStr((byte)str->type, &hex_tmp[0]);
54371             ByteToHexStr((byte)str->length, &hex_tmp[2]);
54372             if (wolfSSL_BIO_write(out, hex_tmp, 4) != 4){
54373                 goto err_exit;
54374             }
54375             str_len += 4;
54376             XMEMSET(hex_tmp, 0, 4);
54377         }
54378 
54379         str_ptr = str->data;
54380         str_end = str->data + str->length;
54381         while (str_ptr < str_end){
54382             ByteToHexStr((byte)*str_ptr, &hex_tmp[0]);
54383             if (wolfSSL_BIO_write(out, hex_tmp, 2) != 2){
54384                 goto err_exit;
54385             }
54386             str_ptr++;
54387             str_len += 2;
54388         }
54389         if (type_len > 0)
54390             XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
54391 
54392         return (int)str_len;
54393     }
54394 
54395     if (type_len > 0){
54396         if (wolfSSL_BIO_write(out, typebuf, (int)type_len) != (int)type_len){
54397             XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
54398             return WOLFSSL_FAILURE;
54399         }
54400         str_len += type_len;
54401     }
54402 
54403     if (flags & ASN1_STRFLGS_ESC_2253){
54404         char esc_ch[] = "+;<>\\";
54405         char* esc_ptr;
54406 
54407         esc_ptr = str->data;
54408         while (*esc_ptr != 0){
54409             if (check_esc_char(*esc_ptr, esc_ch)){
54410                 if (wolfSSL_BIO_write(out,"\\", 1) != 1)
54411                     goto err_exit;
54412                 str_len++;
54413             }
54414             if (wolfSSL_BIO_write(out, esc_ptr, 1) != 1)
54415                 goto err_exit;
54416             str_len++;
54417             esc_ptr++;
54418         }
54419         if (type_len > 0)
54420             XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
54421         return (int)str_len;
54422     }
54423 
54424     if (wolfSSL_BIO_write(out, str->data, str->length) != str->length){
54425         goto err_exit;
54426     }
54427     str_len += str->length;
54428     if (type_len > 0)
54429         XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
54430 
54431     return (int)str_len;
54432 
54433 err_exit:
54434     if (type_len > 0)
54435         XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
54436     return WOLFSSL_FAILURE;
54437 }
54438 #endif /* !NO_BIO */
54439 
54440 #if !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
54441 
54442 
54443 WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME *s, time_t t,
54444                                     int offset_day, long offset_sec)
54445 {
54446     const time_t sec_per_day = 24*60*60;
54447     struct tm* ts = NULL;
54448     struct tm* tmpTime;
54449     time_t t_adj = 0;
54450     time_t offset_day_sec = 0;
54451 #if defined(NEED_TMP_TIME)
54452     struct tm tmpTimeStorage;
54453 
54454     tmpTime = &tmpTimeStorage;
54455 #else
54456     tmpTime = NULL;
54457 #endif
54458     (void)tmpTime;
54459 
54460     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_adj");
54461 
54462     if (s == NULL){
54463         s = wolfSSL_ASN1_TIME_new();
54464         if (s == NULL){
54465             return NULL;
54466         }
54467     }
54468 
54469     /* compute GMT time with offset */
54470     offset_day_sec = offset_day * sec_per_day;
54471     t_adj          = t + offset_day_sec + offset_sec;
54472     ts             = (struct tm *)XGMTIME(&t_adj, tmpTime);
54473     if (ts == NULL){
54474         WOLFSSL_MSG("failed to get time data.");
54475         wolfSSL_ASN1_TIME_free(s);
54476         return NULL;
54477     }
54478 
54479     /* create ASN1 time notation */
54480     /* UTC Time */
54481     if (ts->tm_year >= 50 && ts->tm_year < 150){
54482         char utc_str[ASN_UTC_TIME_SIZE];
54483         int utc_year = 0,utc_mon,utc_day,utc_hour,utc_min,utc_sec;
54484 
54485         if (ts->tm_year >= 50 && ts->tm_year < 100){
54486             utc_year = ts->tm_year;
54487         } else if (ts->tm_year >= 100 && ts->tm_year < 150){
54488             utc_year = ts->tm_year - 100;
54489         }
54490         utc_mon  = ts->tm_mon + 1;
54491         utc_day  = ts->tm_mday;
54492         utc_hour = ts->tm_hour;
54493         utc_min  = ts->tm_min;
54494         utc_sec  = ts->tm_sec;
54495         XSNPRINTF((char *)utc_str, sizeof(utc_str),
54496                   "%02d%02d%02d%02d%02d%02dZ",
54497                   utc_year, utc_mon, utc_day, utc_hour, utc_min, utc_sec);
54498         if (wolfSSL_ASN1_TIME_set_string(s, utc_str) != WOLFSSL_SUCCESS) {
54499             wolfSSL_ASN1_TIME_free(s);
54500             return NULL;
54501         }
54502     /* GeneralizedTime */
54503     } else {
54504         char gt_str[ASN_GENERALIZED_TIME_MAX];
54505         int gt_year,gt_mon,gt_day,gt_hour,gt_min,gt_sec;
54506 
54507         gt_year = ts->tm_year + 1900;
54508         gt_mon  = ts->tm_mon + 1;
54509         gt_day  = ts->tm_mday;
54510         gt_hour = ts->tm_hour;
54511         gt_min  = ts->tm_min;
54512         gt_sec  = ts->tm_sec;
54513         XSNPRINTF((char *)gt_str, sizeof(gt_str),
54514                   "%4d%02d%02d%02d%02d%02dZ",
54515                   gt_year, gt_mon, gt_day, gt_hour, gt_min,gt_sec);
54516         if (wolfSSL_ASN1_TIME_set_string(s, gt_str) != WOLFSSL_SUCCESS) {
54517             wolfSSL_ASN1_TIME_free(s);
54518             return NULL;
54519         }
54520     }
54521 
54522     return s;
54523 }
54524 #endif /* !NO_ASN_TIME && !USER_TIME && !TIME_OVERRIDES */
54525 
54526 #ifndef NO_ASN_TIME
54527 
54528 WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_new(void)
54529 {
54530     WOLFSSL_ASN1_TIME* ret = (WOLFSSL_ASN1_TIME*)
54531             XMALLOC(sizeof(WOLFSSL_ASN1_TIME), NULL, DYNAMIC_TYPE_OPENSSL);
54532     if (!ret)
54533         return NULL;
54534     XMEMSET(ret, 0, sizeof(WOLFSSL_ASN1_TIME));
54535     return ret;
54536 }
54537 
54538 void wolfSSL_ASN1_TIME_free(WOLFSSL_ASN1_TIME* t)
54539 {
54540     if (t) {
54541         XFREE(t, NULL, DYNAMIC_TYPE_OPENSSL);
54542     }
54543 }
54544 /* not a compatibility function - length getter for opaque type */
54545 int wolfSSL_ASN1_TIME_get_length(WOLFSSL_ASN1_TIME *t)
54546 {
54547     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_get_length");
54548     if (t == NULL)
54549         return WOLFSSL_FAILURE;
54550     return t->length;
54551 }
54552 /* not a compatibility function - data getter for opaque type */
54553 unsigned char* wolfSSL_ASN1_TIME_get_data(WOLFSSL_ASN1_TIME *t)
54554 {
54555     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_get_data");
54556     if (t == NULL)
54557         return NULL;
54558     return t->data;
54559 }
54560 
54561 WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME *t,
54562                                                         WOLFSSL_ASN1_TIME **out)
54563 {
54564     int time_type = 0;
54565     WOLFSSL_ASN1_TIME *ret = NULL;
54566 
54567     WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_generalizedtime");
54568     if (t == NULL) {
54569         WOLFSSL_MSG("Invalid ASN_TIME value");
54570     } else {
54571         time_type = t->type;
54572         if (time_type != ASN_UTC_TIME && time_type != ASN_GENERALIZED_TIME){
54573             WOLFSSL_MSG("Invalid ASN_TIME type.");
54574         } else {
54575             if (out == NULL || *out == NULL) {
54576                 ret = wolfSSL_ASN1_TIME_new();
54577                 if (ret == NULL){
54578                     WOLFSSL_MSG("memory alloc failed.");
54579                 }
54580             } else {
54581                 ret = *out;
54582             }
54583         }
54584     }
54585 
54586     if (ret != NULL) {
54587         if (time_type == ASN_GENERALIZED_TIME){
54588             XMEMCPY(ret->data, t->data, ASN_GENERALIZED_TIME_SIZE);
54589         } else { /* ASN_UTC_TIME */
54590             /* convert UTC to generalized time */
54591             ret->type = ASN_GENERALIZED_TIME;
54592             ret->length = ASN_GENERALIZED_TIME_SIZE;
54593             if (t->data[0] >= '5') {
54594                 ret->data[0] = '1'; ret->data[1] = '9';
54595             } else {
54596                 ret->data[0] = '2'; ret->data[1] = '0';
54597             }
54598             XMEMCPY(&ret->data[2], t->data, ASN_UTC_TIME_SIZE);
54599         }
54600     }
54601 
54602     return ret;
54603 }
54604 #endif /* !NO_ASN_TIME */
54605 
54606 #ifndef NO_ASN
54607 int wolfSSL_i2c_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER *a, unsigned char **pp)
54608 {
54609     unsigned char *pptr = NULL;
54610     char pad = 0 ;
54611     unsigned char pad_val = 0;
54612     int ret_size = 0;
54613     unsigned char data1 = 0;
54614     unsigned char neg = 0;
54615     int i = 0;
54616 
54617     WOLFSSL_ENTER("wolfSSL_i2c_ASN1_INTEGER");
54618     if (a == NULL)
54619         return WOLFSSL_FAILURE;
54620 
54621     ret_size = a->intData[1];
54622     if (ret_size == 0)
54623         ret_size = 1;
54624     else{
54625         ret_size = (int)a->intData[1];
54626         neg = a->negative;
54627         data1 = a->intData[2];
54628         if (ret_size == 1 && data1 == 0)
54629             neg = 0;
54630         /* 0x80 or greater positive number in first byte */
54631         if (!neg && (data1 > 127)){
54632             pad = 1;
54633             pad_val = 0;
54634         } else if (neg){
54635             /* negative number */
54636             if (data1 > 128){
54637                 pad = 1;
54638                 pad_val = 0xff;
54639             } else if (data1 == 128){
54640                 for (i = 3; i < a->intData[1] + 2; i++){
54641                     if (a->intData[i]){
54642                         pad = 1;
54643                         pad_val = 0xff;
54644                         break;
54645                     }
54646                 }
54647             }
54648         }
54649         ret_size += (int)pad;
54650     }
54651     if (pp == NULL)
54652         return ret_size;
54653 
54654     pptr = *pp;
54655     if (pad)
54656         *(pptr++) = pad_val;
54657     if (a->intData[1] == 0)
54658         *(pptr++) = 0;
54659     else if (!neg){
54660         /* positive number */
54661         for (i=0; i < a->intData[1]; i++){
54662             *pptr = a->intData[i+2];
54663             pptr++;
54664         }
54665     } else {
54666         /* negative number */
54667         int str_len = 0;
54668 
54669         /* 0 padding from end of buffer */
54670         str_len = (int)a->intData[1];
54671         pptr += a->intData[1] - 1;
54672         while (!a->intData[str_len + 2] && str_len > 1){
54673             *(pptr--) = 0;
54674             str_len--;
54675         }
54676         /* 2's complement next octet */
54677         *(pptr--) = ((a->intData[str_len + 1]) ^ 0xff) + 1;
54678         str_len--;
54679         /* Complement any octets left */
54680         while (str_len > 0){
54681             *(pptr--) = a->intData[str_len + 1] ^ 0xff;
54682             str_len--;
54683         }
54684     }
54685     *pp += ret_size;
54686     return ret_size;
54687 }
54688 #endif /* !NO_ASN */
54689 #endif /* OPENSSL_EXTRA */
54690 
54691 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
54692 long wolfSSL_X509_get_version(const WOLFSSL_X509 *x509)
54693 {
54694     int version = 0;
54695 
54696     WOLFSSL_ENTER("wolfSSL_X509_get_version");
54697 
54698     if (x509 == NULL){
54699         WOLFSSL_MSG("invalid parameter");
54700         return 0L;
54701     }
54702     version = x509->version;
54703     if (version != 0)
54704         return (long)version - 1L;
54705 
54706     return 0L;
54707 }
54708 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
54709 
54710 #if defined(OPENSSL_EXTRA)
54711 int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509 *x)
54712 {
54713     if (x == NULL)
54714         return 0;
54715 
54716     return oid2nid(x->sigOID, oidSigType);
54717 }
54718 #endif  /* OPENSSL_EXTRA */
54719 
54720 #if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
54721 /* return compliant with OpenSSL
54722  *   RSA modulus size in bytes, -1 if error
54723  */
54724 int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa)
54725 {
54726     WOLFSSL_ENTER("wolfSSL_RSA_size");
54727 
54728     if (rsa == NULL)
54729         return WOLFSSL_FATAL_ERROR;
54730     if (rsa->inSet == 0)
54731     {
54732         if (SetRsaInternal((WOLFSSL_RSA*)rsa) != WOLFSSL_SUCCESS) {
54733             WOLFSSL_MSG("SetRsaInternal failed");
54734             return 0;
54735         }
54736     }
54737     return wc_RsaEncryptSize((RsaKey*)rsa->internal);
54738 }
54739 /* return RSA modulus in bits                      */
54740 /* @param rsa a pointer to WOLFSSL_RSA structur    */
54741 /* @return RSA modulus size in bits, 0 if error    */
54742 int wolfSSL_RSA_bits(const WOLFSSL_RSA* rsa)
54743 {
54744     WOLFSSL_ENTER("wolfSSL_RSA_bits");
54745 
54746     if (rsa == NULL)
54747         return WOLFSSL_FAILURE;
54748 
54749     return wolfSSL_BN_num_bits(rsa->n);
54750 }
54751 #endif
54752 
54753 #if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) && \
54754     !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
54755 /* WolfSSL -> OpenSSL */
54756 int SetRsaExternal(WOLFSSL_RSA* rsa)
54757 {
54758     RsaKey* key;
54759     WOLFSSL_MSG("Entering SetRsaExternal");
54760 
54761     if (rsa == NULL || rsa->internal == NULL) {
54762         WOLFSSL_MSG("rsa key NULL error");
54763         return WOLFSSL_FATAL_ERROR;
54764     }
54765 
54766     key = (RsaKey*)rsa->internal;
54767 
54768     if (SetIndividualExternal(&rsa->n, &key->n) != WOLFSSL_SUCCESS) {
54769         WOLFSSL_MSG("rsa n key error");
54770         return WOLFSSL_FATAL_ERROR;
54771     }
54772 
54773     if (SetIndividualExternal(&rsa->e, &key->e) != WOLFSSL_SUCCESS) {
54774         WOLFSSL_MSG("rsa e key error");
54775         return WOLFSSL_FATAL_ERROR;
54776     }
54777 
54778     if (key->type == RSA_PRIVATE) {
54779         if (SetIndividualExternal(&rsa->d, &key->d) != WOLFSSL_SUCCESS) {
54780             WOLFSSL_MSG("rsa d key error");
54781             return WOLFSSL_FATAL_ERROR;
54782         }
54783 
54784         if (SetIndividualExternal(&rsa->p, &key->p) != WOLFSSL_SUCCESS) {
54785             WOLFSSL_MSG("rsa p key error");
54786             return WOLFSSL_FATAL_ERROR;
54787         }
54788 
54789         if (SetIndividualExternal(&rsa->q, &key->q) != WOLFSSL_SUCCESS) {
54790             WOLFSSL_MSG("rsa q key error");
54791             return WOLFSSL_FATAL_ERROR;
54792         }
54793 
54794     #ifndef RSA_LOW_MEM
54795         if (SetIndividualExternal(&rsa->dmp1, &key->dP) != WOLFSSL_SUCCESS) {
54796             WOLFSSL_MSG("rsa dP key error");
54797             return WOLFSSL_FATAL_ERROR;
54798         }
54799 
54800         if (SetIndividualExternal(&rsa->dmq1, &key->dQ) != WOLFSSL_SUCCESS) {
54801             WOLFSSL_MSG("rsa dQ key error");
54802             return WOLFSSL_FATAL_ERROR;
54803         }
54804 
54805         if (SetIndividualExternal(&rsa->iqmp, &key->u) != WOLFSSL_SUCCESS) {
54806             WOLFSSL_MSG("rsa u key error");
54807             return WOLFSSL_FATAL_ERROR;
54808         }
54809     #endif /* !RSA_LOW_MEM */
54810     }
54811     rsa->exSet = 1;
54812 
54813     return WOLFSSL_SUCCESS;
54814 }
54815 #endif
54816 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
54817 /* when calling SetIndividualExternal, mpi should be cleared by caller if no
54818  * longer used. ie mp_free(mpi). This is to free data when fastmath is
54819  * disabled since a copy of mpi is made by this function and placed into bn.
54820  */
54821 int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
54822 {
54823     byte dynamic = 0;
54824 
54825 #ifdef WOLFSSL_DEBUG_OPENSSL
54826     WOLFSSL_MSG("Entering SetIndividualExternal");
54827 #endif
54828 
54829     if (mpi == NULL || bn == NULL) {
54830         WOLFSSL_MSG("mpi NULL error");
54831         return WOLFSSL_FATAL_ERROR;
54832     }
54833 
54834     if (*bn == NULL) {
54835         *bn = wolfSSL_BN_new();
54836         if (*bn == NULL) {
54837             WOLFSSL_MSG("SetIndividualExternal alloc failed");
54838             return WOLFSSL_FATAL_ERROR;
54839         }
54840         dynamic = 1;
54841     }
54842 
54843     if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
54844         WOLFSSL_MSG("mp_copy error");
54845         if (dynamic == 1) {
54846             wolfSSL_BN_free(*bn);
54847         }
54848         return WOLFSSL_FATAL_ERROR;
54849     }
54850 
54851     return WOLFSSL_SUCCESS;
54852 }
54853 
54854 
54855 static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn)
54856 {
54857     if (bn)
54858         XMEMSET(bn, 0, sizeof(WOLFSSL_BIGNUM));
54859 }
54860 
54861 
54862 WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
54863 {
54864     WOLFSSL_BIGNUM* external;
54865     mp_int*        mpi;
54866 
54867 #ifdef WOLFSSL_DEBUG_OPENSSL
54868     WOLFSSL_MSG("wolfSSL_BN_new");
54869 #endif
54870 
54871 #if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
54872     mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
54873     if (mpi == NULL) {
54874         WOLFSSL_MSG("wolfSSL_BN_new malloc mpi failure");
54875         return NULL;
54876     }
54877 #endif
54878 
54879     external = (WOLFSSL_BIGNUM*) XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
54880                                         DYNAMIC_TYPE_BIGINT);
54881     if (external == NULL) {
54882         WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
54883 #if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
54884         XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
54885 #endif
54886         return NULL;
54887     }
54888 
54889 #if defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT)
54890     mpi = &external->fp;
54891 #endif
54892 
54893     InitwolfSSL_BigNum(external);
54894     if (mp_init(mpi) != MP_OKAY) {
54895         wolfSSL_BN_free(external);
54896         return NULL;
54897     }
54898     external->internal = mpi;
54899 
54900     return external;
54901 }
54902 
54903 
54904 #if defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT)
54905 /* This function works without BN_free only with TFM */
54906 void wolfSSL_BN_init(WOLFSSL_BIGNUM* bn)
54907 {
54908     if(bn == NULL)return;
54909 #ifdef WOLFSSL_DEBUG_OPENSSL
54910     WOLFSSL_MSG("wolfSSL_BN_init");
54911 #endif
54912     InitwolfSSL_BigNum(bn);
54913     if (mp_init(&bn->fp) != MP_OKAY)
54914         return;
54915     bn->internal = (void *)&bn->fp;
54916 }
54917 #endif
54918 
54919 void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
54920 {
54921 #ifdef WOLFSSL_DEBUG_OPENSSL
54922     WOLFSSL_MSG("wolfSSL_BN_free");
54923 #endif
54924     if (bn) {
54925         if (bn->internal) {
54926             mp_int* bni = (mp_int*)bn->internal;
54927             mp_free(bni);
54928 #if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
54929             XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
54930 #endif
54931             bn->internal = NULL;
54932         }
54933         XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
54934         /* bn = NULL, don't try to access or double free it */
54935     }
54936 
54937 }
54938 
54939 void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
54940 {
54941 #ifdef WOLFSSL_DEBUG_OPENSSL
54942     WOLFSSL_MSG("wolfSSL_BN_clear_free");
54943 #endif
54944     if (bn) {
54945         if (bn->internal) {
54946             mp_int* bni = (mp_int*)bn->internal;
54947             mp_forcezero(bni);
54948         }
54949         wolfSSL_BN_free(bn);
54950     }
54951 }
54952 
54953 void wolfSSL_BN_clear(WOLFSSL_BIGNUM* bn)
54954 {
54955 #ifdef WOLFSSL_DEBUG_OPENSSL
54956     WOLFSSL_MSG("wolfSSL_BN_clear");
54957 #endif
54958     if (bn && bn->internal) {
54959         mp_forcezero((mp_int*)bn->internal);
54960     }
54961 }
54962 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
54963 
54964 #if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
54965 static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa)
54966 {
54967     if (rsa) {
54968         XMEMSET(rsa, 0, sizeof(WOLFSSL_RSA));
54969     }
54970 }
54971 
54972 
54973 void wolfSSL_RSA_free(WOLFSSL_RSA* rsa)
54974 {
54975     WOLFSSL_ENTER("wolfSSL_RSA_free");
54976 
54977     if (rsa) {
54978 #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
54979         int doFree = 0;
54980 #endif
54981         void* heap = rsa->heap;
54982 
54983 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
54984         wolfSSL_CRYPTO_cleanup_ex_data(&rsa->ex_data);
54985 #endif
54986 #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
54987     #ifndef SINGLE_THREADED
54988         if (wc_LockMutex(&rsa->refMutex) != 0) {
54989             WOLFSSL_MSG("Couldn't lock rsa mutex");
54990         }
54991     #endif
54992 
54993         /* only free if all references to it are done */
54994         rsa->refCount--;
54995         if (rsa->refCount == 0) {
54996             doFree = 1;
54997         }
54998     #ifndef SINGLE_THREADED
54999         wc_UnLockMutex(&rsa->refMutex);
55000     #endif
55001 
55002         if (!doFree) {
55003             return;
55004         }
55005 
55006     #ifndef SINGLE_THREADED
55007         wc_FreeMutex(&rsa->refMutex);
55008     #endif
55009 #endif
55010 
55011         if (rsa->internal) {
55012 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \
55013     !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING)
55014             WC_RNG* rng;
55015 
55016             /* check if RNG is owned before freeing it */
55017             if (rsa->ownRng) {
55018                 rng = ((RsaKey*)rsa->internal)->rng;
55019                 if (rng != NULL && rng != &globalRNG) {
55020                     wc_FreeRng(rng);
55021                     XFREE(rng, heap, DYNAMIC_TYPE_RNG);
55022                 }
55023             }
55024 #endif /* WC_RSA_BLINDING */
55025             wc_FreeRsaKey((RsaKey*)rsa->internal);
55026             XFREE(rsa->internal, heap, DYNAMIC_TYPE_RSA);
55027             rsa->internal = NULL;
55028         }
55029         wolfSSL_BN_free(rsa->iqmp);
55030         wolfSSL_BN_free(rsa->dmq1);
55031         wolfSSL_BN_free(rsa->dmp1);
55032         wolfSSL_BN_free(rsa->q);
55033         wolfSSL_BN_free(rsa->p);
55034         wolfSSL_BN_free(rsa->d);
55035         wolfSSL_BN_free(rsa->e);
55036         wolfSSL_BN_free(rsa->n);
55037 
55038     #ifdef WC_RSA_BLINDING
55039         if (rsa->rng && wc_FreeRng(rsa->rng) != 0) {
55040             WOLFSSL_MSG("Issue freeing rng");
55041         }
55042         XFREE(rsa->rng, heap, DYNAMIC_TYPE_RNG);
55043     #endif
55044 
55045 #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
55046         if (rsa->meth) {
55047             wolfSSL_RSA_meth_free(rsa->meth);
55048         }
55049 #endif
55050 
55051         InitwolfSSL_Rsa(rsa);  /* set back to NULLs for safety */
55052 
55053         XFREE(rsa, heap, DYNAMIC_TYPE_RSA);
55054         (void)heap;
55055 
55056         /* rsa = NULL, don't try to access or double free it */
55057     }
55058 }
55059 
55060 WOLFSSL_RSA* wolfSSL_RSA_new_ex(void* heap, int devId)
55061 {
55062     WOLFSSL_RSA* external;
55063     RsaKey* key;
55064 
55065     WOLFSSL_ENTER("wolfSSL_RSA_new");
55066 
55067     key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA);
55068     if (key == NULL) {
55069         WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure");
55070         return NULL;
55071     }
55072 
55073     external = (WOLFSSL_RSA*)XMALLOC(sizeof(WOLFSSL_RSA), heap,
55074                                      DYNAMIC_TYPE_RSA);
55075     if (external == NULL) {
55076         WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure");
55077         XFREE(key, heap, DYNAMIC_TYPE_RSA);
55078         return NULL;
55079     }
55080 
55081     external->heap = heap;
55082     InitwolfSSL_Rsa(external);
55083 
55084 #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
55085     external->refCount = 1;
55086 #ifndef SINGLE_THREADED
55087     if (wc_InitMutex(&external->refMutex) != 0) {
55088         WOLFSSL_MSG("wc_InitMutex WOLFSSL_RSA failure");
55089         XFREE(external, heap, DYNAMIC_TYPE_RSA);
55090         XFREE(key, heap, DYNAMIC_TYPE_RSA);
55091         return NULL;
55092     }
55093 #endif
55094 #endif
55095 
55096     if (wc_InitRsaKey_ex(key, heap, devId) != 0) {
55097         WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure");
55098         XFREE(external, heap, DYNAMIC_TYPE_RSA);
55099         XFREE(key, heap, DYNAMIC_TYPE_RSA);
55100         return NULL;
55101     }
55102 
55103 #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \
55104     !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING)
55105     {
55106         WC_RNG* rng;
55107 
55108         rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), heap, DYNAMIC_TYPE_RNG);
55109         if (rng != NULL && wc_InitRng_ex(rng, heap, devId) != 0) {
55110             WOLFSSL_MSG("InitRng failure, attempting to use global RNG");
55111             XFREE(rng, heap, DYNAMIC_TYPE_RNG);
55112             rng = NULL;
55113         }
55114 
55115         external->ownRng = 1;
55116         if (rng == NULL && initGlobalRNG) {
55117             external->ownRng = 0;
55118             rng = &globalRNG;
55119         }
55120 
55121         if (rng == NULL) {
55122             WOLFSSL_MSG("wolfSSL_RSA_new no WC_RNG for blinding");
55123             XFREE(external, heap, DYNAMIC_TYPE_RSA);
55124             XFREE(key, heap, DYNAMIC_TYPE_RSA);
55125             return NULL;
55126         }
55127 
55128         wc_RsaSetRNG(key, rng);
55129     }
55130 #else
55131     XMEMSET(key, 0, sizeof(RsaKey));
55132 #endif /* WC_RSA_BLINDING */
55133 
55134     external->internal = key;
55135     external->inSet = 0;
55136     return external;
55137 }
55138 
55139 WOLFSSL_RSA* wolfSSL_RSA_new(void)
55140 {
55141     return wolfSSL_RSA_new_ex(NULL, INVALID_DEVID);
55142 }
55143 #endif /* !NO_RSA && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
55144 
55145 
55146 #if defined(OPENSSL_EXTRA)
55147 WOLFSSL_STACK* wolfSSL_sk_X509_new(void)
55148 {
55149     WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
55150             DYNAMIC_TYPE_OPENSSL);
55151     if (s != NULL) {
55152         XMEMSET(s, 0, sizeof(*s));
55153         s->type = STACK_TYPE_X509;
55154     }
55155 
55156     return s;
55157 }
55158 #endif
55159 
55160 #ifdef OPENSSL_ALL
55161 
55162 WOLFSSL_STACK* wolfSSL_sk_X509_OBJECT_new(void)
55163 {
55164     WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
55165             DYNAMIC_TYPE_OPENSSL);
55166     WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_new");
55167     if (s != NULL) {
55168         XMEMSET(s, 0, sizeof(*s));
55169         s->type = STACK_TYPE_X509_OBJ;
55170     }
55171     return s;
55172 }
55173 
55174 void wolfSSL_sk_X509_OBJECT_free(WOLFSSL_STACK* s)
55175 {
55176     WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_free");
55177     wolfSSL_sk_free(s);
55178 }
55179 
55180 void wolfSSL_sk_X509_OBJECT_pop_free(WOLFSSL_STACK* s,
55181         void (*f) (WOLFSSL_X509_OBJECT*))
55182 {
55183     WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_pop_free");
55184     wolfSSL_sk_pop_free(s, (wolfSSL_sk_freefunc)f);
55185 }
55186 
55187 int wolfSSL_sk_X509_OBJECT_push(WOLFSSL_STACK* sk, WOLFSSL_X509_OBJECT* obj)
55188 {
55189     WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_push");
55190 
55191     if (sk == NULL || obj == NULL) {
55192         return WOLFSSL_FAILURE;
55193     }
55194 
55195     return wolfSSL_sk_push(sk, obj);
55196 }
55197 
55198 #if !defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
55199 int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
55200                                           WOLFSSL_EVP_PKEY* pkey,
55201                                           const WOLFSSL_EVP_CIPHER* enc,
55202                                           char* passwd, int passwdSz,
55203                                           wc_pem_password_cb* cb, void* ctx)
55204 {
55205     int ret = 0;
55206     char password[NAME_SZ];
55207     byte* key = NULL;
55208     word32 keySz;
55209     byte* pem = NULL;
55210     int pemSz;
55211     int type = PKCS8_PRIVATEKEY_TYPE;
55212     int algId;
55213     const byte* curveOid;
55214     word32 oidSz;
55215     int encAlgId;
55216 
55217     if (bio == NULL || pkey == NULL)
55218         return -1;
55219 
55220     keySz = pkey->pkey_sz + 128;
55221     key = (byte*)XMALLOC(keySz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
55222     if (key == NULL)
55223         ret = MEMORY_E;
55224 
55225     if (ret == 0 && enc != NULL && passwd == NULL) {
55226         passwdSz = cb(password, sizeof(password), 1, ctx);
55227         if (passwdSz < 0)
55228             ret = WOLFSSL_FAILURE;
55229         passwd = password;
55230     }
55231 
55232     if (ret == 0 && enc != NULL) {
55233         WC_RNG rng;
55234         ret = wc_InitRng(&rng);
55235         if (ret == 0) {
55236         #ifndef NO_DES3
55237             if (enc == EVP_DES_CBC)
55238                 encAlgId = DESb;
55239             else if (enc == EVP_DES_EDE3_CBC)
55240                 encAlgId = DES3b;
55241             else
55242         #endif
55243         #if !defined(NO_AES) && defined(HAVE_AES_CBC)
55244             #ifdef WOLFSSL_AES_256
55245             if (enc == EVP_AES_256_CBC)
55246                 encAlgId = AES256CBCb;
55247             else
55248             #endif
55249         #endif
55250                 ret = -1;
55251             if (ret == 0) {
55252                 ret = TraditionalEnc((byte*)pkey->pkey.ptr, pkey->pkey_sz, key,
55253                                        &keySz, passwd, passwdSz, PKCS5, PBES2,
55254                                        encAlgId, NULL, 0, WC_PKCS12_ITT_DEFAULT,
55255                                        &rng, NULL);
55256                 if (ret > 0) {
55257                     keySz = ret;
55258                     ret = 0;
55259                 }
55260             }
55261             wc_FreeRng(&rng);
55262         }
55263         type = PKCS8_ENC_PRIVATEKEY_TYPE;
55264     }
55265     if (ret == 0 && enc == NULL) {
55266         type = PKCS8_PRIVATEKEY_TYPE;
55267     #ifdef HAVE_ECC
55268         if (pkey->type == EVP_PKEY_EC) {
55269             algId = ECDSAk;
55270             ret = wc_ecc_get_oid(pkey->ecc->group->curve_oid, &curveOid,
55271                                                                         &oidSz);
55272         }
55273         else
55274     #endif
55275         {
55276             algId = RSAk;
55277             curveOid = NULL;
55278             oidSz = 0;
55279         }
55280 
55281     #ifdef HAVE_ECC
55282         if (ret >= 0)
55283     #endif
55284         {
55285             ret = wc_CreatePKCS8Key(key, &keySz, (byte*)pkey->pkey.ptr,
55286                                          pkey->pkey_sz, algId, curveOid, oidSz);
55287             keySz = ret;
55288         }
55289     }
55290 
55291     if (password == passwd)
55292         XMEMSET(password, 0, passwdSz);
55293 
55294     if (ret >= 0) {
55295         pemSz = 2 * keySz + 2 * 64;
55296         pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
55297         if (pem == NULL)
55298             ret = MEMORY_E;
55299     }
55300 
55301     if (ret >= 0)
55302         ret = wc_DerToPemEx(key, keySz, pem, pemSz, NULL, type);
55303 
55304     if (key != NULL)
55305         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
55306 
55307     if (ret >= 0) {
55308         if (wolfSSL_BIO_write(bio, pem, ret) != ret)
55309             ret = -1;
55310     }
55311 
55312     if (pem != NULL)
55313         XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
55314 
55315     return ret < 0 ? 0 : ret;
55316 
55317 }
55318 
55319 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
55320 int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE f, WOLFSSL_EVP_PKEY* pkey,
55321     const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz,
55322     wc_pem_password_cb* cb, void* ctx)
55323 {
55324     int ret = WOLFSSL_SUCCESS;
55325     BIO *b;
55326 
55327     WOLFSSL_ENTER("wolfSSL_PEM_write_PKCS8PrivateKey");
55328 
55329     b = wolfSSL_BIO_new_fp(f, BIO_NOCLOSE);
55330     if (b == NULL) {
55331         ret = WOLFSSL_FAILURE;
55332     }
55333     if (ret == WOLFSSL_SUCCESS) {
55334         ret = wolfSSL_PEM_write_bio_PKCS8PrivateKey(b, pkey, enc, passwd,
55335                 passwdSz, cb, ctx);
55336     }
55337 
55338     wolfSSL_BIO_free(b);
55339 
55340     return ret;
55341 }
55342 #endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
55343 
55344 static int bio_get_data(WOLFSSL_BIO* bio, byte** data)
55345 {
55346     int ret = 0;
55347     byte* mem = NULL;
55348 #ifndef NO_FILESYSTEM
55349     long memSz;
55350     XFILE file;
55351     long curr;
55352 #endif
55353 
55354     if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
55355     }
55356 #ifndef NO_FILESYSTEM
55357     else if (bio->type == WOLFSSL_BIO_FILE) {
55358         if (wolfSSL_BIO_get_fp(bio, &file) != WOLFSSL_SUCCESS)
55359             ret = BAD_FUNC_ARG;
55360         if (ret == 0) {
55361             curr = XFTELL(file);
55362             if (curr < 0) {
55363                 ret = WOLFSSL_BAD_FILE;
55364             }
55365             if (XFSEEK(file, 0, XSEEK_END) != 0)
55366                 ret = WOLFSSL_BAD_FILE;
55367         }
55368         if (ret == 0) {
55369             memSz = XFTELL(file);
55370             if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0) {
55371                 ret = WOLFSSL_BAD_FILE;
55372             }
55373         }
55374         if (ret == 0) {
55375             memSz -= curr;
55376             ret = (int)memSz;
55377             if (XFSEEK(file, curr, SEEK_SET) != 0)
55378                 ret = WOLFSSL_BAD_FILE;
55379         }
55380     }
55381 #endif
55382 
55383     if (ret > 0) {
55384         mem = (byte*)XMALLOC(ret, bio->heap, DYNAMIC_TYPE_OPENSSL);
55385         if (mem == NULL) {
55386             WOLFSSL_MSG("Memory error");
55387             ret = MEMORY_E;
55388         }
55389         if (ret >= 0) {
55390             if ((ret = wolfSSL_BIO_read(bio, mem, ret)) <= 0) {
55391                 XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
55392                 ret = MEMORY_E;
55393                 mem = NULL;
55394             }
55395         }
55396     }
55397 
55398     *data = mem;
55399 
55400     return ret;
55401 }
55402 
55403 /* DER data is PKCS#8 encrypted. */
55404 WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio,
55405                                                   WOLFSSL_EVP_PKEY** pkey,
55406                                                   wc_pem_password_cb* cb,
55407                                                   void* ctx)
55408 {
55409     int ret;
55410     byte* der;
55411     int len;
55412     byte* p;
55413     word32 algId;
55414     WOLFSSL_EVP_PKEY* key;
55415 
55416     if ((len = bio_get_data(bio, &der)) < 0)
55417         return NULL;
55418 
55419     if (cb != NULL) {
55420         char password[NAME_SZ];
55421         int passwordSz = cb(password, sizeof(password), PEM_PASS_READ, ctx);
55422         if (passwordSz < 0) {
55423             XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
55424             return NULL;
55425         }
55426 
55427         ret = ToTraditionalEnc(der, len, password, passwordSz, &algId);
55428         if (ret < 0) {
55429             XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
55430             return NULL;
55431         }
55432 
55433         ForceZero(password, passwordSz);
55434     }
55435 
55436     p = der;
55437     key = wolfSSL_d2i_PrivateKey_EVP(pkey, &p, len);
55438     XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
55439     return key;
55440 }
55441 
55442 #endif /* !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 */
55443 
55444 /* Detect which type of key it is before decoding. */
55445 WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey(WOLFSSL_EVP_PKEY** pkey,
55446                                              const unsigned char** pp,
55447                                              long length)
55448 {
55449     int ret;
55450     WOLFSSL_EVP_PKEY* key = NULL;
55451     const byte* der = *pp;
55452     word32 idx = 0;
55453     int len = 0;
55454     word32 end = 0;
55455     int cnt = 0;
55456     int type;
55457     word32 algId;
55458     word32 keyLen = (word32)length;
55459 
55460     /* Take off PKCS#8 wrapper if found. */
55461     if ((len = ToTraditionalInline_ex(der, &idx, keyLen, &algId)) >= 0) {
55462         der += idx;
55463         keyLen = len;
55464     }
55465     idx = 0;
55466     len = 0;
55467 
55468     /* Use the number of elements in the outer sequence to determine key type.
55469      */
55470     ret = GetSequence(der, &idx, &len, keyLen);
55471     if (ret >= 0) {
55472         end = idx + len;
55473         while (ret >= 0 && idx < end) {
55474             /* Skip type */
55475             idx++;
55476             /* Get length and skip over - keeping count */
55477             len = 0;
55478             ret = GetLength(der, &idx, &len, keyLen);
55479             if (ret >= 0) {
55480                 if (idx + len > end)
55481                     ret = ASN_PARSE_E;
55482                 else {
55483                     idx += len;
55484                     cnt++;
55485                 }
55486             }
55487         }
55488     }
55489 
55490     if (ret >= 0) {
55491         /* ECC includes version, private[, curve][, public key] */
55492         if (cnt >= 2 && cnt <= 4)
55493             type = EVP_PKEY_EC;
55494         else
55495             type = EVP_PKEY_RSA;
55496 
55497         key = wolfSSL_d2i_PrivateKey(type, pkey, &der, keyLen);
55498         *pp = der;
55499     }
55500 
55501     return key;
55502 }
55503 #endif /* OPENSSL_ALL */
55504 
55505 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
55506     !defined(WOLFCRYPT_ONLY)
55507 /* unlike wolfSSL_X509_NAME_dup this does not malloc a duplicate, only deep
55508  * copy. "to" is expected to be a fresh blank name, if not pointers could be
55509  * lost */
55510 int wolfSSL_X509_NAME_copy(WOLFSSL_X509_NAME* from, WOLFSSL_X509_NAME* to)
55511 {
55512     int i;
55513     WOLFSSL_X509_NAME_ENTRY* ne;
55514 
55515     WOLFSSL_ENTER("wolfSSL_X509_NAME_copy");
55516 
55517     if (from == NULL || to == NULL) {
55518         WOLFSSL_MSG("NULL parameter");
55519         return BAD_FUNC_ARG;
55520     }
55521 
55522 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
55523     if (from->rawLen > 0) {
55524         if (from->rawLen > ASN_NAME_MAX) {
55525             WOLFSSL_MSG("Bad raw size");
55526             return BAD_FUNC_ARG;
55527         }
55528         XMEMCPY(to->raw, from->raw, from->rawLen);
55529         to->rawLen = from->rawLen;
55530     }
55531 #endif
55532 
55533     if (from->dynamicName) {
55534         to->name = (char*)XMALLOC(from->sz, to->heap, DYNAMIC_TYPE_SUBJECT_CN);
55535         if (to->name == NULL)
55536             return WOLFSSL_FAILURE;
55537         to->dynamicName = 1;
55538     }
55539     XMEMCPY(to->name, from->name, from->sz);
55540     to->sz = from->sz;
55541 
55542     for (i = 0; i < MAX_NAME_ENTRIES; i++) {
55543         ne = wolfSSL_X509_NAME_get_entry(from, i);
55544         if (ne != NULL)
55545             wolfSSL_X509_NAME_add_entry(to, ne, i, 1);
55546     }
55547     to->entrySz = from->entrySz;
55548     return WOLFSSL_SUCCESS;
55549 }
55550 
55551 
55552 /* copies over information from "name" to the "cert" subject name
55553  * returns WOLFSSL_SUCCESS on success */
55554 int wolfSSL_X509_set_subject_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
55555 {
55556     WOLFSSL_ENTER("X509_set_subject_name");
55557     if (cert == NULL || name == NULL)
55558         return WOLFSSL_FAILURE;
55559 
55560     FreeX509Name(&cert->subject);
55561     InitX509Name(&cert->subject, 0, cert->heap);
55562 
55563     if (wolfSSL_X509_NAME_copy(name, &cert->subject) != WOLFSSL_SUCCESS) {
55564         FreeX509Name(&cert->subject);
55565         return WOLFSSL_FAILURE;
55566     }
55567 
55568     cert->subject.x509 = cert;
55569     return WOLFSSL_SUCCESS;
55570 }
55571 
55572 
55573 /* copies over information from "name" to the "cert" issuer name
55574  * returns WOLFSSL_SUCCESS on success */
55575 int wolfSSL_X509_set_issuer_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
55576 {
55577     WOLFSSL_ENTER("X509_set_issuer_name");
55578     if (cert == NULL || name == NULL)
55579         return WOLFSSL_FAILURE;
55580 
55581     FreeX509Name(&cert->issuer);
55582     InitX509Name(&cert->issuer, 0, cert->heap);
55583 
55584     if (wolfSSL_X509_NAME_copy(name, &cert->issuer) != WOLFSSL_SUCCESS) {
55585         FreeX509Name(&cert->issuer);
55586         return WOLFSSL_FAILURE;
55587     }
55588 
55589     cert->issuer.x509 = cert;
55590     cert->issuerSet = 1;
55591 
55592     return WOLFSSL_SUCCESS;
55593 }
55594 
55595 
55596 int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
55597 {
55598     if (x509 == NULL || t == NULL) {
55599         return WOLFSSL_FAILURE;
55600     }
55601 
55602     x509->notAfter.type = t->type;
55603     x509->notAfter.length = t->length;
55604 
55605     XMEMCPY(x509->notAfter.data, t->data, CTC_DATE_SIZE);
55606 
55607     return WOLFSSL_SUCCESS;
55608 }
55609 
55610 int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
55611 {
55612     if (x509 == NULL || t == NULL) {
55613         return WOLFSSL_FAILURE;
55614     }
55615 
55616     x509->notBefore.type = t->type;
55617     x509->notBefore.length = t->length;
55618 
55619     XMEMCPY(x509->notBefore.data, t->data, CTC_DATE_SIZE);
55620 
55621     return WOLFSSL_SUCCESS;
55622 }
55623 
55624 int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s)
55625 {
55626     WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber");
55627     if (!x509 || !s || s->length >= EXTERNAL_SERIAL_SIZE)
55628         return WOLFSSL_FAILURE;
55629 
55630     /* WOLFSSL_ASN1_INTEGER has type | size | data */
55631     if (s->length < 3) {
55632         return WOLFSSL_FAILURE;
55633     }
55634     XMEMCPY(x509->serial, s->data + 2, s->length - 2);
55635     x509->serialSz = s->length - 2;
55636     x509->serial[s->length] = 0;
55637 
55638     return WOLFSSL_SUCCESS;
55639 }
55640 
55641 
55642 int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
55643 {
55644     byte* p = NULL;
55645     int derSz = 0;
55646     WOLFSSL_ENTER("wolfSSL_X509_set_pubkey");
55647 
55648     if (cert == NULL || pkey == NULL)
55649         return WOLFSSL_FAILURE;
55650 
55651     /* Regenerate since pkey->pkey.ptr may contain private key */
55652     switch (pkey->type) {
55653 #if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA)
55654     case EVP_PKEY_RSA:
55655         {
55656             RsaKey* rsa;
55657 
55658             if (pkey->rsa == NULL || pkey->rsa->internal == NULL)
55659                 return WOLFSSL_FAILURE;
55660 
55661             rsa = (RsaKey*)pkey->rsa->internal;
55662             derSz = wc_RsaPublicKeyDerSize(rsa, 1);
55663             if (derSz <= 0)
55664                 return WOLFSSL_FAILURE;
55665 
55666             p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
55667             if (p == NULL)
55668                 return WOLFSSL_FAILURE;
55669 
55670             if ((derSz = wc_RsaKeyToPublicDer(rsa, p, derSz)) <= 0) {
55671                 XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
55672                 return WOLFSSL_FAILURE;
55673             }
55674             cert->pubKeyOID = RSAk;
55675         }
55676         break;
55677 #endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
55678 #if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
55679         defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA)
55680     case EVP_PKEY_DSA:
55681         {
55682             DsaKey* dsa;
55683 
55684             if (pkey->dsa == NULL || pkey->dsa->internal == NULL)
55685                 return WOLFSSL_FAILURE;
55686 
55687             dsa = (DsaKey*)pkey->dsa->internal;
55688             /* size of pub, priv, p, q, g + ASN.1 additional information */
55689             derSz = 5 * mp_unsigned_bin_size(&dsa->g) + MAX_ALGO_SZ;
55690             p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
55691             if (p == NULL)
55692                 return WOLFSSL_FAILURE;
55693 
55694             if ((derSz = wc_DsaKeyToPublicDer(dsa, p, derSz)) <= 0) {
55695                 XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
55696                 return WOLFSSL_FAILURE;
55697             }
55698             cert->pubKeyOID = RSAk;
55699         }
55700         break;
55701 #endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */
55702 #ifdef HAVE_ECC
55703     case EVP_PKEY_EC:
55704         {
55705             ecc_key* ecc;
55706 
55707             if (pkey->ecc == NULL || pkey->ecc->internal == NULL)
55708                 return WOLFSSL_FAILURE;
55709 
55710             ecc = (ecc_key*)pkey->ecc->internal;
55711             derSz = wc_EccPublicKeyDerSize(ecc, 1);
55712             if (derSz <= 0)
55713                 return WOLFSSL_FAILURE;
55714 
55715             p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
55716             if (p == NULL)
55717                 return WOLFSSL_FAILURE;
55718 
55719             if ((derSz = wc_EccPublicKeyToDer(ecc, p, derSz, 1)) <= 0) {
55720                 XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
55721                 return WOLFSSL_FAILURE;
55722             }
55723             cert->pubKeyOID = ECDSAk;
55724         }
55725         break;
55726 #endif
55727     default:
55728         return WOLFSSL_FAILURE;
55729     }
55730     cert->pubKey.buffer = p;
55731     cert->pubKey.length = derSz;
55732 
55733     return WOLFSSL_SUCCESS;
55734 }
55735 
55736 int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v)
55737 {
55738     WOLFSSL_ENTER("wolfSSL_X509_set_version");
55739     if ((x509 == NULL) || (v < 0) || (v > INT_MAX)) {
55740         return WOLFSSL_FAILURE;
55741     }
55742     x509->version = (int) v + 1;
55743 
55744     return WOLFSSL_SUCCESS;
55745 }
55746 
55747 #endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && WOLFSSL_CERT_GEN */
55748 
55749 #if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
55750     defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
55751 
55752 void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer,
55753         WOLFSSL_X509* subject, WOLFSSL_X509* req, WOLFSSL_X509_CRL* crl,
55754         int flag)
55755 {
55756     int ret = WOLFSSL_SUCCESS;
55757     WOLFSSL_ENTER("wolfSSL_X509V3_set_ctx");
55758     if (!ctx || !ctx->x509)
55759         return;
55760 
55761     if (!ctx->x509) {
55762         ctx->x509 = wolfSSL_X509_new();
55763         if (!ctx->x509)
55764             return;
55765     }
55766 
55767     /* Set parameters in ctx as long as ret == WOLFSSL_SUCCESS */
55768     if (issuer)
55769         ret = wolfSSL_X509_set_issuer_name(ctx->x509,&issuer->issuer);
55770 
55771     if (subject && ret == WOLFSSL_SUCCESS)
55772         ret = wolfSSL_X509_set_subject_name(ctx->x509,&subject->subject);
55773 
55774     if (req && ret == WOLFSSL_SUCCESS) {
55775         WOLFSSL_MSG("req not implemented.");
55776     }
55777 
55778     if (crl && ret == WOLFSSL_SUCCESS) {
55779         WOLFSSL_MSG("crl not implemented.");
55780     }
55781 
55782     if (flag && ret == WOLFSSL_SUCCESS) {
55783         WOLFSSL_MSG("flag not implemented.");
55784     }
55785 
55786     if (!ret) {
55787         WOLFSSL_MSG("Error setting WOLFSSL_X509V3_CTX parameters.");
55788     }
55789 }
55790 
55791 #ifndef NO_BIO
55792 int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out)
55793 {
55794     int derSz = 0;
55795     int ret = WOLFSSL_FAILURE;
55796     WOLFSSL_BIO* bio = NULL;
55797     WOLFSSL_ENTER("wolfSSL_i2d_X509_REQ");
55798 
55799     if (req == NULL || out == NULL) {
55800         return BAD_FUNC_ARG;
55801     }
55802 
55803     if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
55804         return WOLFSSL_FAILURE;
55805     }
55806 
55807     if (wolfSSL_i2d_X509_REQ_bio(bio, req) != WOLFSSL_SUCCESS) {
55808         WOLFSSL_MSG("wolfSSL_i2d_X509_REQ_bio error");
55809         goto cleanup;
55810     }
55811 
55812     derSz = wolfSSL_BIO_get_len(bio);
55813 
55814     if (*out == NULL) {
55815         *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
55816         if (!*out) {
55817             WOLFSSL_MSG("malloc error");
55818             ret = MEMORY_E;
55819             goto cleanup;
55820         }
55821     }
55822 
55823     if (wolfSSL_BIO_read(bio, *out, derSz) != derSz) {
55824         WOLFSSL_MSG("wolfSSL_BIO_read error");
55825         goto cleanup;
55826     }
55827 
55828     ret = derSz;
55829 cleanup:
55830     wolfSSL_BIO_free(bio);
55831 
55832     return ret;
55833 }
55834 #endif /* !NO_BIO */
55835 
55836 WOLFSSL_X509* wolfSSL_X509_REQ_new(void)
55837 {
55838     return wolfSSL_X509_new();
55839 }
55840 
55841 void wolfSSL_X509_REQ_free(WOLFSSL_X509* req)
55842 {
55843     wolfSSL_X509_free(req);
55844 }
55845 
55846 int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
55847                           const WOLFSSL_EVP_MD *md)
55848 {
55849     int ret;
55850     byte der[2048];
55851     int derSz = sizeof(der);
55852 
55853     if (req == NULL || pkey == NULL || md == NULL) {
55854         WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", BAD_FUNC_ARG);
55855         return WOLFSSL_FAILURE;
55856     }
55857 
55858     /* Create a Cert that has the certificate request fields. */
55859     req->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
55860     ret = wolfssl_x509_make_der(req, 1, der, &derSz, 0);
55861     if (ret != WOLFSSL_SUCCESS) {
55862         WOLFSSL_MSG("Unable to make DER for X509");
55863         WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", ret);
55864         return WOLFSSL_FAILURE;
55865     }
55866 
55867     if (wolfSSL_X509_resign_cert(req, 1, der, sizeof(der), derSz,
55868             (WOLFSSL_EVP_MD*)md, pkey) <= 0) {
55869         return WOLFSSL_FAILURE;
55870     }
55871     return WOLFSSL_SUCCESS;
55872 }
55873 
55874 int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req,
55875                               WOLFSSL_EVP_MD_CTX* md_ctx)
55876 {
55877     if (md_ctx && md_ctx->pctx)
55878         return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey,
55879                 wolfSSL_EVP_MD_CTX_md(md_ctx));
55880     else
55881         return WOLFSSL_FAILURE;
55882 }
55883 
55884 static int regenX509REQDerBuffer(WOLFSSL_X509* x509)
55885 {
55886     int derSz = X509_BUFFER_SZ;
55887     int ret = WOLFSSL_FAILURE;
55888 #ifdef WOLFSSL_SMALL_STACK
55889     byte* der;
55890     der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
55891     if (!der) {
55892         WOLFSSL_MSG("malloc failed");
55893         return WOLFSSL_FAILURE;
55894     }
55895 #else
55896     byte der[X509_BUFFER_SZ];
55897 #endif
55898 
55899     if (wolfssl_x509_make_der(x509, 1, der, &derSz, 0) == WOLFSSL_SUCCESS) {
55900         FreeDer(&x509->derCert);
55901         if (AllocDer(&x509->derCert, derSz, CERT_TYPE, x509->heap) == 0) {
55902             XMEMCPY(x509->derCert->buffer, der, derSz);
55903             ret = WOLFSSL_SUCCESS;
55904         }
55905         else {
55906             WOLFSSL_MSG("Failed to allocate DER buffer for X509");
55907         }
55908     }
55909     else {
55910         WOLFSSL_MSG("Unable to make DER for X509 REQ");
55911     }
55912 #ifdef WOLFSSL_SMALL_STACK
55913     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
55914 #endif
55915     return ret;
55916 }
55917 
55918 int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req,
55919         WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk)
55920 {
55921     if (!req || !ext_sk) {
55922         WOLFSSL_MSG("Bad parameter");
55923         return WOLFSSL_FAILURE;
55924     }
55925 
55926     while (ext_sk) {
55927         WOLFSSL_X509_EXTENSION* ext = ext_sk->data.ext;
55928 
55929         if (wolfSSL_X509_add_ext(req, ext, -1) != WOLFSSL_SUCCESS) {
55930             WOLFSSL_MSG("wolfSSL_X509_add_ext error");
55931             return WOLFSSL_FAILURE;
55932         }
55933 
55934         ext_sk = ext_sk->next;
55935     }
55936 
55937     return regenX509REQDerBuffer(req);
55938 }
55939 
55940 int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req,
55941                               const char *attrname, int type,
55942                               const unsigned char *bytes, int len)
55943 {
55944     WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_txt");
55945 
55946 #ifdef HAVE_LIBEST
55947     if (!req || !attrname || !bytes || type != MBSTRING_ASC) {
55948         WOLFSSL_MSG("Bad parameter");
55949         return WOLFSSL_FAILURE;
55950     }
55951 
55952     if (len < 0) {
55953         len = (int)XSTRLEN((char*)bytes);
55954     }
55955 
55956     /* For now just pretend that we support this for libest testing */
55957     if (len == XSTR_SIZEOF("1.3.6.1.1.1.1.22") &&
55958             XMEMCMP("1.3.6.1.1.1.1.22", bytes, len) == 0) {
55959         /* MAC Address */
55960     }
55961     else if (len == XSTR_SIZEOF("1.2.840.10045.2.1") &&
55962             XMEMCMP("1.2.840.10045.2.1", bytes, len) == 0) {
55963         /* ecPublicKey */
55964     }
55965     else if (len == XSTR_SIZEOF("1.2.840.10045.4.3.3") &&
55966             XMEMCMP("1.2.840.10045.4.3.3", bytes, len) == 0) {
55967         /* ecdsa-with-SHA384 */
55968     }
55969     else {
55970         return WOLFSSL_FAILURE;
55971     }
55972 
55973     /* return error if not built for libest */
55974     return WOLFSSL_SUCCESS;
55975 #else
55976     (void)req;
55977     (void)attrname;
55978     (void)type;
55979     (void)bytes;
55980     (void)len;
55981     return WOLFSSL_FAILURE;
55982 #endif
55983 }
55984 
55985 int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req,
55986                                       int nid, int type,
55987                                       const unsigned char *bytes,
55988                                       int len)
55989 {
55990     WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID");
55991 
55992     if (!req || !bytes || type != MBSTRING_ASC) {
55993         WOLFSSL_MSG("Bad parameter");
55994         return WOLFSSL_FAILURE;
55995     }
55996 
55997     switch (nid) {
55998     case NID_pkcs9_challengePassword:
55999         if (len < 0)
56000             len = (int)XSTRLEN((char*)bytes);
56001         if (len < CTC_NAME_SIZE) {
56002             XMEMCPY(req->challengePw, bytes, len);
56003             req->challengePw[len] = '\0';
56004         }
56005         else {
56006             WOLFSSL_MSG("Challenge password too long");
56007             return WOLFSSL_FAILURE;
56008         }
56009         if (req->challengePwAttr) {
56010             wolfSSL_X509_ATTRIBUTE_free(req->challengePwAttr);
56011         }
56012         req->challengePwAttr = wolfSSL_X509_ATTRIBUTE_new();
56013         if (req->challengePwAttr) {
56014             req->challengePwAttr->value->value.asn1_string =
56015                     wolfSSL_ASN1_STRING_new();
56016             if (wolfSSL_ASN1_STRING_set(
56017                     req->challengePwAttr->value->value.asn1_string,
56018                     bytes, len) != WOLFSSL_SUCCESS) {
56019                 WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
56020                 return WOLFSSL_FAILURE;
56021             }
56022             req->challengePwAttr->value->type = V_ASN1_PRINTABLESTRING;
56023         }
56024         else {
56025             WOLFSSL_MSG("wolfSSL_X509_ATTRIBUTE_new error");
56026             return WOLFSSL_FAILURE;
56027         }
56028         break;
56029     case NID_serialNumber:
56030         if (len < 0)
56031             len = (int)XSTRLEN((char*)bytes);
56032         if (len + 1 > EXTERNAL_SERIAL_SIZE) {
56033             WOLFSSL_MSG("SerialNumber too long");
56034             return WOLFSSL_FAILURE;
56035         }
56036         XMEMCPY(req->serial, bytes, len);
56037         req->serialSz = len;
56038         break;
56039     default:
56040         WOLFSSL_MSG("Unsupported attribute");
56041         return WOLFSSL_FAILURE;
56042     }
56043     return WOLFSSL_SUCCESS;
56044 }
56045 
56046 
56047 /* Return NID as the attr index */
56048 int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req,
56049         int nid, int lastpos)
56050 {
56051     WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr_by_NID");
56052 
56053     /* Since we only support 1 attr per attr type then a lastpos of >= 0
56054      * indicates that one was already returned */
56055     if (!req || lastpos >= 0) {
56056         WOLFSSL_MSG("Bad parameter");
56057         return WOLFSSL_FATAL_ERROR;
56058     }
56059 
56060     switch (nid) {
56061     case NID_pkcs9_challengePassword:
56062         return req->challengePwAttr ? nid : WOLFSSL_FATAL_ERROR;
56063     default:
56064         WOLFSSL_MSG("Unsupported attribute");
56065         return WOLFSSL_FATAL_ERROR;
56066     }
56067 }
56068 
56069 /**
56070  * @param req X509_REQ containing attribute
56071  * @param loc NID of the attribute to return
56072  */
56073 WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr(
56074         const WOLFSSL_X509 *req, int loc)
56075 {
56076     WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr");
56077 
56078     if (!req) {
56079         WOLFSSL_MSG("Bad parameter");
56080         return NULL;
56081     }
56082 
56083     switch (loc) {
56084     case NID_pkcs9_challengePassword:
56085         return req->challengePwAttr;
56086     default:
56087         WOLFSSL_MSG("Unsupported attribute");
56088         return NULL;
56089     }
56090 }
56091 
56092 WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void)
56093 {
56094     WOLFSSL_X509_ATTRIBUTE* ret;
56095     WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_new");
56096     ret = (WOLFSSL_X509_ATTRIBUTE*)XMALLOC(sizeof(WOLFSSL_X509_ATTRIBUTE),
56097             NULL, DYNAMIC_TYPE_OPENSSL);
56098     if (!ret) {
56099         WOLFSSL_MSG("malloc error");
56100         return NULL;
56101     }
56102     XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ATTRIBUTE));
56103     ret->object = wolfSSL_ASN1_OBJECT_new();
56104     ret->value = wolfSSL_ASN1_TYPE_new();
56105     /* Don't allocate ret->set since WOLFSSL_ASN1_TYPE
56106      * is not supported as a stack type */
56107     if (!ret->object || !ret->value) {
56108         WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new or wolfSSL_ASN1_TYPE_new error");
56109         wolfSSL_X509_ATTRIBUTE_free(ret);
56110         return NULL;
56111     }
56112     return ret;
56113 }
56114 
56115 void wolfSSL_X509_ATTRIBUTE_free(WOLFSSL_X509_ATTRIBUTE* attr)
56116 {
56117     WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_free");
56118     if (attr) {
56119         if (attr->object) {
56120             wolfSSL_ASN1_OBJECT_free(attr->object);
56121         }
56122         if (attr->value) {
56123             wolfSSL_ASN1_TYPE_free(attr->value);
56124         }
56125         if (attr->set) {
56126             wolfSSL_sk_pop_free(attr->set, NULL);
56127         }
56128         XFREE(attr, NULL, DYNAMIC_TYPE_OPENSSL);
56129     }
56130 }
56131 
56132 WOLFSSL_ASN1_TYPE *wolfSSL_X509_ATTRIBUTE_get0_type(
56133         WOLFSSL_X509_ATTRIBUTE *attr, int idx)
56134 {
56135     WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_get0_type");
56136 
56137     if (!attr || idx != 0) {
56138         WOLFSSL_MSG("Bad parameter");
56139         return NULL;
56140     }
56141 
56142     return attr->value;
56143 }
56144 
56145 WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x,
56146         WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md)
56147 {
56148     WOLFSSL_ENTER("wolfSSL_X509_to_X509_REQ");
56149     (void)pkey;
56150     (void)md;
56151     return wolfSSL_X509_dup(x);
56152 }
56153 
56154 int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req,
56155                                       WOLFSSL_X509_NAME *name)
56156 {
56157     return wolfSSL_X509_set_subject_name(req, name);
56158 }
56159 
56160 int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey)
56161 {
56162     return wolfSSL_X509_set_pubkey(req, pkey);
56163 }
56164 #endif /* OPENSSL_ALL && !NO_CERTS && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */
56165 
56166 #ifdef WOLFSSL_STATIC_EPHEMERAL
56167 int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr)
56168 {
56169     int ret;
56170     word32 idx = 0;
56171     DerBuffer* der = NULL;
56172 
56173     if (ssl == NULL || ssl->ctx == NULL || keyPtr == NULL) {
56174         return BAD_FUNC_ARG;
56175     }
56176 
56177 #ifndef SINGLE_THREADED
56178     if (!ssl->ctx->staticKELockInit) {
56179         return BUFFER_E; /* no keys set */
56180     }
56181     ret = wc_LockMutex(&ssl->ctx->staticKELock);
56182     if (ret != 0) {
56183         return ret;
56184     }
56185 #endif
56186 
56187     ret = BUFFER_E; /* set default error */
56188     switch (keyAlgo) {
56189     #ifndef NO_DH
56190         case WC_PK_TYPE_DH:
56191             if (ssl != NULL)
56192                 der = ssl->staticKE.dhKey;
56193             if (der == NULL)
56194                 der = ssl->ctx->staticKE.dhKey;
56195             if (der != NULL) {
56196                 DhKey* key = (DhKey*)keyPtr;
56197                 WOLFSSL_MSG("Using static DH key");
56198                 ret = wc_DhKeyDecode(der->buffer, &idx, key, der->length);
56199             }
56200             break;
56201     #endif
56202     #ifdef HAVE_ECC
56203         case WC_PK_TYPE_ECDH:
56204             if (ssl != NULL)
56205                 der = ssl->staticKE.ecKey;
56206             if (der == NULL)
56207                 der = ssl->ctx->staticKE.ecKey;
56208             if (der != NULL) {
56209                 ecc_key* key = (ecc_key*)keyPtr;
56210                 WOLFSSL_MSG("Using static ECDH key");
56211                 ret = wc_EccPrivateKeyDecode(der->buffer, &idx, key, der->length);
56212             }
56213             break;
56214     #endif
56215     #ifdef HAVE_CURVE25519
56216         case WC_PK_TYPE_CURVE25519:
56217             if (ssl != NULL)
56218                 der = ssl->staticKE.x25519Key;
56219             if (der == NULL)
56220                 der = ssl->ctx->staticKE.x25519Key;
56221             if (der != NULL) {
56222                 curve25519_key* key = (curve25519_key*)keyPtr;
56223                 WOLFSSL_MSG("Using static X25519 key");
56224                 ret = wc_Curve25519PrivateKeyDecode(der->buffer, &idx, key,
56225                     der->length);
56226             }
56227             break;
56228     #endif
56229     #ifdef HAVE_CURVE448
56230         case WC_PK_TYPE_CURVE448:
56231             if (ssl != NULL)
56232                 der = ssl->staticKE.x448Key;
56233             if (der == NULL)
56234                 der = ssl->ctx->staticKE.x448Key;
56235             if (der != NULL) {
56236                 curve448_key* key = (curve448_key*)keyPtr;
56237                 WOLFSSL_MSG("Using static X448 key");
56238                 ret = wc_Curve448PrivateKeyDecode(der->buffer, &idx, key,
56239                     der->length);
56240             }
56241             break;
56242     #endif
56243         default:
56244             /* not supported */
56245             ret = NOT_COMPILED_IN;
56246             break;
56247     }
56248 
56249 #ifndef SINGLE_THREADED
56250     wc_UnLockMutex(&ssl->ctx->staticKELock);
56251 #endif
56252     return ret;
56253 }
56254 
56255 static int SetStaticEphemeralKey(WOLFSSL_CTX* ctx,
56256     StaticKeyExchangeInfo_t* staticKE, int keyAlgo, const char* key,
56257     unsigned int keySz, int format, void* heap)
56258 {
56259     int ret = 0;
56260     DerBuffer* der = NULL;
56261     byte* keyBuf = NULL;
56262 #ifndef NO_FILESYSTEM
56263     const char* keyFile = NULL;
56264 #endif
56265 
56266     /* allow empty key to free buffer */
56267     if (staticKE == NULL || (key == NULL && keySz > 0)) {
56268         return BAD_FUNC_ARG;
56269     }
56270 
56271     WOLFSSL_ENTER("SetStaticEphemeralKey");
56272 
56273     /* if just free'ing key then skip loading */
56274     if (key != NULL) {
56275     #ifndef NO_FILESYSTEM
56276         /* load file from filesystem */
56277         if (key != NULL && keySz == 0) {
56278             size_t keyBufSz = 0;
56279             keyFile = (const char*)key;
56280             ret = wc_FileLoad(keyFile, &keyBuf, &keyBufSz, heap);
56281             if (ret != 0) {
56282                 return ret;
56283             }
56284             keySz = (unsigned int)keyBufSz;
56285         }
56286         else
56287     #endif
56288         {
56289             /* use as key buffer directly */
56290             keyBuf = (byte*)key;
56291         }
56292 
56293         if (format == WOLFSSL_FILETYPE_PEM) {
56294         #ifdef WOLFSSL_PEM_TO_DER
56295             int keyFormat = 0;
56296             ret = PemToDer(keyBuf, keySz, PRIVATEKEY_TYPE, &der,
56297                 heap, NULL, &keyFormat);
56298             /* auto detect key type */
56299             if (ret == 0 && keyAlgo == WC_PK_TYPE_NONE) {
56300                 if (keyFormat == ECDSAk)
56301                     keyAlgo = WC_PK_TYPE_ECDH;
56302                 else if (keyFormat == X25519k)
56303                     keyAlgo = WC_PK_TYPE_CURVE25519;
56304                 else
56305                     keyAlgo = WC_PK_TYPE_DH;
56306             }
56307         #else
56308             ret = NOT_COMPILED_IN;
56309         #endif
56310         }
56311         else {
56312             /* Detect PK type (if required) */
56313         #ifdef HAVE_ECC
56314             if (keyAlgo == WC_PK_TYPE_NONE) {
56315                 word32 idx = 0;
56316                 ecc_key eccKey;
56317                 ret = wc_ecc_init_ex(&eccKey, heap, INVALID_DEVID);
56318                 if (ret == 0) {
56319                     ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &eccKey, keySz);
56320                     if (ret == 0)
56321                         keyAlgo = WC_PK_TYPE_ECDH;
56322                     wc_ecc_free(&eccKey);
56323                 }
56324             }
56325         #endif
56326         #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
56327             if (keyAlgo == WC_PK_TYPE_NONE) {
56328                 word32 idx = 0;
56329                 DhKey dhKey;
56330                 ret = wc_InitDhKey_ex(&dhKey, heap, INVALID_DEVID);
56331                 if (ret == 0) {
56332                     ret = wc_DhKeyDecode(keyBuf, &idx, &dhKey, keySz);
56333                     if (ret == 0)
56334                         keyAlgo = WC_PK_TYPE_DH;
56335                     wc_FreeDhKey(&dhKey);
56336                 }
56337             }
56338         #endif
56339         #ifdef HAVE_CURVE25519
56340             if (keyAlgo == WC_PK_TYPE_NONE) {
56341                 word32 idx = 0;
56342                 curve25519_key x25519Key;
56343                 ret = wc_curve25519_init_ex(&x25519Key, heap, INVALID_DEVID);
56344                 if (ret == 0) {
56345                     ret = wc_Curve25519PrivateKeyDecode(keyBuf, &idx, &x25519Key,
56346                         keySz);
56347                     if (ret == 0)
56348                         keyAlgo = WC_PK_TYPE_CURVE25519;
56349                     wc_curve25519_free(&x25519Key);
56350                 }
56351             }
56352         #endif
56353         #ifdef HAVE_CURVE448
56354             if (keyAlgo == WC_PK_TYPE_NONE) {
56355                 word32 idx = 0;
56356                 curve448_key x448Key;
56357                 ret = wc_curve448_init(&x448Key);
56358                 if (ret == 0) {
56359                     ret = wc_Curve448PrivateKeyDecode(keyBuf, &idx, &x448Key,
56360                         keySz);
56361                     if (ret == 0)
56362                         keyAlgo = WC_PK_TYPE_CURVE448;
56363                     wc_curve448_free(&x448Key);
56364                 }
56365             }
56366         #endif
56367 
56368             if (keyAlgo != WC_PK_TYPE_NONE) {
56369                 ret = AllocDer(&der, keySz, PRIVATEKEY_TYPE, heap);
56370                 if (ret == 0) {
56371                     XMEMCPY(der->buffer, keyBuf, keySz);
56372                 }
56373             }
56374         }
56375     }
56376 
56377 #ifndef NO_FILESYSTEM
56378     /* done with keyFile buffer */
56379     if (keyFile && keyBuf) {
56380         XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
56381     }
56382 #endif
56383 
56384 #ifndef SINGLE_THREADED
56385     if (ret == 0 && !ctx->staticKELockInit) {
56386         ret = wc_InitMutex(&ctx->staticKELock);
56387         if (ret == 0) {
56388             ctx->staticKELockInit = 1;
56389         }
56390     }
56391 #endif
56392     if (ret == 0
56393     #ifndef SINGLE_THREADED
56394         && (ret = wc_LockMutex(&ctx->staticKELock)) == 0
56395     #endif
56396     ) {
56397         switch (keyAlgo) {
56398         #ifndef NO_DH
56399             case WC_PK_TYPE_DH:
56400                 FreeDer(&staticKE->dhKey);
56401                 staticKE->dhKey = der; der = NULL;
56402                 break;
56403         #endif
56404         #ifdef HAVE_ECC
56405             case WC_PK_TYPE_ECDH:
56406                 FreeDer(&staticKE->ecKey);
56407                 staticKE->ecKey = der; der = NULL;
56408                 break;
56409         #endif
56410         #ifdef HAVE_CURVE25519
56411             case WC_PK_TYPE_CURVE25519:
56412                 FreeDer(&staticKE->x25519Key);
56413                 staticKE->x25519Key = der; der = NULL;
56414                 break;
56415         #endif
56416         #ifdef HAVE_CURVE448
56417             case WC_PK_TYPE_CURVE448:
56418                 FreeDer(&staticKE->x448Key);
56419                 staticKE->x448Key = der; der = NULL;
56420                 break;
56421         #endif
56422             default:
56423                 /* not supported */
56424                 ret = NOT_COMPILED_IN;
56425                 break;
56426         }
56427 
56428     #ifndef SINGLE_THREADED
56429         wc_UnLockMutex(&ctx->staticKELock);
56430     #endif
56431     }
56432 
56433     if (ret != 0) {
56434         FreeDer(&der);
56435     }
56436 
56437     (void)ctx; /* not used for single threaded */
56438 
56439     WOLFSSL_LEAVE("SetStaticEphemeralKey", ret);
56440 
56441     return ret;
56442 }
56443 
56444 int wolfSSL_CTX_set_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
56445     const char* key, unsigned int keySz, int format)
56446 {
56447     if (ctx == NULL) {
56448         return BAD_FUNC_ARG;
56449     }
56450     return SetStaticEphemeralKey(ctx, &ctx->staticKE, keyAlgo,
56451         key, keySz, format, ctx->heap);
56452 }
56453 int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
56454     const char* key, unsigned int keySz, int format)
56455 {
56456     if (ssl == NULL || ssl->ctx == NULL) {
56457         return BAD_FUNC_ARG;
56458     }
56459     return SetStaticEphemeralKey(ssl->ctx, &ssl->staticKE, keyAlgo,
56460         key, keySz, format, ssl->heap);
56461 }
56462 
56463 static int GetStaticEphemeralKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
56464     int keyAlgo, const unsigned char** key, unsigned int* keySz)
56465 {
56466     int ret = 0;
56467     DerBuffer* der = NULL;
56468 
56469     if (key)   *key = NULL;
56470     if (keySz) *keySz = 0;
56471 
56472 #ifndef SINGLE_THREADED
56473     if (ctx->staticKELockInit &&
56474         (ret = wc_LockMutex(&ctx->staticKELock)) != 0) {
56475         return ret;
56476     }
56477 #endif
56478 
56479     switch (keyAlgo) {
56480     #ifndef NO_DH
56481         case WC_PK_TYPE_DH:
56482             if (ssl != NULL)
56483                 der = ssl->staticKE.dhKey;
56484             if (der == NULL)
56485                 der = ctx->staticKE.dhKey;
56486             break;
56487     #endif
56488     #ifdef HAVE_ECC
56489         case WC_PK_TYPE_ECDH:
56490             if (ssl != NULL)
56491                 der = ssl->staticKE.ecKey;
56492             if (der == NULL)
56493                 der = ctx->staticKE.ecKey;
56494             break;
56495     #endif
56496     #ifdef HAVE_CURVE25519
56497         case WC_PK_TYPE_CURVE25519:
56498             if (ssl != NULL)
56499                 der = ssl->staticKE.x25519Key;
56500             if (der == NULL)
56501                 der = ctx->staticKE.x25519Key;
56502             break;
56503     #endif
56504     #ifdef HAVE_CURVE448
56505         case WC_PK_TYPE_CURVE448:
56506             if (ssl != NULL)
56507                 der = ssl->staticKE.x448Key;
56508             if (der == NULL)
56509                 der = ctx->staticKE.x448Key;
56510             break;
56511     #endif
56512         default:
56513             /* not supported */
56514             ret = NOT_COMPILED_IN;
56515             break;
56516     }
56517 
56518     if (der) {
56519         if (key)
56520             *key = der->buffer;
56521         if (keySz)
56522             *keySz = der->length;
56523     }
56524 
56525 #ifndef SINGLE_THREADED
56526     wc_UnLockMutex(&ctx->staticKELock);
56527 #endif
56528 
56529     return ret;
56530 }
56531 
56532 /* returns pointer to currently loaded static ephemeral as ASN.1 */
56533 /* this can be converted to PEM using wc_DerToPem */
56534 int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
56535     const unsigned char** key, unsigned int* keySz)
56536 {
56537     if (ctx == NULL) {
56538         return BAD_FUNC_ARG;
56539     }
56540 
56541     return GetStaticEphemeralKey(ctx, NULL, keyAlgo, key, keySz);
56542 }
56543 int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
56544     const unsigned char** key, unsigned int* keySz)
56545 {
56546     if (ssl == NULL || ssl->ctx == NULL) {
56547         return BAD_FUNC_ARG;
56548     }
56549 
56550     return GetStaticEphemeralKey(ssl->ctx, ssl, keyAlgo, key, keySz);
56551 }
56552 
56553 #endif /* WOLFSSL_STATIC_EPHEMERAL */
56554 
56555 #if defined(OPENSSL_EXTRA)
56556 /* wolfSSL_THREADID_current is provided as a compat API with
56557  * CRYPTO_THREADID_current to register current thread id into given id object.
56558  * However, CRYPTO_THREADID_current API has been deprecated and no longer
56559  * exists in the OpenSSL 1.0.0 or later.This API only works as a stub
56560  * like as existing wolfSSL_THREADID_set_numeric.
56561  */
56562 void wolfSSL_THREADID_current(WOLFSSL_CRYPTO_THREADID* id)
56563 {
56564     (void)id;
56565     return;
56566 }
56567 /* wolfSSL_THREADID_hash is provided as a compatible API with
56568  * CRYPTO_THREADID_hash which returns a hash value calcurated from the
56569  * specified thread id. However, CRYPTO_THREADID_hash API has been
56570  * deprecated and no longer exists in the OpenSSL 1.0.0 or later.
56571  * This API only works as a stub to returns 0. This behavior is
56572  * equivalent to the latest OpenSSL CRYPTO_THREADID_hash.
56573  */
56574 unsigned long wolfSSL_THREADID_hash(const WOLFSSL_CRYPTO_THREADID* id)
56575 {
56576     (void)id;
56577     return 0UL;
56578 }
56579 /* wolfSSL_CTX_set_ecdh_auto is provided as compatible API with
56580  * SSL_CTX_set_ecdh_auto to enable auto ecdh curve selection functionality.
56581  * Since this functionality is enabled by default in wolfSSL,
56582  * this API exists as a stub.
56583  */
56584 int wolfSSL_CTX_set_ecdh_auto(WOLFSSL_CTX* ctx, int onoff)
56585 {
56586     (void)ctx;
56587     (void)onoff;
56588     return WOLFSSL_SUCCESS;
56589 }
56590 
56591 /**
56592  * set security level (wolfSSL doesn't support security level)
56593  * @param ctx  a pointer to WOLFSSL_EVP_PKEY_CTX structure
56594  * @param level security level
56595  */
56596 void wolfSSL_CTX_set_security_level(WOLFSSL_CTX* ctx, int level)
56597 {
56598     WOLFSSL_ENTER("wolfSSL_CTX_set_security_level");
56599     (void)ctx;
56600     (void)level;
56601 }
56602 /**
56603  * get security level (wolfSSL doesn't support security level)
56604  * @param ctx  a pointer to WOLFSSL_EVP_PKEY_CTX structure
56605  * @return always 0(level 0)
56606  */
56607 int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX* ctx)
56608 {
56609     WOLFSSL_ENTER("wolfSSL_CTX_get_security_level");
56610     (void)ctx;
56611     return 0;
56612 }
56613 
56614 
56615 /**
56616  * Determine whether a WOLFSSL_SESSION object can be used for resumption
56617  * @param s  a pointer to WOLFSSL_SESSION structure
56618  * @return return 1 if session is resumable, otherwise 0.
56619  */
56620 int wolfSSL_SESSION_is_resumable(const WOLFSSL_SESSION *s)
56621 {
56622     s = GetSessionPtr(s);
56623     if (s == NULL)
56624         return 0;
56625 
56626 #ifdef HAVE_SESSION_TICKET
56627     if (s->ticketLen > 0)
56628         return 1;
56629 #endif
56630 
56631     if (s->sessionIDSz > 0)
56632         return 1;
56633 
56634     return 0;
56635 }
56636 
56637 #if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
56638 /*
56639  * This API accepts a user callback which puts key-log records into
56640  * a KEY LOGFILE. The callback is stored into a CTX and propagated to
56641  * each SSL object on its creation timing.
56642  */
56643 void wolfSSL_CTX_set_keylog_callback(WOLFSSL_CTX* ctx, wolfSSL_CTX_keylog_cb_func cb)
56644 {
56645     WOLFSSL_ENTER("wolfSSL_CTX_set_keylog_callback");
56646   /* stores the callback into WOLFSSL_CTX */
56647     if (ctx != NULL) {
56648         ctx->keyLogCb = cb;
56649     }
56650 }
56651 wolfSSL_CTX_keylog_cb_func wolfSSL_CTX_get_keylog_callback(
56652     const WOLFSSL_CTX* ctx)
56653 {
56654     WOLFSSL_ENTER("wolfSSL_CTX_get_keylog_callback");
56655     if (ctx != NULL)
56656         return ctx->keyLogCb;
56657     else
56658         return NULL;
56659 }
56660 #endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
56661 
56662 /**
56663  * Return DH p, q and g parameters
56664  * @param dh a pointer to WOLFSSL_DH
56665  * @param p  a pointer to WOLFSSL_BIGNUM to be obtained from dh
56666  * @param q  a pointer to WOLFSSL_BIGNUM to be obtained from dh
56667  * @param g  a pointer to WOLFSSL_BIGNUM to be obtained from dh
56668  */
56669 void wolfSSL_DH_get0_pqg(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **p,
56670                     const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g)
56671 {
56672     WOLFSSL_ENTER("wolfSSL_DH_get0_pqg");
56673     if (dh == NULL)
56674         return;
56675 
56676     if (p != NULL)
56677         *p = dh->p;
56678     if (q != NULL)
56679         *q = dh->q;
56680     if (g != NULL)
56681         *g = dh->g;
56682 }
56683 
56684 #endif /* OPENSSL_EXTRA */
56685 
56686 /*******************************************************************************
56687  * START OF standard C library wrapping APIs
56688  ******************************************************************************/
56689 #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
56690                              defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
56691                              defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
56692 #ifndef NO_WOLFSSL_STUB
56693 int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
56694                                 void *(*r) (void *, size_t, const char *,
56695                                             int), void (*f) (void *))
56696 {
56697     (void) m;
56698     (void) r;
56699     (void) f;
56700     WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
56701     WOLFSSL_STUB("CRYPTO_set_mem_ex_functions");
56702 
56703     return WOLFSSL_FAILURE;
56704 }
56705 #endif
56706 #endif
56707 
56708 #if defined(OPENSSL_EXTRA)
56709 
56710 /**
56711  * free allocated memory resouce
56712  * @param str  a pointer to resource to be freed
56713  * @param file dummy argument
56714  * @param line dummy argument
56715  */
56716 void wolfSSL_CRYPTO_free(void *str, const char *file, int line)
56717 {
56718     (void)file;
56719     (void)line;
56720     XFREE(str, 0, DYNAMIC_TYPE_TMP_BUFFER);
56721 }
56722 /**
56723  * allocate memory with size of num
56724  * @param num  size of memory allocation to be malloced
56725  * @param file dummy argument
56726  * @param line dummy argument
56727  * @return a pointer to allocated memory on succssesful, otherwise NULL
56728  */
56729 void *wolfSSL_CRYPTO_malloc(size_t num, const char *file, int line)
56730 {
56731     (void)file;
56732     (void)line;
56733     return XMALLOC(num, 0, DYNAMIC_TYPE_TMP_BUFFER);
56734 }
56735 
56736 size_t wolfSSL_strlcpy(char *dst, const char *src, size_t dstSize)
56737 {
56738     size_t i;
56739 
56740     if (!dstSize || !dst || !src)
56741         return 0;
56742 
56743     /* Always have to leave a space for NULL */
56744     for (i = 0; i < (dstSize - 1) && *src != '\0'; i++) {
56745         *dst++ = *src++;
56746     }
56747     *dst = '\0';
56748 
56749     return i; /* return length without NULL */
56750 }
56751 
56752 size_t wolfSSL_strlcat(char *dst, const char *src, size_t dstSize)
56753 {
56754     size_t dstLen;
56755 
56756     if (!dstSize)
56757         return 0;
56758 
56759     dstLen = XSTRLEN(dst);
56760 
56761     if (dstSize < dstLen)
56762         return dstLen + XSTRLEN(src);
56763 
56764     return dstLen + wolfSSL_strlcpy(dst + dstLen, src, dstSize - dstLen);
56765 
56766 }
56767 
56768 #endif
56769 
56770 /*******************************************************************************
56771  * END OF standard C library wrapping APIs
56772  ******************************************************************************/
56773 
56774 /*******************************************************************************
56775  * START OF EX_DATA APIs
56776  ******************************************************************************/
56777 #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
56778                              defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
56779                              defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
56780 void wolfSSL_CRYPTO_cleanup_all_ex_data(void){
56781     WOLFSSL_ENTER("CRYPTO_cleanup_all_ex_data");
56782 }
56783 #endif
56784 
56785 #ifdef HAVE_EX_DATA
56786 void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx)
56787 {
56788     WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
56789 #ifdef MAX_EX_DATA
56790     if(ex_data && idx < MAX_EX_DATA && idx >= 0) {
56791         return ex_data->ex_data[idx];
56792     }
56793 #else
56794     (void)ex_data;
56795     (void)idx;
56796 #endif
56797     return NULL;
56798 }
56799 
56800 int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx, void *data)
56801 {
56802     WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data");
56803 #ifdef MAX_EX_DATA
56804     if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
56805 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
56806         if (ex_data->ex_data_cleanup_routines[idx]) {
56807             if (ex_data->ex_data[idx])
56808                 ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
56809             ex_data->ex_data_cleanup_routines[idx] = NULL;
56810         }
56811 #endif
56812         ex_data->ex_data[idx] = data;
56813         return WOLFSSL_SUCCESS;
56814     }
56815 #else
56816     (void)ex_data;
56817     (void)idx;
56818     (void)data;
56819 #endif
56820     return WOLFSSL_FAILURE;
56821 }
56822 
56823 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
56824 int wolfSSL_CRYPTO_set_ex_data_with_cleanup(
56825     WOLFSSL_CRYPTO_EX_DATA* ex_data,
56826     int idx,
56827     void *data,
56828     wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
56829 {
56830     WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data_with_cleanup");
56831     if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
56832         if (ex_data->ex_data_cleanup_routines[idx] && ex_data->ex_data[idx])
56833             ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
56834         ex_data->ex_data[idx] = data;
56835         ex_data->ex_data_cleanup_routines[idx] = cleanup_routine;
56836         return WOLFSSL_SUCCESS;
56837     }
56838     return WOLFSSL_FAILURE;
56839 }
56840 #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
56841 
56842 /**
56843  * Issues unique index for the class specified by class_index.
56844  * Other parameter except class_index are ignored.
56845  * Currently, following class_index are accepted:
56846  *  - CRYPTO_EX_INDEX_SSL
56847  *  - CRYPTO_EX_INDEX_SSL_CTX
56848  *  - CRYPTO_EX_INDEX_X509
56849  * @param class_index index one of CRYPTO_EX_INDEX_xxx
56850  * @param argp  parameters to be saved
56851  * @param argl  parameters to be saved
56852  * @param new_func a pointer to WOLFSSL_CRYPTO_EX_new
56853  * @param dup_func a pointer to WOLFSSL_CRYPTO_EX_dup
56854  * @param free_func a pointer to WOLFSSL_CRYPTO_EX_free
56855  * @return index value grater or equal to zero on success, -1 on failure.
56856  */
56857 int wolfSSL_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
56858                                            WOLFSSL_CRYPTO_EX_new* new_func,
56859                                            WOLFSSL_CRYPTO_EX_dup* dup_func,
56860                                            WOLFSSL_CRYPTO_EX_free* free_func)
56861 {
56862     WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_new_index");
56863     (void)argl;
56864     (void)argp;
56865     (void)new_func;
56866     (void)dup_func;
56867     (void)free_func;
56868 
56869     return get_ex_new_index(class_index);
56870 }
56871 #endif /* HAVE_EX_DATA */
56872 
56873 /*******************************************************************************
56874  * END OF EX_DATA APIs
56875  ******************************************************************************/
56876 
56877 /*******************************************************************************
56878  * START OF BUF_MEM API
56879  ******************************************************************************/
56880 
56881 #if defined(OPENSSL_EXTRA)
56882 
56883 /* Begin functions for openssl/buffer.h */
56884 WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void)
56885 {
56886     WOLFSSL_BUF_MEM* buf;
56887     buf = (WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), NULL,
56888                                                         DYNAMIC_TYPE_OPENSSL);
56889     if (buf) {
56890         XMEMSET(buf, 0, sizeof(WOLFSSL_BUF_MEM));
56891     }
56892     return buf;
56893 }
56894 
56895 
56896 /* returns length of buffer on success */
56897 int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len)
56898 {
56899     int len_int = (int)len;
56900     int mx;
56901 
56902     /* verify provided arguments */
56903     if (buf == NULL || len_int < 0) {
56904         return 0; /* BAD_FUNC_ARG; */
56905     }
56906 
56907     /* check to see if fits in existing length */
56908     if (buf->length > len) {
56909         buf->length = len;
56910         return len_int;
56911     }
56912 
56913     /* check to see if fits in max buffer */
56914     if (buf->max >= len) {
56915         if (buf->data != NULL) {
56916             XMEMSET(&buf->data[buf->length], 0, len - buf->length);
56917         }
56918         buf->length = len;
56919         return len_int;
56920     }
56921 
56922     /* expand size, to handle growth */
56923     mx = (len_int + 3) / 3 * 4;
56924 
56925     /* use realloc */
56926     buf->data = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
56927     if (buf->data == NULL) {
56928         return 0; /* ERR_R_MALLOC_FAILURE; */
56929     }
56930 
56931     buf->max = mx;
56932     XMEMSET(&buf->data[buf->length], 0, len - buf->length);
56933     buf->length = len;
56934 
56935     return len_int;
56936 }
56937 
56938 void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf)
56939 {
56940     if (buf) {
56941         if (buf->data) {
56942             XFREE(buf->data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
56943             buf->data = NULL;
56944         }
56945         buf->max = 0;
56946         buf->length = 0;
56947         XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
56948     }
56949 }
56950 /* End Functions for openssl/buffer.h */
56951 
56952 #endif /* OPENSSL_EXTRA */
56953 
56954 /*******************************************************************************
56955  * END OF BUF_MEM API
56956  ******************************************************************************/
56957 
56958 /*******************************************************************************
56959  * START OF TXT_DB API
56960  ******************************************************************************/
56961 
56962 #if defined(OPENSSL_ALL) && !defined(NO_BIO)
56963 /**
56964  * This function reads a tab delimetered CSV input and returns
56965  * a populated WOLFSSL_TXT_DB structure.
56966  * @param in Tab delimetered CSV input
56967  * @param num Number of fields in each row.
56968  * @return
56969  */
56970 WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num)
56971 {
56972     WOLFSSL_TXT_DB *ret = NULL;
56973     char *buf = NULL;
56974     char *bufEnd = NULL;
56975     char *idx = NULL;
56976     char* lineEnd = NULL;
56977     int bufSz;
56978     int failed = 1;
56979     /* Space in front of str reserved for field pointers + \0 */
56980     int fieldsSz = (num + 1) * sizeof(char *);
56981     WOLFSSL_ENTER("wolfSSL_TXT_DB_read");
56982 
56983     if (!in || num <= 0 || num > WOLFSSL_TXT_DB_MAX_FIELDS) {
56984         WOLFSSL_MSG("Bad parameter or too many fields");
56985         return NULL;
56986     }
56987 
56988     if (!(ret = (WOLFSSL_TXT_DB*)XMALLOC(sizeof(WOLFSSL_TXT_DB), NULL,
56989             DYNAMIC_TYPE_OPENSSL))) {
56990         WOLFSSL_MSG("malloc error");
56991         goto error;
56992     }
56993     XMEMSET (ret, 0, sizeof(WOLFSSL_TXT_DB));
56994     ret->num_fields = num;
56995 
56996     if (!(ret->data = wolfSSL_sk_WOLFSSL_STRING_new())) {
56997         WOLFSSL_MSG("wolfSSL_sk_WOLFSSL_STRING_new error");
56998         goto error;
56999     }
57000 
57001     bufSz = wolfSSL_BIO_get_len(in);
57002     if (bufSz <= 0 ||
57003             !(buf = (char*)XMALLOC(bufSz+1, NULL,
57004                     DYNAMIC_TYPE_TMP_BUFFER))) {
57005         WOLFSSL_MSG("malloc error or no data in BIO");
57006         goto error;
57007     }
57008 
57009     if (wolfSSL_BIO_read(in, buf, bufSz) != bufSz) {
57010         WOLFSSL_MSG("malloc error or no data in BIO");
57011         goto error;
57012     }
57013 
57014     buf[bufSz] = '\0';
57015     idx = buf;
57016     for (bufEnd = buf + bufSz; idx < bufEnd; idx = lineEnd + 1) {
57017         char* strBuf = NULL;
57018         char** fieldPtr = NULL;
57019         int fieldPtrIdx = 0;
57020         char* fieldCheckIdx = NULL;
57021         lineEnd = XSTRNSTR(idx, "\n", (unsigned int)(bufEnd - idx));
57022         if (!lineEnd)
57023             lineEnd = bufEnd;
57024         if (idx == lineEnd) /* empty line */
57025             continue;
57026         if (*idx == '#')
57027             continue;
57028         *lineEnd = '\0';
57029         strBuf = (char*)XMALLOC(fieldsSz + lineEnd - idx + 1, NULL,
57030                                 DYNAMIC_TYPE_OPENSSL);
57031         if (!strBuf) {
57032             WOLFSSL_MSG("malloc error");
57033             goto error;
57034         }
57035         XMEMCPY(strBuf + fieldsSz, idx, lineEnd - idx + 1); /* + 1 for NULL */
57036         XMEMSET(strBuf, 0, fieldsSz);
57037         /* Check for appropriate number of fields */
57038         fieldPtr = (char**)strBuf;
57039         fieldCheckIdx = strBuf + fieldsSz;
57040         fieldPtr[fieldPtrIdx++] = fieldCheckIdx;
57041         while (*fieldCheckIdx != '\0') {
57042             /* Handle escaped tabs */
57043             if (*fieldCheckIdx == '\t' && fieldCheckIdx[-1] != '\\') {
57044                 fieldPtr[fieldPtrIdx++] = fieldCheckIdx + 1;
57045                 *fieldCheckIdx = '\0';
57046                 if (fieldPtrIdx > num) {
57047                     WOLFSSL_MSG("too many fields");
57048                     XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL);
57049                     goto error;
57050                 }
57051             }
57052             fieldCheckIdx++;
57053         }
57054         if (fieldPtrIdx != num) {
57055             WOLFSSL_MSG("wrong number of fields");
57056             XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL);
57057             goto error;
57058         }
57059         if (wolfSSL_sk_push(ret->data, strBuf) != WOLFSSL_SUCCESS) {
57060             WOLFSSL_MSG("wolfSSL_sk_push error");
57061             XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL);
57062             goto error;
57063         }
57064     }
57065 
57066     failed = 0;
57067 error:
57068     if (failed && ret) {
57069         XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL);
57070         ret = NULL;
57071     }
57072     if (buf) {
57073         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
57074     }
57075     return ret;
57076 }
57077 
57078 long wolfSSL_TXT_DB_write(WOLFSSL_BIO *out, WOLFSSL_TXT_DB *db)
57079 {
57080     const WOLF_STACK_OF(WOLFSSL_STRING)* data;
57081     long totalLen = 0;
57082     char buf[512]; /* Should be more than enough for a single row */
57083     char* bufEnd = buf + sizeof(buf);
57084     int sz;
57085     int i;
57086 
57087     WOLFSSL_ENTER("wolfSSL_TXT_DB_write");
57088 
57089     if (!out || !db || !db->num_fields) {
57090         WOLFSSL_MSG("Bad parameter");
57091         return WOLFSSL_FAILURE;
57092     }
57093 
57094     data = db->data;
57095     while (data) {
57096         char** fields = (char**)data->data.string;
57097         char* idx = buf;
57098 
57099         if (!fields) {
57100             WOLFSSL_MSG("Missing row");
57101             return WOLFSSL_FAILURE;
57102         }
57103 
57104         for (i = 0; i < db->num_fields; i++) {
57105             const char* fieldValue = fields[i];
57106             if (!fieldValue) {
57107                 fieldValue = "";
57108             }
57109 
57110             /* Copy over field escaping tabs */
57111             while (*fieldValue != '\0') {
57112                 if (idx+1 < bufEnd) {
57113                     if (*fieldValue == '\t')
57114                         *idx++ = '\\';
57115                     *idx++ = *fieldValue++;
57116                 }
57117                 else {
57118                     WOLFSSL_MSG("Data row is too big");
57119                     return WOLFSSL_FAILURE;
57120                 }
57121             }
57122             if (idx < bufEnd) {
57123                 *idx++ = '\t';
57124             }
57125             else {
57126                 WOLFSSL_MSG("Data row is too big");
57127                 return WOLFSSL_FAILURE;
57128             }
57129         }
57130         idx[-1] = '\n';
57131         sz = (int)(idx - buf);
57132 
57133         if (wolfSSL_BIO_write(out, buf, sz) != sz) {
57134             WOLFSSL_MSG("wolfSSL_BIO_write error");
57135             return WOLFSSL_FAILURE;
57136         }
57137         totalLen += sz;
57138 
57139         data = data->next;
57140     }
57141 
57142     return totalLen;
57143 }
57144 
57145 int wolfSSL_TXT_DB_insert(WOLFSSL_TXT_DB *db, WOLFSSL_STRING *row)
57146 {
57147     WOLFSSL_ENTER("wolfSSL_TXT_DB_insert");
57148 
57149     if (!db || !row || !db->data) {
57150         WOLFSSL_MSG("Bad parameter");
57151         return WOLFSSL_FAILURE;
57152     }
57153 
57154     if (wolfSSL_sk_push(db->data, row) != WOLFSSL_SUCCESS) {
57155         WOLFSSL_MSG("wolfSSL_sk_push error");
57156         return WOLFSSL_FAILURE;
57157     }
57158 
57159     return WOLFSSL_SUCCESS;
57160 }
57161 
57162 void wolfSSL_TXT_DB_free(WOLFSSL_TXT_DB *db)
57163 {
57164     WOLFSSL_ENTER("wolfSSL_TXT_DB_free");
57165     if (db) {
57166         if (db->data) {
57167             wolfSSL_sk_pop_free(db->data, NULL);
57168         }
57169         XFREE(db, NULL, DYNAMIC_TYPE_OPENSSL);
57170     }
57171 }
57172 
57173 int wolfSSL_TXT_DB_create_index(WOLFSSL_TXT_DB *db, int field,
57174         void* qual, wolf_sk_hash_cb hash, wolf_sk_compare_cb cmp)
57175 {
57176     WOLFSSL_ENTER("wolfSSL_TXT_DB_create_index");
57177     (void)qual;
57178 
57179     if (!db || !hash || !cmp || field >= db->num_fields || field < 0) {
57180         WOLFSSL_MSG("Bad parameter");
57181         return WOLFSSL_FAILURE;
57182     }
57183 
57184     db->hash_fn[field] = hash;
57185     db->comp[field] = cmp;
57186 
57187     return WOLFSSL_SUCCESS;
57188 }
57189 
57190 WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, int idx,
57191         WOLFSSL_STRING *value)
57192 {
57193     WOLFSSL_ENTER("wolfSSL_TXT_DB_get_by_index");
57194 
57195     if (!db || !db->data || idx < 0 || idx >= db->num_fields) {
57196         WOLFSSL_MSG("Bad parameter");
57197         return NULL;
57198     }
57199 
57200     if (!db->hash_fn[idx] || !db->comp[idx]) {
57201         WOLFSSL_MSG("Missing hash or cmp functions");
57202         return NULL;
57203     }
57204 
57205     /* If first data struct has correct hash and cmp function then
57206      * assume others do too */
57207     if (db->data->hash_fn != db->hash_fn[idx] ||
57208             db->data->comp != db->comp[idx]) {
57209         /* Set the hash and comp functions */
57210         WOLF_STACK_OF(WOLFSSL_STRING)* data = db->data;
57211         while (data) {
57212             if (data->comp != db->comp[idx] ||
57213                     data->hash_fn != db->hash_fn[idx]) {
57214                 data->comp = db->comp[idx];
57215                 data->hash_fn = db->hash_fn[idx];
57216                 data->hash = 0;
57217             }
57218             data= data->next;
57219         }
57220     }
57221     return (WOLFSSL_STRING*) wolfSSL_lh_retrieve(db->data, value);
57222 }
57223 
57224 #endif /* OPENSSL_ALL && !NO_BIO */
57225 
57226 /*******************************************************************************
57227  * END OF TXT_DB API
57228  ******************************************************************************/
57229 
57230 /*******************************************************************************
57231  * START OF CONF API
57232  ******************************************************************************/
57233 
57234 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
57235  || defined(HAVE_STUNNEL)
57236 #ifndef NO_WOLFSSL_STUB
57237 void wolfSSL_OPENSSL_config(char *config_name)
57238 {
57239     (void)config_name;
57240     WOLFSSL_STUB("OPENSSL_config");
57241 }
57242 #endif /* !NO_WOLFSSL_STUB */
57243 #endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || HAVE_STUNNEL*/
57244 
57245 #if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && defined(OPENSSL_ALL)
57246 
57247 /**
57248  * This is the same hashing algo for WOLFSSL_CONF_VALUE as OpenSSL
57249  */
57250 static unsigned long wolfSSL_CONF_VALUE_hash(const WOLFSSL_CONF_VALUE *val)
57251 {
57252     if (val)
57253         return (wolfSSL_LH_strhash(val->section) << 2) ^
57254                 wolfSSL_LH_strhash(val->name);
57255     else
57256         return 0;
57257 }
57258 
57259 static int wolfssl_conf_value_cmp(const WOLFSSL_CONF_VALUE *a,
57260                                   const WOLFSSL_CONF_VALUE *b)
57261 {
57262     int cmp_val;
57263 
57264     if (!a || !b) {
57265         return WOLFSSL_FATAL_ERROR;
57266     }
57267 
57268     if (a->section != b->section) {
57269         if ((cmp_val = XSTRCMP(a->section, b->section)) != 0) {
57270             return cmp_val;
57271         }
57272     }
57273 
57274     if (a->name && b->name) {
57275         return XSTRCMP(a->name, b->name);
57276     }
57277     else if (a->name == b->name) {
57278         return 0;
57279     }
57280     else {
57281         return a->name ? 1 : -1;
57282     }
57283 }
57284 
57285 /* Use SHA for hashing as OpenSSL uses a hash algorithm that is
57286  * "not as good as MD5, but still good" so using SHA should be more
57287  * than good enough for this application. The produced hashes don't
57288  * need to line up between OpenSSL and wolfSSL. The hashes are for
57289  * internal indexing only */
57290 unsigned long wolfSSL_LH_strhash(const char *str)
57291 {
57292     unsigned long ret = 0;
57293 #ifndef NO_SHA
57294     wc_Sha sha;
57295     int strLen;
57296     byte digest[WC_SHA_DIGEST_SIZE];
57297 #endif
57298     WOLFSSL_ENTER("wolfSSL_LH_strhash");
57299 
57300     if (!str)
57301         return 0;
57302 
57303 #ifndef NO_SHA
57304     strLen = (int)XSTRLEN(str);
57305 
57306     if (wc_InitSha_ex(&sha, NULL, 0) != 0) {
57307         WOLFSSL_MSG("SHA1 Init failed");
57308         return 0;
57309     }
57310 
57311     ret = wc_ShaUpdate(&sha, (const byte *)str, (word32)strLen);
57312     if (ret != 0) {
57313         WOLFSSL_MSG("SHA1 Update failed");
57314     } else {
57315         ret = wc_ShaFinal(&sha, digest);
57316         if (ret != 0) {
57317             WOLFSSL_MSG("SHA1 Final failed");
57318         }
57319     }
57320     wc_ShaFree(&sha);
57321     if (ret != 0)
57322         return 0;
57323 
57324     /* Take first 4 bytes in small endian as unsigned long */
57325     ret  =  (unsigned int)digest[0];
57326     ret |= ((unsigned int)digest[1] << 8 );
57327     ret |= ((unsigned int)digest[2] << 16);
57328     ret |= ((unsigned int)digest[3] << 24);
57329 #else
57330     WOLFSSL_MSG("No SHA available for wolfSSL_LH_strhash");
57331 #endif
57332     return ret;
57333 }
57334 
57335 WOLFSSL_CONF_VALUE *wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(
57336         WOLF_LHASH_OF(WOLFSSL_CONF_VALUE) *sk, WOLFSSL_CONF_VALUE *data)
57337 {
57338     WOLFSSL_ENTER("wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve");
57339 
57340     if (!sk || !data) {
57341         WOLFSSL_MSG("Bad parameter");
57342         return NULL;
57343     }
57344 
57345     return (WOLFSSL_CONF_VALUE*)wolfSSL_lh_retrieve(sk, data);
57346 }
57347 
57348 int wolfSSL_CONF_modules_load(const WOLFSSL_CONF *cnf, const char *appname,
57349                       unsigned long flags)
57350 {
57351     WOLFSSL_ENTER("wolfSSL_CONF_modules_load");
57352     WOLFSSL_MSG("All wolfSSL modules are already compiled in. "
57353                 "wolfSSL_CONF_modules_load doesn't load anything new.");
57354     (void)cnf;
57355     (void)appname;
57356     (void)flags;
57357     return WOLFSSL_SUCCESS;
57358 }
57359 
57360 WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new(void)
57361 {
57362     WOLFSSL_CONF_VALUE* ret;
57363 
57364     WOLFSSL_ENTER("wolfSSL_CONF_new");
57365 
57366     ret = (WOLFSSL_CONF_VALUE*)XMALLOC(sizeof(WOLFSSL_CONF_VALUE),
57367             NULL, DYNAMIC_TYPE_OPENSSL);
57368     if (ret)
57369         XMEMSET(ret, 0, sizeof(WOLFSSL_CONF_VALUE));
57370     return ret;
57371 }
57372 
57373 int wolfSSL_CONF_add_string(WOLFSSL_CONF *conf,
57374         WOLFSSL_CONF_VALUE *section, WOLFSSL_CONF_VALUE *value)
57375 {
57376     WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
57377 
57378     if (!conf || !section || !value) {
57379         WOLFSSL_MSG("Bad parameter");
57380         return WOLFSSL_FAILURE;
57381     }
57382 
57383     sk = (WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *)section->value;
57384     value->section = section->section;
57385 
57386     if (wolfSSL_sk_CONF_VALUE_push(sk, value) != WOLFSSL_SUCCESS) {
57387         WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error");
57388         return WOLFSSL_FAILURE;
57389     }
57390     if (wolfSSL_sk_CONF_VALUE_push(conf->data, value) != WOLFSSL_SUCCESS) {
57391         WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error");
57392         return WOLFSSL_FAILURE;
57393     }
57394 
57395     return WOLFSSL_SUCCESS;
57396 }
57397 
57398 WOLFSSL_CONF_VALUE *wolfSSL_CONF_new_section(WOLFSSL_CONF *conf,
57399         const char *section)
57400 {
57401     WOLFSSL_CONF_VALUE* ret = NULL;
57402     WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
57403     int slen;
57404 
57405     WOLFSSL_ENTER("wolfSSL_CONF_new_section");
57406 
57407     if (!conf || !section) {
57408         WOLFSSL_MSG("Bad parameter");
57409         return NULL;
57410     }
57411 
57412     slen = (int)XSTRLEN(section);
57413 
57414     if (!(ret = wolfSSL_CONF_VALUE_new())) {
57415         WOLFSSL_MSG("wolfSSL_CONF_new error");
57416         goto error;
57417     }
57418 
57419     if (!(ret->section = (char*)XMALLOC(slen+1, NULL, DYNAMIC_TYPE_OPENSSL))) {
57420         WOLFSSL_MSG("section malloc error");
57421         goto error;
57422     }
57423     XMEMCPY(ret->section, section, slen+1);
57424 
57425     if (!(sk = wolfSSL_sk_CONF_VALUE_new(NULL))) {
57426         WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_new error");
57427         goto error;
57428     }
57429 
57430     ret->value = (char*)sk;
57431 
57432     if (wolfSSL_sk_CONF_VALUE_push(conf->data, ret) != WOLFSSL_SUCCESS) {
57433         WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error");
57434         goto error;
57435     }
57436 
57437     return ret;
57438 error:
57439     if (ret) {
57440         /* NULL so that wolfSSL_X509V3_conf_free doesn't attempt to free it */
57441         ret->value = NULL;
57442         wolfSSL_X509V3_conf_free(ret);
57443     }
57444     if (sk) {
57445         wolfSSL_sk_CONF_VALUE_free(sk);
57446     }
57447     return NULL;
57448 }
57449 
57450 WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf,
57451         const char *section)
57452 {
57453     WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
57454 
57455     WOLFSSL_ENTER("wolfSSL_CONF_get_section");
57456 
57457     if (!conf || !section) {
57458         WOLFSSL_MSG("Bad parameter");
57459         return NULL;
57460     }
57461 
57462     sk = conf->data;
57463 
57464     while (sk) {
57465         WOLFSSL_CONF_VALUE* val = sk->data.conf;
57466         if (val) {
57467             if (!val->name && XSTRCMP(section, val->section) == 0) {
57468                 return val;
57469             }
57470         }
57471         sk = sk->next;
57472     }
57473 
57474     return NULL;
57475 }
57476 
57477 WOLFSSL_CONF *wolfSSL_NCONF_new(void *meth)
57478 {
57479     WOLFSSL_CONF* ret;
57480     WOLFSSL_ENTER("wolfSSL_NCONF_new");
57481 
57482     if (meth) {
57483         WOLFSSL_MSG("wolfSSL does not support CONF_METHOD");
57484     }
57485 
57486     ret = (WOLFSSL_CONF*)XMALLOC(sizeof(WOLFSSL_CONF), NULL, DYNAMIC_TYPE_OPENSSL);
57487     if (ret) {
57488         XMEMSET(ret, 0, sizeof(WOLFSSL_CONF));
57489         ret->data = wolfSSL_sk_CONF_VALUE_new(NULL);
57490         if (!ret->data) {
57491             wolfSSL_NCONF_free(ret);
57492             return NULL;
57493         }
57494     }
57495     return ret;
57496 }
57497 
57498 char *wolfSSL_NCONF_get_string(const WOLFSSL_CONF *conf,
57499         const char *group, const char *name)
57500 {
57501     WOLFSSL_CONF_VALUE find_val;
57502     WOLFSSL_CONF_VALUE *val;
57503     WOLFSSL_ENTER("wolfSSL_NCONF_get_string");
57504 
57505     if (!conf) {
57506 #ifdef HAVE_SECURE_GETENV
57507         return secure_getenv(name);
57508 #else
57509         WOLFSSL_MSG("Missing secure_getenv");
57510         return NULL;
57511 #endif
57512     }
57513 
57514     find_val.name = (char *)name;
57515     if (group) {
57516         find_val.section = (char *)group;
57517         val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val);
57518         if (val)
57519             return val->value;
57520         if (XSTRCMP(group, "ENV") == 0) {
57521 #ifdef HAVE_SECURE_GETENV
57522             return secure_getenv(name);
57523 #else
57524         WOLFSSL_MSG("Missing secure_getenv");
57525             return NULL;
57526 #endif
57527         }
57528     }
57529 
57530     find_val.section = (char *)"default";
57531     val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val);
57532     if (val)
57533         return val->value;
57534     else
57535         return NULL;
57536 }
57537 
57538 int wolfSSL_NCONF_get_number(const CONF *conf, const char *group,
57539         const char *name, long *result)
57540 {
57541     char *str;
57542     WOLFSSL_ENTER("wolfSSL_NCONF_get_number");
57543 
57544     if (!conf || !name || !result) {
57545         WOLFSSL_MSG("Bad parameter");
57546         return WOLFSSL_FAILURE;
57547     }
57548 
57549     if (!(str = wolfSSL_NCONF_get_string(conf, group, name))) {
57550         WOLFSSL_MSG("wolfSSL_NCONF_get_string error");
57551         return WOLFSSL_FAILURE;
57552     }
57553 
57554     *result = atol(str);
57555     return WOLFSSL_SUCCESS;
57556 }
57557 
57558 /**
57559  * The WOLFSSL_CONF->value member is treated as a
57560  * WOLFSSL_STACK_OF(WOLFSSL_CONF_VALUE) which becomes
57561  * the return value.
57562  * @param conf
57563  * @param section
57564  * @return WOLFSSL_STACK_OF(WOLFSSL_CONF_VALUE)
57565  */
57566 WOLFSSL_STACK *wolfSSL_NCONF_get_section(
57567         const WOLFSSL_CONF *conf, const char *section)
57568 {
57569     WOLFSSL_CONF_VALUE *val;
57570     WOLFSSL_CONF_VALUE find_val;
57571 
57572     WOLFSSL_ENTER("wolfSSL_NCONF_get_section");
57573 
57574     if (!conf || !section) {
57575         WOLFSSL_MSG("Bad parameter");
57576         return NULL;
57577     }
57578 
57579     find_val.name = NULL;
57580     find_val.section = (char*)section;
57581     val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val);
57582     if (val)
57583         return (WOLFSSL_STACK*)val->value;
57584     else
57585         return NULL;
57586 }
57587 
57588 #if  !defined(NO_BIO)
57589 static WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section,
57590         char* name, char* value)
57591 {
57592     WOLFSSL_CONF_VALUE* ret;
57593     int len;
57594 
57595     WOLFSSL_ENTER("wolfSSL_CONF_VALUE_new_values");
57596 
57597     if (!(ret = wolfSSL_CONF_VALUE_new())) {
57598         WOLFSSL_MSG("wolfSSL_CONF_VALUE_new error");
57599         return NULL;
57600     }
57601 
57602     if (section) {
57603         len = (int)XSTRLEN(section);
57604         ret->section = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL);
57605         if (!ret->section) {
57606             WOLFSSL_MSG("malloc error");
57607             wolfSSL_X509V3_conf_free(ret);
57608             return NULL;
57609         }
57610         XMEMCPY(ret->section, section, len+1);
57611     }
57612 
57613     if (name) {
57614         len = (int)XSTRLEN(name);
57615         ret->name = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL);
57616         if (!ret->name) {
57617             WOLFSSL_MSG("malloc error");
57618             wolfSSL_X509V3_conf_free(ret);
57619             return NULL;
57620         }
57621         XMEMCPY(ret->name, name, len+1);
57622     }
57623 
57624     if (value) {
57625         len = (int)XSTRLEN(value);
57626         ret->value = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL);
57627         if (!ret->value) {
57628             WOLFSSL_MSG("malloc error");
57629             wolfSSL_X509V3_conf_free(ret);
57630             return NULL;
57631         }
57632         XMEMCPY(ret->value, value, len+1);
57633     }
57634 
57635     return ret;
57636 }
57637 
57638 static char* expandValue(WOLFSSL_CONF *conf, const char* section,
57639         char *str)
57640 {
57641     int strLen = (int)XSTRLEN(str);
57642     char* ret = NULL;
57643 
57644     /* Check to see if there is anything to expand */
57645     if (XSTRNSTR(str, "$", strLen)) {
57646         int idx = 0;
57647         char* strIdx = str;
57648         ret = (char*)XMALLOC(strLen + 1, NULL, DYNAMIC_TYPE_OPENSSL);
57649         if (!ret) {
57650             WOLFSSL_MSG("malloc error");
57651             return str;
57652         }
57653 
57654         while (*strIdx) {
57655             if (*strIdx == '$') {
57656                 /* Expand variable */
57657                 char* startIdx = ++strIdx;
57658                 char* endIdx;
57659                 const char* s = section;
57660                 const char* value;
57661                 char prevValue;
57662 
57663                 if (*startIdx == '{') {
57664                     /* First read the section.
57665                      * format: ${section_name::var_name} */
57666                     s = ++startIdx;
57667                     while (*strIdx && *strIdx != ':') strIdx++;
57668                     if (!*strIdx || s == strIdx || strIdx[1] != ':') {
57669                         WOLFSSL_MSG("invalid section name in "
57670                                     "variable expansion");
57671                         goto expand_cleanup;
57672                     }
57673                     *strIdx = '\0';
57674                     strIdx += 2;
57675                     startIdx = strIdx;
57676                 }
57677                 while (*strIdx && (XISALNUM(*strIdx) || *strIdx == '_'))
57678                     strIdx++;
57679                 endIdx = strIdx;
57680                 if (startIdx == endIdx) {
57681                     WOLFSSL_MSG("invalid variable name in config");
57682                     goto expand_cleanup;
57683                 }
57684                 if (s != section) {
57685                     /* We are expecting a trailing '}' */
57686                     if (*strIdx != '}') {
57687                         WOLFSSL_MSG("Missing '}' in variable");
57688                         goto expand_cleanup;
57689                     }
57690                     strIdx++;
57691                 }
57692                 /* Save char value at the end of the name so that we can place
57693                  * a null char there. */
57694                 prevValue = *endIdx;
57695                 *endIdx = '\0';
57696                 value = wolfSSL_NCONF_get_string(conf, s, startIdx);
57697                 *endIdx = prevValue;
57698                 /* Skip copy if no value or zero-length value */
57699                 if (value && *value) {
57700                     int valueLen = (int)XSTRLEN(value);
57701                     char* newRet;
57702                     /* This will allocate slightly more memory than necessary
57703                      * but better be safe */
57704                     strLen += valueLen;
57705                     newRet = (char*)XREALLOC(ret, strLen + 1, NULL,
57706                             DYNAMIC_TYPE_OPENSSL);
57707                     if (!newRet) {
57708                         WOLFSSL_MSG("realloc error");
57709                         goto expand_cleanup;
57710                     }
57711                     ret = newRet;
57712                     XMEMCPY(ret + idx, value, valueLen);
57713                     idx += valueLen;
57714                 }
57715             }
57716             else {
57717                 ret[idx++] = *strIdx++;
57718             }
57719         }
57720         ret[idx] = '\0';
57721     }
57722 
57723     return ret ? ret : str;
57724 
57725 expand_cleanup:
57726     if (ret)
57727         XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL);
57728     return NULL;
57729 }
57730 
57731 #define SKIP_WHITESPACE(idx, max_idx) \
57732     while (idx < max_idx && (*idx == ' ' || *idx == '\t')) \
57733         {idx++;}
57734 int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline)
57735 {
57736     int ret = WOLFSSL_FAILURE;
57737     WOLFSSL_BIO *in = NULL;
57738     char* buf = NULL;
57739     char* idx = NULL;
57740     char* bufEnd = NULL;
57741     CONF_VALUE* section = NULL;
57742     long line = 0;
57743     int bufLen = 0;
57744 
57745     if (!conf || !file) {
57746         WOLFSSL_MSG("Bad parameter");
57747         return WOLFSSL_FAILURE;
57748     }
57749 
57750     /* Open file */
57751     if (!(in = wolfSSL_BIO_new_file(file, "rb"))) {
57752         WOLFSSL_MSG("wolfSSL_BIO_new_file error");
57753         return WOLFSSL_FAILURE;
57754     }
57755 
57756     /* Read file */
57757     bufLen = wolfSSL_BIO_get_len(in);
57758     if (bufLen <= 0) {
57759         WOLFSSL_MSG("wolfSSL_BIO_get_len error");
57760         goto cleanup;
57761     }
57762     if (!(buf = (char*)XMALLOC(bufLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER))) {
57763         WOLFSSL_MSG("malloc error");
57764         goto cleanup;
57765     }
57766     if (wolfSSL_BIO_read(in, buf, bufLen) != bufLen) {
57767         WOLFSSL_MSG("wolfSSL_BIO_read error");
57768         goto cleanup;
57769     }
57770 
57771     if (!(section = wolfSSL_CONF_new_section(conf, "default"))) {
57772         WOLFSSL_MSG("wolfSSL_CONF_new_section error");
57773         goto cleanup;
57774     }
57775 
57776     /* LETS START READING SOME CONFIGS */
57777     idx = buf;
57778     bufEnd = buf + bufLen;
57779     while (idx < bufEnd) {
57780         char* lineEnd = XSTRNSTR(idx, "\n", (unsigned int)(bufEnd - idx));
57781         char* maxIdx;
57782         if (!lineEnd)
57783             lineEnd = bufEnd; /* Last line in file */
57784         maxIdx = XSTRNSTR(idx, "#", (unsigned int)(lineEnd - idx));
57785         if (!maxIdx)
57786             maxIdx = lineEnd;
57787         line++;
57788         SKIP_WHITESPACE(idx, maxIdx);
57789         if (idx == maxIdx) {
57790             /* Empty line */
57791             idx = lineEnd + 1;
57792             continue;
57793         }
57794 
57795         if (*idx == '[') {
57796             /* New section. Spaces not allowed in section name. */
57797             char* sectionName;
57798             int sectionNameLen;
57799 
57800             if (idx < maxIdx)
57801                 idx++;
57802             else {
57803                 WOLFSSL_MSG("Invalid section definition.");
57804                 goto cleanup;
57805             }
57806 
57807             SKIP_WHITESPACE(idx, maxIdx);
57808             sectionName = idx;
57809             /* Find end of section name */
57810             while (idx < maxIdx && *idx != ' ' && *idx != ']')
57811                 idx++;
57812             sectionNameLen = (int)(idx - sectionName);
57813             SKIP_WHITESPACE(idx, maxIdx);
57814 
57815             if (*idx != ']') {
57816                 WOLFSSL_MSG("Section definition error. "
57817                             "Closing brace not found.");
57818                 goto cleanup;
57819             }
57820 
57821             sectionName[sectionNameLen] = '\0';
57822             if (!(section = wolfSSL_CONF_get_section(conf, sectionName))) {
57823                 section = wolfSSL_CONF_new_section(conf, sectionName);
57824                 if (!section)
57825                     goto cleanup;
57826             }
57827         }
57828         else {
57829             char* name;
57830             int   nameLen;
57831             char* value;
57832             char* exValue; /* expanded value */
57833             int   valueLen;
57834             WOLFSSL_CONF_VALUE* newVal = NULL;
57835 
57836             SKIP_WHITESPACE(idx, maxIdx);
57837             name = idx;
57838             /* Find end of name */
57839             while (idx < maxIdx && *idx != ' ' && *idx != '=')
57840                 idx++;
57841             nameLen = (int)(idx - name);
57842             SKIP_WHITESPACE(idx, maxIdx);
57843             if (*idx != '=') {
57844                 WOLFSSL_MSG("Missing equals sign");
57845                 goto cleanup;
57846             }
57847             idx++;
57848             SKIP_WHITESPACE(idx, maxIdx);
57849             value = idx;
57850             /* Find end of value */
57851             idx = maxIdx-1;
57852             while (idx >= value && (*idx == ' ' || *idx == '\t'))
57853                 idx--;
57854             valueLen = (int)(idx - value + 1);
57855 
57856             /* Sanity checks */
57857             if (nameLen <= 0 || valueLen <= 0) {
57858                 WOLFSSL_MSG("Sanity checks failed");
57859                 goto cleanup;
57860             }
57861             name[nameLen] = '\0';
57862             value[valueLen] = '\0';
57863 
57864             if (!(exValue = expandValue(conf, section->section, value))) {
57865                 WOLFSSL_MSG("Variable expansion failed");
57866                 goto cleanup;
57867             }
57868 
57869             if (!(newVal = wolfSSL_CONF_VALUE_new_values(NULL,
57870                     name, exValue))) {
57871                 WOLFSSL_MSG("wolfSSL_CONF_VALUE_new_values error");
57872                 if (exValue != value)
57873                     XFREE(exValue, NULL, DYNAMIC_TYPE_OPENSSL);
57874                 goto cleanup;
57875             }
57876 
57877             if (exValue != value)
57878                 XFREE(exValue, NULL, DYNAMIC_TYPE_OPENSSL);
57879 
57880             if (wolfSSL_CONF_add_string(conf, section, newVal) !=
57881                     WOLFSSL_SUCCESS) {
57882                 WOLFSSL_MSG("wolfSSL_CONF_add_string error");
57883                 goto cleanup;
57884             }
57885         }
57886         idx = lineEnd + 1;
57887     }
57888 
57889     ret = WOLFSSL_SUCCESS;
57890 cleanup:
57891     if (in)
57892         wolfSSL_BIO_free(in);
57893     if (buf)
57894         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
57895     if (eline)
57896         *eline = line;
57897     return ret;
57898 }
57899 #endif /* !NO_BIO */
57900 
57901 void wolfSSL_NCONF_free(WOLFSSL_CONF *conf)
57902 {
57903     WOLFSSL_ENTER("wolfSSL_NCONF_free");
57904     if (conf) {
57905         wolfSSL_sk_CONF_VALUE_free(conf->data);
57906         XFREE(conf, NULL, DYNAMIC_TYPE_OPENSSL);
57907     }
57908 }
57909 
57910 void wolfSSL_X509V3_conf_free(WOLFSSL_CONF_VALUE *val)
57911 {
57912     WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
57913 
57914     if (val) {
57915         if (val->name) {
57916             /* Not a section. Don't free section as it is a shared pointer. */
57917             XFREE(val->name, NULL, DYNAMIC_TYPE_OPENSSL);
57918             if (val->value)
57919                 XFREE(val->value, NULL, DYNAMIC_TYPE_OPENSSL);
57920         }
57921         else {
57922             /* Section so val->value is a stack */
57923             if (val->section)
57924                 XFREE(val->section, NULL, DYNAMIC_TYPE_OPENSSL);
57925             /* Only free the stack structures. The contained conf values
57926              * will be freed in wolfSSL_NCONF_free */
57927             sk = (WOLF_STACK_OF(WOLFSSL_CONF_VALUE)*)val->value;
57928             while (sk) {
57929                 WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *tmp = sk->next;
57930                 XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
57931                 sk = tmp;
57932             }
57933         }
57934         XFREE(val, NULL, DYNAMIC_TYPE_OPENSSL);
57935     }
57936 }
57937 
57938 WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(wolf_sk_compare_cb compFunc)
57939 {
57940     WOLFSSL_STACK* ret;
57941     WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_new");
57942     ret = wolfSSL_sk_new_node(NULL);
57943     if (!ret)
57944         return NULL;
57945     ret->comp = compFunc ? compFunc : (wolf_sk_compare_cb)wolfssl_conf_value_cmp;
57946     ret->hash_fn = (wolf_sk_hash_cb)wolfSSL_CONF_VALUE_hash;
57947     ret->type = STACK_TYPE_CONF_VALUE;
57948     return ret;
57949 }
57950 
57951 /* Free the structure for WOLFSSL_CONF_VALUE stack
57952  *
57953  * sk  stack to free nodes in
57954  */
57955 void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk)
57956 {
57957     WOLFSSL_STACK* tmp;
57958     WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_free");
57959 
57960     if (sk == NULL)
57961         return;
57962 
57963     /* parse through stack freeing each node */
57964     while (sk) {
57965         tmp = sk->next;
57966         wolfSSL_X509V3_conf_free(sk->data.conf);
57967         XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
57968         sk = tmp;
57969     }
57970 }
57971 
57972 int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk)
57973 {
57974     WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_num");
57975     if (sk)
57976         return wolfSSL_sk_num(sk);
57977     return 0;
57978 }
57979 
57980 WOLFSSL_CONF_VALUE *wolfSSL_sk_CONF_VALUE_value(const WOLFSSL_STACK *sk, int i)
57981 {
57982     WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_value");
57983     if (sk)
57984         return (WOLFSSL_CONF_VALUE*)wolfSSL_sk_value(sk, i);
57985     return NULL;
57986 }
57987 
57988 /* return 1 on success 0 on fail */
57989 int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk,
57990         WOLFSSL_CONF_VALUE* val)
57991 {
57992     WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_push");
57993 
57994     if (sk == NULL || val == NULL) {
57995         return WOLFSSL_FAILURE;
57996     }
57997 
57998     return wolfSSL_sk_push(sk, val);
57999 }
58000 
58001 #endif /* !NO_CERTS && OPENSSL_EXTRA && OPENSSL_ALL */
58002 
58003 #ifdef OPENSSL_EXTRA
58004 #ifndef NO_WOLFSSL_STUB
58005 /* Returns default file name and path of config file. However
58006    a wolfssl.cnf file is not currently supported */
58007 char* wolfSSL_CONF_get1_default_config_file(void)
58008 {
58009     WOLFSSL_ENTER("wolfSSL_CONF_get1_default_config_file");
58010     WOLFSSL_STUB("CONF_get1_default_config_file");
58011     return NULL;
58012 }
58013 #endif
58014 
58015 /**
58016  * Allocate WOLFSSL_CONF_CTX instance
58017  * @return pointer to WOLFSSL_CONF_CTX structure on success and NULL on fail
58018  */
58019 WOLFSSL_CONF_CTX* wolfSSL_CONF_CTX_new(void)
58020 {
58021     WOLFSSL_CONF_CTX* cctx;
58022 
58023     WOLFSSL_ENTER("wolfSSL_CONF_CTX_new");
58024 
58025     cctx = (WOLFSSL_CONF_CTX*)XMALLOC(sizeof(WOLFSSL_CONF_CTX), NULL,
58026                                                     DYNAMIC_TYPE_OPENSSL);
58027     if (!cctx) {
58028         WOLFSSL_MSG("malloc error");
58029         return NULL;
58030     }
58031     XMEMSET(cctx, 0, sizeof(WOLFSSL_CONF_CTX));
58032 
58033     return cctx;
58034 }
58035 /**
58036  * Release WOLFSSL_CONF_CTX instance
58037  * @param cctx a pointer to WOLFSSL_CONF_CTX structure to be freed
58038  */
58039 void wolfSSL_CONF_CTX_free(WOLFSSL_CONF_CTX* cctx)
58040 {
58041     WOLFSSL_ENTER("wolfSSL_CONF_CTX_free");
58042 
58043     if (cctx) {
58044         XFREE(cctx, NULL, DYNAMIC_TYPE_OPENSSL);
58045     }
58046     WOLFSSL_LEAVE("wolfSSL_CONF_CTX_free", 1);
58047 }
58048 /**
58049  * Set WOLFSSL_CTX instance to WOLFSSL_CONF_CTX
58050  * @param cctx a pointer to WOLFSSL_CONF_CTX structure to set a WOLFSSL_CTX
58051  *             pointer to its ctx
58052  * @param ctx  a pointer to WOLFSSL_CTX structure to be set
58053  */
58054 void wolfSSL_CONF_CTX_set_ssl_ctx(WOLFSSL_CONF_CTX* cctx, WOLFSSL_CTX *ctx)
58055 {
58056     WOLFSSL_ENTER("wolfSSL_CONF_CTX_set_ssl_ctx");
58057 
58058     /* sanity check */
58059     if (cctx == NULL) {
58060         WOLFSSL_MSG("cctx is null");
58061         return;
58062     }
58063 
58064     cctx->ctx = ctx;
58065     WOLFSSL_LEAVE("wolfSSL_CONF_CTX_set_ssl_ctx", 1);
58066 }
58067 /**
58068  * set flag value into WOLFSSL_CONF_CTX
58069  * @param cctx  a pointer to WOLFSSL_CONF_CTX structure to be set
58070  * @param flags falg value to be OR'd
58071  * @return OR'd flag value, otherwise 0
58072  */
58073 unsigned int wolfSSL_CONF_CTX_set_flags(WOLFSSL_CONF_CTX* cctx,
58074                                                             unsigned int flags)
58075 {
58076     /* sanity check */
58077     if (cctx == NULL)
58078         return 0;
58079 
58080     cctx->flags |= flags;
58081     return cctx->flags;
58082 }
58083 
58084 /**
58085  * finish configuration command operation
58086  * @param cctx  a pointer to WOLFSSL_CONF_CTX structure to be set
58087  * @return WOLFSSL_SUCCESS on success
58088  */
58089 int wolfSSL_CONF_CTX_finish(WOLFSSL_CONF_CTX* cctx)
58090 {
58091     (void)cctx;
58092     return WOLFSSL_SUCCESS;
58093 }
58094 /*
58095  * The following definitions and static functions are used for
58096  * wolfSSL_CONF_cmd() to handle command.
58097  *
58098  * Definitions below are a part of conf_cmds_tbl[] contents.
58099  *  WOLFSSL_CONF_FILE_CMDx  represents command name in configuration file
58100  *  WOLFSSL_CONF_CMDL_CMDx  represents command name on command line
58101  *
58102  * The static functions after the definition section process
58103  *                 those FILE or CMDL which are defined in the conf_cmds_tbl.
58104  *
58105  * To add a new command handling:
58106  *  1. Add new #define to a section of WOLFSSL_CONF_FILE_CMD* and
58107  *                                      WOLFSSL_CONF_CMDL_CMD*
58108  *  2. Add new static function after #define section, before
58109  *                      "typedef struct conf_cmd_tbl {" line
58110  *  3. Add new entry to conf_cmds_tbl[] by following other command entries
58111  */
58112 #define WOLFSSL_CONF_FILE_CMD1  "Curves"
58113 #define WOLFSSL_CONF_FILE_CMD2  "Certificate"
58114 #define WOLFSSL_CONF_FILE_CMD3  "PrivateKey"
58115 #define WOLFSSL_CONF_FILE_CMD4  "Protocol"
58116 #define WOLFSSL_CONF_FILE_CMD5  "Options"
58117 #define WOLFSSL_CONF_FILE_CMD6  "ServerInfoFile"
58118 #define WOLFSSL_CONF_FILE_CMD7  "SignatureAlgorithms"
58119 #define WOLFSSL_CONF_FILE_CMD8  "ClientSignatureAlgorithms"
58120 #define WOLFSSL_CONF_FILE_CMD9  "CipherString"
58121 
58122 #define WOLFSSL_CONF_CMDL_CMD1  "curves"
58123 #define WOLFSSL_CONF_CMDL_CMD2  "cert"
58124 #define WOLFSSL_CONF_CMDL_CMD3  "key"
58125 #define WOLFSSL_CONF_CMDL_CMD4  NULL
58126 #define WOLFSSL_CONF_CMDL_CMD5  NULL
58127 #define WOLFSSL_CONF_CMDL_CMD6  NULL
58128 #define WOLFSSL_CONF_CMDL_CMD7  "sigalgs"
58129 #define WOLFSSL_CONF_CMDL_CMD8  "client_sigalgs"
58130 #define WOLFSSL_CONF_CMDL_CMD9  "cipher"
58131 
58132 #if !defined(NO_DH) && !defined(NO_BIO)
58133 #define WOLFSSL_CONF_FILE_CMD10 "DHParameters"
58134 #define WOLFSSL_CONF_CMDL_CMD10 "dhparam"
58135 #endif
58136 
58137 #ifdef HAVE_ECC
58138 #define WOLFSSL_CONF_FILE_CMD11 "ECDHParameters"
58139 #define WOLFSSL_CONF_CMDL_CMD11 "named_curves"
58140 #endif
58141 
58142 /**
58143  * process Cipher String command
58144  * @param cctx  a pointer to WOLFSSL_CONF_CTX structure
58145  * @param value arguments for cmd
58146  * @return WOLFSSL_SUCCESS on success,
58147  *     otherwise WOLFSSL_FAILURE or
58148  *               -3 if value is null or
58149  *               negative value on other failure
58150  */
58151 static int cmdfunc_cipherstring(WOLFSSL_CONF_CTX* cctx, const char* value)
58152 {
58153     int ret = -3;
58154 
58155     WOLFSSL_ENTER("cmdfunc_cipherstring");
58156 
58157      /* sanity check */
58158     if (cctx == NULL)
58159         return WOLFSSL_FAILURE;
58160 
58161     if (value == NULL) {
58162         WOLFSSL_MSG("bad arguments");
58163         return ret;
58164     }
58165 
58166     if (cctx->ctx) {
58167         ret = wolfSSL_CTX_set_cipher_list(cctx->ctx, value);
58168     }
58169 
58170     if (((cctx->ctx  && ret == WOLFSSL_SUCCESS) ||
58171          (!cctx->ctx && ret == -3)) &&
58172         cctx->ssl) {
58173         ret = wolfSSL_set_cipher_list(cctx->ssl, value);
58174     }
58175 
58176     WOLFSSL_LEAVE("cmdfunc_cipherstring", ret);
58177     return ret;
58178 }
58179 
58180 /**
58181  * process curves command
58182  * @param cctx  a pointer to WOLFSSL_CONF_CTX structure
58183  * @param value arguments for cmd
58184  * @return WOLFSSL_SUCCESS on success,
58185  *     otherwise WOLFSSL_FAILURE or
58186  *               -3 if value is null or
58187  *               negative value on other failure
58188  */
58189 #if defined(HAVE_ECC)
58190 static int cmdfunc_curves(WOLFSSL_CONF_CTX* cctx, const char* value)
58191 {
58192     int ret = -3;
58193 
58194     WOLFSSL_ENTER("cmdfunc_curves");
58195 
58196      /* sanity check */
58197     if (cctx == NULL)
58198         return WOLFSSL_FAILURE;
58199 
58200     if (value == NULL) {
58201         WOLFSSL_MSG("bad arguments");
58202         return ret;
58203     }
58204 
58205     if (cctx->ctx) {
58206         ret = wolfSSL_CTX_set1_curves_list(cctx->ctx, value);
58207     }
58208 
58209     if (((cctx->ctx  && ret == WOLFSSL_SUCCESS) ||
58210          (!cctx->ctx && ret == -3)) &&
58211         cctx->ssl) {
58212         ret = wolfSSL_set1_curves_list(cctx->ssl, value);
58213     }
58214 
58215     WOLFSSL_LEAVE("cmdfunc_curves", ret);
58216     return ret;
58217 }
58218 #endif
58219 
58220 #ifndef NO_FILESYSTEM
58221 /**
58222  * process cert command
58223  * @param cctx  a pointer to WOLFSSL_CONF_CTX structure
58224  * @param value arguments for cmd
58225  * @return WOLFSSL_SUCCESS on success,
58226  *     otherwise WOLFSSL_FAILURE or
58227  *               -3 if value is null or
58228  *               negative value on other failure
58229  */
58230 static int cmdfunc_cert(WOLFSSL_CONF_CTX* cctx, const char* value)
58231 {
58232     int ret = -3;
58233 
58234     WOLFSSL_ENTER("cmdfunc_cert");
58235 
58236     /* sanity check */
58237     if (cctx == NULL)
58238         return WOLFSSL_FAILURE;
58239 
58240     if (value == NULL) {
58241         WOLFSSL_MSG("bad arguments");
58242         return ret;
58243     }
58244 
58245     if (!(cctx->flags & WOLFSSL_CONF_FLAG_CERTIFICATE)) {
58246         WOLFSSL_MSG("certificate flag is not set");
58247         return -2;
58248     }
58249 
58250     if (cctx->ctx) {
58251         ret = wolfSSL_CTX_use_certificate_chain_file(cctx->ctx, value);
58252     }
58253 
58254     if (((cctx->ctx  && ret == WOLFSSL_SUCCESS) ||
58255          (!cctx->ctx && ret == -3)) &&
58256         cctx->ssl) {
58257         ret = wolfSSL_use_certificate_file(cctx->ssl, value,
58258                                                     WOLFSSL_FILETYPE_PEM);
58259     }
58260 
58261     WOLFSSL_LEAVE("cmdfunc_cert", ret);
58262     return ret;
58263 }
58264 /**
58265  * process key command
58266  * @param cctx  a pointer to WOLFSSL_CONF_CTX structure
58267  * @param value arguments for cmd
58268  * @return WOLFSSL_SUCCESS on success,
58269  *     otherwise WOLFSSL_FAILURE or
58270  *               -3 if value is null or
58271  *               negative value on other failure
58272  */
58273 static int cmdfunc_key(WOLFSSL_CONF_CTX* cctx, const char* value)
58274 {
58275     int ret = -3;
58276 
58277     WOLFSSL_ENTER("cmdfunc_key");
58278 
58279      /* sanity check */
58280     if (cctx == NULL)
58281         return WOLFSSL_FAILURE;
58282 
58283     if (value == NULL) {
58284         WOLFSSL_MSG("bad arguments");
58285         return ret;
58286     }
58287 
58288     if (!(cctx->flags & WOLFSSL_CONF_FLAG_CERTIFICATE)) {
58289         WOLFSSL_MSG("certificate flag is not set");
58290         return -2;
58291     }
58292 
58293     if (cctx->ctx) {
58294         ret = wolfSSL_CTX_use_PrivateKey_file(cctx->ctx, value,
58295                                                     WOLFSSL_FILETYPE_PEM);
58296     }
58297 
58298     if (((cctx->ctx  && ret == WOLFSSL_SUCCESS) ||
58299          (!cctx->ctx && ret == -3)) &&
58300         cctx->ssl) {
58301         ret = wolfSSL_use_PrivateKey_file(cctx->ssl, value,
58302                                                     WOLFSSL_FILETYPE_PEM);
58303     }
58304 
58305     WOLFSSL_LEAVE("cmdfunc_key", ret);
58306     return ret;
58307 }
58308 #endif /* NO_FILESYSTEM */
58309 /**
58310  * process DH parameter command
58311  * @param cctx  a pointer to WOLFSSL_CONF_CTX structure
58312  * @param value arguments for cmd
58313  * @return WOLFSSL_SUCCESS on success,
58314  *     otherwise WOLFSSL_FAILURE or
58315  *               -3 if value is null or
58316  *               negative value on other failure
58317  */
58318 #if !defined(NO_DH) && !defined(NO_BIO)
58319 static int cmdfunc_dhparam(WOLFSSL_CONF_CTX* cctx, const char* value)
58320 {
58321     int ret = -3;
58322     WOLFSSL_DH* dh = NULL;
58323     WOLFSSL_BIO* bio = NULL;
58324 
58325     WOLFSSL_MSG("cmdfunc_dhparam");
58326 
58327      /* sanity check */
58328     if (cctx == NULL)
58329         return WOLFSSL_FAILURE;
58330 
58331     if (value == NULL) {
58332         WOLFSSL_MSG("bad arguments");
58333         return ret;
58334     }
58335 
58336     if (cctx->ctx || cctx->ssl) {
58337         bio = wolfSSL_BIO_new_file(value, "rb");
58338         if (!bio) {
58339             WOLFSSL_MSG("bio new file failed");
58340             return WOLFSSL_FAILURE;
58341         }
58342         dh = wolfSSL_PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
58343         if (!dh) {
58344             wolfSSL_BIO_free(bio);
58345             WOLFSSL_MSG("PEM read bio failed");
58346             return WOLFSSL_FAILURE;
58347         }
58348     } else {
58349         return 1;
58350     }
58351 
58352     if (cctx->ctx) {
58353         ret = (int)wolfSSL_CTX_set_tmp_dh(cctx->ctx, dh);
58354     }
58355 
58356     if (((cctx->ctx  && ret == WOLFSSL_SUCCESS) ||
58357          (!cctx->ctx && ret == -3)) &&
58358         cctx->ssl) {
58359         ret = (int)wolfSSL_CTX_set_tmp_dh(cctx->ssl->ctx, dh);
58360     }
58361 
58362     if (dh)
58363         wolfSSL_DH_free(dh);
58364     if (bio)
58365         wolfSSL_BIO_free(bio);
58366 
58367     WOLFSSL_LEAVE("cmdfunc_dhparam", ret);
58368     return ret;
58369 }
58370 #endif /* !NO_DH && !NO_BIO */
58371 /**
58372  * command table
58373  */
58374 typedef struct conf_cmd_tbl {
58375     const char* file_cmd;
58376     const char* cmdline_cmd;
58377     word32 data_type;
58378     int (*cmdfunc)(WOLFSSL_CONF_CTX* cctx, const char* value);
58379 }conf_cmd_tbl;
58380 
58381 static const conf_cmd_tbl conf_cmds_tbl[] = {
58382 #if defined(HAVE_ECC)
58383     /* cmd Curves */
58384     {WOLFSSL_CONF_FILE_CMD1, WOLFSSL_CONF_CMDL_CMD1,
58385                                     WOLFSSL_CONF_TYPE_STRING, cmdfunc_curves},
58386 #endif
58387 #if !defined(NO_FILESYSTEM)
58388     /* cmd Certificate */
58389     {WOLFSSL_CONF_FILE_CMD2, WOLFSSL_CONF_CMDL_CMD2,
58390                                     WOLFSSL_CONF_TYPE_FILE, cmdfunc_cert},
58391     /* cmd PrivateKey */
58392     {WOLFSSL_CONF_FILE_CMD3, WOLFSSL_CONF_CMDL_CMD3,
58393                                     WOLFSSL_CONF_TYPE_FILE, cmdfunc_key},
58394 #endif
58395     /* cmd Protocol */
58396     {WOLFSSL_CONF_FILE_CMD4, WOLFSSL_CONF_CMDL_CMD4,
58397                                     WOLFSSL_CONF_TYPE_STRING, NULL},
58398     /* cmd Options */
58399     {WOLFSSL_CONF_FILE_CMD5, WOLFSSL_CONF_CMDL_CMD5,
58400                                     WOLFSSL_CONF_TYPE_STRING, NULL},
58401     /* cmd ServerInfoFile */
58402     {WOLFSSL_CONF_FILE_CMD6, WOLFSSL_CONF_CMDL_CMD6,
58403                                     WOLFSSL_CONF_TYPE_FILE, NULL},
58404     /* cmd SignatureAlgorithms */
58405     {WOLFSSL_CONF_FILE_CMD7, WOLFSSL_CONF_CMDL_CMD7,
58406                                     WOLFSSL_CONF_TYPE_STRING, NULL},
58407     /* cmd ClientSignatureAlgorithms */
58408     {WOLFSSL_CONF_FILE_CMD8, WOLFSSL_CONF_CMDL_CMD8,
58409                                     WOLFSSL_CONF_TYPE_STRING, NULL},
58410     /* cmd CipherString */
58411     {WOLFSSL_CONF_FILE_CMD9, WOLFSSL_CONF_CMDL_CMD9,
58412                               WOLFSSL_CONF_TYPE_STRING, cmdfunc_cipherstring},
58413 #if !defined(NO_DH) && !defined(NO_BIO)
58414     /* cmd DHParameters */
58415     {WOLFSSL_CONF_FILE_CMD10, WOLFSSL_CONF_CMDL_CMD10,
58416                                     WOLFSSL_CONF_TYPE_FILE, cmdfunc_dhparam},
58417 #endif
58418 #ifdef HAVE_ECC
58419     /* cmd ECHDParameters */
58420     {WOLFSSL_CONF_FILE_CMD11, WOLFSSL_CONF_CMDL_CMD11,
58421                                     WOLFSSL_CONF_TYPE_STRING, NULL},
58422 #endif
58423 };
58424 /* size of command table */
58425 static const size_t size_of_cmd_tbls = sizeof(conf_cmds_tbl)
58426                                                     / sizeof(conf_cmd_tbl);
58427 
58428 static const conf_cmd_tbl* wolfssl_conf_find_cmd(WOLFSSL_CONF_CTX* cctx,
58429                                          const char* cmd)
58430 {
58431     size_t i = 0;
58432     size_t cmdlen = 0;
58433 
58434     if (cctx->flags & WOLFSSL_CONF_FLAG_CMDLINE) {
58435         cmdlen = XSTRLEN(cmd);
58436 
58437         if (cmdlen < 2) {
58438             WOLFSSL_MSG("bad cmdline command");
58439             return NULL;
58440         }
58441         /* skip "-" prefix */
58442         ++cmd;
58443     }
58444 
58445     for (i = 0; i < size_of_cmd_tbls; i++) {
58446         /* check if the cmd is valid */
58447         if (cctx->flags & WOLFSSL_CONF_FLAG_CMDLINE) {
58448             if (conf_cmds_tbl[i].cmdline_cmd != NULL &&
58449                 XSTRCMP(cmd, conf_cmds_tbl[i].cmdline_cmd) == 0) {
58450                 return &conf_cmds_tbl[i];
58451             }
58452         }
58453 
58454         if (cctx->flags & WOLFSSL_CONF_FLAG_FILE) {
58455             if (conf_cmds_tbl[i].file_cmd != NULL &&
58456                 XSTRCMP(cmd, conf_cmds_tbl[i].file_cmd) == 0) {
58457                 return &conf_cmds_tbl[i];
58458             }
58459         }
58460     }
58461 
58462     return NULL;
58463 }
58464 
58465 /**
58466  * send configuration command
58467  * @param cctx  a pointer to WOLFSSL_CONF_CTX structure
58468  * @param cmd   configuration command
58469  * @param value arguments for cmd
58470  * @return 1 when cmd is recognised, but value is not used
58471  *         2 both cmd and value are used
58472  *  otherwise WOLFSSL_FAILURE
58473  *         -2 if cmd is not recognised
58474  *         -3 if value is NULL, but cmd is recognized
58475  */
58476 int wolfSSL_CONF_cmd(WOLFSSL_CONF_CTX* cctx, const char* cmd, const char* value)
58477 {
58478     int ret = WOLFSSL_FAILURE;
58479     const conf_cmd_tbl* confcmd = NULL;
58480     WOLFSSL_ENTER("wolfSSL_CONF_cmd");
58481 
58482     /* sanity check */
58483     if (cctx == NULL || cmd == NULL) {
58484         WOLFSSL_MSG("bad arguments");
58485         return ret;
58486     }
58487 
58488     confcmd = wolfssl_conf_find_cmd(cctx, cmd);
58489     if (confcmd == NULL)
58490         return -2;
58491 
58492     if (confcmd->cmdfunc == NULL) {
58493         WOLFSSL_MSG("cmd not yet implemented");
58494         return -2;
58495     }
58496 
58497     ret = confcmd->cmdfunc(cctx, value);
58498 
58499     /* return code compliant with OpenSSL */
58500     if (ret < -3)
58501         ret = 0;
58502 
58503     WOLFSSL_LEAVE("wolfSSL_CONF_cmd", ret);
58504     return ret;
58505 }
58506 
58507 /**
58508  *
58509  * @param cctx a pointer to WOLFSSL_CONF_CTX structure
58510  * @param cmd  configuration command
58511  * @return The SSL_CONF_TYPE_* type or SSL_CONF_TYPE_UNKNOWN if an
58512  *         unvalid command
58513  */
58514 int wolfSSL_CONF_cmd_value_type(WOLFSSL_CONF_CTX *cctx, const char *cmd)
58515 {
58516     const conf_cmd_tbl* confcmd = NULL;
58517     WOLFSSL_ENTER("wolfSSL_CONF_cmd_value_type");
58518 
58519     confcmd = wolfssl_conf_find_cmd(cctx, cmd);
58520     if (confcmd == NULL)
58521         return SSL_CONF_TYPE_UNKNOWN;
58522     return (int)confcmd->data_type;
58523 }
58524 
58525 #endif /* OPENSSL_EXTRA */
58526 
58527 
58528 /*******************************************************************************
58529  * END OF CONF API
58530  ******************************************************************************/
58531 
58532 /*******************************************************************************
58533  * START OF BIO API
58534  ******************************************************************************/
58535 
58536 #ifndef NO_BIO
58537 
58538 #ifdef OPENSSL_EXTRA
58539 
58540     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_md(void)
58541     {
58542         static WOLFSSL_BIO_METHOD meth;
58543 
58544         WOLFSSL_ENTER("wolfSSL_BIO_f_md");
58545         meth.type = WOLFSSL_BIO_MD;
58546 
58547         return &meth;
58548     }
58549 
58550     /* return the context and initialize the BIO state */
58551     int wolfSSL_BIO_get_md_ctx(WOLFSSL_BIO *bio, WOLFSSL_EVP_MD_CTX **mdcp)
58552     {
58553         int ret = WOLFSSL_FAILURE;
58554 
58555         if ((bio != NULL) && (mdcp != NULL)) {
58556             *mdcp = (WOLFSSL_EVP_MD_CTX*)bio->ptr;
58557             ret = WOLFSSL_SUCCESS;
58558         }
58559 
58560         return ret;
58561     }
58562 
58563     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void)
58564     {
58565         static WOLFSSL_BIO_METHOD meth;
58566 
58567         WOLFSSL_ENTER("BIO_f_buffer");
58568         meth.type = WOLFSSL_BIO_BUFFER;
58569 
58570         return &meth;
58571     }
58572 
58573     #ifndef NO_WOLFSSL_STUB
58574     long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO* bio, long size)
58575     {
58576         /* wolfSSL has internal buffer, compatibility only */
58577         WOLFSSL_ENTER("BIO_set_write_buffer_size");
58578         WOLFSSL_MSG("Buffer resize failed");
58579         WOLFSSL_STUB("BIO_set_write_buffer_size");
58580         (void)bio;
58581         (void) size;
58582 
58583         /* Even though this is only a STUB at the moment many user applications
58584          * may attempt to use this. OpenSSL documentation specifies the return
58585          * "return 1 if the buffer was successfully resized or 0 for failure."
58586          * since wolfSSL does not resize the buffer will always return failure
58587          * by default due to memory concerns until this stub is promoted to
58588          * a non-stub function */
58589         return WOLFSSL_FAILURE; /* 0, no resize happened */
58590     }
58591     #endif
58592 
58593     WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_bio(void)
58594     {
58595         static WOLFSSL_BIO_METHOD bio_meth;
58596 
58597         WOLFSSL_ENTER("wolfSSL_BIO_s_bio");
58598         bio_meth.type = WOLFSSL_BIO_BIO;
58599 
58600         return &bio_meth;
58601     }
58602 
58603 
58604 #ifndef NO_FILESYSTEM
58605     WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void)
58606     {
58607         static WOLFSSL_BIO_METHOD file_meth;
58608 
58609         WOLFSSL_ENTER("wolfSSL_BIO_s_file");
58610         file_meth.type = WOLFSSL_BIO_FILE;
58611 
58612         return &file_meth;
58613     }
58614 #endif
58615 
58616 
58617     WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void)
58618     {
58619         static WOLFSSL_BIO_METHOD meth;
58620 
58621         WOLFSSL_ENTER("wolfSSL_BIO_f_ssl");
58622         meth.type = WOLFSSL_BIO_SSL;
58623 
58624         return &meth;
58625     }
58626 
58627 
58628     WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void)
58629     {
58630         static WOLFSSL_BIO_METHOD meth;
58631 
58632         WOLFSSL_ENTER("wolfSSL_BIO_s_socket");
58633         meth.type = WOLFSSL_BIO_SOCKET;
58634 
58635         return &meth;
58636     }
58637 
58638 
58639     WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int closeF)
58640     {
58641         WOLFSSL_BIO* bio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket());
58642 
58643         WOLFSSL_ENTER("BIO_new_socket");
58644         if (bio) {
58645             bio->type  = WOLFSSL_BIO_SOCKET;
58646             bio->shutdown = (byte)closeF;
58647             bio->num   = sfd;
58648         }
58649         return bio;
58650     }
58651 
58652     /**
58653      * Create new socket BIO object. This is a pure TCP connection with
58654      * no SSL or TLS protection.
58655      * @param str IP address to connect to
58656      * @return New BIO object or NULL on failure
58657      */
58658     WOLFSSL_BIO *wolfSSL_BIO_new_connect(const char *str)
58659     {
58660         WOLFSSL_BIO *bio;
58661         const char* port;
58662         WOLFSSL_ENTER("wolfSSL_BIO_new_connect");
58663         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket());
58664         if (bio) {
58665             port = XSTRSTR(str, ":");
58666 
58667             if (port != NULL)
58668                 bio->port = (word16)XATOI(port + 1);
58669             else
58670                 port = str + XSTRLEN(str); /* point to null terminator */
58671 
58672             bio->ip = (char*)XMALLOC((port - str) + 1, /* +1 for null char */
58673                     bio->heap, DYNAMIC_TYPE_OPENSSL);
58674             XMEMCPY(bio->ip, str, port - str);
58675             bio->ip[port - str] = '\0';
58676             bio->type  = WOLFSSL_BIO_SOCKET;
58677         }
58678         return bio;
58679     }
58680 
58681     /**
58682      * Create new socket BIO object. This is a pure TCP connection with
58683      * no SSL or TLS protection.
58684      * @param port port  to connect to
58685      * @return New BIO object or NULL on failure
58686      */
58687     WOLFSSL_BIO *wolfSSL_BIO_new_accept(const char *port)
58688     {
58689         WOLFSSL_BIO *bio;
58690         WOLFSSL_ENTER("wolfSSL_BIO_new_accept");
58691         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket());
58692         if (bio) {
58693             bio->port = (word16)XATOI(port);
58694             bio->type  = WOLFSSL_BIO_SOCKET;
58695         }
58696         return bio;
58697     }
58698 
58699 
58700     /**
58701      * Set the port to connect to in the BIO object
58702      * @param b BIO object
58703      * @param port destination port
58704      * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
58705      */
58706     long wolfSSL_BIO_set_conn_port(WOLFSSL_BIO *b, char* port)
58707     {
58708         int p;
58709         WOLFSSL_ENTER("wolfSSL_BIO_set_conn_port");
58710 
58711         if (!b || !port) {
58712             WOLFSSL_ENTER("Bad parameter");
58713             return WOLFSSL_FAILURE;
58714         }
58715 
58716         p = XATOI(port);
58717         if (!p || p < 0) {
58718             WOLFSSL_ENTER("Port parsing error");
58719             return WOLFSSL_FAILURE;
58720         }
58721 
58722         while (b != NULL && b->type != WOLFSSL_BIO_SOCKET) {
58723             b = b->next;
58724         }
58725         if (b == NULL) {
58726             WOLFSSL_MSG("Failed to find socket BIO in chain.");
58727             return WOLFSSL_FAILURE;
58728         }
58729 
58730         b->port = (word16)p;
58731         return WOLFSSL_SUCCESS;
58732     }
58733 
58734 #ifdef HAVE_HTTP_CLIENT
58735     /**
58736      * Attempt to connect to the destination address and port
58737      * @param b BIO object
58738      * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
58739      */
58740     long wolfSSL_BIO_do_connect(WOLFSSL_BIO *b)
58741     {
58742         SOCKET_T sfd = SOCKET_INVALID;
58743         WOLFSSL_ENTER("wolfSSL_BIO_do_connect");
58744 
58745         if (!b) {
58746             WOLFSSL_ENTER("Bad parameter");
58747             return WOLFSSL_FAILURE;
58748         }
58749 
58750         while (b && b->type != WOLFSSL_BIO_SOCKET)
58751             b = b->next;
58752 
58753         if (!b) {
58754             WOLFSSL_ENTER("No socket BIO in chain");
58755             return WOLFSSL_FAILURE;
58756         }
58757 
58758         if (wolfIO_TcpConnect(&sfd, b->ip, b->port, 0) < 0 ) {
58759             WOLFSSL_ENTER("wolfIO_TcpConnect error");
58760             return WOLFSSL_FAILURE;
58761         }
58762 
58763         b->num = sfd;
58764         b->shutdown = BIO_CLOSE;
58765         return WOLFSSL_SUCCESS;
58766     }
58767 
58768 #ifdef HAVE_SOCKADDR
58769     int wolfSSL_BIO_do_accept(WOLFSSL_BIO *b)
58770     {
58771         SOCKET_T sfd = SOCKET_INVALID;
58772         WOLFSSL_ENTER("wolfSSL_BIO_do_accept");
58773 
58774         if (!b) {
58775             WOLFSSL_MSG("Bad parameter");
58776             return WOLFSSL_FAILURE;
58777         }
58778 
58779         while (b && b->type != WOLFSSL_BIO_SOCKET)
58780             b = b->next;
58781 
58782         if (!b) {
58783             WOLFSSL_ENTER("No socket BIO in chain");
58784             return WOLFSSL_FAILURE;
58785         }
58786 
58787         if (b->num == WOLFSSL_BIO_ERROR) {
58788             if (wolfIO_TcpBind(&sfd, b->port) < 0) {
58789                 WOLFSSL_ENTER("wolfIO_TcpBind error");
58790                 return WOLFSSL_FAILURE;
58791             }
58792             b->num = sfd;
58793             b->shutdown = BIO_CLOSE;
58794         }
58795         else {
58796             WOLFSSL_BIO* new_bio;
58797             int newfd = wolfIO_TcpAccept(b->num, NULL, NULL);
58798             if (newfd < 0) {
58799                 WOLFSSL_ENTER("wolfIO_TcpBind error");
58800                 return WOLFSSL_FAILURE;
58801             }
58802             /* Create a socket BIO for using the accept'ed connection */
58803             new_bio = wolfSSL_BIO_new_socket(newfd, BIO_CLOSE);
58804             if (new_bio == NULL) {
58805                 WOLFSSL_ENTER("wolfSSL_BIO_new_socket error");
58806                 CloseSocket(newfd);
58807                 return WOLFSSL_FAILURE;
58808             }
58809             wolfSSL_BIO_set_callback(new_bio,
58810                     wolfSSL_BIO_get_callback(b));
58811             wolfSSL_BIO_set_callback_arg(new_bio,
58812                     wolfSSL_BIO_get_callback_arg(b));
58813             /* Push onto bio chain for user retrieval */
58814             if (wolfSSL_BIO_push(b, new_bio) == NULL) {
58815                 WOLFSSL_ENTER("wolfSSL_BIO_push error");
58816                 /* newfd is closed when bio is free'd */
58817                 wolfSSL_BIO_free(new_bio);
58818                 return WOLFSSL_FAILURE;
58819             }
58820         }
58821 
58822         return WOLFSSL_SUCCESS;
58823     }
58824 #endif /* HAVE_SOCKADDR */
58825 #endif /* HAVE_HTTP_CLIENT */
58826 
58827     int wolfSSL_BIO_eof(WOLFSSL_BIO* b)
58828     {
58829         WOLFSSL_ENTER("BIO_eof");
58830         if ((b != NULL) && (b->eof))
58831             return 1;
58832 
58833         return 0;
58834     }
58835 
58836     long wolfSSL_BIO_do_handshake(WOLFSSL_BIO *b)
58837     {
58838         WOLFSSL_ENTER("wolfSSL_BIO_do_handshake");
58839         if (b == NULL) {
58840             WOLFSSL_MSG("Bad parameter");
58841             return WOLFSSL_FAILURE;
58842         }
58843         if (b->type == WOLFSSL_BIO_SSL && b->ptr != NULL) {
58844             return wolfSSL_negotiate((WOLFSSL*)b->ptr);
58845         }
58846         else {
58847             WOLFSSL_MSG("Not SSL BIO or no SSL object set");
58848             return WOLFSSL_FAILURE;
58849         }
58850     }
58851 
58852     void wolfSSL_BIO_ssl_shutdown(WOLFSSL_BIO* b)
58853     {
58854         int rc;
58855 
58856         WOLFSSL_ENTER("wolfSSL_BIO_ssl_shutdown");
58857 
58858         if (b == NULL) {
58859             WOLFSSL_MSG("BIO is null.");
58860             return;
58861         }
58862 
58863         while (b != NULL && b->type != WOLFSSL_BIO_SSL) {
58864             b = b->next;
58865         }
58866         if (b == NULL) {
58867             WOLFSSL_MSG("Failed to find SSL BIO in chain.");
58868             return;
58869         }
58870 
58871         if (b->ptr != NULL) {
58872             rc = wolfSSL_shutdown((WOLFSSL*)b->ptr);
58873             if (rc == SSL_SHUTDOWN_NOT_DONE) {
58874                 /* In this case, call again to give us a chance to read the
58875                  * close notify alert from the other end. */
58876                 wolfSSL_shutdown((WOLFSSL*)b->ptr);
58877             }
58878         }
58879         else {
58880             WOLFSSL_MSG("BIO has no SSL pointer set.");
58881         }
58882     }
58883 
58884     long wolfSSL_BIO_set_ssl(WOLFSSL_BIO* b, WOLFSSL* ssl, int closeF)
58885     {
58886         long ret = WOLFSSL_FAILURE;
58887 
58888         WOLFSSL_ENTER("wolfSSL_BIO_set_ssl");
58889 
58890         if (b != NULL) {
58891             b->ptr   = ssl;
58892             b->shutdown = (byte)closeF;
58893             if (b->next != NULL)
58894                 wolfSSL_set_bio(ssl, b->next, b->next);
58895     /* add to ssl for bio free if SSL_free called before/instead of free_all? */
58896             ret = WOLFSSL_SUCCESS;
58897         }
58898 
58899         return ret;
58900     }
58901 
58902     long wolfSSL_BIO_get_ssl(WOLFSSL_BIO* bio, WOLFSSL** ssl)
58903     {
58904         WOLFSSL_ENTER("wolfSSL_BIO_get_ssl");
58905 
58906         if (bio == NULL) {
58907             WOLFSSL_MSG("bio is null.");
58908             return WOLFSSL_FAILURE;
58909         }
58910         if (ssl == NULL) {
58911             WOLFSSL_MSG("ssl is null.");
58912             return WOLFSSL_FAILURE;
58913         }
58914         if (bio->type != WOLFSSL_BIO_SSL) {
58915             WOLFSSL_MSG("bio type is not WOLFSSL_BIO_SSL.");
58916             return WOLFSSL_FAILURE;
58917         }
58918 
58919         *ssl = (WOLFSSL*)bio->ptr;
58920 
58921         return WOLFSSL_SUCCESS;
58922     }
58923 
58924     WOLFSSL_BIO* wolfSSL_BIO_new_ssl_connect(WOLFSSL_CTX* ctx)
58925     {
58926         WOLFSSL* ssl = NULL;
58927         WOLFSSL_BIO* sslBio = NULL;
58928         WOLFSSL_BIO* connBio = NULL;
58929         int err = 0;
58930 
58931         WOLFSSL_ENTER("wolfSSL_BIO_new_ssl_connect");
58932 
58933         if (ctx == NULL) {
58934             WOLFSSL_MSG("ctx is NULL.");
58935             err = 1;
58936         }
58937 
58938         if (err == 0) {
58939             ssl = wolfSSL_new(ctx);
58940             if (ssl == NULL) {
58941                 WOLFSSL_MSG("Failed to create SSL object from ctx.");
58942                 err = 1;
58943             }
58944         }
58945         if (err == 0) {
58946             sslBio = wolfSSL_BIO_new(wolfSSL_BIO_f_ssl());
58947             if (sslBio == NULL) {
58948                 WOLFSSL_MSG("Failed to create SSL BIO.");
58949                 err = 1;
58950             }
58951         }
58952         if (err == 0 && wolfSSL_BIO_set_ssl(sslBio, ssl, BIO_CLOSE) !=
58953             WOLFSSL_SUCCESS) {
58954             WOLFSSL_MSG("Failed to set SSL pointer in BIO.");
58955             err = 1;
58956         }
58957         if (err == 0) {
58958             connBio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket());
58959             if (connBio == NULL) {
58960                 WOLFSSL_MSG("Failed to create connect BIO.");
58961                 err = 1;
58962             }
58963             else {
58964                 wolfSSL_BIO_push(sslBio, connBio);
58965             }
58966         }
58967 
58968         if (err == 1) {
58969             wolfSSL_free(ssl);
58970             wolfSSL_BIO_free(sslBio);
58971             wolfSSL_BIO_free(connBio);
58972         }
58973 
58974         return sslBio;
58975     }
58976 
58977     long wolfSSL_BIO_set_conn_hostname(WOLFSSL_BIO* b, char* name)
58978     {
58979         size_t currLen = 0;
58980         size_t newLen = 0;
58981 
58982         WOLFSSL_ENTER("wolfSSL_BIO_set_conn_hostname");
58983 
58984         if (name == NULL) {
58985             WOLFSSL_MSG("Hostname is NULL.");
58986             return WOLFSSL_FAILURE;
58987         }
58988 
58989         while (b != NULL && b->type != WOLFSSL_BIO_SOCKET) {
58990             b = b->next;
58991         }
58992         if (b == NULL) {
58993             WOLFSSL_MSG("Failed to find socket BIO in chain.");
58994             return WOLFSSL_FAILURE;
58995         }
58996 
58997         newLen = XSTRLEN(name);
58998         if (b->ip == NULL) {
58999             /* +1 for null char */
59000             b->ip = (char*)XMALLOC(newLen + 1, b->heap, DYNAMIC_TYPE_OPENSSL);
59001             if (b->ip == NULL) {
59002                 WOLFSSL_MSG("Hostname malloc failed.");
59003                 return WOLFSSL_FAILURE;
59004             }
59005         }
59006         else {
59007             currLen = XSTRLEN(b->ip);
59008             if (currLen != newLen) {
59009                 b->ip = (char*)XREALLOC(b->ip, newLen + 1, b->heap,
59010                     DYNAMIC_TYPE_OPENSSL);
59011                 if (b->ip == NULL) {
59012                     WOLFSSL_MSG("Hostname realloc failed.");
59013                     return WOLFSSL_FAILURE;
59014                 }
59015             }
59016         }
59017 
59018         XMEMCPY(b->ip, name, newLen);
59019         b->ip[newLen] = '\0';
59020 
59021         return WOLFSSL_SUCCESS;
59022     }
59023 
59024 #ifndef NO_FILESYSTEM
59025     long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int closeF)
59026     {
59027         WOLFSSL_ENTER("wolfSSL_BIO_set_fd");
59028 
59029         if (b != NULL) {
59030             b->num = fd;
59031             b->shutdown = (byte)closeF;
59032         }
59033 
59034         return WOLFSSL_SUCCESS;
59035     }
59036 #endif
59037 
59038     /* Sets the close flag */
59039     int wolfSSL_BIO_set_close(WOLFSSL_BIO *b, long flag)
59040     {
59041         WOLFSSL_ENTER("wolfSSL_BIO_set_close");
59042         if (b != NULL) {
59043             b->shutdown = (byte)flag;
59044         }
59045 
59046         return WOLFSSL_SUCCESS;
59047     }
59048 
59049 #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
59050     WOLFSSL_BIO* wolfSSL_BIO_new(const WOLFSSL_BIO_METHOD* method)
59051 #else
59052     WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method)
59053 #endif
59054     {
59055         WOLFSSL_BIO* bio;
59056 
59057         WOLFSSL_ENTER("wolfSSL_BIO_new");
59058         if (method == NULL) {
59059             WOLFSSL_MSG("Bad method pointer passed in");
59060             return NULL;
59061         }
59062 
59063         bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
59064                 DYNAMIC_TYPE_OPENSSL);
59065         if (bio) {
59066             XMEMSET(bio, 0, sizeof(WOLFSSL_BIO));
59067             bio->type = (byte)method->type;
59068 #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
59069             bio->method = (WOLFSSL_BIO_METHOD*)method;
59070 #else
59071             bio->method = method;
59072 #endif
59073             bio->shutdown = BIO_CLOSE; /* default to close things */
59074             bio->num = WOLFSSL_BIO_ERROR;
59075             bio->init = 1;
59076             if (method->type == WOLFSSL_BIO_MEMORY ||
59077                     method->type == WOLFSSL_BIO_BIO) {
59078                 bio->mem_buf =(WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM),
59079                                                        0, DYNAMIC_TYPE_OPENSSL);
59080                 if (bio->mem_buf == NULL) {
59081                     WOLFSSL_MSG("Memory error");
59082                     wolfSSL_BIO_free(bio);
59083                     return NULL;
59084                 }
59085                 bio->mem_buf->data = (char*)bio->ptr;
59086             }
59087 
59088             if (method->type == WOLFSSL_BIO_MD) {
59089                 bio->ptr = wolfSSL_EVP_MD_CTX_new();
59090                 if (bio->ptr == NULL) {
59091                     WOLFSSL_MSG("Memory error");
59092                     wolfSSL_BIO_free(bio);
59093                     return NULL;
59094                 }
59095             }
59096 
59097             /* check if is custom method */
59098             if (method->createCb) {
59099                 method->createCb(bio);
59100             }
59101 
59102         #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
59103             bio->refCount = 1;
59104             #ifndef SINGLE_THREADED
59105             if (wc_InitMutex(&bio->refMutex) != 0) {
59106                 wolfSSL_BIO_free(bio);
59107                 WOLFSSL_MSG("wc_InitMutex failed for WOLFSSL_BIO");
59108                 return NULL;
59109             }
59110             #endif
59111         #endif
59112 
59113 }
59114         return bio;
59115     }
59116 
59117     WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(const void* buf, int len)
59118     {
59119         WOLFSSL_BIO* bio = NULL;
59120 
59121         if (buf == NULL) {
59122             return bio;
59123         }
59124 
59125         bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
59126         if (bio == NULL) {
59127             return bio;
59128         }
59129 
59130         if (len < 0) {
59131             /* The length of the string including terminating null. */
59132             len = (int)XSTRLEN((const char*)buf) + 1;
59133         }
59134         bio->num = bio->wrSz = len;
59135         bio->ptr = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
59136         if (bio->ptr == NULL) {
59137             wolfSSL_BIO_free(bio);
59138             return NULL;
59139         }
59140         if (bio->mem_buf != NULL) {
59141             bio->mem_buf->data = (char*)bio->ptr;
59142             bio->mem_buf->length = bio->num;
59143         }
59144 
59145         XMEMCPY(bio->ptr, buf, len);
59146 
59147         return bio;
59148     }
59149 
59150     /*
59151      * Note : If the flag BIO_NOCLOSE is set then freeing memory buffers is up
59152      *        to the application.
59153      * Returns 1 on success, 0 on failure
59154      */
59155     int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
59156     {
59157         int ret;
59158     #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
59159         int doFree = 0;
59160     #endif
59161 
59162         /* unchain?, doesn't matter in goahead since from free all */
59163         WOLFSSL_ENTER("wolfSSL_BIO_free");
59164         if (bio) {
59165 
59166             if (bio->infoCb) {
59167                 /* info callback is called before free */
59168                 ret = (int)bio->infoCb(bio, WOLFSSL_BIO_CB_FREE, NULL, 0, 0, 1);
59169                 if (ret <= 0) {
59170                     return ret;
59171                 }
59172             }
59173 
59174         #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
59175             #ifndef SINGLE_THREADED
59176             if (wc_LockMutex(&bio->refMutex) != 0) {
59177                 WOLFSSL_MSG("Couldn't lock BIO mutex");
59178                 return WOLFSSL_FAILURE;
59179             }
59180             #endif
59181 
59182             /* only free if all references to it are done */
59183             bio->refCount--;
59184             if (bio->refCount == 0) {
59185                 doFree = 1;
59186             }
59187 
59188             #ifndef SINGLE_THREADED
59189             wc_UnLockMutex(&bio->refMutex);
59190             #endif
59191 
59192             if (!doFree) {
59193                 /* return success if BIO ref count is not 1 yet */
59194                 return WOLFSSL_SUCCESS;
59195             }
59196             #ifndef SINGLE_THREADED
59197             wc_FreeMutex(&bio->refMutex);
59198             #endif
59199         #endif
59200 
59201         #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
59202             wolfSSL_CRYPTO_cleanup_ex_data(&bio->ex_data);
59203         #endif
59204 
59205             /* call custom set free callback */
59206             if (bio->method && bio->method->freeCb) {
59207                 bio->method->freeCb(bio);
59208             }
59209 
59210             /* remove from pair by setting the paired bios pair to NULL */
59211             if (bio->pair != NULL) {
59212                 bio->pair->pair = NULL;
59213             }
59214 
59215             if (bio->ip != NULL) {
59216                 XFREE(bio->ip, bio->heap, DYNAMIC_TYPE_OPENSSL);
59217             }
59218 
59219             if (bio->shutdown) {
59220                 if (bio->type == WOLFSSL_BIO_SSL && bio->ptr)
59221                     wolfSSL_free((WOLFSSL*)bio->ptr);
59222             #ifdef CloseSocket
59223                 if ((bio->type == WOLFSSL_BIO_SOCKET) && (bio->num > 0))
59224                     CloseSocket(bio->num);
59225             #endif
59226             }
59227 
59228         #ifndef NO_FILESYSTEM
59229             if (bio->type == WOLFSSL_BIO_FILE && bio->shutdown == BIO_CLOSE) {
59230                 if (bio->ptr) {
59231                     XFCLOSE((XFILE)bio->ptr);
59232                 }
59233             #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\
59234                 && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)
59235                 else if (bio->num != WOLFSSL_BIO_ERROR) {
59236                     XCLOSE(bio->num);
59237                 }
59238             #endif
59239             }
59240         #endif
59241 
59242             if (bio->shutdown != BIO_NOCLOSE) {
59243                 if (bio->type == WOLFSSL_BIO_MEMORY && bio->ptr != NULL) {
59244                     if (bio->mem_buf != NULL) {
59245                         if (bio->mem_buf->data != (char*)bio->ptr) {
59246                             XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
59247                             bio->ptr = NULL;
59248                         }
59249                     }
59250                     else {
59251                         XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
59252                         bio->ptr = NULL;
59253                     }
59254                 }
59255                 if (bio->mem_buf != NULL) {
59256                     wolfSSL_BUF_MEM_free(bio->mem_buf);
59257                     bio->mem_buf = NULL;
59258                 }
59259             }
59260 
59261             if (bio->type == WOLFSSL_BIO_MD) {
59262                 wolfSSL_EVP_MD_CTX_free((WOLFSSL_EVP_MD_CTX*)bio->ptr);
59263             }
59264 
59265             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
59266             return WOLFSSL_SUCCESS;
59267         }
59268         return WOLFSSL_FAILURE;
59269     }
59270 
59271     /* like BIO_free, but no return value */
59272     void wolfSSL_BIO_vfree(WOLFSSL_BIO* bio)
59273     {
59274         wolfSSL_BIO_free(bio);
59275     }
59276 
59277 
59278     void wolfSSL_BIO_free_all(WOLFSSL_BIO* bio)
59279     {
59280         WOLFSSL_ENTER("BIO_free_all");
59281         while (bio) {
59282             WOLFSSL_BIO* next = bio->next;
59283             wolfSSL_BIO_free(bio);
59284             bio = next;
59285         }
59286     }
59287 
59288 
59289     WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO* top, WOLFSSL_BIO* append)
59290     {
59291         WOLFSSL_ENTER("BIO_push");
59292         top->next    = append;
59293         append->prev = top;
59294 
59295         /* SSL BIO's should use the next object in the chain for IO */
59296         if (top->type == WOLFSSL_BIO_SSL && top->ptr)
59297             wolfSSL_set_bio((WOLFSSL*)top->ptr, append, append);
59298 
59299         return top;
59300     }
59301 
59302 /* Removes a WOLFSSL_BIO struct from the WOLFSSL_BIO linked list.
59303  *
59304  * bio is the WOLFSSL_BIO struct in the list and removed.
59305  *
59306  * The return WOLFSSL_BIO struct is the next WOLFSSL_BIO in the list or NULL if
59307  * there is none.
59308  */
59309 WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* bio)
59310 {
59311     if (bio == NULL) {
59312         WOLFSSL_MSG("Bad argument passed in");
59313         return NULL;
59314     }
59315 
59316     if (bio->prev != NULL) {
59317         bio->prev->next = bio->next;
59318     }
59319 
59320     if (bio->next != NULL) {
59321         bio->next->prev = bio->prev;
59322     }
59323 
59324     return bio->next;
59325 }
59326 
59327 
59328 
59329 WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void)
59330 {
59331     static WOLFSSL_BIO_METHOD meth;
59332 
59333     WOLFSSL_ENTER("wolfSSL_BIO_s_mem");
59334     meth.type = WOLFSSL_BIO_MEMORY;
59335 
59336     return &meth;
59337 }
59338 
59339 
59340 WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void)
59341 {
59342     static WOLFSSL_BIO_METHOD meth;
59343 
59344     WOLFSSL_ENTER("wolfSSL_BIO_f_base64");
59345     meth.type = WOLFSSL_BIO_BASE64;
59346 
59347     return &meth;
59348 }
59349 
59350 
59351 /* Set the flag for the bio.
59352  *
59353  * bio   the structure to set the flag in
59354  * flags the flag to use
59355  */
59356 void wolfSSL_BIO_set_flags(WOLFSSL_BIO* bio, int flags)
59357 {
59358     WOLFSSL_ENTER("wolfSSL_BIO_set_flags");
59359 
59360     if (bio != NULL) {
59361         bio->flags |= flags;
59362     }
59363 }
59364 
59365 void wolfSSL_BIO_clear_flags(WOLFSSL_BIO *bio, int flags)
59366 {
59367     WOLFSSL_ENTER("wolfSSL_BIO_clear_flags");
59368     if (bio != NULL) {
59369         bio->flags &= ~flags;
59370     }
59371 }
59372 
59373 /* Set ex_data for WOLFSSL_BIO
59374  *
59375  * bio  : BIO structure to set ex_data in
59376  * idx  : Index of ex_data to set
59377  * data : Data to set in ex_data
59378  *
59379  * Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
59380  */
59381 int wolfSSL_BIO_set_ex_data(WOLFSSL_BIO *bio, int idx, void *data)
59382 {
59383     WOLFSSL_ENTER("wolfSSL_BIO_set_ex_data");
59384 #ifdef HAVE_EX_DATA
59385     if (bio != NULL && idx < MAX_EX_DATA) {
59386         return wolfSSL_CRYPTO_set_ex_data(&bio->ex_data, idx, data);
59387     }
59388 #else
59389     (void)bio;
59390     (void)idx;
59391     (void)data;
59392 #endif
59393     return WOLFSSL_FAILURE;
59394 }
59395 
59396 int wolfSSL_BIO_get_fd(WOLFSSL_BIO *bio, int* fd)
59397 {
59398     WOLFSSL_ENTER("wolfSSL_BIO_get_fd");
59399 
59400     if (bio != NULL) {
59401         if (fd != NULL)
59402             *fd = bio->num;
59403         return bio->num;
59404     }
59405 
59406     return WOLFSSL_BIO_ERROR;
59407 }
59408 
59409 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
59410 /* Set ex_data for WOLFSSL_BIO
59411  *
59412  * bio  : BIO structure to set ex_data in
59413  * idx  : Index of ex_data to set
59414  * data : Data to set in ex_data
59415  * cleanup_routine : Function pointer to clean up data
59416  *
59417  * Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
59418  */
59419 int wolfSSL_BIO_set_ex_data_with_cleanup(
59420     WOLFSSL_BIO *bio,
59421     int idx,
59422     void *data,
59423     wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
59424 {
59425     WOLFSSL_ENTER("wolfSSL_BIO_set_ex_data_with_cleanup");
59426     if (bio != NULL && idx < MAX_EX_DATA) {
59427         return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&bio->ex_data, idx, data,
59428                                                        cleanup_routine);
59429     }
59430     return WOLFSSL_FAILURE;
59431 }
59432 #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
59433 
59434 /* Get ex_data in WOLFSSL_BIO at given index
59435  *
59436  * bio  : BIO structure to get ex_data from
59437  * idx  : Index of ex_data to get data from
59438  *
59439  * Returns void pointer to ex_data on success or NULL on failure
59440  */
59441 void *wolfSSL_BIO_get_ex_data(WOLFSSL_BIO *bio, int idx)
59442 {
59443     WOLFSSL_ENTER("wolfSSL_BIO_get_ex_data");
59444 #ifdef HAVE_EX_DATA
59445     if (bio != NULL && idx < MAX_EX_DATA && idx >= 0) {
59446         return wolfSSL_CRYPTO_get_ex_data(&bio->ex_data, idx);
59447     }
59448 #else
59449     (void)bio;
59450     (void)idx;
59451 #endif
59452     return NULL;
59453 }
59454 
59455 #endif /* OPENSSL_EXTRA */
59456 
59457 #ifndef NO_FILESYSTEM
59458     PRAGMA_CLANG_DIAG_PUSH
59459     PRAGMA_CLANG("clang diagnostic ignored \"-Wformat-nonliteral\"")
59460 #endif
59461 
59462 #if defined(OPENSSL_EXTRA) && !defined(NO_BIO)
59463 /* returns amount printed on success, negative in fail case */
59464 int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args)
59465 {
59466     int ret = -1;
59467 
59468     if (bio == NULL)
59469         return WOLFSSL_FATAL_ERROR;
59470 
59471     switch (bio->type) {
59472 #if !defined(NO_FILESYSTEM)
59473         case WOLFSSL_BIO_FILE:
59474             if (bio->ptr == NULL) {
59475                 va_end(args);
59476                 return -1;
59477             }
59478             ret = XVFPRINTF((XFILE)bio->ptr, format, args);
59479             break;
59480 #endif
59481 
59482         case WOLFSSL_BIO_MEMORY:
59483     /* In Visual Studio versions prior to Visual Studio 2013, the va_* symbols
59484        aren't defined. If using Visual Studio 2013 or later, define
59485        HAVE_VA_COPY. */
59486     #if !defined(_WIN32) || defined(HAVE_VA_COPY)
59487         case WOLFSSL_BIO_SSL:
59488             {
59489                 int count;
59490                 char* pt = NULL;
59491                 va_list copy;
59492 
59493                 #ifdef FUSION_RTOS
59494                    copy = args;    /* hack, depends on internal implementation
59495                                     * of va_list in VisualDSP++ */
59496                 #else
59497                     va_copy(copy, args);
59498                 #endif
59499                 count = XVSNPRINTF(NULL, 0, format, args);
59500                 if (count >= 0)
59501                 {
59502                     pt = (char*)XMALLOC(count + 1, bio->heap,
59503                                         DYNAMIC_TYPE_TMP_BUFFER);
59504                     if (pt != NULL)
59505                     {
59506                         count = XVSNPRINTF(pt, count + 1, format, copy);
59507                         if (count >= 0)
59508                         {
59509                             ret = wolfSSL_BIO_write(bio, pt, count);
59510                         }
59511                         XFREE(pt, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
59512                     }
59513                 }
59514                 va_end(copy);
59515             }
59516             break;
59517     #endif /* !_WIN32 || HAVE_VA_COPY */
59518 
59519         default:
59520             WOLFSSL_MSG("Unsupported WOLFSSL_BIO type for wolfSSL_BIO_printf");
59521             break;
59522     }
59523 
59524     return ret;
59525 }
59526 
59527 /* returns amount printed on success, negative in fail case */
59528 int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...)
59529 {
59530     int ret;
59531     va_list args;
59532     va_start(args, format);
59533 
59534     ret = wolfSSL_BIO_vprintf(bio, format, args);
59535 
59536     va_end(args);
59537 
59538     return ret;
59539 }
59540 #endif /* OPENSSL_EXTRA && !NO_BIO */
59541 
59542 #ifndef NO_FILESYSTEM
59543     PRAGMA_CLANG_DIAG_POP
59544 #endif
59545 
59546 #undef  LINE_LEN
59547 #define LINE_LEN 16
59548 int wolfSSL_BIO_dump(WOLFSSL_BIO *bio, const char *buf, int length)
59549 {
59550     int ret = 0;
59551 
59552     if (bio == NULL)
59553         return 0;
59554 
59555 #ifndef NO_FILESYSTEM
59556     if (bio->type == WOLFSSL_BIO_FILE) {
59557         int i;
59558         char line[80];
59559 
59560         if (!buf) {
59561             return XFPUTS("\tNULL", (XFILE)bio->ptr);
59562         }
59563 
59564         XSPRINTF(line, "\t");
59565         for (i = 0; i < LINE_LEN; i++) {
59566             if (i < length)
59567                 XSPRINTF(line + 1 + i * 3,"%02x ", buf[i]);
59568             else
59569                 XSPRINTF(line + 1 + i * 3, "   ");
59570         }
59571         XSPRINTF(line + 1 + LINE_LEN * 3, "| ");
59572         for (i = 0; i < LINE_LEN; i++) {
59573             if (i < length) {
59574                 XSPRINTF(line + 3 + LINE_LEN * 3 + i,
59575                      "%c", 31 < buf[i] && buf[i] < 127 ? buf[i] : '.');
59576             }
59577         }
59578         ret += XFPUTS(line, (XFILE)bio->ptr);
59579 
59580         if (length > LINE_LEN)
59581             ret += wolfSSL_BIO_dump(bio, buf + LINE_LEN, length - LINE_LEN);
59582     }
59583 #else
59584     (void)buf;
59585     (void)length;
59586 #endif
59587 
59588     return ret;
59589 }
59590 
59591 #if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
59592     defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
59593     defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
59594     defined(WOLFSSL_HAPROXY)
59595 
59596     int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name) {
59597     #ifndef NO_FILESYSTEM
59598         XFILE fp;
59599 
59600         WOLFSSL_ENTER("wolfSSL_BIO_new_file");
59601 
59602         if ((wolfSSL_BIO_get_fp(b, &fp) == WOLFSSL_SUCCESS) && (fp != XBADFILE))
59603         {
59604             XFCLOSE(fp);
59605         }
59606 
59607         fp = XFOPEN(name, "rb");
59608         if (fp == XBADFILE)
59609             return WOLFSSL_BAD_FILE;
59610 
59611         if (wolfSSL_BIO_set_fp(b, fp, BIO_CLOSE) != WOLFSSL_SUCCESS) {
59612             XFCLOSE(fp);
59613             return WOLFSSL_BAD_FILE;
59614         }
59615 
59616         /* file is closed when bio is free'd */
59617         return WOLFSSL_SUCCESS;
59618     #else
59619         (void)name;
59620         (void)b;
59621         return WOLFSSL_NOT_IMPLEMENTED;
59622     #endif
59623     }
59624 
59625 #endif
59626 
59627 #if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
59628     || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
59629 
59630 WOLFSSL_BIO *wolfSSL_BIO_new_file(const char *filename, const char *mode)
59631 {
59632 #ifndef NO_FILESYSTEM
59633     WOLFSSL_BIO* bio;
59634     XFILE fp;
59635 
59636     WOLFSSL_ENTER("wolfSSL_BIO_new_file");
59637 
59638     fp = XFOPEN(filename, mode);
59639     if (fp == XBADFILE)
59640         return NULL;
59641 
59642     bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
59643     if (bio == NULL) {
59644         XFCLOSE(fp);
59645         return bio;
59646     }
59647 
59648     if (wolfSSL_BIO_set_fp(bio, fp, BIO_CLOSE) != WOLFSSL_SUCCESS) {
59649         XFCLOSE(fp);
59650         wolfSSL_BIO_free(bio);
59651         bio = NULL;
59652     }
59653 
59654     /* file is closed when BIO is free'd */
59655     return bio;
59656 #else
59657     (void)filename;
59658     (void)mode;
59659     return NULL;
59660 #endif /* NO_FILESYSTEM */
59661 }
59662 
59663 #ifndef NO_FILESYSTEM
59664 WOLFSSL_BIO* wolfSSL_BIO_new_fp(XFILE fp, int close_flag)
59665 {
59666     WOLFSSL_BIO* bio;
59667 
59668     WOLFSSL_ENTER("wolfSSL_BIO_new_fp");
59669 
59670     bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
59671     if (bio == NULL) {
59672         return bio;
59673     }
59674 
59675     if (wolfSSL_BIO_set_fp(bio, fp, close_flag) != WOLFSSL_SUCCESS) {
59676         wolfSSL_BIO_free(bio);
59677         bio = NULL;
59678     }
59679 
59680     /* file is closed when BIO is free'd or by user depending on flag */
59681     return bio;
59682 }
59683 #endif
59684 #endif
59685 
59686 #if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
59687     || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
59688 
59689 /* Creates a new bio pair.
59690 Returns WOLFSSL_SUCCESS if no error, WOLFSSL_FAILURE otherwise.*/
59691 int wolfSSL_BIO_new_bio_pair(WOLFSSL_BIO **bio1_p, size_t writebuf1,
59692                                          WOLFSSL_BIO **bio2_p, size_t writebuf2)
59693 {
59694     WOLFSSL_BIO *bio1 = NULL, *bio2 = NULL;
59695     int ret = 1;
59696 
59697     WOLFSSL_ENTER("wolfSSL_BIO_new_bio_pair()");
59698 
59699     if (bio1_p == NULL || bio2_p == NULL) {
59700         WOLFSSL_MSG("Bad Function Argument");
59701         return BAD_FUNC_ARG;
59702     }
59703 
59704     /* set up the new bio structures and write buf sizes */
59705     if ((bio1 = wolfSSL_BIO_new(wolfSSL_BIO_s_bio())) == NULL) {
59706         WOLFSSL_MSG("Bio allocation failed");
59707         ret = WOLFSSL_FAILURE;
59708     }
59709     if (ret) {
59710         if ((bio2 = wolfSSL_BIO_new(wolfSSL_BIO_s_bio())) == NULL) {
59711             WOLFSSL_MSG("Bio allocation failed");
59712             ret = WOLFSSL_FAILURE;
59713         }
59714     }
59715     if (ret && writebuf1) {
59716         if (!(ret = wolfSSL_BIO_set_write_buf_size(bio1, (long)writebuf1))) {
59717             WOLFSSL_MSG("wolfSSL_BIO_set_write_buf() failure");
59718         }
59719     }
59720     if (ret && writebuf2) {
59721         if (!(ret = wolfSSL_BIO_set_write_buf_size(bio2, (long)writebuf2))) {
59722             WOLFSSL_MSG("wolfSSL_BIO_set_write_buf() failure");
59723         }
59724     }
59725 
59726     if (ret) {
59727         if ((ret = wolfSSL_BIO_make_bio_pair(bio1, bio2))) {
59728             *bio1_p = bio1;
59729             *bio2_p = bio2;
59730         }
59731     }
59732     if (!ret) {
59733         wolfSSL_BIO_free(bio1);
59734         bio1 = NULL;
59735         wolfSSL_BIO_free(bio2);
59736         bio2 = NULL;
59737     }
59738     return ret;
59739 }
59740 
59741 #endif
59742 
59743 #ifdef OPENSSL_ALL
59744 
59745 #ifndef NO_WOLFSSL_STUB
59746 void wolfSSL_BIO_set_init(WOLFSSL_BIO* bio, int init)
59747 {
59748     WOLFSSL_STUB("wolfSSL_BIO_set_init");
59749     (void)bio;
59750     (void)init;
59751 }
59752 #endif /* NO_WOLFSSL_STUB */
59753 
59754 void wolfSSL_BIO_set_shutdown(WOLFSSL_BIO* bio, int shut)
59755 {
59756     WOLFSSL_ENTER("wolfSSL_BIO_set_shutdown");
59757     if (bio != NULL)
59758         bio->shutdown = shut;
59759 }
59760 
59761 int wolfSSL_BIO_get_shutdown(WOLFSSL_BIO* bio)
59762 {
59763     WOLFSSL_ENTER("wolfSSL_BIO_get_shutdown");
59764     return bio != NULL && bio->shutdown;
59765 }
59766 
59767 void wolfSSL_BIO_clear_retry_flags(WOLFSSL_BIO* bio)
59768 {
59769     WOLFSSL_ENTER("wolfSSL_BIO_clear_retry_flags");
59770 
59771     if (bio)
59772         bio->flags &= ~(WOLFSSL_BIO_FLAG_READ|WOLFSSL_BIO_FLAG_RETRY);
59773 }
59774 
59775 int wolfSSL_BIO_should_retry(WOLFSSL_BIO *bio)
59776 {
59777     int ret = 0;
59778     if (bio != NULL) {
59779         ret = (int)(bio->flags & WOLFSSL_BIO_FLAG_RETRY);
59780     }
59781 
59782     return ret;
59783 }
59784 
59785 #endif /* OPENSSL_ALL */
59786 
59787 #endif /* !NO_BIO */
59788 
59789 /*******************************************************************************
59790  * END OF BIO API
59791  ******************************************************************************/
59792 
59793 /*******************************************************************************
59794  * START OF RAND API
59795  ******************************************************************************/
59796 
59797 #if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
59798 static int wolfSSL_RAND_InitMutex(void)
59799 {
59800     if (gRandMethodsInit == 0) {
59801         if (wc_InitMutex(&gRandMethodMutex) != 0) {
59802             WOLFSSL_MSG("Bad Init Mutex rand methods");
59803             return BAD_MUTEX_E;
59804         }
59805         gRandMethodsInit = 1;
59806     }
59807     return 0;
59808 }
59809 #endif
59810 
59811 #ifdef OPENSSL_EXTRA
59812 
59813 /* Checks if the global RNG has been created. If not then one is created.
59814  *
59815  * Returns WOLFSSL_SUCCESS when no error is encountered.
59816  */
59817 static int wolfSSL_RAND_Init(void)
59818 {
59819     int ret = WOLFSSL_FAILURE;
59820 #ifdef HAVE_GLOBAL_RNG
59821     if (wc_LockMutex(&globalRNGMutex) == 0) {
59822         if (initGlobalRNG == 0) {
59823             ret = wc_InitRng(&globalRNG);
59824             if (ret == 0) {
59825                 initGlobalRNG = 1;
59826                 ret = WOLFSSL_SUCCESS;
59827             }
59828         }
59829         wc_UnLockMutex(&globalRNGMutex);
59830     }
59831 #endif
59832     return ret;
59833 }
59834 
59835 
59836 /* WOLFSSL_SUCCESS on ok */
59837 int wolfSSL_RAND_seed(const void* seed, int len)
59838 {
59839 #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
59840     if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
59841         if (gRandMethods && gRandMethods->seed) {
59842             int ret = gRandMethods->seed(seed, len);
59843             wc_UnLockMutex(&gRandMethodMutex);
59844             return ret;
59845         }
59846         wc_UnLockMutex(&gRandMethodMutex);
59847     }
59848 #else
59849     (void)seed;
59850     (void)len;
59851 #endif
59852 
59853     /* Make sure global shared RNG (globalRNG) is initialized */
59854     return wolfSSL_RAND_Init();
59855 }
59856 
59857 
59858 /* Returns the path for reading seed data from.
59859  * Uses the env variable $RANDFILE first if set, if not then used $HOME/.rnd
59860  *
59861  * Note uses stdlib by default unless XGETENV macro is overwritten
59862  *
59863  * fname buffer to hold path
59864  * len   length of fname buffer
59865  *
59866  * Returns a pointer to fname on success and NULL on failure
59867  */
59868 const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
59869 {
59870 #ifndef NO_FILESYSTEM
59871     char* rt;
59872     char ap[] = "/.rnd";
59873 
59874     WOLFSSL_ENTER("wolfSSL_RAND_file_name");
59875 
59876     if (fname == NULL) {
59877         return NULL;
59878     }
59879 
59880     XMEMSET(fname, 0, len);
59881     /* if access to stdlib.h */
59882     if ((rt = XGETENV("RANDFILE")) != NULL) {
59883         if (len > XSTRLEN(rt)) {
59884             XMEMCPY(fname, rt, XSTRLEN(rt));
59885         }
59886         else {
59887             WOLFSSL_MSG("RANDFILE too large for buffer");
59888             rt = NULL;
59889         }
59890     }
59891 
59892     /* $RANDFILE was not set or is too large, check $HOME */
59893     if (rt == NULL) {
59894         WOLFSSL_MSG("Environment variable RANDFILE not set");
59895         if ((rt = XGETENV("HOME")) == NULL) {
59896             WOLFSSL_MSG("Environment variable HOME not set");
59897             return NULL;
59898         }
59899 
59900         if (len > XSTRLEN(rt) +  XSTRLEN(ap)) {
59901             fname[0] = '\0';
59902             XSTRNCAT(fname, rt, len);
59903             XSTRNCAT(fname, ap, len - XSTRLEN(rt));
59904             return fname;
59905         }
59906         else {
59907             WOLFSSL_MSG("HOME too large for buffer");
59908             return NULL;
59909         }
59910     }
59911 
59912     return fname;
59913 #else
59914     /* no filesystem defined */
59915     WOLFSSL_ENTER("wolfSSL_RAND_file_name");
59916     WOLFSSL_MSG("No filesystem feature enabled, not compiled in");
59917     (void)fname;
59918     (void)len;
59919     return NULL;
59920 #endif
59921 }
59922 
59923 
59924 /* Writes 1024 bytes from the RNG to the given file name.
59925  *
59926  * fname name of file to write to
59927  *
59928  * Returns the number of bytes written
59929  */
59930 int wolfSSL_RAND_write_file(const char* fname)
59931 {
59932     int bytes = 0;
59933 
59934     WOLFSSL_ENTER("RAND_write_file");
59935 
59936     if (fname == NULL) {
59937         return SSL_FAILURE;
59938     }
59939 
59940 #ifndef NO_FILESYSTEM
59941     {
59942     #ifndef WOLFSSL_SMALL_STACK
59943         unsigned char buf[1024];
59944     #else
59945         unsigned char* buf = (unsigned char *)XMALLOC(1024, NULL,
59946                                                        DYNAMIC_TYPE_TMP_BUFFER);
59947         if (buf == NULL) {
59948             WOLFSSL_MSG("malloc failed");
59949             return SSL_FAILURE;
59950         }
59951     #endif
59952         bytes = 1024; /* default size of buf */
59953 
59954         if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
59955             WOLFSSL_MSG("No RNG to use");
59956         #ifdef WOLFSSL_SMALL_STACK
59957             XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
59958         #endif
59959             return 0;
59960         }
59961 
59962         if (wc_RNG_GenerateBlock(&globalRNG, buf, bytes) != 0) {
59963             WOLFSSL_MSG("Error generating random buffer");
59964             bytes = 0;
59965         }
59966         else {
59967             XFILE f;
59968 
59969             f = XFOPEN(fname, "wb");
59970             if (f == XBADFILE) {
59971                 WOLFSSL_MSG("Error opening the file");
59972                 bytes = 0;
59973             }
59974             else {
59975                 XFWRITE(buf, 1, bytes, f);
59976                 XFCLOSE(f);
59977             }
59978         }
59979         ForceZero(buf, bytes);
59980     #ifdef WOLFSSL_SMALL_STACK
59981         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
59982     #endif
59983     }
59984 #endif
59985 
59986     return bytes;
59987 }
59988 
59989 #ifndef FREERTOS_TCP
59990 
59991 /* These constant values are protocol values made by egd */
59992 #if defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API) && !defined(NETOS)
59993     #define WOLFSSL_EGD_NBLOCK 0x01
59994     #include <sys/un.h>
59995 #endif
59996 
59997 /* This collects entropy from the path nm and seeds the global PRNG with it.
59998  *
59999  * nm is the file path to the egd server
60000  *
60001  * Returns the number of bytes read.
60002  */
60003 int wolfSSL_RAND_egd(const char* nm)
60004 {
60005 #if defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API) && !defined(HAVE_FIPS) && \
60006     defined(HAVE_HASHDRBG)
60007     struct sockaddr_un rem;
60008     int fd;
60009     int ret = WOLFSSL_SUCCESS;
60010     word32 bytes = 0;
60011     word32 idx   = 0;
60012 #ifndef WOLFSSL_SMALL_STACK
60013     unsigned char buf[256];
60014 #else
60015     unsigned char* buf;
60016     buf = (unsigned char*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
60017     if (buf == NULL) {
60018         WOLFSSL_MSG("Not enough memory");
60019         return WOLFSSL_FATAL_ERROR;
60020     }
60021 #endif
60022 
60023     XMEMSET(&rem, 0, sizeof(struct sockaddr_un));
60024     if (nm == NULL) {
60025     #ifdef WOLFSSL_SMALL_STACK
60026         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
60027     #endif
60028         return WOLFSSL_FATAL_ERROR;
60029     }
60030 
60031     fd = socket(AF_UNIX, SOCK_STREAM, 0);
60032     if (fd < 0) {
60033         WOLFSSL_MSG("Error creating socket");
60034     #ifdef WOLFSSL_SMALL_STACK
60035         XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
60036     #endif
60037         return WOLFSSL_FATAL_ERROR;
60038     }
60039     rem.sun_family = AF_UNIX;
60040     XSTRNCPY(rem.sun_path, nm, sizeof(rem.sun_path) - 1);
60041     rem.sun_path[sizeof(rem.sun_path)-1] = '\0';
60042 
60043     /* connect to egd server */
60044     if (connect(fd, (struct sockaddr*)&rem, sizeof(struct sockaddr_un)) == -1) {
60045         WOLFSSL_MSG("error connecting to egd server");
60046         ret = WOLFSSL_FATAL_ERROR;
60047     }
60048 
60049     while (ret == WOLFSSL_SUCCESS && bytes < 255 && idx + 2 < 256) {
60050         buf[idx]     = WOLFSSL_EGD_NBLOCK;
60051         buf[idx + 1] = 255 - bytes; /* request 255 bytes from server */
60052         ret = (int)write(fd, buf + idx, 2);
60053         if (ret != 2) {
60054             if (errno == EAGAIN) {
60055                 ret = WOLFSSL_SUCCESS;
60056                 continue;
60057             }
60058             WOLFSSL_MSG("error requesting entropy from egd server");
60059             ret = WOLFSSL_FATAL_ERROR;
60060             break;
60061         }
60062 
60063         /* attempting to read */
60064         buf[idx] = 0;
60065         ret = (int)read(fd, buf + idx, 256 - bytes);
60066         if (ret == 0) {
60067             WOLFSSL_MSG("error reading entropy from egd server");
60068             ret = WOLFSSL_FATAL_ERROR;
60069             break;
60070         }
60071         if (ret > 0 && buf[idx] > 0) {
60072             bytes += buf[idx]; /* egd stores amount sent in first byte */
60073             if (bytes + idx > 255 || buf[idx] > ret) {
60074                 WOLFSSL_MSG("Buffer error");
60075                 ret = WOLFSSL_FATAL_ERROR;
60076                 break;
60077             }
60078             XMEMMOVE(buf + idx, buf + idx + 1, buf[idx]);
60079             idx = bytes;
60080             ret = WOLFSSL_SUCCESS;
60081             if (bytes >= 255) {
60082                 break;
60083             }
60084         }
60085         else {
60086             if (errno == EAGAIN || errno == EINTR) {
60087                 WOLFSSL_MSG("EGD would read");
60088                 ret = WOLFSSL_SUCCESS; /* try again */
60089             }
60090             else if (buf[idx] == 0) {
60091                 /* if egd returned 0 then there is no more entropy to be had.
60092                    Do not try more reads. */
60093                 ret = WOLFSSL_SUCCESS;
60094                 break;
60095             }
60096             else {
60097                 WOLFSSL_MSG("Error with read");
60098                 ret = WOLFSSL_FATAL_ERROR;
60099             }
60100         }
60101     }
60102 
60103     if (bytes > 0 && ret == WOLFSSL_SUCCESS) {
60104         /* call to check global RNG is created */
60105         if (wolfSSL_RAND_Init() != SSL_SUCCESS) {
60106             WOLFSSL_MSG("Error with initializing global RNG structure");
60107             ret = WOLFSSL_FATAL_ERROR;
60108         }
60109         else if (wc_RNG_DRBG_Reseed(&globalRNG, (const byte*) buf, bytes)
60110                 != 0) {
60111             WOLFSSL_MSG("Error with reseeding DRBG structure");
60112             ret = WOLFSSL_FATAL_ERROR;
60113         }
60114         #ifdef SHOW_SECRETS
60115         else { /* print out entropy found only when no error occured */
60116             word32 i;
60117             printf("EGD Entropy = ");
60118             for (i = 0; i < bytes; i++) {
60119                 printf("%02X", buf[i]);
60120             }
60121             printf("\n");
60122         }
60123         #endif
60124     }
60125 
60126     ForceZero(buf, bytes);
60127     #ifdef WOLFSSL_SMALL_STACK
60128     XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
60129     #endif
60130     close(fd);
60131 
60132     if (ret == WOLFSSL_SUCCESS) {
60133         return bytes;
60134     }
60135     else {
60136         return ret;
60137     }
60138 #else
60139     WOLFSSL_MSG("Type of socket needed is not available");
60140     WOLFSSL_MSG("\tor using mode where DRBG API is not available");
60141     (void)nm;
60142 
60143     return WOLFSSL_FATAL_ERROR;
60144 #endif /* USE_WOLFSSL_IO && !USE_WINDOWS_API && !HAVE_FIPS && HAVE_HASHDRBG */
60145 }
60146 
60147 #endif /* !FREERTOS_TCP */
60148 
60149 void wolfSSL_RAND_Cleanup(void)
60150 {
60151 #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
60152     if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
60153         if (gRandMethods && gRandMethods->cleanup)
60154             gRandMethods->cleanup();
60155         wc_UnLockMutex(&gRandMethodMutex);
60156     }
60157 
60158     if (wc_FreeMutex(&gRandMethodMutex) == 0)
60159         gRandMethodsInit = 0;
60160 #endif
60161 #ifdef HAVE_GLOBAL_RNG
60162     if (wc_LockMutex(&globalRNGMutex) == 0) {
60163         if (initGlobalRNG) {
60164             wc_FreeRng(&globalRNG);
60165             initGlobalRNG = 0;
60166         }
60167         wc_UnLockMutex(&globalRNGMutex);
60168     }
60169 #endif
60170 }
60171 
60172 /* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise WOLFSSL_FAILURE */
60173 int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num)
60174 {
60175     int ret;
60176     int hash;
60177     byte secret[DRBG_SEED_LEN]; /* secret length arbitraily choosen */
60178 
60179 #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
60180     if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
60181         if (gRandMethods && gRandMethods->pseudorand) {
60182             ret = gRandMethods->pseudorand(buf, num);
60183             wc_UnLockMutex(&gRandMethodMutex);
60184             return ret;
60185         }
60186         wc_UnLockMutex(&gRandMethodMutex);
60187     }
60188 #endif
60189 
60190 #ifdef WOLFSSL_HAVE_PRF
60191     #ifndef NO_SHA256
60192     hash = WC_SHA256;
60193     #elif defined(WOLFSSL_SHA384)
60194     hash = WC_SHA384;
60195     #elif !defined(NO_SHA)
60196     hash = WC_SHA;
60197     #elif !defined(NO_MD5)
60198     hash = WC_MD5;
60199     #endif
60200 
60201     /* get secret value from source of entropy */
60202     ret = wolfSSL_RAND_bytes(secret, DRBG_SEED_LEN);
60203 
60204     /* uses input buffer to seed for pseudo random number generation, each
60205      * thread will potentially have different results this way */
60206     if (ret == WOLFSSL_SUCCESS) {
60207         PRIVATE_KEY_UNLOCK();
60208         ret = wc_PRF(buf, num, secret, DRBG_SEED_LEN, (const byte*)buf, num,
60209                 hash, NULL, INVALID_DEVID);
60210         PRIVATE_KEY_LOCK();
60211         ret = (ret == 0) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE;
60212     }
60213 #else
60214     /* fall back to just doing wolfSSL_RAND_bytes if PRF not avialbale */
60215     ret = wolfSSL_RAND_bytes(buf, num);
60216     (void)hash;
60217     (void)secret;
60218 #endif
60219     return ret;
60220 }
60221 
60222 /* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise WOLFSSL_FAILURE */
60223 int wolfSSL_RAND_bytes(unsigned char* buf, int num)
60224 {
60225     int     ret = 0;
60226     WC_RNG* rng = NULL;
60227 #ifdef WOLFSSL_SMALL_STACK
60228     WC_RNG* tmpRNG = NULL;
60229 #else
60230     WC_RNG  tmpRNG[1];
60231 #endif
60232     int initTmpRng = 0;
60233     int blockCount = 0;
60234 #ifdef HAVE_GLOBAL_RNG
60235     int used_global = 0;
60236 #endif
60237 
60238     WOLFSSL_ENTER("wolfSSL_RAND_bytes");
60239     /* sanity check */
60240     if (buf == NULL || num < 0)
60241         /* return code compliant with OpenSSL */
60242         return 0;
60243 
60244     /* if a RAND callback has been set try and use it */
60245 #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
60246     if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
60247         if (gRandMethods && gRandMethods->bytes) {
60248             ret = gRandMethods->bytes(buf, num);
60249             wc_UnLockMutex(&gRandMethodMutex);
60250             return ret;
60251         }
60252         wc_UnLockMutex(&gRandMethodMutex);
60253     }
60254 #endif
60255 #ifdef HAVE_GLOBAL_RNG
60256     if (initGlobalRNG) {
60257         if (wc_LockMutex(&globalRNGMutex) != 0) {
60258             WOLFSSL_MSG("Bad Lock Mutex rng");
60259             return ret;
60260         }
60261 
60262         rng = &globalRNG;
60263         used_global = 1;
60264     }
60265     else
60266 #endif
60267     {
60268     #ifdef WOLFSSL_SMALL_STACK
60269         tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
60270         if (tmpRNG == NULL)
60271             return ret;
60272     #endif
60273         if (wc_InitRng(tmpRNG) == 0) {
60274             rng = tmpRNG;
60275             initTmpRng = 1;
60276         }
60277     }
60278     if (rng) {
60279         /* handles size greater than RNG_MAX_BLOCK_LEN */
60280         blockCount = num / RNG_MAX_BLOCK_LEN;
60281 
60282         while (blockCount--) {
60283             ret = wc_RNG_GenerateBlock(rng, buf, RNG_MAX_BLOCK_LEN);
60284             if (ret != 0) {
60285                 WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
60286                 break;
60287             }
60288             num -= RNG_MAX_BLOCK_LEN;
60289             buf += RNG_MAX_BLOCK_LEN;
60290         }
60291 
60292         if (ret == 0 && num)
60293             ret = wc_RNG_GenerateBlock(rng, buf, num);
60294 
60295         if (ret != 0)
60296             WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
60297         else
60298             ret = WOLFSSL_SUCCESS;
60299     }
60300 
60301 #ifdef HAVE_GLOBAL_RNG
60302     if (used_global == 1)
60303         wc_UnLockMutex(&globalRNGMutex);
60304 #endif
60305     if (initTmpRng)
60306         wc_FreeRng(tmpRNG);
60307 #ifdef WOLFSSL_SMALL_STACK
60308     if (tmpRNG)
60309         XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
60310 #endif
60311 
60312     return ret;
60313 }
60314 
60315 
60316 int wolfSSL_RAND_poll(void)
60317 {
60318     byte  entropy[16];
60319     int  ret = 0;
60320     word32 entropy_sz = 16;
60321 
60322     WOLFSSL_ENTER("wolfSSL_RAND_poll");
60323     if (initGlobalRNG == 0){
60324         WOLFSSL_MSG("Global RNG no Init");
60325         return  WOLFSSL_FAILURE;
60326     }
60327     ret = wc_GenerateSeed(&globalRNG.seed, entropy, entropy_sz);
60328     if (ret != 0){
60329         WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
60330         ret = WOLFSSL_FAILURE;
60331     }else
60332         ret = WOLFSSL_SUCCESS;
60333 
60334     return ret;
60335 }
60336 
60337     /* If a valid struct is provided with function pointers, will override
60338        RAND_seed, bytes, cleanup, add, pseudo_bytes and status.  If a NULL
60339        pointer is passed in, it will cancel any previous function overrides.
60340 
60341        Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. */
60342     int wolfSSL_RAND_set_rand_method(const WOLFSSL_RAND_METHOD *methods)
60343     {
60344     #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
60345         if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
60346             gRandMethods = methods;
60347             wc_UnLockMutex(&gRandMethodMutex);
60348             return WOLFSSL_SUCCESS;
60349         }
60350     #else
60351         (void)methods;
60352     #endif
60353         return WOLFSSL_FAILURE;
60354     }
60355 
60356     /* Returns WOLFSSL_SUCCESS if the RNG has been seeded with enough data */
60357     int wolfSSL_RAND_status(void)
60358     {
60359         int ret = WOLFSSL_SUCCESS;
60360     #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
60361         if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
60362             if (gRandMethods && gRandMethods->status)
60363                 ret = gRandMethods->status();
60364             wc_UnLockMutex(&gRandMethodMutex);
60365         }
60366         else {
60367             ret = WOLFSSL_FAILURE;
60368         }
60369     #else
60370         /* wolfCrypt provides enough seed internally, so return success */
60371     #endif
60372         return ret;
60373     }
60374 
60375     void wolfSSL_RAND_add(const void* add, int len, double entropy)
60376     {
60377     #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
60378         if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
60379             if (gRandMethods && gRandMethods->add) {
60380                 /* callback has return code, but RAND_add does not */
60381                 (void)gRandMethods->add(add, len, entropy);
60382             }
60383             wc_UnLockMutex(&gRandMethodMutex);
60384         }
60385     #else
60386         /* wolfSSL seeds/adds internally, use explicit RNG if you want
60387            to take control */
60388         (void)add;
60389         (void)len;
60390         (void)entropy;
60391     #endif
60392     }
60393 
60394 #endif /* OPENSSL_EXTRA */
60395 
60396 /*******************************************************************************
60397  * END OF RAND API
60398  ******************************************************************************/
60399 
60400 /*******************************************************************************
60401  * START OF EVP_CIPHER API
60402  ******************************************************************************/
60403 
60404 #ifdef OPENSSL_EXTRA
60405 
60406     /* store for external read of iv, WOLFSSL_SUCCESS on success */
60407     int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
60408     {
60409         WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
60410 
60411         if (ctx == NULL) {
60412             WOLFSSL_MSG("Bad function argument");
60413             return WOLFSSL_FATAL_ERROR;
60414         }
60415 
60416         switch (ctx->cipherType) {
60417 #ifndef NO_AES
60418 #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
60419             case AES_128_CBC_TYPE :
60420             case AES_192_CBC_TYPE :
60421             case AES_256_CBC_TYPE :
60422                 WOLFSSL_MSG("AES CBC");
60423                 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
60424                 break;
60425 #endif
60426 #ifdef HAVE_AESGCM
60427             case AES_128_GCM_TYPE :
60428             case AES_192_GCM_TYPE :
60429             case AES_256_GCM_TYPE :
60430                 WOLFSSL_MSG("AES GCM");
60431                 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
60432                 break;
60433 #endif /* HAVE_AESGCM */
60434 #ifdef HAVE_AES_ECB
60435             case AES_128_ECB_TYPE :
60436             case AES_192_ECB_TYPE :
60437             case AES_256_ECB_TYPE :
60438                 WOLFSSL_MSG("AES ECB");
60439                 break;
60440 #endif
60441 #ifdef WOLFSSL_AES_COUNTER
60442             case AES_128_CTR_TYPE :
60443             case AES_192_CTR_TYPE :
60444             case AES_256_CTR_TYPE :
60445                 WOLFSSL_MSG("AES CTR");
60446                 XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
60447                 break;
60448 #endif /* WOLFSSL_AES_COUNTER */
60449 #ifdef WOLFSSL_AES_CFB
60450 #if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
60451             case AES_128_CFB1_TYPE:
60452             case AES_192_CFB1_TYPE:
60453             case AES_256_CFB1_TYPE:
60454                 WOLFSSL_MSG("AES CFB1");
60455                 break;
60456             case AES_128_CFB8_TYPE:
60457             case AES_192_CFB8_TYPE:
60458             case AES_256_CFB8_TYPE:
60459                 WOLFSSL_MSG("AES CFB8");
60460                 break;
60461 #endif /* !HAVE_SELFTEST && !HAVE_FIPS */
60462             case AES_128_CFB128_TYPE:
60463             case AES_192_CFB128_TYPE:
60464             case AES_256_CFB128_TYPE:
60465                 WOLFSSL_MSG("AES CFB128");
60466                 break;
60467 #endif /* WOLFSSL_AES_CFB */
60468 #if defined(WOLFSSL_AES_OFB)
60469             case AES_128_OFB_TYPE:
60470             case AES_192_OFB_TYPE:
60471             case AES_256_OFB_TYPE:
60472                 WOLFSSL_MSG("AES OFB");
60473                 break;
60474 #endif /* WOLFSSL_AES_OFB */
60475 #ifdef WOLFSSL_AES_XTS
60476             case AES_128_XTS_TYPE:
60477             case AES_256_XTS_TYPE:
60478                 WOLFSSL_MSG("AES XTS");
60479                 break;
60480 #endif /* WOLFSSL_AES_XTS */
60481 #endif /* NO_AES */
60482 
60483 #ifndef NO_DES3
60484             case DES_CBC_TYPE :
60485                 WOLFSSL_MSG("DES CBC");
60486                 XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
60487                 break;
60488 
60489             case DES_EDE3_CBC_TYPE :
60490                 WOLFSSL_MSG("DES EDE3 CBC");
60491                 XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
60492                 break;
60493 #endif
60494 #ifdef WOLFSSL_DES_ECB
60495             case DES_ECB_TYPE :
60496                 WOLFSSL_MSG("DES ECB");
60497                 break;
60498             case DES_EDE3_ECB_TYPE :
60499                 WOLFSSL_MSG("DES3 ECB");
60500                 break;
60501 #endif
60502 
60503 #ifdef HAVE_IDEA
60504             case IDEA_CBC_TYPE :
60505                 WOLFSSL_MSG("IDEA CBC");
60506                 XMEMCPY(ctx->iv, &ctx->cipher.idea.reg, IDEA_BLOCK_SIZE);
60507                 break;
60508 #endif
60509             case ARC4_TYPE :
60510                 WOLFSSL_MSG("ARC4");
60511                 break;
60512 
60513             case NULL_CIPHER_TYPE :
60514                 WOLFSSL_MSG("NULL");
60515                 break;
60516 
60517             default: {
60518                 WOLFSSL_MSG("bad type");
60519                 return WOLFSSL_FATAL_ERROR;
60520             }
60521         }
60522         return WOLFSSL_SUCCESS;
60523     }
60524 
60525     /* set internal IV from external, WOLFSSL_SUCCESS on success */
60526     int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
60527     {
60528 
60529         WOLFSSL_ENTER("wolfSSL_SetInternalIV");
60530 
60531         if (ctx == NULL) {
60532             WOLFSSL_MSG("Bad function argument");
60533             return WOLFSSL_FATAL_ERROR;
60534         }
60535 
60536         switch (ctx->cipherType) {
60537 
60538 #ifndef NO_AES
60539 #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
60540             case AES_128_CBC_TYPE :
60541             case AES_192_CBC_TYPE :
60542             case AES_256_CBC_TYPE :
60543                 WOLFSSL_MSG("AES CBC");
60544                 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
60545                 break;
60546 #endif
60547 #ifdef HAVE_AESGCM
60548             case AES_128_GCM_TYPE :
60549             case AES_192_GCM_TYPE :
60550             case AES_256_GCM_TYPE :
60551                 WOLFSSL_MSG("AES GCM");
60552                 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
60553                 break;
60554 #endif
60555 #ifdef HAVE_AES_ECB
60556             case AES_128_ECB_TYPE :
60557             case AES_192_ECB_TYPE :
60558             case AES_256_ECB_TYPE :
60559                 WOLFSSL_MSG("AES ECB");
60560                 break;
60561 #endif
60562 #ifdef WOLFSSL_AES_COUNTER
60563             case AES_128_CTR_TYPE :
60564             case AES_192_CTR_TYPE :
60565             case AES_256_CTR_TYPE :
60566                 WOLFSSL_MSG("AES CTR");
60567                 XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
60568                 break;
60569 #endif
60570 
60571 #endif /* NO_AES */
60572 
60573 #ifndef NO_DES3
60574             case DES_CBC_TYPE :
60575                 WOLFSSL_MSG("DES CBC");
60576                 XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
60577                 break;
60578 
60579             case DES_EDE3_CBC_TYPE :
60580                 WOLFSSL_MSG("DES EDE3 CBC");
60581                 XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
60582                 break;
60583 #endif
60584 #ifdef WOLFSSL_DES_ECB
60585             case DES_ECB_TYPE :
60586                 WOLFSSL_MSG("DES ECB");
60587                 break;
60588             case DES_EDE3_ECB_TYPE :
60589                 WOLFSSL_MSG("DES3 ECB");
60590                 break;
60591 #endif
60592 
60593 #ifdef HAVE_IDEA
60594             case IDEA_CBC_TYPE :
60595                 WOLFSSL_MSG("IDEA CBC");
60596                 XMEMCPY(&ctx->cipher.idea.reg, ctx->iv, IDEA_BLOCK_SIZE);
60597                 break;
60598 #endif
60599             case ARC4_TYPE :
60600                 WOLFSSL_MSG("ARC4");
60601                 break;
60602 
60603             case NULL_CIPHER_TYPE :
60604                 WOLFSSL_MSG("NULL");
60605                 break;
60606 
60607             default: {
60608                 WOLFSSL_MSG("bad type");
60609                 return WOLFSSL_FATAL_ERROR;
60610             }
60611         }
60612         return WOLFSSL_SUCCESS;
60613     }
60614 
60615 #ifndef NO_DES3
60616 
60617 void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
60618                             unsigned char* iv, int len)
60619 {
60620     (void)len;
60621 
60622     WOLFSSL_MSG("wolfSSL_3des_iv");
60623 
60624     if (ctx == NULL || iv == NULL) {
60625         WOLFSSL_MSG("Bad function argument");
60626         return;
60627     }
60628 
60629     if (doset)
60630         wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
60631     else
60632         XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
60633 }
60634 
60635 #endif /* NO_DES3 */
60636 
60637 
60638 #ifndef NO_AES
60639 
60640 void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
60641                       unsigned char* iv, int len)
60642 {
60643     (void)len;
60644 
60645     WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
60646 
60647     if (ctx == NULL || iv == NULL) {
60648         WOLFSSL_MSG("Bad function argument");
60649         return;
60650     }
60651 
60652     if (doset)
60653        (void)wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
60654     else
60655         XMEMCPY(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
60656 }
60657 
60658 #endif /* NO_AES */
60659 
60660 #endif /* OPENSSL_EXTRA */
60661 
60662 /*******************************************************************************
60663  * END OF EVP_CIPHER API
60664  ******************************************************************************/
60665 
60666 #ifndef NO_CERTS
60667 
60668 /*******************************************************************************
60669  * START OF X509_STORE_CTX APIs
60670  ******************************************************************************/
60671 
60672 #ifdef OPENSSL_EXTRA
60673 
60674 WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void)
60675 {
60676     WOLFSSL_X509_STORE_CTX* ctx;
60677     WOLFSSL_ENTER("X509_STORE_CTX_new");
60678 
60679     ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(sizeof(WOLFSSL_X509_STORE_CTX), NULL,
60680                                     DYNAMIC_TYPE_X509_CTX);
60681     if (ctx != NULL) {
60682         ctx->param = NULL;
60683         wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
60684     }
60685 
60686     return ctx;
60687 }
60688 
60689 
60690 int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
60691      WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509, WOLF_STACK_OF(WOLFSSL_X509)* sk)
60692 {
60693     WOLFSSL_X509* x509_cert;
60694     int ret = 0;
60695     (void)sk;
60696     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init");
60697 
60698     if (ctx != NULL) {
60699         ctx->store = store;
60700         #ifndef WOLFSSL_X509_STORE_CERTS
60701         ctx->current_cert = x509;
60702         #else
60703         if(x509 != NULL){
60704             ctx->current_cert = wolfSSL_X509_d2i(NULL, x509->derCert->buffer,
60705                     x509->derCert->length);
60706             if(ctx->current_cert == NULL)
60707                 return WOLFSSL_FAILURE;
60708         } else
60709             ctx->current_cert = NULL;
60710         #endif
60711 
60712         ctx->chain  = sk;
60713         /* Add intermediate certificates from stack to store */
60714         while (sk != NULL) {
60715             x509_cert = sk->data.x509;
60716             if (x509_cert != NULL && x509_cert->isCa) {
60717                 ret = wolfSSL_X509_STORE_add_cert(store, x509_cert);
60718                 if (ret < 0) {
60719                     return WOLFSSL_FAILURE;
60720                 }
60721             }
60722             sk = sk->next;
60723         }
60724 
60725         ctx->sesChain = NULL;
60726         ctx->domain = NULL;
60727 #ifdef HAVE_EX_DATA
60728         XMEMSET(&ctx->ex_data, 0, sizeof(ctx->ex_data));
60729 #endif
60730         ctx->userCtx = NULL;
60731         ctx->error = 0;
60732         ctx->error_depth = 0;
60733         ctx->discardSessionCerts = 0;
60734 #ifdef OPENSSL_EXTRA
60735         if (ctx->param == NULL) {
60736             ctx->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
60737                            sizeof(WOLFSSL_X509_VERIFY_PARAM),
60738                            NULL, DYNAMIC_TYPE_OPENSSL);
60739             if (ctx->param == NULL){
60740                 WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init failed");
60741                 return WOLFSSL_FAILURE;
60742             }
60743         }
60744 #endif
60745         return WOLFSSL_SUCCESS;
60746     }
60747     return WOLFSSL_FAILURE;
60748 }
60749 
60750 
60751 /* free's extra data */
60752 void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
60753 {
60754     WOLFSSL_ENTER("X509_STORE_CTX_free");
60755     if (ctx != NULL) {
60756 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
60757         wolfSSL_CRYPTO_cleanup_ex_data(&ctx->ex_data);
60758 #endif
60759     #ifdef OPENSSL_EXTRA
60760         if (ctx->param != NULL) {
60761             XFREE(ctx->param, NULL, DYNAMIC_TYPE_OPENSSL);
60762             ctx->param = NULL;
60763         }
60764     #endif
60765         XFREE(ctx, NULL, DYNAMIC_TYPE_X509_CTX);
60766     }
60767 }
60768 
60769 
60770 void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
60771 {
60772     if (ctx != NULL) {
60773 #ifdef OPENSSL_EXTRA
60774         if (ctx->param != NULL) {
60775             XFREE(ctx->param, NULL, DYNAMIC_TYPE_OPENSSL);
60776             ctx->param = NULL;
60777         }
60778 #endif
60779         wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
60780     }
60781 }
60782 
60783 
60784 void wolfSSL_X509_STORE_CTX_trusted_stack(WOLFSSL_X509_STORE_CTX *ctx, WOLF_STACK_OF(WOLFSSL_X509) *sk)
60785 {
60786     if (ctx != NULL) {
60787         ctx->chain = sk;
60788     }
60789 }
60790 
60791 
60792 /* Returns corresponding X509 error from internal ASN error <e> */
60793 static int GetX509Error(int e)
60794 {
60795     switch (e) {
60796         case ASN_BEFORE_DATE_E:
60797             return X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
60798         case ASN_AFTER_DATE_E:
60799             return X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
60800         case ASN_NO_SIGNER_E:
60801             return X509_V_ERR_INVALID_CA;
60802         case ASN_SELF_SIGNED_E:
60803             return X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
60804         case ASN_PATHLEN_INV_E:
60805         case ASN_PATHLEN_SIZE_E:
60806             return X509_V_ERR_PATH_LENGTH_EXCEEDED;
60807         case ASN_SIG_OID_E:
60808         case ASN_SIG_CONFIRM_E:
60809         case ASN_SIG_HASH_E:
60810         case ASN_SIG_KEY_E:
60811             return X509_V_ERR_CERT_SIGNATURE_FAILURE;
60812         default:
60813             WOLFSSL_MSG("Error not configured or implemented yet");
60814             return e;
60815     }
60816 }
60817 
60818 /* Verifies certificate chain using WOLFSSL_X509_STORE_CTX
60819  * returns 0 on success or < 0 on failure.
60820  */
60821 int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
60822 {
60823     int ret = 0;
60824     int depth = 0;
60825     int error;
60826 #ifndef NO_ASN_TIME
60827     byte *afterDate, *beforeDate;
60828 #endif
60829 
60830     WOLFSSL_ENTER("wolfSSL_X509_verify_cert");
60831 
60832     if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL
60833          && ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
60834             ret = wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
60835                     ctx->current_cert->derCert->buffer,
60836                     ctx->current_cert->derCert->length,
60837                     WOLFSSL_FILETYPE_ASN1);
60838 
60839         /* If there was an error, process it and add it to CTX */
60840         if (ret < 0) {
60841             /* Get corresponding X509 error */
60842             error = GetX509Error(ret);
60843             /* Set error depth */
60844             if (ctx->chain)
60845                 depth = (int)ctx->chain->num;
60846 
60847             wolfSSL_X509_STORE_CTX_set_error(ctx, error);
60848             wolfSSL_X509_STORE_CTX_set_error_depth(ctx, depth);
60849         #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
60850             if (ctx->store && ctx->store->verify_cb)
60851                 ctx->store->verify_cb(0, ctx);
60852         #endif
60853         }
60854 
60855     #ifndef NO_ASN_TIME
60856         error = 0;
60857         /* wolfSSL_CertManagerVerifyBuffer only returns ASN_AFTER_DATE_E or
60858          ASN_BEFORE_DATE_E if there are no additional errors found in the
60859          cert. Therefore, check if the cert is expired or not yet valid
60860          in order to return the correct expected error. */
60861         afterDate = ctx->current_cert->notAfter.data;
60862         beforeDate = ctx->current_cert->notBefore.data;
60863 
60864         if (XVALIDATE_DATE(afterDate, (byte)ctx->current_cert->notAfter.type,
60865                                                                    AFTER) < 1) {
60866             error = X509_V_ERR_CERT_HAS_EXPIRED;
60867         }
60868         else if (XVALIDATE_DATE(beforeDate,
60869                     (byte)ctx->current_cert->notBefore.type, BEFORE) < 1) {
60870             error = X509_V_ERR_CERT_NOT_YET_VALID;
60871         }
60872 
60873         if (error != 0 ) {
60874             wolfSSL_X509_STORE_CTX_set_error(ctx, error);
60875             wolfSSL_X509_STORE_CTX_set_error_depth(ctx, depth);
60876         #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
60877             if (ctx->store && ctx->store->verify_cb)
60878                 ctx->store->verify_cb(0, ctx);
60879         #endif
60880         }
60881     #endif
60882 
60883         /* OpenSSL returns 0 when a chain can't be built */
60884         if (ret == ASN_NO_SIGNER_E)
60885             return WOLFSSL_FAILURE;
60886         else
60887             return ret;
60888     }
60889     return WOLFSSL_FATAL_ERROR;
60890 }
60891 
60892 #endif /* OPENSSL_EXTRA */
60893 
60894 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
60895     WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
60896                                                     WOLFSSL_X509_STORE_CTX* ctx)
60897     {
60898         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_current_cert");
60899         if (ctx)
60900             return ctx->current_cert;
60901         return NULL;
60902     }
60903 
60904 
60905     int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
60906     {
60907         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error");
60908         if (ctx != NULL)
60909             return ctx->error;
60910         return 0;
60911     }
60912 
60913 
60914     int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
60915     {
60916         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error_depth");
60917         if(ctx)
60918             return ctx->error_depth;
60919         return WOLFSSL_FATAL_ERROR;
60920     }
60921 
60922 /* get X509_STORE_CTX ex_data, max idx is MAX_EX_DATA */
60923 void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
60924 {
60925     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data");
60926 #ifdef HAVE_EX_DATA
60927     if (ctx != NULL) {
60928         return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
60929     }
60930 #else
60931     (void)ctx;
60932     (void)idx;
60933 #endif
60934     return NULL;
60935 }
60936 #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
60937 
60938 #ifdef OPENSSL_EXTRA
60939     void wolfSSL_X509_STORE_CTX_set_verify_cb(WOLFSSL_X509_STORE_CTX *ctx,
60940                                   WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
60941     {
60942         WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_verify_cb");
60943         if(ctx == NULL)
60944             return;
60945         ctx->verify_cb = verify_cb;
60946     }
60947 
60948 /* Gets pointer to X509_STORE that was used to create context.
60949  *
60950  * Return valid pointer on success, NULL if ctx was NULL or not initialized
60951  */
60952 WOLFSSL_X509_STORE* wolfSSL_X509_STORE_CTX_get0_store(
60953         WOLFSSL_X509_STORE_CTX* ctx)
60954 {
60955     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get0_store");
60956 
60957     if (ctx == NULL)
60958         return NULL;
60959 
60960     return ctx->store;
60961 }
60962 
60963 WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_cert(WOLFSSL_X509_STORE_CTX* ctx)
60964 {
60965     if (ctx == NULL)
60966         return NULL;
60967 
60968     return ctx->current_cert;
60969 }
60970 
60971 void wolfSSL_X509_STORE_CTX_set_time(WOLFSSL_X509_STORE_CTX* ctx,
60972                                     unsigned long flags,
60973                                     time_t t)
60974 {
60975     (void)flags;
60976 
60977     if (ctx == NULL || ctx->param == NULL)
60978         return;
60979 
60980     ctx->param->check_time = t;
60981     ctx->param->flags |= WOLFSSL_USE_CHECK_TIME;
60982 }
60983 
60984 #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
60985 #ifndef NO_WOLFSSL_STUB
60986 int wolfSSL_X509_STORE_CTX_set_purpose(WOLFSSL_X509_STORE_CTX *ctx,
60987                                        int purpose)
60988 {
60989     (void)ctx;
60990     (void)purpose;
60991     WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_set_purpose");
60992     return 0;
60993 }
60994 #endif
60995 #endif /* WOLFSSL_QT || OPENSSL_ALL */
60996 #endif /* OPENSSL_EXTRA */
60997 
60998 #ifdef OPENSSL_EXTRA
60999 
61000 /* set X509_STORE_CTX ex_data, max idx is MAX_EX_DATA. Return WOLFSSL_SUCCESS
61001  * on success, WOLFSSL_FAILURE on error. */
61002 int wolfSSL_X509_STORE_CTX_set_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx,
61003                                        void *data)
61004 {
61005     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_ex_data");
61006 #ifdef HAVE_EX_DATA
61007     if (ctx != NULL)
61008     {
61009         return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
61010     }
61011 #else
61012     (void)ctx;
61013     (void)idx;
61014     (void)data;
61015 #endif
61016     return WOLFSSL_FAILURE;
61017 }
61018 
61019 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
61020 /* set X509_STORE_CTX ex_data, max idx is MAX_EX_DATA. Return WOLFSSL_SUCCESS
61021  * on success, WOLFSSL_FAILURE on error. */
61022 int wolfSSL_X509_STORE_CTX_set_ex_data_with_cleanup(
61023     WOLFSSL_X509_STORE_CTX* ctx,
61024     int idx,
61025     void *data,
61026     wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
61027 {
61028     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_ex_data_with_cleanup");
61029     if (ctx != NULL)
61030     {
61031         return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ctx->ex_data, idx, data,
61032                                                        cleanup_routine);
61033     }
61034     return WOLFSSL_FAILURE;
61035 }
61036 #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
61037 
61038 #if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL)
61039 void wolfSSL_X509_STORE_CTX_set_depth(WOLFSSL_X509_STORE_CTX* ctx, int depth)
61040 {
61041     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_depth");
61042     if (ctx)
61043         ctx->depth = depth;
61044 }
61045 #endif
61046 
61047 
61048 WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_current_issuer(
61049         WOLFSSL_X509_STORE_CTX* ctx)
61050 {
61051     int ret;
61052     WOLFSSL_X509* issuer;
61053 
61054     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get0_current_issuer");
61055 
61056     if (ctx == NULL) {
61057         return NULL;
61058     }
61059 
61060     ret = wolfSSL_X509_STORE_CTX_get1_issuer(&issuer, ctx, ctx->current_cert);
61061     if (ret == WOLFSSL_SUCCESS) {
61062         return issuer;
61063     }
61064 
61065     return NULL;
61066 }
61067 
61068 /* Set an error stat in the X509 STORE CTX
61069  *
61070  */
61071 void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int er)
61072 {
61073     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error");
61074 
61075     if (ctx != NULL) {
61076         ctx->error = er;
61077     }
61078 }
61079 
61080 /* Set the error depth in the X509 STORE CTX */
61081 void wolfSSL_X509_STORE_CTX_set_error_depth(WOLFSSL_X509_STORE_CTX* ctx,
61082                                                                       int depth)
61083 {
61084     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error_depth");
61085 
61086     if (ctx != NULL) {
61087         ctx->error_depth = depth;
61088     }
61089 }
61090 
61091 WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx)
61092 {
61093     WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_chain");
61094 
61095     if (ctx == NULL) {
61096         return NULL;
61097     }
61098 
61099 #ifdef SESSION_CERTS
61100     /* if chain is null but sesChain is available then populate stack */
61101     if (ctx->chain == NULL && ctx->sesChain != NULL) {
61102         int i;
61103         WOLFSSL_X509_CHAIN* c = ctx->sesChain;
61104         WOLFSSL_STACK*     sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK),
61105                                     NULL, DYNAMIC_TYPE_X509);
61106 
61107         if (sk == NULL) {
61108             return NULL;
61109         }
61110 
61111         XMEMSET(sk, 0, sizeof(WOLFSSL_STACK));
61112 
61113         for (i = 0; i < c->count && i < MAX_CHAIN_DEPTH; i++) {
61114             WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i);
61115 
61116             if (x509 == NULL) {
61117                 WOLFSSL_MSG("Unable to get x509 from chain");
61118                 wolfSSL_sk_X509_pop_free(sk, NULL);
61119                 return NULL;
61120             }
61121 
61122             if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) {
61123                 WOLFSSL_MSG("Unable to load x509 into stack");
61124                 wolfSSL_sk_X509_pop_free(sk, NULL);
61125                 wolfSSL_X509_free(x509);
61126                 return NULL;
61127             }
61128         }
61129 
61130 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
61131         /* add CA used to verify top of chain to the list */
61132         if (c->count > 0) {
61133             WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, c->count - 1);
61134             if (x509 != NULL) {
61135                 WOLFSSL_X509* issuer = NULL;
61136                 if (wolfSSL_X509_STORE_CTX_get1_issuer(&issuer, ctx, x509)
61137                         == WOLFSSL_SUCCESS) {
61138                     /* check that the certificate being looked up is not self
61139                      * signed and that a issuer was found */
61140                     if (issuer != NULL && wolfSSL_X509_NAME_cmp(&x509->issuer,
61141                                 &x509->subject) != 0) {
61142                         if (wolfSSL_sk_X509_push(sk, issuer) != WOLFSSL_SUCCESS) {
61143                             WOLFSSL_MSG("Unable to load CA x509 into stack");
61144                             wolfSSL_sk_X509_pop_free(sk, NULL);
61145                             wolfSSL_X509_free(issuer);
61146                             return NULL;
61147                         }
61148                     }
61149                     else {
61150                         WOLFSSL_MSG("Certificate is self signed");
61151                         if (issuer != NULL)
61152                             wolfSSL_X509_free(issuer);
61153                     }
61154                 }
61155                 else {
61156                     WOLFSSL_MSG("Could not find CA for certificate");
61157                 }
61158             }
61159         }
61160 #endif
61161         ctx->chain = sk;
61162     }
61163 #endif /* SESSION_CERTS */
61164 
61165     return ctx->chain;
61166 }
61167 
61168 /* like X509_STORE_CTX_get_chain(), but return a copy with data reference
61169    counts increased */
61170 WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain(WOLFSSL_X509_STORE_CTX* ctx)
61171 {
61172     WOLFSSL_STACK* ref;
61173 
61174     if (ctx == NULL) {
61175         return NULL;
61176     }
61177 
61178     /* get chain in ctx */
61179     ref = wolfSSL_X509_STORE_CTX_get_chain(ctx);
61180     if (ref == NULL) {
61181         return ref;
61182     }
61183 
61184     /* create duplicate of ctx chain */
61185     return wolfSSL_sk_dup(ref);
61186 }
61187 
61188 #ifndef NO_WOLFSSL_STUB
61189 WOLFSSL_X509_STORE_CTX *wolfSSL_X509_STORE_CTX_get0_parent_ctx(
61190                                                    WOLFSSL_X509_STORE_CTX *ctx)
61191 {
61192     (void)ctx;
61193     WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_get0_parent_ctx");
61194     return NULL;
61195 }
61196 
61197 int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
61198                             WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
61199 {
61200     (void)ctx;
61201     (void)idx;
61202     (void)name;
61203     (void)obj;
61204     WOLFSSL_STUB("X509_STORE_get_by_subject");
61205     return 0;
61206 }
61207 #endif
61208 
61209 
61210 #endif /* OPENSSL_EXTRA */
61211 
61212 #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
61213 #if defined(WOLFSSL_SIGNER_DER_CERT)
61214 WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs(
61215     WOLFSSL_X509_STORE_CTX* ctx, WOLFSSL_X509_NAME* name)
61216 {
61217     WOLF_STACK_OF(WOLFSSL_X509)* ret = NULL;
61218     int err = 0;
61219     WOLFSSL_X509_STORE* store = NULL;
61220     WOLFSSL_STACK* sk = NULL;
61221     WOLFSSL_STACK* certToFilter = NULL;
61222     WOLFSSL_X509_NAME* certToFilterName = NULL;
61223     WOLF_STACK_OF(WOLFSSL_X509)* filteredCerts = NULL;
61224     WOLFSSL_X509* filteredCert = NULL;
61225 
61226     WOLFSSL_ENTER("wolfSSL_X509_STORE_get1_certs");
61227 
61228     if (name == NULL) {
61229         err = 1;
61230     }
61231 
61232     if (err == 0) {
61233         store = wolfSSL_X509_STORE_CTX_get0_store(ctx);
61234         if (store == NULL) {
61235             err = 1;
61236         }
61237     }
61238 
61239     if (err == 0) {
61240         filteredCerts = wolfSSL_sk_X509_new();
61241         if (filteredCerts == NULL) {
61242             err = 1;
61243         }
61244     }
61245 
61246     if (err == 0) {
61247         sk = wolfSSL_CertManagerGetCerts(store->cm);
61248         if (sk == NULL) {
61249             err = 1;
61250         }
61251     }
61252 
61253     if (err == 0) {
61254         certToFilter = sk;
61255         while (certToFilter != NULL) {
61256             certToFilterName = wolfSSL_X509_get_subject_name(
61257                                     certToFilter->data.x509);
61258             if (certToFilterName != NULL) {
61259                 if (wolfSSL_X509_NAME_cmp(certToFilterName, name) == 0) {
61260                     filteredCert = wolfSSL_X509_dup(certToFilter->data.x509);
61261                     if (filteredCert == NULL) {
61262                         err = 1;
61263                         break;
61264                     }
61265                     else {
61266                         wolfSSL_sk_X509_push(filteredCerts, filteredCert);
61267                     }
61268                 }
61269             }
61270             certToFilter = certToFilter->next;
61271         }
61272     }
61273 
61274     if (err == 1) {
61275         if (filteredCerts != NULL) {
61276             wolfSSL_sk_X509_pop_free(filteredCerts, NULL);
61277         }
61278         ret = NULL;
61279     }
61280     else {
61281         ret = filteredCerts;
61282     }
61283 
61284     if (sk != NULL) {
61285         wolfSSL_sk_X509_pop_free(sk, NULL);
61286     }
61287 
61288     return ret;
61289 }
61290 #endif /* WOLFSSL_SIGNER_DER_CERT */
61291 
61292 #endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */
61293 
61294 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
61295     defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
61296 int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
61297     WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x)
61298 {
61299     WOLFSSL_STACK* node;
61300 
61301     if (issuer == NULL || ctx == NULL || x == NULL)
61302         return WOLFSSL_FATAL_ERROR;
61303 
61304     if (ctx->chain != NULL) {
61305         for (node = ctx->chain; node != NULL; node = node->next) {
61306             if (wolfSSL_X509_check_issued(node->data.x509, x) == X509_V_OK) {
61307                 *issuer = x;
61308                 return WOLFSSL_SUCCESS;
61309             }
61310         }
61311     }
61312 
61313     /* Result is ignored when passed to wolfSSL_OCSP_cert_to_id(). */
61314 
61315     return x509GetIssuerFromCM(issuer, ctx->store->cm, x);
61316 }
61317 #endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
61318 
61319 /*******************************************************************************
61320  * END OF X509_STORE_CTX APIs
61321  ******************************************************************************/
61322 
61323 /*******************************************************************************
61324  * START OF X509_STORE APIs
61325  ******************************************************************************/
61326 
61327 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
61328     defined(WOLFSSL_WPAS_SMALL)
61329 WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
61330 {
61331     WOLFSSL_X509_STORE* store = NULL;
61332     WOLFSSL_ENTER("SSL_X509_STORE_new");
61333 
61334     if ((store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL,
61335                                     DYNAMIC_TYPE_X509_STORE)) == NULL)
61336         goto err_exit;
61337 
61338     XMEMSET(store, 0, sizeof(WOLFSSL_X509_STORE));
61339     store->isDynamic = 1;
61340     store->refCount = 1;
61341 
61342 #ifndef SINGLE_THREADED
61343     if (wc_InitMutex(&store->refMutex) != 0)
61344         goto err_exit;
61345 #endif
61346 
61347     if ((store->cm = wolfSSL_CertManagerNew()) == NULL)
61348         goto err_exit;
61349 
61350 #ifdef HAVE_CRL
61351     store->crl = store->cm->crl;
61352 #endif
61353 
61354 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
61355     if ((store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
61356                            sizeof(WOLFSSL_X509_VERIFY_PARAM),
61357                            NULL, DYNAMIC_TYPE_OPENSSL)) == NULL) {
61358         goto err_exit;
61359     }
61360     XMEMSET(store->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));
61361     if ((store->lookup.dirs = (WOLFSSL_BY_DIR*)XMALLOC(sizeof(WOLFSSL_BY_DIR),
61362                            NULL, DYNAMIC_TYPE_OPENSSL)) == NULL) {
61363         WOLFSSL_MSG("store->lookup.dir memory allocation error");
61364         goto err_exit;
61365     }
61366     XMEMSET(store->lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR));
61367     if (wc_InitMutex(&store->lookup.dirs->lock) != 0) {
61368             WOLFSSL_MSG("Bad mutex init");
61369             goto err_exit;
61370     }
61371 #endif
61372 
61373     return store;
61374 
61375 err_exit:
61376     if (store == NULL)
61377         return NULL;
61378 
61379     wolfSSL_X509_STORE_free(store);
61380 
61381     return NULL;
61382 }
61383 
61384 void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
61385 {
61386     int doFree = 0;
61387     if (store != NULL && store->isDynamic) {
61388 #ifndef SINGLE_THREADED
61389         if (wc_LockMutex(&store->refMutex) != 0) {
61390             WOLFSSL_MSG("Couldn't lock store mutex");
61391         }
61392 #endif
61393         store->refCount--;
61394         if (store->refCount == 0)
61395             doFree = 1;
61396 #ifndef SINGLE_THREADED
61397         wc_UnLockMutex(&store->refMutex);
61398 #endif
61399 
61400         if (doFree) {
61401 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
61402             wolfSSL_CRYPTO_cleanup_ex_data(&store->ex_data);
61403 #endif
61404             if (store->cm != NULL) {
61405                 wolfSSL_CertManagerFree(store->cm);
61406                 store->cm = NULL;
61407             }
61408 #ifdef OPENSSL_ALL
61409             if (store->objs != NULL) {
61410                 wolfSSL_sk_X509_OBJECT_pop_free(store->objs, NULL);
61411             }
61412 #endif
61413 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
61414             if (store->param != NULL) {
61415                 XFREE(store->param, NULL, DYNAMIC_TYPE_OPENSSL);
61416                 store->param = NULL;
61417             }
61418 
61419             if (store->lookup.dirs != NULL) {
61420 #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
61421                 if (store->lookup.dirs->dir_entry) {
61422                     wolfSSL_sk_BY_DIR_entry_free(store->lookup.dirs->dir_entry);
61423                 }
61424 #endif
61425                 wc_FreeMutex(&store->lookup.dirs->lock);
61426                 XFREE(store->lookup.dirs, NULL, DYNAMIC_TYPE_OPENSSL);
61427                 store->lookup.dirs = NULL;
61428             }
61429 #endif
61430             XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
61431         }
61432     }
61433 }
61434 
61435 /**
61436  * Get ex_data in WOLFSSL_STORE at given index
61437  * @param store a pointer to WOLFSSL_X509_STORE structure
61438  * @param idx   Index of ex_data to get data from
61439  * @return void pointer to ex_data on success or NULL on failure
61440  */
61441 void* wolfSSL_X509_STORE_get_ex_data(WOLFSSL_X509_STORE* store, int idx)
61442 {
61443     WOLFSSL_ENTER("wolfSSL_X509_STORE_get_ex_data");
61444 #ifdef HAVE_EX_DATA
61445     if (store != NULL && idx < MAX_EX_DATA && idx >= 0) {
61446         return wolfSSL_CRYPTO_get_ex_data(&store->ex_data, idx);
61447     }
61448 #else
61449     (void)store;
61450     (void)idx;
61451 #endif
61452     return NULL;
61453 }
61454 
61455 int wolfSSL_X509_STORE_up_ref(WOLFSSL_X509_STORE* store)
61456 {
61457     if (store) {
61458 #ifndef SINGLE_THREADED
61459         if (wc_LockMutex(&store->refMutex) != 0) {
61460             WOLFSSL_MSG("Failed to lock store mutex");
61461         }
61462 #endif
61463         store->refCount++;
61464 #ifndef SINGLE_THREADED
61465         wc_UnLockMutex(&store->refMutex);
61466 #endif
61467 
61468         return WOLFSSL_SUCCESS;
61469     }
61470 
61471     return WOLFSSL_FAILURE;
61472 }
61473 
61474 /**
61475  * Set ex_data for WOLFSSL_STORE
61476  * @param store a pointer to WOLFSSL_X509_STORE structure
61477  * @param idx   Index of ex data to set
61478  * @param data  Data to set in ex data
61479  * @return WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
61480  */
61481 int wolfSSL_X509_STORE_set_ex_data(WOLFSSL_X509_STORE* store, int idx,
61482                                                                      void *data)
61483 {
61484     WOLFSSL_ENTER("wolfSSL_X509_STORE_set_ex_data");
61485 #ifdef HAVE_EX_DATA
61486     if (store != NULL && idx < MAX_EX_DATA) {
61487         return wolfSSL_CRYPTO_set_ex_data(&store->ex_data, idx, data);
61488     }
61489 #else
61490     (void)store;
61491     (void)idx;
61492     (void)data;
61493 #endif
61494     return WOLFSSL_FAILURE;
61495 }
61496 
61497 #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
61498 /**
61499  * Set ex_data for WOLFSSL_STORE
61500  * @param store a pointer to WOLFSSL_X509_STORE structure
61501  * @param idx   Index of ex data to set
61502  * @param data  Data to set in ex data
61503  * @return WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
61504  */
61505 int wolfSSL_X509_STORE_set_ex_data_with_cleanup(
61506     WOLFSSL_X509_STORE* store,
61507     int idx,
61508     void *data,
61509     wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
61510 {
61511     WOLFSSL_ENTER("wolfSSL_X509_STORE_set_ex_data_with_cleanup");
61512     if (store != NULL && idx < MAX_EX_DATA) {
61513         return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&store->ex_data, idx,
61514                                                        data, cleanup_routine);
61515     }
61516     return WOLFSSL_FAILURE;
61517 }
61518 
61519 #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
61520 
61521 #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER || WOLFSSL_WPAS_SMALL */
61522 
61523 #ifdef OPENSSL_EXTRA
61524 
61525 #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
61526     void wolfSSL_X509_STORE_set_verify_cb(WOLFSSL_X509_STORE *st,
61527                                  WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
61528     {
61529         WOLFSSL_ENTER("WOLFSSL_X509_STORE_set_verify_cb");
61530         if (st != NULL) {
61531             st->verify_cb = verify_cb;
61532         }
61533     }
61534 #endif /* WOLFSSL_QT || OPENSSL_ALL */
61535 
61536 WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
61537                                                WOLFSSL_X509_LOOKUP_METHOD* m)
61538 {
61539     WOLFSSL_ENTER("SSL_X509_STORE_add_lookup");
61540     if (store == NULL || m == NULL)
61541         return NULL;
61542 
61543     /* Make sure the lookup has a back reference to the store. */
61544     store->lookup.store = store;
61545     /* store a type to know which method wants to be used for */
61546     store->lookup.type = m->type;
61547     return &store->lookup;
61548 }
61549 
61550 int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
61551 {
61552     int result = WOLFSSL_FATAL_ERROR;
61553 
61554     WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
61555     if (store != NULL && store->cm != NULL && x509 != NULL
61556                                                 && x509->derCert != NULL) {
61557         DerBuffer* derCert = NULL;
61558 
61559         result = AllocDer(&derCert, x509->derCert->length,
61560             x509->derCert->type, NULL);
61561         if (result == 0) {
61562             /* AddCA() frees the buffer. */
61563             XMEMCPY(derCert->buffer,
61564                             x509->derCert->buffer, x509->derCert->length);
61565             result = AddCA(store->cm, &derCert, WOLFSSL_USER_CA, VERIFY);
61566         }
61567     }
61568 
61569     WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
61570 
61571     if (result != WOLFSSL_SUCCESS) {
61572         result = WOLFSSL_FATAL_ERROR;
61573     }
61574 
61575     return result;
61576 }
61577 
61578 int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag)
61579 {
61580     int ret = WOLFSSL_SUCCESS;
61581 
61582     WOLFSSL_ENTER("wolfSSL_X509_STORE_set_flags");
61583 
61584     if (store == NULL)
61585         return WOLFSSL_FAILURE;
61586 
61587     if ((flag & WOLFSSL_CRL_CHECKALL) || (flag & WOLFSSL_CRL_CHECK)) {
61588         ret = wolfSSL_CertManagerEnableCRL(store->cm, (int)flag);
61589     }
61590 
61591     return ret;
61592 }
61593 
61594 
61595 int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store)
61596 {
61597     (void)store;
61598     return WOLFSSL_SUCCESS;
61599 }
61600 
61601 #if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
61602 /* Loads certificate(s) files in pem format into X509_STORE struct from either
61603  * a file or directory.
61604  * Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE if an error occurs.
61605  */
61606 WOLFSSL_API int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str,
61607                                               const char *file, const char *dir)
61608 {
61609     WOLFSSL_CTX* ctx;
61610     char *name = NULL;
61611     int ret = WOLFSSL_SUCCESS;
61612     int successes = 0;
61613 #ifdef WOLFSSL_SMALL_STACK
61614     ReadDirCtx* readCtx = NULL;
61615 #else
61616     ReadDirCtx  readCtx[1];
61617 #endif
61618 
61619     WOLFSSL_ENTER("X509_STORE_load_locations");
61620 
61621     if (str == NULL || str->cm == NULL || (file == NULL  && dir == NULL))
61622         return WOLFSSL_FAILURE;
61623 
61624     /* tmp ctx for setting our cert manager */
61625     ctx = wolfSSL_CTX_new(cm_pick_method());
61626     if (ctx == NULL)
61627         return WOLFSSL_FAILURE;
61628 
61629     wolfSSL_CertManagerFree(ctx->cm);
61630     ctx->cm = str->cm;
61631 
61632 #ifdef HAVE_CRL
61633     if (str->cm->crl == NULL) {
61634         if (wolfSSL_CertManagerEnableCRL(str->cm, 0) != WOLFSSL_SUCCESS) {
61635             WOLFSSL_MSG("Enable CRL failed");
61636             wolfSSL_CTX_free(ctx);
61637             return WOLFSSL_FAILURE;
61638         }
61639     }
61640 #endif
61641 
61642     /* Load individual file */
61643     if (file) {
61644         /* Try to process file with type DETECT_CERT_TYPE to parse the
61645            correct certificate header and footer type */
61646         ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, DETECT_CERT_TYPE,
61647                                                       NULL, 0, str->cm->crl, 0);
61648         if (ret != WOLFSSL_SUCCESS) {
61649             WOLFSSL_MSG("Failed to load file");
61650             ret = WOLFSSL_FAILURE;
61651         }
61652     }
61653 
61654     /* Load files in dir */
61655     if (dir && ret == WOLFSSL_SUCCESS) {
61656         #ifdef WOLFSSL_SMALL_STACK
61657             readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
61658                                                        DYNAMIC_TYPE_TMP_BUFFER);
61659             if (readCtx == NULL) {
61660                 WOLFSSL_MSG("Memory error");
61661                 wolfSSL_CTX_free(ctx);
61662                 return WOLFSSL_FAILURE;
61663             }
61664         #endif
61665 
61666         /* try to load each regular file in dir */
61667         ret = wc_ReadDirFirst(readCtx, dir, &name);
61668         while (ret == 0 && name) {
61669             WOLFSSL_MSG(name);
61670             /* Try to process file with type DETECT_CERT_TYPE to parse the
61671                correct certificate header and footer type */
61672             ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, DETECT_CERT_TYPE,
61673                                                       NULL, 0, str->cm->crl, 0);
61674             /* Not failing on load errors */
61675             if (ret != WOLFSSL_SUCCESS)
61676                 WOLFSSL_MSG("Failed to load file in path, continuing");
61677             else
61678                 successes++;
61679 
61680             ret = wc_ReadDirNext(readCtx, dir, &name);
61681         }
61682         wc_ReadDirClose(readCtx);
61683 
61684         /* Success if at least one file in dir was loaded */
61685         if (successes > 0)
61686             ret = WOLFSSL_SUCCESS;
61687         else {
61688             WOLFSSL_ERROR(ret);
61689             ret = WOLFSSL_FAILURE;
61690         }
61691 
61692         #ifdef WOLFSSL_SMALL_STACK
61693             XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_DIRCTX);
61694         #endif
61695     }
61696 
61697     ctx->cm = NULL;
61698     wolfSSL_CTX_free(ctx);
61699 
61700     return ret;
61701 }
61702 #endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
61703 
61704 int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE* store)
61705 {
61706     int i = 0;
61707     int cnt_ret = 0;
61708     Signer **table;
61709 
61710     WOLFSSL_ENTER("wolfSSL_X509_CA_num");
61711     if (store == NULL || store->cm == NULL){
61712         WOLFSSL_MSG("invalid parameter");
61713         return WOLFSSL_FAILURE;
61714     }
61715 
61716     table = store->cm->caTable;
61717     if (table){
61718         if (wc_LockMutex(&store->cm->caLock) == 0){
61719             for (i = 0; i < CA_TABLE_SIZE; i++) {
61720                 Signer* signer = table[i];
61721                 while (signer) {
61722                     Signer* next = signer->next;
61723                     cnt_ret++;
61724                     signer = next;
61725                 }
61726             }
61727             wc_UnLockMutex(&store->cm->caLock);
61728         }
61729     }
61730 
61731     return cnt_ret;
61732 }
61733 
61734 /******************************************************************************
61735 * wolfSSL_X509_STORE_GetCerts - retrieve stack of X509 in a certificate store ctx
61736 *
61737 * This API can be used in SSL verify callback function to view cert chain
61738 * See examples/client/client.c and myVerify() function in test.h
61739 *
61740 * RETURNS:
61741 * returns stack of X509 certs on success, otherwise returns a NULL.
61742 */
61743 WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s)
61744 {
61745     int  certIdx = 0;
61746     WOLFSSL_BUFFER_INFO* cert = NULL;
61747     DecodedCert* dCert = NULL;
61748     WOLFSSL_X509* x509 = NULL;
61749     WOLFSSL_STACK* sk = NULL;
61750     int found = 0;
61751 
61752     if (s == NULL) {
61753         return NULL;
61754     }
61755 
61756     sk = wolfSSL_sk_X509_new();
61757 
61758     if (sk == NULL) {
61759         return NULL;
61760     }
61761 
61762     for (certIdx = s->totalCerts - 1; certIdx >= 0; certIdx--) {
61763         /* get certificate buffer */
61764         cert = &s->certs[certIdx];
61765 
61766         dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
61767 
61768         if (dCert == NULL) {
61769             goto error;
61770         }
61771         XMEMSET(dCert, 0, sizeof(DecodedCert));
61772 
61773         InitDecodedCert(dCert, cert->buffer, cert->length, NULL);
61774 
61775         /* Parse Certificate */
61776         if (ParseCert(dCert, CERT_TYPE, NO_VERIFY, NULL)){
61777             goto error;
61778         }
61779         x509 = wolfSSL_X509_new();
61780 
61781         if (x509 == NULL) {
61782             goto error;
61783         }
61784         InitX509(x509, 1, NULL);
61785 
61786         if (CopyDecodedToX509(x509, dCert) == 0) {
61787 
61788             if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) {
61789                 WOLFSSL_MSG("Unable to load x509 into stack");
61790                 wolfSSL_X509_free(x509);
61791                 goto error;
61792             }
61793         }
61794         else {
61795             goto error;
61796         }
61797         found = 1;
61798 
61799         FreeDecodedCert(dCert);
61800         XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT);
61801         dCert = NULL;
61802     }
61803 
61804     if (!found) {
61805         wolfSSL_sk_X509_pop_free(sk, NULL);
61806         sk = NULL;
61807     }
61808     return sk;
61809 
61810 error:
61811     if (dCert) {
61812         FreeDecodedCert(dCert);
61813         XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT);
61814     }
61815 
61816     if (sk)
61817         wolfSSL_sk_X509_pop_free(sk, NULL);
61818 
61819     return NULL;
61820 }
61821 #endif /* OPENSSL_EXTRA */
61822 
61823 #ifdef OPENSSL_ALL
61824 WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects(
61825     WOLFSSL_X509_STORE* store)
61826 {
61827     WOLFSSL_STACK* ret = NULL;
61828     WOLFSSL_STACK* cert_stack = NULL;
61829     WOLFSSL_X509* x509 = NULL;
61830     WOLFSSL_ENTER("wolfSSL_X509_STORE_get0_objects");
61831 
61832     if (store == NULL || store->cm == NULL) {
61833         WOLFSSL_MSG("Missing or empty store");
61834         return NULL;
61835     }
61836 
61837     if (store->objs != NULL) {
61838 #if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
61839         /* want to update objs stack by cm stack again before returning it*/
61840         wolfSSL_sk_X509_OBJECT_pop_free(store->objs, NULL);
61841         store->objs = NULL;
61842 #else
61843         if (wolfSSL_sk_X509_OBJECT_num(store->objs) == 0) {
61844             /* Let's try generating the stack again */
61845             wolfSSL_sk_X509_OBJECT_pop_free(store->objs, NULL);
61846             store->objs = NULL;
61847         }
61848         else
61849             return store->objs;
61850 #endif
61851     }
61852 
61853     if ((ret = wolfSSL_sk_X509_OBJECT_new()) == NULL) {
61854         WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_new error");
61855         goto err_cleanup;
61856     }
61857 
61858 #if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
61859     cert_stack = wolfSSL_CertManagerGetCerts(store->cm);
61860     /* wolfSSL_sk_X509_pop checks for NULL */
61861     while ((x509 = wolfSSL_sk_X509_pop(cert_stack)) != NULL) {
61862         WOLFSSL_X509_OBJECT* obj = wolfSSL_X509_OBJECT_new();
61863         if (obj == NULL) {
61864             WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error");
61865             goto err_cleanup;
61866         }
61867         if (wolfSSL_sk_X509_OBJECT_push(ret, obj) != WOLFSSL_SUCCESS) {
61868             WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error");
61869             wolfSSL_X509_OBJECT_free(obj);
61870             goto err_cleanup;
61871         }
61872         obj->type = WOLFSSL_X509_LU_X509;
61873         obj->data.x509 = x509;
61874     }
61875 #endif
61876 
61877 #ifdef HAVE_CRL
61878     if (store->cm->crl != NULL) {
61879         WOLFSSL_X509_OBJECT* obj = wolfSSL_X509_OBJECT_new();
61880         if (obj == NULL) {
61881             WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error");
61882             goto err_cleanup;
61883         }
61884         if (wolfSSL_sk_X509_OBJECT_push(ret, obj) != WOLFSSL_SUCCESS) {
61885             WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error");
61886             wolfSSL_X509_OBJECT_free(obj);
61887             goto err_cleanup;
61888         }
61889         obj->type = WOLFSSL_X509_LU_CRL;
61890         obj->data.crl = store->cm->crl;
61891     }
61892 #endif
61893 
61894     if (cert_stack)
61895         wolfSSL_sk_X509_pop_free(cert_stack, NULL);
61896     store->objs = ret;
61897     return ret;
61898 err_cleanup:
61899     if (ret)
61900         wolfSSL_sk_X509_OBJECT_free(ret);
61901     if (cert_stack)
61902         wolfSSL_sk_X509_pop_free(cert_stack, NULL);
61903     if (x509)
61904         wolfSSL_X509_free(x509);
61905     return NULL;
61906 }
61907 #endif /* OPENSSL_ALL */
61908 
61909 /*******************************************************************************
61910  * END OF X509_STORE APIs
61911  ******************************************************************************/
61912 
61913 /*******************************************************************************
61914  * START OF PKCS7 APIs
61915  ******************************************************************************/
61916 #ifdef HAVE_PKCS7
61917 
61918 #ifdef OPENSSL_ALL
61919 PKCS7* wolfSSL_PKCS7_new(void)
61920 {
61921     WOLFSSL_PKCS7* pkcs7;
61922     int ret = 0;
61923 
61924     pkcs7 = (WOLFSSL_PKCS7*)XMALLOC(sizeof(*pkcs7), NULL, DYNAMIC_TYPE_PKCS7);
61925     if (pkcs7 != NULL) {
61926         XMEMSET(pkcs7, 0, sizeof(*pkcs7));
61927         ret = wc_PKCS7_Init(&pkcs7->pkcs7, NULL, INVALID_DEVID);
61928     }
61929 
61930     if (ret != 0 && pkcs7 != NULL) {
61931         XFREE(pkcs7, NULL, DYNAMIC_TYPE_PKCS7);
61932         pkcs7 = NULL;
61933     }
61934 
61935     return (PKCS7*)pkcs7;
61936 }
61937 
61938 /******************************************************************************
61939 * wolfSSL_PKCS7_SIGNED_new - allocates PKCS7 and initialize it for a signed data
61940 *
61941 * RETURNS:
61942 * returns pointer to the PKCS7 structure on success, otherwise returns NULL
61943 */
61944 PKCS7_SIGNED* wolfSSL_PKCS7_SIGNED_new(void)
61945 {
61946     byte signedData[]= { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02};
61947     PKCS7* pkcs7 = NULL;
61948 
61949     if ((pkcs7 = wolfSSL_PKCS7_new()) == NULL)
61950         return NULL;
61951     pkcs7->contentOID = SIGNED_DATA;
61952     if ((wc_PKCS7_SetContentType(pkcs7, signedData, sizeof(signedData))) < 0) {
61953         if (pkcs7) {
61954             wolfSSL_PKCS7_free(pkcs7);
61955             return NULL;
61956         }
61957     }
61958     return pkcs7;
61959 }
61960 
61961 void wolfSSL_PKCS7_free(PKCS7* pkcs7)
61962 {
61963     WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
61964 
61965     if (p7 != NULL) {
61966         if (p7->data != NULL)
61967             XFREE(p7->data, NULL, DYNAMIC_TYPE_PKCS7);
61968         wc_PKCS7_Free(&p7->pkcs7);
61969         if (p7->certs)
61970             wolfSSL_sk_pop_free(p7->certs, NULL);
61971         XFREE(p7, NULL, DYNAMIC_TYPE_PKCS7);
61972     }
61973 }
61974 
61975 void wolfSSL_PKCS7_SIGNED_free(PKCS7_SIGNED* p7)
61976 {
61977     wolfSSL_PKCS7_free(p7);
61978     return;
61979 }
61980 
61981 PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len)
61982 {
61983     return wolfSSL_d2i_PKCS7_ex(p7, in, len, NULL, 0);
61984 }
61985 
61986 /*****************************************************************************
61987 * wolfSSL_d2i_PKCS7_ex - Converts the given unsigned char buffer of size len
61988 * into a PKCS7 object.  Optionally, accepts a byte buffer of content which
61989 * is stored as the PKCS7 object's content, to support detached signatures.
61990 * @param content The content which is signed, in case the signature is
61991 *                detached.  Ignored if NULL.
61992 * @param contentSz The size of the passed in content.
61993 *
61994 * RETURNS:
61995 * returns pointer to a PKCS7 structure on success, otherwise returns NULL
61996 */
61997 PKCS7* wolfSSL_d2i_PKCS7_ex(PKCS7** p7, const unsigned char** in, int len,
61998         byte* content, word32 contentSz)
61999 {
62000     WOLFSSL_PKCS7* pkcs7 = NULL;
62001     word32 idx = 0;
62002 
62003     WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_ex");
62004 
62005     if (in == NULL || *in == NULL)
62006         return NULL;
62007 
62008     if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
62009         return NULL;
62010 
62011     if (GetSequence(*in, &idx, &pkcs7->len, len) < 0) {
62012         wolfSSL_PKCS7_free((PKCS7*)pkcs7);
62013         return NULL;
62014     }
62015     pkcs7->len += idx;
62016 
62017     pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
62018     if (pkcs7->data == NULL) {
62019         wolfSSL_PKCS7_free((PKCS7*)pkcs7);
62020         return NULL;
62021     }
62022     XMEMCPY(pkcs7->data, *in, pkcs7->len);
62023 
62024     if (content != NULL) {
62025         pkcs7->pkcs7.content = content;
62026         pkcs7->pkcs7.contentSz = contentSz;
62027     }
62028     if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len)
62029                                                                          != 0) {
62030         wolfSSL_PKCS7_free((PKCS7*)pkcs7);
62031         return NULL;
62032     }
62033 
62034     if (p7 != NULL)
62035         *p7 = (PKCS7*)pkcs7;
62036     *in += pkcs7->len;
62037     return (PKCS7*)pkcs7;
62038 }
62039 
62040 /**
62041  * This API was added as a helper function for libest. It
62042  * extracts a stack of certificates from the pkcs7 object.
62043  * @param pkcs7 PKCS7 parameter object
62044  * @return WOLFSSL_STACK_OF(WOLFSSL_X509)*
62045  */
62046 WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7)
62047 {
62048     int i;
62049     WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
62050     WOLF_STACK_OF(WOLFSSL_X509)* ret = NULL;
62051 
62052     WOLFSSL_ENTER("wolfSSL_PKCS7_to_stack");
62053 
62054     if (!p7) {
62055         WOLFSSL_MSG("Bad parameter");
62056         return NULL;
62057     }
62058 
62059     if (p7->certs)
62060         return p7->certs;
62061 
62062     for (i = 0; i < MAX_PKCS7_CERTS && p7->pkcs7.cert[i]; i++) {
62063         WOLFSSL_X509* x509 = wolfSSL_X509_d2i(NULL, p7->pkcs7.cert[i],
62064             p7->pkcs7.certSz[i]);
62065         if (!ret)
62066             ret = wolfSSL_sk_X509_new();
62067         if (x509) {
62068             if (wolfSSL_sk_X509_push(ret, x509) != WOLFSSL_SUCCESS) {
62069                 wolfSSL_X509_free(x509);
62070                 WOLFSSL_MSG("wolfSSL_sk_X509_push error");
62071                 goto error;
62072             }
62073         }
62074         else {
62075             WOLFSSL_MSG("wolfSSL_X509_d2i error");
62076             goto error;
62077         }
62078     }
62079 
62080     /* Save stack to free later */
62081     if (p7->certs)
62082         wolfSSL_sk_pop_free(p7->certs, NULL);
62083     p7->certs = ret;
62084 
62085     return ret;
62086 error:
62087     if (ret) {
62088         wolfSSL_sk_pop_free(ret, NULL);
62089     }
62090     return NULL;
62091 }
62092 
62093 WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* pkcs7, WOLFSSL_STACK* certs,
62094                                           int flags)
62095 {
62096     WOLFSSL_STACK* signers = NULL;
62097     WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
62098 
62099     if (p7 == NULL)
62100         return NULL;
62101     /* Only PKCS#7 messages with a single cert that is the verifying certificate
62102      * is supported.
62103      */
62104     if ((flags | PKCS7_NOINTERN) == PKCS7_NOINTERN)
62105         return NULL;
62106 
62107     signers = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
62108         DYNAMIC_TYPE_X509);
62109     if (signers == NULL)
62110         return NULL;
62111 
62112     signers->num = 1;
62113     signers->data.x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
62114         DYNAMIC_TYPE_X509);
62115     if (signers->data.x509 == NULL) {
62116         XFREE(signers, NULL, DYNAMIC_TYPE_X509);
62117         return NULL;
62118     }
62119 
62120     if (DecodeToX509(signers->data.x509, p7->pkcs7.singleCert,
62121                                                  p7->pkcs7.singleCertSz) != 0) {
62122         XFREE(signers->data.x509, NULL, DYNAMIC_TYPE_X509);
62123         XFREE(signers, NULL, DYNAMIC_TYPE_X509);
62124         return NULL;
62125     }
62126 
62127     (void)certs;
62128 
62129     return signers;
62130 }
62131 
62132 #ifndef NO_BIO
62133 
62134 PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7)
62135 {
62136     WOLFSSL_PKCS7* pkcs7;
62137     int ret;
62138 
62139     WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_bio");
62140 
62141     if (bio == NULL)
62142         return NULL;
62143 
62144     if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
62145         return NULL;
62146 
62147     pkcs7->len = wolfSSL_BIO_get_len(bio);
62148     pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
62149     if (pkcs7->data == NULL) {
62150         wolfSSL_PKCS7_free((PKCS7*)pkcs7);
62151         return NULL;
62152     }
62153 
62154     if ((ret = wolfSSL_BIO_read(bio, pkcs7->data, pkcs7->len)) <= 0) {
62155         wolfSSL_PKCS7_free((PKCS7*)pkcs7);
62156         return NULL;
62157     }
62158     /* pkcs7->len may change if using b64 for example */
62159     pkcs7->len = ret;
62160 
62161     if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len)
62162                                                                          != 0) {
62163         wolfSSL_PKCS7_free((PKCS7*)pkcs7);
62164         return NULL;
62165     }
62166 
62167     if (p7 != NULL)
62168         *p7 = (PKCS7*)pkcs7;
62169     return (PKCS7*)pkcs7;
62170 }
62171 
62172 int wolfSSL_i2d_PKCS7(PKCS7 *p7, unsigned char **out)
62173 {
62174     byte* output = NULL;
62175     int localBuf = 0;
62176     int len;
62177     WC_RNG rng;
62178     int ret = WOLFSSL_FAILURE;
62179     WOLFSSL_ENTER("wolfSSL_i2d_PKCS7");
62180 
62181     if (!out || !p7) {
62182         WOLFSSL_MSG("Bad parameter");
62183         return WOLFSSL_FAILURE;
62184     }
62185 
62186     if (!p7->rng) {
62187         if (wc_InitRng(&rng) != 0) {
62188             WOLFSSL_MSG("wc_InitRng error");
62189             return WOLFSSL_FAILURE;
62190         }
62191         p7->rng = &rng;
62192     }
62193 
62194     if ((len = wc_PKCS7_EncodeSignedData(p7, NULL, 0)) < 0) {
62195         WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error");
62196         goto cleanup;
62197     }
62198 
62199     if (*out == NULL) {
62200         output = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
62201         if (!output) {
62202             WOLFSSL_MSG("malloc error");
62203             goto cleanup;
62204         }
62205         localBuf = 1;
62206     }
62207     else {
62208         output = *out;
62209     }
62210 
62211     if ((len = wc_PKCS7_EncodeSignedData(p7, output, len)) < 0) {
62212         WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error");
62213         goto cleanup;
62214     }
62215 
62216     ret = len;
62217 cleanup:
62218     if (p7->rng == &rng) {
62219         wc_FreeRng(&rng);
62220         p7->rng = NULL;
62221     }
62222     if (ret == WOLFSSL_FAILURE && localBuf && output)
62223         XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
62224     if (ret != WOLFSSL_FAILURE)
62225         *out = output;
62226     return ret;
62227 }
62228 
62229 int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7)
62230 {
62231     byte* output = NULL;
62232     int len;
62233     int ret = WOLFSSL_FAILURE;
62234     WOLFSSL_ENTER("wolfSSL_i2d_PKCS7_bio");
62235 
62236     if (!bio || !p7) {
62237         WOLFSSL_MSG("Bad parameter");
62238         return WOLFSSL_FAILURE;
62239     }
62240 
62241     if ((len = wolfSSL_i2d_PKCS7(p7, &output)) == WOLFSSL_FAILURE) {
62242         WOLFSSL_MSG("wolfSSL_i2d_PKCS7 error");
62243         goto cleanup;
62244     }
62245 
62246     if (wolfSSL_BIO_write(bio, output, len) <= 0) {
62247         WOLFSSL_MSG("wolfSSL_BIO_write error");
62248         goto cleanup;
62249     }
62250 
62251     ret = WOLFSSL_SUCCESS;
62252 cleanup:
62253     if (output)
62254         XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
62255     return ret;
62256 }
62257 
62258 int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs,
62259         WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags)
62260 {
62261     int ret = 0;
62262     unsigned char* mem = NULL;
62263     int memSz = 0;
62264     WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
62265 
62266     WOLFSSL_ENTER("wolfSSL_PKCS7_verify");
62267 
62268     if (pkcs7 == NULL)
62269         return WOLFSSL_FAILURE;
62270 
62271     if (in != NULL) {
62272         if ((memSz = wolfSSL_BIO_get_mem_data(in, &mem)) < 0)
62273             return WOLFSSL_FAILURE;
62274 
62275         p7->pkcs7.content = mem;
62276         p7->pkcs7.contentSz = memSz;
62277     }
62278 
62279     /* certs is the list of certificates to find the cert with issuer/serial. */
62280     (void)certs;
62281     /* store is the certificate store to use to verify signer certificate
62282      * associated with the signers.
62283      */
62284     (void)store;
62285 
62286     ret = wc_PKCS7_VerifySignedData(&p7->pkcs7, p7->data, p7->len);
62287     if (ret != 0)
62288         return WOLFSSL_FAILURE;
62289 
62290     if ((flags & PKCS7_NOVERIFY) != PKCS7_NOVERIFY) {
62291         /* All signer certificates are verified. */
62292         return WOLFSSL_FAILURE;
62293     }
62294 
62295     if (out != NULL)
62296        wolfSSL_BIO_write(out, p7->pkcs7.content, p7->pkcs7.contentSz);
62297 
62298     return WOLFSSL_SUCCESS;
62299 }
62300 
62301 /**
62302  * This API was added as a helper function for libest. It
62303  * encodes a stack of certificates to pkcs7 format.
62304  * @param pkcs7 PKCS7 parameter object
62305  * @param certs WOLFSSL_STACK_OF(WOLFSSL_X509)*
62306  * @param out   Output bio
62307  * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
62308  */
62309 int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs,
62310         WOLFSSL_BIO* out)
62311 {
62312     int ret;
62313     WOLFSSL_PKCS7* p7;
62314     WOLFSSL_ENTER("wolfSSL_PKCS7_encode_certs");
62315 
62316     if (!pkcs7 || !certs || !out) {
62317         WOLFSSL_MSG("Bad parameter");
62318         return WOLFSSL_FAILURE;
62319     }
62320 
62321     p7 = (WOLFSSL_PKCS7*)pkcs7;
62322 
62323     /* take ownership of certs */
62324     p7->certs = certs;
62325 
62326     if (pkcs7->certList) {
62327         WOLFSSL_MSG("wolfSSL_PKCS7_encode_certs called multiple times on same "
62328                     "struct");
62329         return WOLFSSL_FAILURE;
62330     }
62331 
62332     if (certs) {
62333         /* Save some of the values */
62334         int hashOID = pkcs7->hashOID;
62335         byte version = pkcs7->version;
62336 
62337         if (!certs->data.x509 || !certs->data.x509->derCert) {
62338             WOLFSSL_MSG("Missing cert");
62339             return WOLFSSL_FAILURE;
62340         }
62341 
62342         if (wc_PKCS7_InitWithCert(pkcs7, certs->data.x509->derCert->buffer,
62343                                       certs->data.x509->derCert->length) != 0) {
62344             WOLFSSL_MSG("wc_PKCS7_InitWithCert error");
62345             return WOLFSSL_FAILURE;
62346         }
62347         certs = certs->next;
62348 
62349         pkcs7->hashOID = hashOID;
62350         pkcs7->version = version;
62351     }
62352 
62353     /* Add the certs to the PKCS7 struct */
62354     while (certs) {
62355         if (!certs->data.x509 || !certs->data.x509->derCert) {
62356             WOLFSSL_MSG("Missing cert");
62357             return WOLFSSL_FAILURE;
62358         }
62359         if (wc_PKCS7_AddCertificate(pkcs7, certs->data.x509->derCert->buffer,
62360                                       certs->data.x509->derCert->length) != 0) {
62361             WOLFSSL_MSG("wc_PKCS7_AddCertificate error");
62362             return WOLFSSL_FAILURE;
62363         }
62364         certs = certs->next;
62365     }
62366 
62367     if (wc_PKCS7_SetSignerIdentifierType(pkcs7, DEGENERATE_SID) != 0) {
62368         WOLFSSL_MSG("wc_PKCS7_SetSignerIdentifierType error");
62369         return WOLFSSL_FAILURE;
62370     }
62371 
62372     ret = wolfSSL_i2d_PKCS7_bio(out, pkcs7);
62373 
62374     return ret;
62375 }
62376 
62377 /******************************************************************************
62378 * wolfSSL_PEM_write_bio_PKCS7 - writes the PKCS7 data to BIO
62379 *
62380 * RETURNS:
62381 * returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
62382 */
62383 int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7)
62384 {
62385 #ifdef WOLFSSL_SMALL_STACK
62386     byte* outputHead;
62387     byte* outputFoot;
62388 #else
62389     byte outputHead[2048];
62390     byte outputFoot[2048];
62391 #endif
62392     word32 outputHeadSz = 2048;
62393     word32 outputFootSz = 2048;
62394     word32 outputSz = 0;
62395     byte*  output = NULL;
62396     byte*  pem = NULL;
62397     int    pemSz = -1;
62398     enum wc_HashType hashType;
62399     byte hashBuf[WC_MAX_DIGEST_SIZE];
62400     word32 hashSz = -1;
62401 
62402     WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PKCS7()");
62403 
62404     if (bio == NULL || p7 == NULL)
62405         return WOLFSSL_FAILURE;
62406 
62407 #ifdef WOLFSSL_SMALL_STACK
62408     outputHead = (byte*)XMALLOC(outputHeadSz, bio->heap,
62409         DYNAMIC_TYPE_TMP_BUFFER);
62410     if (outputHead == NULL)
62411         return MEMORY_E;
62412 
62413     outputFoot = (byte*)XMALLOC(outputFootSz, bio->heap,
62414         DYNAMIC_TYPE_TMP_BUFFER);
62415     if (outputFoot == NULL)
62416         goto error;
62417 
62418 #endif
62419 
62420     XMEMSET(hashBuf, 0, WC_MAX_DIGEST_SIZE);
62421     XMEMSET(outputHead, 0, outputHeadSz);
62422     XMEMSET(outputFoot, 0, outputFootSz);
62423 
62424     hashType = wc_OidGetHash(p7->hashOID);
62425     hashSz = wc_HashGetDigestSize(hashType);
62426     if (hashSz > WC_MAX_DIGEST_SIZE)
62427         return WOLFSSL_FAILURE;
62428 
62429     /* only SIGNED_DATA is supported */
62430     switch (p7->contentOID) {
62431         case SIGNED_DATA:
62432             break;
62433         default:
62434             WOLFSSL_MSG("Unknown PKCS#7 Type");
62435             return WOLFSSL_FAILURE;
62436     };
62437 
62438     if ((wc_PKCS7_EncodeSignedData_ex(p7, hashBuf, hashSz,
62439         outputHead, &outputHeadSz, outputFoot, &outputFootSz)) != 0)
62440         return WOLFSSL_FAILURE;
62441 
62442     outputSz = outputHeadSz + p7->contentSz + outputFootSz;
62443     output = (byte*)XMALLOC(outputSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
62444 
62445     if (!output)
62446          return WOLFSSL_FAILURE;
62447 
62448     XMEMSET(output, 0, outputSz);
62449     outputSz = 0;
62450     XMEMCPY(&output[outputSz], outputHead, outputHeadSz);
62451     outputSz += outputHeadSz;
62452     XMEMCPY(&output[outputSz], p7->content, p7->contentSz);
62453     outputSz += p7->contentSz;
62454     XMEMCPY(&output[outputSz], outputFoot, outputFootSz);
62455     outputSz += outputFootSz;
62456 
62457     /* get PEM size */
62458     pemSz = wc_DerToPemEx(output, outputSz, NULL, 0, NULL, CERT_TYPE);
62459     if (pemSz < 0)
62460         goto error;
62461 
62462     pemSz++; /* for '\0'*/
62463 
62464     /* create PEM buffer and convert from DER to PEM*/
62465     if ((pem = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER))
62466                                                                         == NULL)
62467         goto error;
62468 
62469     XMEMSET(pem, 0, pemSz);
62470 
62471     if (wc_DerToPemEx(output, outputSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
62472         goto error;
62473     }
62474     if ((wolfSSL_BIO_write(bio, pem, pemSz) == pemSz)) {
62475         XFREE(output, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
62476         XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
62477 #ifdef WOLFSSL_SMALL_STACK
62478         XFREE(outputHead, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
62479         XFREE(outputFoot, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
62480 #endif
62481         return WOLFSSL_SUCCESS;
62482     }
62483 
62484 error:
62485 #ifdef WOLFSSL_SMALL_STACK
62486     if (outputHead) {
62487         XFREE(outputHead, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
62488     }
62489     if (outputFoot) {
62490         XFREE(outputFoot, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
62491     }
62492 #endif
62493     if (output) {
62494         XFREE(output, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
62495     }
62496     if (pem) {
62497         XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
62498     }
62499     return WOLFSSL_FAILURE;
62500 }
62501 
62502 #ifdef HAVE_SMIME
62503 /*****************************************************************************
62504 * wolfSSL_SMIME_read_PKCS7 - Reads the given S/MIME message and parses it into
62505 * a PKCS7 object. In case of a multipart message, stores the signed data in
62506 * bcont.
62507 *
62508 * RETURNS:
62509 * returns pointer to a PKCS7 structure on success, otherwise returns NULL
62510 */
62511 WOLFSSL_API PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in,
62512         WOLFSSL_BIO** bcont)
62513 {
62514     MimeHdr* allHdrs = NULL;
62515     MimeHdr* curHdr = NULL;
62516     MimeParam* curParam = NULL;
62517     int inLen = 0;
62518     byte* bcontMem = NULL;
62519     int bcontMemSz = 0;
62520     int sectionLen = 0;
62521     int ret = -1;
62522     char* section = NULL;
62523     char* canonLine = NULL;
62524     char* canonSection = NULL;
62525     PKCS7* pkcs7 = NULL;
62526     word32 outLen = 0;
62527     byte* out = NULL;
62528     byte* outHead = NULL;
62529 
62530     int canonPos = 0;
62531     int lineLen = 0;
62532     int remainLen = 0;
62533     byte isEnd = 0;
62534     size_t canonSize = 0;
62535     size_t boundLen = 0;
62536     char* boundary = NULL;
62537 
62538     static const char* kContType = "Content-Type";
62539     static const char* kCTE = "Content-Transfer-Encoding";
62540     static const char* kMultSigned = "multipart/signed";
62541     static const char* kAppPkcsSign = "application/pkcs7-signature";
62542     static const char* kAppXPkcsSign = "application/x-pkcs7-signature";
62543     static const char* kAppPkcs7Mime = "application/pkcs7-mime";
62544     static const char* kAppXPkcs7Mime = "application/x-pkcs7-mime";
62545 
62546 
62547     if (in == NULL || bcont == NULL) {
62548         goto error;
62549     }
62550     inLen = wolfSSL_BIO_get_len(in);
62551     if (inLen <= 0) {
62552         goto error;
62553     }
62554     remainLen = wolfSSL_BIO_get_len(in);
62555     if (remainLen <= 0) {
62556         goto error;
62557     }
62558 
62559     section = (char*)XMALLOC(remainLen+1, NULL, DYNAMIC_TYPE_PKCS7);
62560     if (section == NULL) {
62561         goto error;
62562     }
62563     lineLen = wolfSSL_BIO_gets(in, section, remainLen);
62564     if (lineLen <= 0) {
62565         goto error;
62566     }
62567     while (isEnd == 0 && remainLen > 0) {
62568         sectionLen += lineLen;
62569         remainLen -= lineLen;
62570         lineLen = wolfSSL_BIO_gets(in, &section[sectionLen], remainLen);
62571         if (lineLen <= 0) {
62572             goto error;
62573         }
62574         /* Line with just newline signals end of headers. */
62575         if ((lineLen==2 && !XSTRNCMP(&section[sectionLen],
62576                                      "\r\n", 2)) ||
62577             (lineLen==1 && (section[sectionLen] == '\r' ||
62578                             section[sectionLen] == '\n'))) {
62579             isEnd = 1;
62580         }
62581     }
62582     section[sectionLen] = '\0';
62583     ret = wc_MIME_parse_headers(section, sectionLen, &allHdrs);
62584     if (ret < 0) {
62585         WOLFSSL_MSG("Parsing MIME headers failed.");
62586         goto error;
62587     }
62588     isEnd = 0;
62589     section[0] = '\0';
62590     sectionLen = 0;
62591 
62592     curHdr = wc_MIME_find_header_name(kContType, allHdrs);
62593     if (curHdr && !XSTRNCMP(curHdr->body, kMultSigned,
62594                             XSTR_SIZEOF(kMultSigned))) {
62595         curParam = wc_MIME_find_param_attr("protocol", curHdr->params);
62596         if (curParam && (!XSTRNCMP(curParam->value, kAppPkcsSign,
62597                                    XSTR_SIZEOF(kAppPkcsSign)) ||
62598                          !XSTRNCMP(curParam->value, kAppXPkcsSign,
62599                                    XSTR_SIZEOF(kAppXPkcsSign)))) {
62600             curParam = wc_MIME_find_param_attr("boundary", curHdr->params);
62601             if (curParam == NULL) {
62602                 goto error;
62603             }
62604 
62605             boundLen = XSTRLEN(curParam->value) + 2;
62606             boundary = (char*)XMALLOC(boundLen+1, NULL, DYNAMIC_TYPE_PKCS7);
62607             if (boundary == NULL) {
62608                 goto error;
62609             }
62610             XMEMSET(boundary, 0, (word32)(boundLen+1));
62611             boundary[0] = boundary[1] = '-';
62612             XSTRNCPY(&boundary[2], curParam->value, boundLen-2);
62613 
62614             /* Parse up to first boundary, ignore everything here. */
62615             lineLen = wolfSSL_BIO_gets(in, section, remainLen);
62616             if (lineLen <= 0) {
62617                 goto error;
62618             }
62619             while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
62620                    remainLen > 0) {
62621                 sectionLen += lineLen;
62622                 remainLen -= lineLen;
62623                 lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
62624                                            remainLen);
62625                 if (lineLen <= 0) {
62626                     goto error;
62627                 }
62628             }
62629 
62630             section[0] = '\0';
62631             sectionLen = 0;
62632             canonSize = remainLen + 1;
62633             canonSection = (char*)XMALLOC(canonSize, NULL,
62634                                           DYNAMIC_TYPE_PKCS7);
62635             if (canonSection == NULL) {
62636                 goto error;
62637             }
62638 
62639             lineLen = wolfSSL_BIO_gets(in, section, remainLen);
62640             while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
62641                             remainLen > 0) {
62642                 canonLine = wc_MIME_canonicalize(&section[sectionLen]);
62643                 if (canonLine == NULL) {
62644                     goto error;
62645                 }
62646                 /* If line endings were added, the initial length may be
62647                  * exceeded. */
62648                 if ((canonPos + XSTRLEN(canonLine) + 1) >= canonSize) {
62649                     canonSize = canonPos + XSTRLEN(canonLine) + 1;
62650                     canonSection = (char*)XREALLOC(canonSection, canonSize,
62651                                                    NULL, DYNAMIC_TYPE_PKCS7);
62652                     if (canonSection == NULL) {
62653                         goto error;
62654                     }
62655                 }
62656                 XMEMCPY(&canonSection[canonPos], canonLine,
62657                         (int)XSTRLEN(canonLine));
62658                 canonPos += XSTRLEN(canonLine);
62659                 XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
62660                 canonLine = NULL;
62661 
62662                 sectionLen += lineLen;
62663                 remainLen -= lineLen;
62664 
62665                 lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
62666                                            remainLen);
62667                 if (lineLen <= 0) {
62668                     goto error;
62669                 }
62670             }
62671 
62672             if (canonPos > 0) {
62673                 canonPos--;
62674             }
62675 
62676             /* Strip the final trailing newline.  Support \r, \n or \r\n. */
62677             if (canonSection[canonPos] == '\n') {
62678                 if (canonPos > 0) {
62679                     canonPos--;
62680                 }
62681             }
62682 
62683             if (canonSection[canonPos] == '\r') {
62684                 if (canonPos > 0) {
62685                     canonPos--;
62686                 }
62687             }
62688 
62689             canonSection[canonPos+1] = '\0';
62690 
62691             *bcont = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
62692             ret = wolfSSL_BIO_write(*bcont, canonSection,
62693                                     (int)XSTRLEN(canonSection));
62694             if (ret != (int)XSTRLEN(canonSection)) {
62695                 goto error;
62696             }
62697             if ((bcontMemSz = wolfSSL_BIO_get_mem_data(*bcont, &bcontMem))
62698                                                                           < 0) {
62699                 goto error;
62700             }
62701             XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
62702             canonSection = NULL;
62703 
62704 
62705             wc_MIME_free_hdrs(allHdrs);
62706             allHdrs = NULL;
62707             section[0] = '\0';
62708             sectionLen = 0;
62709             lineLen = wolfSSL_BIO_gets(in, section, remainLen);
62710             if (lineLen <= 0) {
62711                 goto error;
62712             }
62713             while (isEnd == 0 && remainLen > 0) {
62714                 sectionLen += lineLen;
62715                 remainLen -= lineLen;
62716                 lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
62717                                            remainLen);
62718                 if (lineLen <= 0) {
62719                     goto error;
62720                 }
62721                 /* Line with just newline signals end of headers. */
62722                 if ((lineLen==2 && !XSTRNCMP(&section[sectionLen],
62723                                              "\r\n", 2)) ||
62724                     (lineLen==1 && (section[sectionLen] == '\r' ||
62725                                     section[sectionLen] == '\n'))) {
62726                     isEnd = 1;
62727                 }
62728             }
62729             section[sectionLen] = '\0';
62730             ret = wc_MIME_parse_headers(section, sectionLen, &allHdrs);
62731             if (ret < 0) {
62732                 WOLFSSL_MSG("Parsing MIME headers failed.");
62733                 goto error;
62734             }
62735             curHdr = wc_MIME_find_header_name(kContType, allHdrs);
62736             if (curHdr == NULL || (XSTRNCMP(curHdr->body, kAppPkcsSign,
62737                                    XSTR_SIZEOF(kAppPkcsSign)) &&
62738                                    XSTRNCMP(curHdr->body, kAppXPkcsSign,
62739                                    XSTR_SIZEOF(kAppXPkcsSign)))) {
62740                 WOLFSSL_MSG("S/MIME headers not found inside "
62741                             "multipart message.\n");
62742                 goto error;
62743             }
62744 
62745             section[0] = '\0';
62746             sectionLen = 0;
62747             lineLen = wolfSSL_BIO_gets(in, section, remainLen);
62748             while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
62749                    remainLen > 0) {
62750                 sectionLen += lineLen;
62751                 remainLen -= lineLen;
62752                 lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
62753                                            remainLen);
62754                 if (lineLen <= 0) {
62755                     goto error;
62756                 }
62757             }
62758 
62759             XFREE(boundary, NULL, DYNAMIC_TYPE_PKCS7);
62760             boundary = NULL;
62761         }
62762     }
62763     else if (curHdr && (!XSTRNCMP(curHdr->body, kAppPkcs7Mime,
62764                                   XSTR_SIZEOF(kAppPkcs7Mime)) ||
62765                         !XSTRNCMP(curHdr->body, kAppXPkcs7Mime,
62766                                   XSTR_SIZEOF(kAppXPkcs7Mime)))) {
62767         sectionLen = wolfSSL_BIO_get_len(in);
62768         if (sectionLen <= 0) {
62769             goto error;
62770         }
62771         ret = wolfSSL_BIO_read(in, section, sectionLen);
62772         if (ret < 0 || ret != sectionLen) {
62773             WOLFSSL_MSG("Error reading input BIO.");
62774             goto error;
62775         }
62776     }
62777     else {
62778         WOLFSSL_MSG("S/MIME headers not found.");
62779         goto error;
62780     }
62781 
62782     curHdr = wc_MIME_find_header_name(kCTE, allHdrs);
62783     if (curHdr == NULL) {
62784         WOLFSSL_MSG("Content-Transfer-Encoding header not found, "
62785                     "assuming base64 encoding.");
62786     }
62787     else if (XSTRNCMP(curHdr->body, "base64", XSTRLEN("base64"))) {
62788         WOLFSSL_MSG("S/MIME encodings other than base64 are not "
62789                     "currently supported.\n");
62790         goto error;
62791     }
62792 
62793     if (section == NULL || sectionLen <= 0) {
62794         goto error;
62795     }
62796     outLen = ((sectionLen*3+3)/4)+1;
62797     out = (byte*)XMALLOC(outLen*sizeof(byte), NULL, DYNAMIC_TYPE_PKCS7);
62798     outHead = out;
62799     if (outHead == NULL) {
62800         goto error;
62801     }
62802     /* Strip trailing newlines. */
62803     while ((sectionLen > 0) &&
62804            (section[sectionLen-1] == '\r' || section[sectionLen-1] == '\n')) {
62805         sectionLen--;
62806     }
62807     section[sectionLen] = '\0';
62808     ret = Base64_Decode((const byte*)section, sectionLen, out, &outLen);
62809     if (ret < 0) {
62810         WOLFSSL_MSG("Error base64 decoding S/MIME message.");
62811         goto error;
62812     }
62813     pkcs7 = wolfSSL_d2i_PKCS7_ex(NULL, (const unsigned char**)&out, outLen,
62814         bcontMem, bcontMemSz);
62815 
62816     wc_MIME_free_hdrs(allHdrs);
62817     XFREE(outHead, NULL, DYNAMIC_TYPE_PKCS7);
62818     XFREE(section, NULL, DYNAMIC_TYPE_PKCS7);
62819 
62820     return pkcs7;
62821 
62822 error:
62823     wc_MIME_free_hdrs(allHdrs);
62824     XFREE(boundary, NULL, DYNAMIC_TYPE_PKCS7);
62825     XFREE(outHead, NULL, DYNAMIC_TYPE_PKCS7);
62826     XFREE(section, NULL, DYNAMIC_TYPE_PKCS7);
62827     if (canonSection != NULL)
62828         XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
62829     if (bcont) {
62830         wolfSSL_BIO_free(*bcont);
62831         *bcont = NULL; /* reset 'bcount' pointer to NULL on failure */
62832     }
62833 
62834     return NULL;
62835 }
62836 #endif /* HAVE_SMIME */
62837 #endif /* !NO_BIO */
62838 #endif /* OPENSSL_ALL */
62839 
62840 #endif /* HAVE_PKCS7 */
62841 /*******************************************************************************
62842  * END OF PKCS7 APIs
62843  ******************************************************************************/
62844 
62845 /*******************************************************************************
62846  * START OF PKCS12 APIs
62847  ******************************************************************************/
62848 #ifdef OPENSSL_EXTRA
62849 
62850 /* no-op function. Was initially used for adding encryption algorithms available
62851  * for PKCS12 */
62852 void wolfSSL_PKCS12_PBE_add(void)
62853 {
62854     WOLFSSL_ENTER("wolfSSL_PKCS12_PBE_add");
62855 }
62856 
62857 #if !defined(NO_FILESYSTEM)
62858 WOLFSSL_X509_PKCS12 *wolfSSL_d2i_PKCS12_fp(XFILE fp,
62859         WOLFSSL_X509_PKCS12 **pkcs12)
62860 {
62861     WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_fp");
62862     return (WOLFSSL_X509_PKCS12 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)pkcs12,
62863         PKCS12_TYPE);
62864 }
62865 #endif /* !NO_FILESYSTEM */
62866 
62867 #endif /* OPENSSL_EXTRA */
62868 
62869 #if defined(HAVE_PKCS12)
62870 
62871 #ifdef OPENSSL_EXTRA
62872 
62873 #if !defined(NO_ASN) && !defined(NO_PWDBASED)
62874 
62875 #ifndef NO_BIO
62876 WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12)
62877 {
62878     WC_PKCS12* localPkcs12 = NULL;
62879     unsigned char* mem = NULL;
62880     int ret;
62881     word32 size;
62882 
62883     WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
62884 
62885     if (bio == NULL) {
62886         WOLFSSL_MSG("Bad Function Argument bio is NULL");
62887         return NULL;
62888     }
62889 
62890     localPkcs12 = wc_PKCS12_new();
62891     if (localPkcs12 == NULL) {
62892         WOLFSSL_MSG("Memory error");
62893         return NULL;
62894     }
62895 
62896     if (pkcs12 != NULL) {
62897         *pkcs12 = localPkcs12;
62898     }
62899 
62900     ret = wolfSSL_BIO_get_mem_data(bio, &mem);
62901     if (mem == NULL || ret <= 0) {
62902         WOLFSSL_MSG("Failed to get data from bio struct");
62903         wc_PKCS12_free(localPkcs12);
62904         if (pkcs12 != NULL) {
62905             *pkcs12 = NULL;
62906         }
62907         return NULL;
62908     }
62909     size = ret;
62910 
62911     ret = wc_d2i_PKCS12(mem, size, localPkcs12);
62912     if (ret < 0) {
62913         WOLFSSL_MSG("Failed to get PKCS12 sequence");
62914         wc_PKCS12_free(localPkcs12);
62915         if (pkcs12 != NULL) {
62916             *pkcs12 = NULL;
62917         }
62918         return NULL;
62919     }
62920 
62921     return localPkcs12;
62922 }
62923 
62924 /* Converts the PKCS12 to DER format and outputs it into bio.
62925  *
62926  * bio is the structure to hold output DER
62927  * pkcs12 structure to create DER from
62928  *
62929  * return 1 for success or 0 if an error occurs
62930  */
62931 int wolfSSL_i2d_PKCS12_bio(WOLFSSL_BIO *bio, WC_PKCS12 *pkcs12)
62932 {
62933     int ret = WOLFSSL_FAILURE;
62934 
62935     WOLFSSL_ENTER("wolfSSL_i2d_PKCS12_bio");
62936 
62937     if ((bio != NULL) && (pkcs12 != NULL)) {
62938         word32 certSz = 0;
62939         byte *certDer = NULL;
62940 
62941         certSz = wc_i2d_PKCS12(pkcs12, &certDer, NULL);
62942         if ((certSz > 0) && (certDer != NULL)) {
62943             if (wolfSSL_BIO_write(bio, certDer, certSz) == (int)certSz) {
62944                 ret = WOLFSSL_SUCCESS;
62945             }
62946         }
62947 
62948         if (certDer != NULL) {
62949             XFREE(certDer, NULL, DYNAMIC_TYPE_PKCS);
62950         }
62951     }
62952 
62953     return ret;
62954 }
62955 #endif /* !NO_BIO */
62956 
62957 /* Creates a new WC_PKCS12 structure
62958  *
62959  * pass  password to use
62960  * name  friendlyName to use
62961  * pkey  private key to go into PKCS12 bundle
62962  * cert  certificate to go into PKCS12 bundle
62963  * ca    extra certificates that can be added to bundle. Can be NULL
62964  * keyNID  type of encryption to use on the key (-1 means no encryption)
62965  * certNID type of encryption to use on the certificate
62966  * itt     number of iterations with encryption
62967  * macItt  number of iterations with mac creation
62968  * keyType flag for signature and/or encryption key
62969  *
62970  * returns a pointer to a new WC_PKCS12 structure on success and NULL on fail
62971  */
62972 WC_PKCS12* wolfSSL_PKCS12_create(char* pass, char* name, WOLFSSL_EVP_PKEY* pkey,
62973         WOLFSSL_X509* cert, WOLF_STACK_OF(WOLFSSL_X509)* ca, int keyNID,
62974         int certNID, int itt, int macItt, int keyType)
62975 {
62976     WC_PKCS12* pkcs12;
62977     WC_DerCertList* list = NULL;
62978     word32 passSz;
62979     byte* keyDer = NULL;
62980     word32 keyDerSz;
62981     byte* certDer;
62982     int certDerSz;
62983 
62984     WOLFSSL_ENTER("wolfSSL_PKCS12_create()");
62985 
62986     if (pass == NULL || pkey == NULL || cert == NULL) {
62987         WOLFSSL_LEAVE("wolfSSL_PKCS12_create()", BAD_FUNC_ARG);
62988         return NULL;
62989     }
62990     passSz = (word32)XSTRLEN(pass);
62991 
62992     keyDer = (byte*)pkey->pkey.ptr;
62993     keyDerSz = pkey->pkey_sz;
62994 
62995     certDer = (byte*)wolfSSL_X509_get_der(cert, &certDerSz);
62996     if (certDer == NULL) {
62997         return NULL;
62998     }
62999 
63000     if (ca != NULL) {
63001         WC_DerCertList* cur;
63002         unsigned long numCerts = ca->num;
63003         byte* curDer;
63004         int   curDerSz = 0;
63005         WOLFSSL_STACK* sk = ca;
63006 
63007         while (numCerts > 0 && sk != NULL) {
63008             cur = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList), NULL,
63009                     DYNAMIC_TYPE_PKCS);
63010             if (cur == NULL) {
63011                 wc_FreeCertList(list, NULL);
63012                 return NULL;
63013             }
63014 
63015             curDer = (byte*)wolfSSL_X509_get_der(sk->data.x509, &curDerSz);
63016             if (curDer == NULL || curDerSz < 0) {
63017                 XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
63018                 wc_FreeCertList(list, NULL);
63019                 return NULL;
63020             }
63021 
63022             cur->buffer = (byte*)XMALLOC(curDerSz, NULL, DYNAMIC_TYPE_PKCS);
63023             if (cur->buffer == NULL) {
63024                 XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
63025                 wc_FreeCertList(list, NULL);
63026                 return NULL;
63027             }
63028             XMEMCPY(cur->buffer, curDer, curDerSz);
63029             cur->bufferSz = curDerSz;
63030             cur->next = list;
63031             list = cur;
63032 
63033             sk = sk->next;
63034             numCerts--;
63035         }
63036     }
63037 
63038     pkcs12 = wc_PKCS12_create(pass, passSz, name, keyDer, keyDerSz,
63039             certDer, certDerSz, list, keyNID, certNID, itt, macItt,
63040             keyType, NULL);
63041 
63042     if (ca != NULL) {
63043         wc_FreeCertList(list, NULL);
63044     }
63045 
63046     return pkcs12;
63047 }
63048 
63049 
63050 /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure */
63051 int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
63052           WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert,
63053           WOLF_STACK_OF(WOLFSSL_X509)** ca)
63054 {
63055     DecodedCert DeCert;
63056     void* heap = NULL;
63057     int ret;
63058     byte* certData = NULL;
63059     word32 certDataSz;
63060     byte* pk = NULL;
63061     word32 pkSz;
63062     WC_DerCertList* certList = NULL;
63063 
63064     WOLFSSL_ENTER("wolfSSL_PKCS12_parse");
63065 
63066     /* make sure we init return args */
63067     if (pkey) *pkey = NULL;
63068     if (cert) *cert = NULL;
63069     if (ca)   *ca = NULL;
63070 
63071     if (pkcs12 == NULL || psw == NULL || pkey == NULL || cert == NULL) {
63072         WOLFSSL_MSG("Bad argument value");
63073         return WOLFSSL_FAILURE;
63074     }
63075 
63076     heap  = wc_PKCS12_GetHeap(pkcs12);
63077 
63078     if (ca == NULL) {
63079         ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
63080             NULL);
63081     }
63082     else {
63083         ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
63084             &certList);
63085     }
63086     if (ret < 0) {
63087         WOLFSSL_LEAVE("wolfSSL_PKCS12_parse", ret);
63088         return WOLFSSL_FAILURE;
63089     }
63090 
63091     /* Decode cert and place in X509 stack struct */
63092     if (certList != NULL) {
63093         WC_DerCertList* current = certList;
63094 
63095         *ca = (WOLF_STACK_OF(WOLFSSL_X509)*)XMALLOC(
63096             sizeof(WOLF_STACK_OF(WOLFSSL_X509)), heap, DYNAMIC_TYPE_X509);
63097         if (*ca == NULL) {
63098             if (pk != NULL) {
63099                 XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
63100             }
63101             if (certData != NULL) {
63102                 XFREE(*cert, heap, DYNAMIC_TYPE_PKCS); *cert = NULL;
63103             }
63104             /* Free up WC_DerCertList and move on */
63105             while (current != NULL) {
63106                 WC_DerCertList* next = current->next;
63107 
63108                 XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
63109                 XFREE(current, heap, DYNAMIC_TYPE_PKCS);
63110                 current = next;
63111             }
63112             return WOLFSSL_FAILURE;
63113         }
63114         XMEMSET(*ca, 0, sizeof(WOLF_STACK_OF(WOLFSSL_X509)));
63115 
63116         /* add list of DER certs as X509's to stack */
63117         while (current != NULL) {
63118             WC_DerCertList*  toFree = current;
63119             WOLFSSL_X509* x509;
63120 
63121             x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
63122                 DYNAMIC_TYPE_X509);
63123             InitX509(x509, 1, heap);
63124             InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap);
63125             if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
63126                 WOLFSSL_MSG("Issue with parsing certificate");
63127                 FreeDecodedCert(&DeCert);
63128                 wolfSSL_X509_free(x509);
63129             }
63130             else {
63131                 if (CopyDecodedToX509(x509, &DeCert) != 0) {
63132                     WOLFSSL_MSG("Failed to copy decoded cert");
63133                     FreeDecodedCert(&DeCert);
63134                     wolfSSL_X509_free(x509);
63135                     wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
63136                     if (pk != NULL) {
63137                         XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
63138                     }
63139                     if (certData != NULL) {
63140                         XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
63141                     }
63142                     /* Free up WC_DerCertList */
63143                     while (current != NULL) {
63144                         WC_DerCertList* next = current->next;
63145 
63146                         XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
63147                         XFREE(current, heap, DYNAMIC_TYPE_PKCS);
63148                         current = next;
63149                     }
63150                     return WOLFSSL_FAILURE;
63151                 }
63152                 FreeDecodedCert(&DeCert);
63153 
63154                 if (wolfSSL_sk_X509_push(*ca, x509) != 1) {
63155                     WOLFSSL_MSG("Failed to push x509 onto stack");
63156                     wolfSSL_X509_free(x509);
63157                     wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
63158                     if (pk != NULL) {
63159                         XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
63160                     }
63161                     if (certData != NULL) {
63162                         XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
63163                     }
63164 
63165                     /* Free up WC_DerCertList */
63166                     while (current != NULL) {
63167                         WC_DerCertList* next = current->next;
63168 
63169                         XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
63170                         XFREE(current, heap, DYNAMIC_TYPE_PKCS);
63171                         current = next;
63172                     }
63173                     return WOLFSSL_FAILURE;
63174                 }
63175             }
63176             current = current->next;
63177             XFREE(toFree->buffer, heap, DYNAMIC_TYPE_PKCS);
63178             XFREE(toFree, heap, DYNAMIC_TYPE_PKCS);
63179         }
63180     }
63181 
63182 
63183     /* Decode cert and place in X509 struct */
63184     if (certData != NULL) {
63185         *cert = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
63186             DYNAMIC_TYPE_X509);
63187         if (*cert == NULL) {
63188             if (pk != NULL) {
63189                 XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
63190             }
63191             if (ca != NULL) {
63192                 wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
63193             }
63194             XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
63195             return WOLFSSL_FAILURE;
63196         }
63197         InitX509(*cert, 1, heap);
63198         InitDecodedCert(&DeCert, certData, certDataSz, heap);
63199         if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
63200             WOLFSSL_MSG("Issue with parsing certificate");
63201         }
63202         if (CopyDecodedToX509(*cert, &DeCert) != 0) {
63203             WOLFSSL_MSG("Failed to copy decoded cert");
63204             FreeDecodedCert(&DeCert);
63205             if (pk != NULL) {
63206                 XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
63207             }
63208             if (ca != NULL) {
63209                 wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
63210             }
63211             wolfSSL_X509_free(*cert); *cert = NULL;
63212             return WOLFSSL_FAILURE;
63213         }
63214         FreeDecodedCert(&DeCert);
63215         XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
63216     }
63217 
63218 
63219     /* get key type */
63220     ret = BAD_STATE_E;
63221     if (pk != NULL) { /* decode key if present */
63222         *pkey = wolfSSL_EVP_PKEY_new_ex(heap);
63223         if (*pkey == NULL) {
63224             wolfSSL_X509_free(*cert); *cert = NULL;
63225             if (ca != NULL) {
63226                 wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
63227             }
63228             XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
63229             return WOLFSSL_FAILURE;
63230         }
63231     #ifndef NO_RSA
63232         {
63233             word32 keyIdx = 0;
63234         #ifdef WOLFSSL_SMALL_STACK
63235             RsaKey *key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
63236             if (key == NULL)
63237                 return WOLFSSL_FAILURE;
63238         #else
63239             RsaKey key[1];
63240         #endif
63241 
63242             if (wc_InitRsaKey(key, heap) != 0) {
63243                 ret = BAD_STATE_E;
63244             }
63245             else {
63246                 if ((ret = wc_RsaPrivateKeyDecode(pk, &keyIdx, key, pkSz))
63247                                                                          == 0) {
63248                     (*pkey)->type = EVP_PKEY_RSA;
63249                     (*pkey)->rsa  = wolfSSL_RSA_new();
63250                     (*pkey)->ownRsa = 1; /* we own RSA */
63251                     if ((*pkey)->rsa == NULL) {
63252                         WOLFSSL_MSG("issue creating EVP RSA key");
63253                         wolfSSL_X509_free(*cert); *cert = NULL;
63254                         if (ca != NULL) {
63255                             wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
63256                         }
63257                         wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
63258                         XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
63259                     #ifdef WOLFSSL_SMALL_STACK
63260                         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
63261                     #endif
63262                         return WOLFSSL_FAILURE;
63263                     }
63264                     if (wolfSSL_RSA_LoadDer_ex((*pkey)->rsa, pk, pkSz,
63265                                      WOLFSSL_RSA_LOAD_PRIVATE) != SSL_SUCCESS) {
63266                         WOLFSSL_MSG("issue loading RSA key");
63267                         wolfSSL_X509_free(*cert); *cert = NULL;
63268                         if (ca != NULL) {
63269                             wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
63270                         }
63271                         wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
63272                         XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
63273                     #ifdef WOLFSSL_SMALL_STACK
63274                         XFREE(key, NULL, DYNAMIC_TYPE_RSA);
63275                     #endif
63276                         return WOLFSSL_FAILURE;
63277                     }
63278 
63279                     WOLFSSL_MSG("Found PKCS12 RSA key");
63280                     ret = 0; /* set in success state for upcoming ECC check */
63281                 }
63282                 wc_FreeRsaKey(key);
63283             }
63284         #ifdef WOLFSSL_SMALL_STACK
63285             XFREE(key, NULL, DYNAMIC_TYPE_RSA);
63286         #endif
63287         }
63288     #endif /* NO_RSA */
63289 
63290     #ifdef HAVE_ECC
63291         {
63292             word32  keyIdx = 0;
63293         #ifdef WOLFSSL_SMALL_STACK
63294             ecc_key *key = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
63295             if (key == NULL)
63296                 return WOLFSSL_FAILURE;
63297         #else
63298             ecc_key key[1];
63299         #endif
63300 
63301             if (ret != 0) { /* if is in fail state check if ECC key */
63302                 if (wc_ecc_init(key) != 0) {
63303                     wolfSSL_X509_free(*cert); *cert = NULL;
63304                     if (ca != NULL) {
63305                         wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
63306                     }
63307                     wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
63308                     XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
63309                 #ifdef WOLFSSL_SMALL_STACK
63310                     XFREE(key, NULL, DYNAMIC_TYPE_ECC);
63311                 #endif
63312                     return WOLFSSL_FAILURE;
63313                 }
63314 
63315                 if ((ret = wc_EccPrivateKeyDecode(pk, &keyIdx, key, pkSz))
63316                                                                          != 0) {
63317                     wolfSSL_X509_free(*cert); *cert = NULL;
63318                     if (ca != NULL) {
63319                         wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
63320                     }
63321                     wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
63322                     XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
63323                     WOLFSSL_MSG("Bad PKCS12 key format");
63324                 #ifdef WOLFSSL_SMALL_STACK
63325                     XFREE(key, NULL, DYNAMIC_TYPE_ECC);
63326                 #endif
63327                     return WOLFSSL_FAILURE;
63328                 }
63329                 (*pkey)->type = EVP_PKEY_EC;
63330                 (*pkey)->pkey_curve = key->dp->oidSum;
63331                 wc_ecc_free(key);
63332                 WOLFSSL_MSG("Found PKCS12 ECC key");
63333             }
63334         #ifdef WOLFSSL_SMALL_STACK
63335             XFREE(key, NULL, DYNAMIC_TYPE_ECC);
63336         #endif
63337         }
63338     #else
63339         if (ret != 0) { /* if is in fail state and no ECC then fail */
63340             wolfSSL_X509_free(*cert); *cert = NULL;
63341             if (ca != NULL) {
63342                 wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
63343             }
63344             wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
63345             XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
63346             WOLFSSL_MSG("Bad PKCS12 key format");
63347             return WOLFSSL_FAILURE;
63348         }
63349     #endif /* HAVE_ECC */
63350 
63351         (*pkey)->save_type = 0;
63352         (*pkey)->pkey_sz   = pkSz;
63353         (*pkey)->pkey.ptr  = (char*)pk;
63354     }
63355 
63356     (void)ret;
63357     (void)ca;
63358 
63359     return WOLFSSL_SUCCESS;
63360 }
63361 
63362 int wolfSSL_PKCS12_verify_mac(WC_PKCS12 *pkcs12, const char *psw,
63363         int pswLen)
63364 {
63365     WOLFSSL_ENTER("wolfSSL_PKCS12_verify_mac");
63366 
63367     if (!pkcs12) {
63368         return WOLFSSL_FAILURE;
63369     }
63370 
63371     return wc_PKCS12_verify_ex(pkcs12, (const byte*)psw, pswLen) == 0 ?
63372             WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
63373 }
63374 
63375 #endif /* !NO_ASN && !NO_PWDBASED */
63376 
63377 #endif /* OPENSSL_EXTRA */
63378 
63379 #endif /* HAVE_PKCS12 */
63380 /*******************************************************************************
63381  * END OF PKCS12 APIs
63382  ******************************************************************************/
63383 
63384 #endif /* !NO_CERTS */
63385 
63386 #endif /* !WOLFCRYPT_ONLY */
63387 
63388 /*******************************************************************************
63389  * START OF CRYPTO-ONLY APIs
63390  ******************************************************************************/
63391 
63392 #if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
63393     defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
63394     defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
63395     defined(WOLFSSL_HAPROXY)
63396 
63397 #ifndef NO_SHA
63398     /* One shot SHA1 hash of message.
63399      *
63400      * d  message to hash
63401      * n  size of d buffer
63402      * md buffer to hold digest. Should be SHA_DIGEST_SIZE.
63403      *
63404      * Note: if md is null then a static buffer of SHA_DIGEST_SIZE is used.
63405      *       When the static buffer is used this function is not thread safe.
63406      *
63407      * Returns a pointer to the message digest on success and NULL on failure.
63408      */
63409     unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n,
63410             unsigned char *md)
63411     {
63412         static byte dig[WC_SHA_DIGEST_SIZE];
63413         byte* ret = md;
63414         wc_Sha sha;
63415 
63416         WOLFSSL_ENTER("wolfSSL_SHA1");
63417 
63418         if (wc_InitSha_ex(&sha, NULL, INVALID_DEVID) != 0) {
63419             WOLFSSL_MSG("SHA1 Init failed");
63420             return NULL;
63421         }
63422 
63423         if (wc_ShaUpdate(&sha, (const byte*)d, (word32)n) != 0) {
63424             WOLFSSL_MSG("SHA1 Update failed");
63425             return NULL;
63426         }
63427 
63428         if (md == NULL) {
63429             WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA1 IS NOT "
63430                         "THREAD SAFE WHEN md == NULL");
63431             ret = dig;
63432         }
63433         if (wc_ShaFinal(&sha, ret) != 0) {
63434             WOLFSSL_MSG("SHA1 Final failed");
63435             wc_ShaFree(&sha);
63436             return NULL;
63437         }
63438         wc_ShaFree(&sha);
63439 
63440         return ret;
63441     }
63442 #endif /* ! NO_SHA */
63443 
63444 #ifdef WOLFSSL_SHA224
63445     /* One shot SHA224 hash of message.
63446      *
63447      * d  message to hash
63448      * n  size of d buffer
63449      * md buffer to hold digest. Should be WC_SHA224_DIGEST_SIZE.
63450      *
63451      * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
63452      *       When the static buffer is used this function is not thread safe.
63453      *
63454      * Returns a pointer to the message digest on success and NULL on failure.
63455      */
63456       unsigned char *wolfSSL_SHA224(const unsigned char *d, size_t n,
63457             unsigned char *md)
63458      {
63459         static byte dig[WC_SHA224_DIGEST_SIZE];
63460         byte* ret = md;
63461         wc_Sha256 sha;
63462 
63463         WOLFSSL_ENTER("wolfSSL_SHA224");
63464 
63465         if (wc_InitSha224_ex(&sha, NULL, INVALID_DEVID) != 0) {
63466             WOLFSSL_MSG("SHA224 Init failed");
63467             return NULL;
63468         }
63469 
63470         if (wc_Sha224Update(&sha, (const byte*)d, (word32)n) != 0) {
63471             WOLFSSL_MSG("SHA224 Update failed");
63472             return NULL;
63473         }
63474 
63475         if (md == NULL) {
63476             WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA224 IS NOT "
63477                         "THREAD SAFE WHEN md == NULL");
63478             ret = dig;
63479         }
63480         if (wc_Sha224Final(&sha, ret) != 0) {
63481             WOLFSSL_MSG("SHA224 Final failed");
63482             wc_Sha224Free(&sha);
63483             return NULL;
63484         }
63485         wc_Sha224Free(&sha);
63486 
63487         return ret;
63488     }
63489 #endif
63490 
63491 #ifndef NO_SHA256
63492     /* One shot SHA256 hash of message.
63493      *
63494      * d  message to hash
63495      * n  size of d buffer
63496      * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
63497      *
63498      * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
63499      *       When the static buffer is used this function is not thread safe.
63500      *
63501      * Returns a pointer to the message digest on success and NULL on failure.
63502      */
63503     unsigned char *wolfSSL_SHA256(const unsigned char *d, size_t n,
63504             unsigned char *md)
63505     {
63506         static byte dig[WC_SHA256_DIGEST_SIZE];
63507         byte* ret = md;
63508         wc_Sha256 sha;
63509 
63510         WOLFSSL_ENTER("wolfSSL_SHA256");
63511 
63512         if (wc_InitSha256_ex(&sha, NULL, INVALID_DEVID) != 0) {
63513             WOLFSSL_MSG("SHA256 Init failed");
63514             return NULL;
63515         }
63516 
63517         if (wc_Sha256Update(&sha, (const byte*)d, (word32)n) != 0) {
63518             WOLFSSL_MSG("SHA256 Update failed");
63519             return NULL;
63520         }
63521 
63522         if (md == NULL) {
63523             WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA256 IS NOT "
63524                         "THREAD SAFE WHEN md == NULL");
63525             ret = dig;
63526         }
63527         if (wc_Sha256Final(&sha, ret) != 0) {
63528             WOLFSSL_MSG("SHA256 Final failed");
63529             wc_Sha256Free(&sha);
63530             return NULL;
63531         }
63532         wc_Sha256Free(&sha);
63533 
63534         return ret;
63535     }
63536 #endif /* ! NO_SHA256 */
63537 
63538 #ifdef WOLFSSL_SHA384
63539      /* One shot SHA384 hash of message.
63540       *
63541       * d  message to hash
63542       * n  size of d buffer
63543       * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
63544       *
63545       * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
63546       *       When the static buffer is used this function is not thread safe.
63547       *
63548       * Returns a pointer to the message digest on success and NULL on failure.
63549       */
63550      unsigned char *wolfSSL_SHA384(const unsigned char *d, size_t n,
63551              unsigned char *md)
63552      {
63553          static byte dig[WC_SHA384_DIGEST_SIZE];
63554          byte* ret = md;
63555          wc_Sha384 sha;
63556 
63557          WOLFSSL_ENTER("wolfSSL_SHA384");
63558 
63559          if (wc_InitSha384_ex(&sha, NULL, INVALID_DEVID) != 0) {
63560              WOLFSSL_MSG("SHA384 Init failed");
63561              return NULL;
63562          }
63563 
63564          if (wc_Sha384Update(&sha, (const byte*)d, (word32)n) != 0) {
63565              WOLFSSL_MSG("SHA384 Update failed");
63566              return NULL;
63567          }
63568 
63569          if (md == NULL) {
63570              WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA384 IS NOT "
63571                          "THREAD SAFE WHEN md == NULL");
63572              ret = dig;
63573          }
63574          if (wc_Sha384Final(&sha, ret) != 0) {
63575              WOLFSSL_MSG("SHA384 Final failed");
63576              wc_Sha384Free(&sha);
63577              return NULL;
63578          }
63579          wc_Sha384Free(&sha);
63580 
63581          return ret;
63582      }
63583 #endif /* WOLFSSL_SHA384  */
63584 
63585 #if defined(WOLFSSL_SHA512)
63586      /* One shot SHA512 hash of message.
63587       *
63588       * d  message to hash
63589       * n  size of d buffer
63590       * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
63591       *
63592       * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
63593       *       When the static buffer is used this function is not thread safe.
63594       *
63595       * Returns a pointer to the message digest on success and NULL on failure.
63596       */
63597      unsigned char *wolfSSL_SHA512(const unsigned char *d, size_t n,
63598              unsigned char *md)
63599      {
63600          static byte dig[WC_SHA512_DIGEST_SIZE];
63601          byte* ret = md;
63602          wc_Sha512 sha;
63603 
63604          WOLFSSL_ENTER("wolfSSL_SHA512");
63605 
63606          if (wc_InitSha512_ex(&sha, NULL, INVALID_DEVID) != 0) {
63607              WOLFSSL_MSG("SHA512 Init failed");
63608              return NULL;
63609          }
63610 
63611          if (wc_Sha512Update(&sha, (const byte*)d, (word32)n) != 0) {
63612              WOLFSSL_MSG("SHA512 Update failed");
63613              return NULL;
63614          }
63615 
63616          if (md == NULL) {
63617              WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA512 IS NOT "
63618                          "THREAD SAFE WHEN md == NULL");
63619              ret = dig;
63620          }
63621          if (wc_Sha512Final(&sha, ret) != 0) {
63622              WOLFSSL_MSG("SHA512 Final failed");
63623              wc_Sha512Free(&sha);
63624              return NULL;
63625          }
63626          wc_Sha512Free(&sha);
63627 
63628          return ret;
63629      }
63630 #endif /* WOLFSSL_SHA512 */
63631 #endif /* OPENSSL_EXTRA || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
63632         * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
63633 
63634 /*******************************************************************************
63635  * END OF CRYPTO-ONLY APIs
63636  ******************************************************************************/
63637